64 return "tap-windows6";
91const static GUID
GUID_DEVCLASS_NET = { 0x4d36e972L, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
92const static GUID
GUID_DEVINTERFACE_NET = { 0xcac88484, 0x7515, 0x4c03, { 0x82, 0xe6, 0x71, 0xa8, 0x7a, 0xba, 0xc3, 0x61 } };
96#define NI_TEST_FIRST (1<<0)
97#define NI_IP_NETMASK (1<<1)
98#define NI_OPTIONS (1<<2)
103 const in_addr_t netmask,
104 const unsigned int flags);
112 DWORD adapter_index);
116static void exec_command(
const char *prefix,
const struct argv *a,
int n,
int msglevel);
144 if (addr.
family == AF_INET)
149 add ?
"add" :
"remove",
157 add ?
"add" :
"remove",
168 msg(
M_WARN,
"TUN: %s address failed using service: %s [status=%u if_index=%d]",
219 size_t dstlen = strlen(
dns.domains);
221 size_t extra = dstlen ? 2 : 1;
222 if (dstlen + srclen + extra >
sizeof(
dns.domains))
224 msg(
M_WARN,
"DNS search domains sent to service truncated to %d", i);
229 dns.domains[dstlen++] =
',';
234 msg(
D_LOW,
"%s DNS domains on '%s' (if_index = %d) using service",
235 (add ?
"Setting" :
"Deleting"),
dns.iface.name,
dns.iface.index);
243 msg(
M_WARN,
"TUN: %s DNS domains failed using service: %s [status=%u if_name=%s]",
249 msg(
M_INFO,
"DNS domains %s using service", (add ?
"set" :
"deleted"));
262 int addr_len = add ? len : 0;
263 const char *ip_proto_name = family == AF_INET6 ?
"IPv6" :
"IPv4";
288 if (addr_len > _countof(dns.
addr))
290 addr_len = _countof(dns.
addr);
292 msg(
M_WARN,
"Number of %s DNS addresses sent to service truncated to %d",
293 ip_proto_name, addr_len);
296 for (
int i = 0; i < addr_len; ++i)
298 if (family == AF_INET6)
308 msg(
D_LOW,
"%s %s dns servers on '%s' (if_index = %d) using service",
318 msg(
M_WARN,
"TUN: %s %s dns failed using service: %s [status=%u if_name=%s]",
324 msg(
M_INFO,
"%s dns servers %s using service", ip_proto_name, (add ?
"set" :
"deleted"));
358 if (addr_len > _countof(wins.
addr))
360 addr_len = _countof(wins.
addr);
362 msg(
M_WARN,
"Number of WINS addresses sent to service truncated to %d",
366 for (
int i = 0; i < addr_len; ++i)
371 msg(
D_LOW,
"%s WINS servers on '%s' (if_index = %d) using service",
381 msg(
M_WARN,
"TUN: %s WINS failed using service: %s [status=%u if_name=%s]",
387 msg(
M_INFO,
"WINS servers %s using service", (add ?
"set" :
"deleted"));
400 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
412 if (family == AF_INET6 && mtu < 1280)
414 msg(
M_INFO,
"NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
424 msg(
M_NONFATAL,
"TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]",
429 msg(
M_INFO,
"%s MTU set to %d on interface %d using service", family_name, mtu, mtu_msg.
iface.
index);
447 argv_printf(&
argv,
"%s%s nicconfig where (InterfaceIndex=%ld) call SetDNSDomain '%s'",
505 msg(
M_NONFATAL,
"TUN: creating %s adapter using service failed: %s [status=%u]",
522static void solaris_error_close(
struct tuntap *tt,
const struct env_set *
es,
const char *actual,
bool unplumb_inet6);
527#if defined(TARGET_DARWIN)
528#include <sys/kern_control.h>
529#include <net/if_utun.h>
530#include <sys/sys_domain.h>
536is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type)
545 return !strcmp(dev_type, match_type);
549 return !strncmp(dev, match_type, strlen(match_type));
536is_dev_type(
const char *dev,
const char *dev_type,
const char *match_type) {
…}
584 return "[unknown-dev-type]";
594 const char *dev_type,
595 const char *dev_node,
625 const bool looks_like_netmask = ((addr & 0xFF000000) == 0xFF000000);
628 if (looks_like_netmask)
630 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",
637 if (!looks_like_netmask)
639 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",
655 in_addr_t remote_netmask)
659 msg(
M_INFO,
"CHECK_ADDR_CLASH type=%d public=%s local=%s, remote_netmask=%s",
670 const in_addr_t test_netmask = 0xFFFFFF00;
671 const in_addr_t public_net =
public &test_netmask;
672 const in_addr_t local_net = local & test_netmask;
673 const in_addr_t remote_net = remote_netmask & test_netmask;
675 if (
public == local ||
public == remote_netmask)
678 "WARNING: --%s address [%s] conflicts with --ifconfig address pair [%s, %s]. %s",
686 if (public_net == local_net || public_net == remote_net)
689 "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",
699 const in_addr_t public_network =
public &remote_netmask;
700 const in_addr_t virtual_network = local & remote_netmask;
701 if (public_network == virtual_network)
704 "WARNING: --%s address [%s] conflicts with --ifconfig subnet [%s, %s] -- local and remote addresses cannot be inside of the --ifconfig subnet. %s",
724 if ((rgi.
flags & needed) == needed)
727 if (lan_network == 0xC0A80000 || lan_network == 0xC0A80100)
729 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.");
743 if (
tt->did_ifconfig_setup && !disable)
828 msg(
M_FATAL,
"Error: problem with tun vs. tap setting");
853 setenv_str(
es,
"ifconfig_remote", ifconfig_remote_netmask);
857 setenv_str(
es,
"ifconfig_netmask", ifconfig_remote_netmask);
866 setenv_str(
es,
"ifconfig_ipv6_local", ifconfig_ipv6_local);
868 setenv_str(
es,
"ifconfig_ipv6_remote", ifconfig_ipv6_remote);
882 const char *dev_type,
884 const char *ifconfig_local_parm,
885 const char *ifconfig_remote_netmask_parm,
886 const char *ifconfig_ipv6_local_parm,
887 int ifconfig_ipv6_netbits_parm,
888 const char *ifconfig_ipv6_remote_parm,
889 struct addrinfo *local_public,
890 struct addrinfo *remote_public,
891 const bool strict_warn,
905 if (ifconfig_local_parm && ifconfig_remote_netmask_parm)
931 ifconfig_remote_netmask_parm,
941 struct addrinfo *curele;
949 for (curele = local_public; curele; curele = curele->ai_next)
951 if (curele->ai_family == AF_INET)
953 const in_addr_t local = ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
962 for (curele = remote_public; curele; curele = curele->ai_next)
964 if (curele->ai_family == AF_INET)
966 const in_addr_t remote = ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
995 if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm)
1002 if (inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->
local_ipv6 ) != 1
1003 || inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->
remote_ipv6 ) != 1)
1005 msg(
M_FATAL,
"init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm );
1058 msg(
M_FATAL,
"Cannot allocate memory for ring buffer");
1066 msg(
M_FATAL,
"Cannot create events for ring buffer");
1115#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1116 || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
1127create_arbitrary_remote(
struct tuntap *tt )
1133 if (remote == tt->
local)
1155#if !defined(TARGET_LINUX)
1161#if defined(TARGET_LINUX)
1162 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1164 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1167 if (net_iface_up(ctx, ifname,
true) < 0)
1169 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1172 if (net_addr_v6_add(ctx, ifname, &tt->
local_ipv6,
1175 msg(
M_FATAL,
"Linux can't add IPv6 to interface %s", ifname);
1177#elif defined(TARGET_ANDROID)
1180 snprintf(out6,
sizeof(out6),
"%s/%d %d",
1182 management_android_control(
management,
"IFCONFIG6", out6);
1183#elif defined(TARGET_SOLARIS)
1203 "Solaris ifconfig IPv6 (prepare) failed"))
1205 solaris_error_close(tt,
es, ifname,
true);
1224 solaris_error_close(tt,
es, ifname,
true);
1234#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
1235 || defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) \
1236 || defined(TARGET_DRAGONFLY)
1242 "generic BSD ifconfig inet6 failed");
1244#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 \
1245 && __FreeBSD_version < 1300000
1265 "FreeBSD BSD 'ifconfig inet6 -ifdisabled' failed");
1268#elif defined(TARGET_AIX)
1278 "generic BSD ifconfig inet6 failed");
1281#elif defined (_WIN32)
1284 msg(
M_INFO,
"******** NOTE: Please manually set the v6 IP of '%s' to %s (if it is not already set)",
1285 ifname, ifconfig_ipv6_local);
1314 argv_printf(&
argv,
"%s%s interface ipv6 set address %lu %s/%d store=active",
1316 ifconfig_ipv6_local, netbits);
1332 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.");
1335#if !defined(TARGET_LINUX)
1354#if !defined(_WIN32) && !defined(TARGET_ANDROID)
1361#if !defined(TARGET_LINUX)
1362 const char *ifconfig_local = NULL;
1363 const char *ifconfig_remote_netmask = NULL;
1374#if defined(TARGET_LINUX)
1375 if (net_iface_mtu_set(ctx, ifname, tun_mtu) < 0)
1377 msg(
M_FATAL,
"Linux can't set mtu (%d) on %s", tun_mtu, ifname);
1380 if (net_iface_up(ctx, ifname,
true) < 0)
1382 msg(
M_FATAL,
"Linux can't bring %s up", ifname);
1387 if (net_addr_ptp_v4_add(ctx, ifname, &tt->
local,
1390 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1395 if (net_addr_v4_add(ctx, ifname, &tt->
local,
1398 msg(
M_FATAL,
"Linux can't add IP to interface %s", ifname);
1401#elif defined(TARGET_ANDROID)
1404 snprintf(out,
sizeof(out),
"%s %s %d %s", ifconfig_local,
1406 management_android_control(
management,
"IFCONFIG", out);
1408#elif defined(TARGET_SOLARIS)
1417 ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1422 solaris_error_close(tt,
es, ifname,
false);
1431 ifname, ifconfig_local, ifconfig_local,
1432 ifconfig_remote_netmask, tun_mtu);
1438 ifconfig_remote_netmask);
1444 solaris_error_close(tt,
es, ifname,
false);
1460#elif defined(TARGET_OPENBSD)
1462 in_addr_t remote_end;
1474 "%s %s %s %s mtu %d netmask 255.255.255.255 up -link0",
1476 ifconfig_remote_netmask, tun_mtu);
1480 remote_end = create_arbitrary_remote( tt );
1484 ifconfig_remote_netmask);
1490 ifconfig_remote_netmask, tun_mtu);
1507#elif defined(TARGET_NETBSD)
1508 in_addr_t remote_end = INADDR_ANY;
1514 ifconfig_remote_netmask, tun_mtu);
1518 remote_end = create_arbitrary_remote(tt);
1521 tun_mtu, ifconfig_remote_netmask);
1532 ifconfig_remote_netmask, tun_mtu);
1549#elif defined(TARGET_DARWIN)
1558 "NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure");
1566 ifconfig_remote_netmask, tun_mtu);
1572 ifconfig_remote_netmask, tun_mtu);
1577 ifname, ifconfig_local, ifconfig_remote_netmask,
1596#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
1603 ifconfig_remote_netmask, tun_mtu);
1609 ifname, ifconfig_local, netbits, tun_mtu );
1615#elif defined(TARGET_AIX)
1623 msg(
M_FATAL,
"no tun support on AIX (canthappen)");
1628 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1635#elif defined (_WIN32)
1639 "******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
1640 ifname, ifconfig_local,
1641 ifconfig_remote_netmask);
1674#elif defined(TARGET_HAIKU)
1677 ifname, ifconfig_local, ifconfig_remote_netmask, tun_mtu);
1682 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.");
1685#if !defined(TARGET_LINUX)
1699#ifdef ENABLE_MANAGEMENT
1729#if defined(TARGET_LINUX)
1737 msg(
M_WARN,
"Linux can't del IP from iface %s",
1745 msg(
M_WARN,
"Linux can't del IP from iface %s",
1749#elif defined(TARGET_FREEBSD)
1768#if defined(TARGET_LINUX)
1774#elif defined(TARGET_FREEBSD)
1820#ifdef TARGET_SOLARIS
1825#if defined(TARGET_OPENBSD) || defined(TARGET_DARWIN)
1845#include <netinet/ip.h>
1849header_modify_read_write_return(
int len)
1853 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
1862write_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1874 type = htonl(AF_INET6);
1878 type = htonl(AF_INET);
1881 iv[0].iov_base = &type;
1882 iv[0].iov_len =
sizeof(type);
1883 iv[1].iov_base = buf;
1884 iv[1].iov_len = len;
1886 return header_modify_read_write_return(writev(tt->fd, iv, 2));
1890 return write(tt->fd, buf, len);
1895read_tun_header(
struct tuntap *tt, uint8_t *buf,
int len)
1902 iv[0].iov_base = &type;
1903 iv[0].iov_len =
sizeof(type);
1904 iv[1].iov_base = buf;
1905 iv[1].iov_len = len;
1907 return header_modify_read_write_return(readv(tt->fd, iv, 2));
1911 return read(tt->fd, buf, len);
1922#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
1924tun_dco_enabled(
struct tuntap *tt)
1931#if !(defined(_WIN32) || defined(TARGET_LINUX) || defined(TARGET_SOLARIS))
1933open_tun_generic(
const char *dev,
const char *dev_type,
const char *dev_node,
1937 char dynamic_name[256];
1938 bool dynamic_opened =
false;
1945 snprintf(tunname,
sizeof(tunname),
"%s", dev_node);
1957 for (
int i = 0; i < 256; ++i)
1961#if defined(TARGET_HAIKU)
1964 snprintf(tunname,
sizeof(tunname),
1965 "/dev/%s%s%d", dev, sep, i);
1966 snprintf(dynamic_name,
sizeof(dynamic_name),
1967 "%s%s%d", dev, sep, i);
1968 if ((tt->fd = open(tunname, O_RDWR)) > 0)
1970 dynamic_opened =
true;
1975 if (!dynamic_opened)
1977 msg(
M_FATAL,
"Cannot allocate TUN/TAP dev dynamically");
1985 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
1989 if (!dynamic_opened)
1992 if (if_nametoindex( dev ) > 0)
1994 msg(
M_INFO,
"TUN/TAP device %s exists previously, keep at program end", dev );
1998 if ((tt->fd = open(tunname, O_RDWR)) < 0)
2000 msg(
M_ERR,
"Cannot open TUN/TAP dev %s", tunname);
2006 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
2014#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2016open_tun_dco_generic(
const char *dev,
const char *dev_type,
2019 char dynamic_name[256];
2020 bool dynamic_opened =
false;
2030 if (strcmp(dev,
"tun") == 0)
2032 for (
int i = 0; i < 256; ++i)
2034 snprintf(dynamic_name,
sizeof(dynamic_name),
2039 dynamic_opened =
true;
2040 msg(
M_INFO,
"DCO device %s opened", dynamic_name);
2044 else if (ret == -EPERM)
2049 if (!dynamic_opened)
2051 msg(
M_FATAL,
"Cannot allocate DCO dev dynamically");
2065 msg(
M_INFO,
"DCO device %s already exists, won't be destroyed at shutdown",
2071 msg(
M_ERR,
"Cannot open DCO device %s: %s (%d)", dev,
2072 strerror(-ret), ret);
2076 msg(
M_INFO,
"DCO device %s opened", dev);
2085#if !(defined(_WIN32) || defined(TARGET_SOLARIS))
2087close_tun_generic(
struct tuntap *tt)
2099#if defined (TARGET_ANDROID)
2101open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2104#define ANDROID_TUNNAME "vpnservice-tun"
2109 int oldtunfd = tt->fd;
2115 management_android_control(
management,
"DNS6SERVER",
2121 management_android_control(
management,
"DNSSERVER",
2133 buf_printf(&buf,
"%s %d",
tt->options.http_proxy,
tt->options.http_proxy_port);
2163 msg(
M_ERR,
"ERROR: Cannot open TUN");
2190#elif defined(TARGET_LINUX)
2192#ifndef HAVE_LINUX_SOCKIOS_H
2193#error header file linux/sockios.h required
2199open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *
tt,
2204 if (tun_dco_enabled(tt))
2206 open_tun_dco_generic(dev, dev_type, tt, ctx);
2213 const char *node = dev_node;
2216 node =
"/dev/net/tun";
2222 if ((tt->fd = open(node, O_RDWR)) < 0)
2224 msg(
M_ERR,
"ERROR: Cannot open TUN/TAP dev %s", node);
2231 ifr.ifr_flags = IFF_NO_PI;
2233#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2234 ifr.ifr_flags |= IFF_ONE_QUEUE;
2242 ifr.ifr_flags |= IFF_TUN;
2246 ifr.ifr_flags |= IFF_TAP;
2250 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device",
2257 if (strcmp(dev,
"tun") && strcmp(dev,
"tap"))
2266 if (ioctl(tt->fd, TUNSETIFF, (
void *) &ifr) < 0)
2268 msg(
M_ERR,
"ERROR: Cannot ioctl TUNSETIFF %s", dev);
2271 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2276#if defined(IFF_ONE_QUEUE) && defined(SIOCSIFTXQLEN)
2279 struct ifreq netifr;
2282 if ((ctl_fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0)
2285 strncpynt(netifr.ifr_name, ifr.ifr_name, IFNAMSIZ);
2286 netifr.ifr_qlen = tt->
options.txqueuelen;
2287 if (ioctl(ctl_fd, SIOCSIFTXQLEN, (
void *) &netifr) >= 0)
2293 msg(
M_WARN |
M_ERRNO,
"Note: Cannot set tx queue length on %s", ifr.ifr_name);
2299 msg(
M_WARN |
M_ERRNO,
"Note: Cannot open control socket on %s", ifr.ifr_name);
2314open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2322#ifdef ENABLE_FEATURE_TUN_PERSIST
2326#define TUNSETGROUP _IOW('T', 206, int)
2330tuncfg(
const char *dev,
const char *dev_type,
const char *dev_node,
2331 int persist_mode,
const char *username,
const char *groupname,
2341 open_tun(dev, dev_type, dev_node, tt, ctx);
2342 if (ioctl(tt->fd, TUNSETPERSIST, persist_mode) < 0)
2344 msg(
M_ERR,
"Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev);
2346 if (username != NULL)
2352 msg(
M_ERR,
"Cannot get user entry for %s", username);
2356 msg(
M_ERR,
"Cannot ioctl TUNSETOWNER(%s) %s", username, dev);
2359 if (groupname != NULL)
2365 msg(
M_ERR,
"Cannot get group entry for %s", groupname);
2369 msg(
M_ERR,
"Cannot ioctl TUNSETGROUP(%s) %s", groupname, dev);
2373 msg(
M_INFO,
"Persist state set to: %s", (persist_mode ?
"ON" :
"OFF"));
2383#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
2384 if (tun_dco_enabled(tt))
2389 close_tun_generic(tt);
2396 return write(tt->fd, buf, len);
2402 return read(tt->fd, buf, len);
2405#elif defined(TARGET_SOLARIS)
2408#error I need the symbol TUNNEWPPA from net/if_tun.h
2412open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2415 int if_fd = -1, ip_muxid = -1, arp_muxid = -1, arp_fd = -1, ppa = -1;
2418 const char *ip_node = NULL, *arp_node = NULL;
2419 const char *dev_tuntap_type;
2421 struct strioctl strioc_if, strioc_ppa;
2431 ip_node =
"/dev/udp";
2434 dev_node =
"/dev/tun";
2436 dev_tuntap_type =
"tun";
2437 link_type = I_PLINK;
2441 ip_node =
"/dev/udp";
2444 dev_node =
"/dev/tap";
2446 arp_node = dev_node;
2447 dev_tuntap_type =
"tap";
2448 link_type = I_PLINK;
2452 msg(
M_FATAL,
"I don't recognize device %s as a tun or tap device",
2456 if ((tt->ip_fd = open(ip_node, O_RDWR, 0)) < 0)
2458 msg(
M_ERR,
"Can't open %s", ip_node);
2461 if ((tt->fd = open(dev_node, O_RDWR, 0)) < 0)
2463 msg(
M_ERR,
"Can't open %s", dev_node);
2471 while (*ptr && !isdigit((
int) *ptr))
2479 strioc_ppa.ic_cmd = TUNNEWPPA;
2480 strioc_ppa.ic_timout = 0;
2481 strioc_ppa.ic_len =
sizeof(ppa);
2482 strioc_ppa.ic_dp = (
char *)&ppa;
2486 bool found_one =
false;
2487 while (!found_one && ppa < 64)
2489 int new_ppa = ioctl(tt->fd, I_STR, &strioc_ppa);
2492 msg(
M_INFO,
"open_tun: got dynamic interface '%s%d'", dev_tuntap_type, new_ppa );
2497 if (errno != EEXIST)
2499 msg(
M_ERR,
"open_tun: unexpected error trying to find free %s interface", dev_tuntap_type );
2505 msg(
M_ERR,
"open_tun: could not find free %s interface, give up.", dev_tuntap_type );
2510 if ((ppa = ioctl(tt->fd, I_STR, &strioc_ppa)) < 0)
2512 msg(
M_ERR,
"Can't assign PPA for new interface (%s%d)", dev_tuntap_type, ppa );
2516 if ((if_fd = open(dev_node, O_RDWR, 0)) < 0)
2518 msg(
M_ERR,
"Can't open %s (2)", dev_node);
2521 if (ioctl(if_fd, I_PUSH,
"ip") < 0)
2523 msg(
M_ERR,
"Can't push IP module");
2529 if (ioctl(if_fd, IF_UNITSEL, (
char *) &ppa) < 0)
2531 msg(
M_ERR,
"Can't set PPA %d", ppa);
2538 snprintf(tt->
actual_name, 32,
"%s%d", dev_tuntap_type, ppa);
2542 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0)
2549 if (ioctl(if_fd, SIOCSLIFNAME, &ifr) < 0)
2551 msg(
M_ERR,
"Can't set PPA %d", ppa);
2553 if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0)
2558 if (ioctl(if_fd, I_PUSH,
"arp") < 0)
2560 msg(
M_ERR,
"Can't push ARP module");
2566 if (ioctl(tt->ip_fd, I_POP, NULL) < 0)
2572 if (ioctl(tt->ip_fd, I_PUSH,
"arp") < 0)
2574 msg(
M_ERR,
"Can't push ARP module\n");
2578 if ((arp_fd = open(arp_node, O_RDWR, 0)) < 0)
2580 msg(
M_ERR,
"Can't open %s\n", arp_node);
2583 if (ioctl(arp_fd, I_PUSH,
"arp") < 0)
2585 msg(
M_ERR,
"Can't push ARP module\n");
2589 strioc_if.ic_cmd = SIOCSLIFNAME;
2590 strioc_if.ic_timout = 0;
2591 strioc_if.ic_len =
sizeof(ifr);
2592 strioc_if.ic_dp = (
char *)𝔦
2593 if (ioctl(arp_fd, I_STR, &strioc_if) < 0)
2595 msg(
M_ERR,
"Can't set ifname to arp\n");
2599 if ((ip_muxid = ioctl(tt->ip_fd, link_type, if_fd)) < 0)
2601 msg(
M_ERR,
"Can't link %s device to IP", dev_tuntap_type);
2606 if ((arp_muxid = ioctl(tt->ip_fd, link_type, arp_fd)) < 0)
2608 msg(
M_ERR,
"Can't link %s device to ARP", dev_tuntap_type);
2615 ifr.lifr_ip_muxid = ip_muxid;
2618 ifr.lifr_arp_muxid = arp_muxid;
2621 if (ioctl(tt->ip_fd, SIOCSLIFMUXID, &ifr) < 0)
2625 ioctl(tt->ip_fd, I_PUNLINK, arp_muxid);
2627 ioctl(tt->ip_fd, I_PUNLINK, ip_muxid);
2628 msg(
M_ERR,
"Can't set multiplexor id");
2639solaris_close_tun(
struct tuntap *tt)
2658 if (ioctl(tt->ip_fd, SIOCGLIFFLAGS, &ifr) < 0)
2663 if (ioctl(tt->ip_fd, SIOCGLIFMUXID, &ifr) < 0)
2670 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_arp_muxid) < 0)
2676 if (ioctl(tt->ip_fd, I_PUNLINK, ifr.lifr_ip_muxid) < 0)
2700 solaris_close_tun(tt);
2710 const char *actual,
bool unplumb_inet6 )
2739 sbuf.buf = (
char *)buf;
2740 return putmsg(tt->fd, NULL, &sbuf, 0) >= 0 ? sbuf.len : -1;
2750 sbuf.buf = (
char *)buf;
2751 return getmsg(tt->fd, NULL, &sbuf, &f) >= 0 ? sbuf.len : -1;
2754#elif defined(TARGET_OPENBSD)
2757open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2760 open_tun_generic(dev, dev_type, dev_node, tt);
2765 struct tuninfo info;
2767 if (ioctl(tt->fd, TUNGIFINFO, &info) < 0)
2773 info.flags |= IFF_MULTICAST;
2776 if (ioctl(tt->fd, TUNSIFINFO, &info) < 0)
2801 close_tun_generic(tt);
2814 close_tun_generic(tt);
2826 return write_tun_header(tt, buf, len);
2832 return read_tun_header(tt, buf, len);
2835#elif defined(TARGET_NETBSD)
2852open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
2859 if (strcmp(dev,
"tap") == 0)
2862 if ((tt->fd = open(
"/dev/tap", O_RDWR)) < 0)
2864 msg(
M_FATAL,
"Cannot allocate NetBSD TAP dev dynamically");
2866 if (ioctl( tt->fd, TAPGIFNAME, (
void *)&ifr ) < 0)
2868 msg(
M_FATAL,
"Cannot query NetBSD TAP device name");
2872 msg(
M_INFO,
"TUN/TAP device %s opened", ifr.ifr_name);
2881 open_tun_generic(dev, dev_type, dev_node, tt);
2886 int i = IFF_POINTOPOINT|IFF_MULTICAST;
2887 ioctl(tt->fd, TUNSIFMODE, &i);
2889 ioctl(tt->fd, TUNSLMODE, &i);
2894 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
2915 close_tun_generic(tt);
2928 close_tun_generic(tt);
2938netbsd_modify_read_write_return(
int len)
2942 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
2963 type = htonl(AF_INET6);
2967 type = htonl(AF_INET);
2970 iv[0].iov_base = (
char *)&type;
2971 iv[0].iov_len =
sizeof(type);
2972 iv[1].iov_base = buf;
2973 iv[1].iov_len = len;
2975 return netbsd_modify_read_write_return(writev(tt->fd, iv, 2));
2979 return write(tt->fd, buf, len);
2991 iv[0].iov_base = (
char *)&type;
2992 iv[0].iov_len =
sizeof(type);
2993 iv[1].iov_base = buf;
2994 iv[1].iov_len = len;
2996 return netbsd_modify_read_write_return(readv(tt->fd, iv, 2));
3000 return read(tt->fd, buf, len);
3004#elif defined(TARGET_FREEBSD)
3007freebsd_modify_read_write_return(
int len)
3011 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
3020open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3023 if (tun_dco_enabled(tt))
3025 open_tun_dco_generic(dev, dev_type, tt, ctx);
3029 open_tun_generic(dev, dev_type, dev_node, tt);
3034 int i = IFF_POINTOPOINT | IFF_MULTICAST;
3037 i = IFF_BROADCAST | IFF_MULTICAST;
3040 if (ioctl(tt->fd, TUNSIFMODE, &i) < 0)
3047 if (ioctl(tt->fd, TUNSIFHEAD, &i) < 0)
3069 close_tun_generic(tt);
3083 close_tun_generic(tt);
3087 "FreeBSD 'destroy tun interface' failed (non-critical)");
3102 iph = (
struct ip *) buf;
3106 type = htonl(AF_INET6);
3110 type = htonl(AF_INET);
3113 iv[0].iov_base = (
char *)&type;
3114 iv[0].iov_len =
sizeof(type);
3115 iv[1].iov_base = buf;
3116 iv[1].iov_len = len;
3118 return freebsd_modify_read_write_return(writev(tt->fd, iv, 2));
3122 return write(tt->fd, buf, len);
3134 iv[0].iov_base = (
char *)&type;
3135 iv[0].iov_len =
sizeof(type);
3136 iv[1].iov_base = buf;
3137 iv[1].iov_len = len;
3139 return freebsd_modify_read_write_return(readv(tt->fd, iv, 2));
3143 return read(tt->fd, buf, len);
3147#elif defined(TARGET_DRAGONFLY)
3150dragonfly_modify_read_write_return(
int len)
3154 return len >
sizeof(u_int32_t) ? len -
sizeof(u_int32_t) : 0;
3163open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3166 open_tun_generic(dev, dev_type, dev_node, tt);
3173 ioctl(tt->fd, TUNSLMODE, &i);
3175 ioctl(tt->fd, TUNSIFHEAD, &i);
3184 close_tun_generic(tt);
3197 iph = (
struct ip *) buf;
3201 type = htonl(AF_INET6);
3205 type = htonl(AF_INET);
3208 iv[0].iov_base = (
char *)&type;
3209 iv[0].iov_len =
sizeof(type);
3210 iv[1].iov_base = buf;
3211 iv[1].iov_len = len;
3213 return dragonfly_modify_read_write_return(writev(tt->fd, iv, 2));
3217 return write(tt->fd, buf, len);
3229 iv[0].iov_base = (
char *)&type;
3230 iv[0].iov_len =
sizeof(type);
3231 iv[1].iov_base = buf;
3232 iv[1].iov_len = len;
3234 return dragonfly_modify_read_write_return(readv(tt->fd, iv, 2));
3238 return read(tt->fd, buf, len);
3242#elif defined(TARGET_DARWIN)
3264utun_open_helper(
struct ctl_info ctlInfo,
int utunnum)
3266 struct sockaddr_ctl sc;
3269 fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
3278 if (ioctl(fd, CTLIOCGINFO, &ctlInfo) == -1)
3287 sc.sc_id = ctlInfo.ctl_id;
3288 sc.sc_len =
sizeof(sc);
3289 sc.sc_family = AF_SYSTEM;
3290 sc.ss_sysaddr = AF_SYS_CONTROL;
3292 sc.sc_unit = utunnum+1;
3298 if (connect(fd, (
struct sockaddr *)&sc,
sizeof(sc)) < 0)
3313open_darwin_utun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt)
3315 struct ctl_info ctlInfo;
3319 socklen_t utunname_len =
sizeof(utunname);
3323 if (dev_node && (strcmp(
"utun", dev_node) != 0 ))
3325 if (sscanf(dev_node,
"utun%d", &utunnum) != 1)
3327 msg(
M_FATAL,
"Cannot parse 'dev-node %s' please use 'dev-node utunX'"
3328 "to use a utun device number X", dev_node);
3335 if (strlcpy(ctlInfo.ctl_name, UTUN_CONTROL_NAME,
sizeof(ctlInfo.ctl_name)) >=
3336 sizeof(ctlInfo.ctl_name))
3338 msg(
M_ERR,
"Opening utun: UTUN_CONTROL_NAME too long");
3344 for (utunnum = 0; utunnum < 255; utunnum++)
3348 ASSERT(snprintf(ifname,
sizeof(ifname),
"utun%d", utunnum) > 0);
3349 if (if_nametoindex(ifname))
3353 fd = utun_open_helper(ctlInfo, utunnum);
3364 fd = utun_open_helper(ctlInfo, utunnum);
3376 if (getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, utunname, &utunname_len))
3383 msg(
M_INFO,
"Opened utun device %s", utunname);
3388open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3393 || (dev_node && !strncmp(dev_node,
"utun", 4)))
3400 msg(
M_FATAL,
"Cannot use utun devices with --dev-type %s",
3406 open_darwin_utun(dev, dev_type, dev_node, tt);
3413 msg(
M_INFO,
"Failed to open utun device. Falling back to /dev/tun device");
3414 open_tun_generic(dev, dev_type, NULL, tt);
3431 if (dev_node && strcmp(dev_node,
"tun")==0)
3436 open_tun_generic(dev, dev_type, dev_node, tt);
3450 const char *ifconfig_ipv6_local =
3459 close_tun_generic(tt);
3470 return write_tun_header(tt, buf, len);
3474 return write(tt->fd, buf, len);
3483 return read_tun_header(tt, buf, len);
3487 return read(tt->fd, buf, len);
3491#elif defined(TARGET_AIX)
3494open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
3498 char dynamic_name[20];
3503 msg(
M_FATAL,
"no support for 'tun' devices on AIX" );
3506 if (strncmp( dev,
"tap", 3 ) != 0 || dev_node)
3508 msg(
M_FATAL,
"'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.", dev );
3511 if (strcmp( dev,
"tap" ) == 0)
3514 for (i = 0; i<99; i++)
3516 snprintf(tunname,
sizeof(tunname),
"/dev/tap%d", i);
3517 if (access( tunname, F_OK ) < 0 && errno == ENOENT)
3524 msg(
M_FATAL,
"cannot find unused tap device" );
3527 snprintf( dynamic_name,
sizeof(dynamic_name),
"tap%d", i );
3534 while (isdigit(*p) )
3540 msg(
M_FATAL,
"TAP device name must be '--dev tapNNNN'" );
3543 snprintf(tunname,
sizeof(tunname),
"/dev/%s", dev);
3548 if (access( tunname, F_OK ) < 0 && errno == ENOENT)
3568 if ((tt->fd = open(tunname, O_RDWR)) < 0)
3570 msg(
M_ERR,
"Cannot open TAP device '%s'", tunname);
3575 msg(
M_INFO,
"TUN/TAP device %s opened", tunname);
3604 close_tun_generic(tt);
3617 return write(tt->fd, buf, len);
3623 return read(tt->fd, buf, len);
3626#elif defined(_WIN32)
3668 err = GetLastError();
3669 if (err == ERROR_IO_PENDING)
3725 dmsg(
D_WIN32_IO,
"WIN32 I/O: TAP Write immediate return [%d,%d]",
3731 err = GetLastError();
3732 if (err == ERROR_IO_PENDING)
3766 err = GetLastError();
3784 HDEVINFO dev_info_set;
3789 dev_info_set = SetupDiGetClassDevsEx(&
GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT, NULL, NULL, NULL);
3790 if (dev_info_set == INVALID_HANDLE_VALUE)
3792 err = GetLastError();
3797 for (DWORD i = 0;; ++i)
3799 SP_DEVINFO_DATA device_info_data;
3802 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3804 char device_instance_id[256];
3808 ULONG dev_interface_list_size;
3811 ZeroMemory(&device_info_data,
sizeof(SP_DEVINFO_DATA));
3812 device_info_data.cbSize =
sizeof(SP_DEVINFO_DATA);
3813 res = SetupDiEnumDeviceInfo(dev_info_set, i, &device_info_data);
3816 if (GetLastError() == ERROR_NO_MORE_ITEMS)
3826 dev_key = SetupDiOpenDevRegKey(dev_info_set, &device_info_data, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
3827 if (dev_key == INVALID_HANDLE_VALUE)
3834 status = RegQueryValueEx(dev_key,
3835 net_cfg_instance_id_string,
3840 if (
status != ERROR_SUCCESS)
3845 len =
sizeof(device_instance_id);
3846 res = SetupDiGetDeviceInstanceId(dev_info_set, &device_info_data, device_instance_id, len, &len);
3852 cr = CM_Get_Device_Interface_List_Size(&dev_interface_list_size,
3855 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3857 if (cr != CR_SUCCESS)
3862 char *dev_interface_list =
gc_malloc(dev_interface_list_size,
false,
gc);
3865 dev_interface_list_size,
3866 CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
3867 if (cr != CR_SUCCESS)
3872 char *dev_if = dev_interface_list;
3875 while (strlen(dev_if) > 0)
3893 last->
next = dev_iif;
3897 dev_if += strlen(dev_if) + 1;
3901 RegCloseKey(dev_key);
3904 SetupDiDestroyDeviceInfoList(dev_info_set);
3926 if (
status != ERROR_SUCCESS)
3928 msg(
M_FATAL,
"Error opening registry key: %s", ADAPTER_KEY);
3934 char enum_name[256];
3935 char unit_string[256];
3937 char component_id_string[] =
"ComponentId";
3938 char component_id[256];
3939 char net_cfg_instance_id_string[] =
"NetCfgInstanceId";
3940 BYTE net_cfg_instance_id[256];
3943 len =
sizeof(enum_name);
3953 if (
status == ERROR_NO_MORE_ITEMS)
3957 else if (
status != ERROR_SUCCESS)
3959 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s",
3963 snprintf(unit_string,
sizeof(unit_string),
"%s\\%s",
3964 ADAPTER_KEY, enum_name);
3973 if (
status != ERROR_SUCCESS)
3979 len =
sizeof(component_id);
3980 status = RegQueryValueEx(
3982 component_id_string,
3985 (LPBYTE)component_id,
3988 if (
status != ERROR_SUCCESS || data_type != REG_SZ)
3991 unit_string, component_id_string);
3995 len =
sizeof(net_cfg_instance_id);
3996 status = RegQueryValueEx(
3998 net_cfg_instance_id_string,
4001 net_cfg_instance_id,
4004 if (
status == ERROR_SUCCESS && data_type == REG_SZ)
4017 else if (strcasecmp(component_id,
"ovpn-dco") == 0)
4045 RegCloseKey(unit_key);
4050 RegCloseKey(adapter_key);
4058 HKEY network_connections_key;
4066 NETWORK_CONNECTIONS_KEY,
4069 &network_connections_key);
4071 if (
status != ERROR_SUCCESS)
4073 msg(
M_FATAL,
"Error opening registry key: %s", NETWORK_CONNECTIONS_KEY);
4078 char enum_name[256];
4079 char connection_string[256];
4080 HKEY connection_key;
4081 WCHAR name_data[256];
4083 const WCHAR name_string[] = L
"Name";
4085 len =
sizeof(enum_name);
4087 network_connections_key,
4095 if (
status == ERROR_NO_MORE_ITEMS)
4099 else if (
status != ERROR_SUCCESS)
4101 msg(
M_FATAL,
"Error enumerating registry subkeys of key: %s",
4102 NETWORK_CONNECTIONS_KEY);
4105 snprintf(connection_string,
sizeof(connection_string),
4106 "%s\\%s\\Connection",
4107 NETWORK_CONNECTIONS_KEY, enum_name);
4116 if (
status != ERROR_SUCCESS)
4118 dmsg(
D_REGISTRY,
"Error opening registry key: %s", connection_string);
4122 len =
sizeof(name_data);
4123 status = RegQueryValueExW(
4131 if (
status != ERROR_SUCCESS || name_type != REG_SZ)
4134 NETWORK_CONNECTIONS_KEY, connection_string, name_string);
4143 n = WideCharToMultiByte(CP_UTF8, 0, name_data, -1, NULL, 0, NULL, NULL);
4145 WideCharToMultiByte(CP_UTF8, 0, name_data, -1,
name, n, NULL, NULL);
4160 RegCloseKey(connection_key);
4165 RegCloseKey(network_connections_key);
4177 const unsigned int mask = 3;
4178 const char *err = NULL;
4180 if (local == remote)
4182 err =
"must be different";
4185 if ((local & (~mask)) != (remote & (~mask)))
4187 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";
4190 if ((local & mask) == 0
4191 || (local & mask) == 3
4192 || (remote & mask) == 0
4193 || (remote & mask) == 3)
4195 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";
4203 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.",
4216 printf(
"On Windows, point-to-point IP support (i.e. --dev tun)\n");
4217 printf(
"is emulated by the TAP-Windows driver. The major limitation\n");
4218 printf(
"imposed by this approach is that the --ifconfig local and\n");
4219 printf(
"remote endpoints must be part of the same 255.255.255.252\n");
4220 printf(
"subnet. The following list shows examples of endpoint\n");
4221 printf(
"pairs which satisfy this requirement. Only the final\n");
4222 printf(
"component of the IP address pairs is at issue.\n\n");
4223 printf(
"As an example, the following option would be correct:\n");
4224 printf(
" --ifconfig 10.7.0.5 10.7.0.6 (on host A)\n");
4225 printf(
" --ifconfig 10.7.0.6 10.7.0.5 (on host B)\n");
4226 printf(
"because [5,6] is part of the below list.\n\n");
4228 for (i = 0; i < 256; i += 4)
4230 printf(
"[%3d,%3d] ", i+1, i+2);
4248 bool warn_panel_null =
false;
4249 bool warn_panel_dup =
false;
4250 bool warn_tap_dup =
false;
4261 msg(msglev,
"Available adapters [name, GUID, driver]:");
4280 warn_panel_dup =
true;
4282 else if (links == 0)
4286 warn_panel_null =
true;
4287 msg(msglev,
"[NULL] %s", tr->
guid);
4296 if (tr != tr1 && !strcmp(tr->
guid, tr1->
guid))
4298 warn_tap_dup =
true;
4306 msg(warnlev,
"WARNING: Some TAP-Windows adapters have duplicate GUIDs");
4311 msg(warnlev,
"WARNING: Some TAP-Windows adapters have duplicate links from the Network Connections control panel");
4314 if (warn_panel_null)
4316 msg(warnlev,
"WARNING: Some TAP-Windows adapters have no link from the Network Connections control panel");
4378 msg(
M_FATAL,
"There are no TAP-Windows, Wintun or ovpn-dco adapters "
4379 "on this system. You should be able to create an adapter "
4380 "by using tapctl.exe utility.");
4390 uint8_t *actual_name,
4391 int actual_name_size,
4392 const struct tap_reg *tap_reg_src,
4443 if (windows_driver !=
NULL)
4476 ASSERT(actual_name_size > 0);
4522const IP_ADAPTER_INFO *
4526 IP_ADAPTER_INFO *pi = NULL;
4529 if ((
status = GetAdaptersInfo(NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4531 msg(
M_INFO,
"GetAdaptersInfo #1 failed (status=%u) : %s",
4537 pi = (PIP_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4538 if ((
status = GetAdaptersInfo(pi, &size)) != NO_ERROR)
4540 msg(
M_INFO,
"GetAdaptersInfo #2 failed (status=%u) : %s",
4549const IP_PER_ADAPTER_INFO *
4553 IP_PER_ADAPTER_INFO *pi = NULL;
4558 if ((
status = GetPerAdapterInfo(index, NULL, &size)) != ERROR_BUFFER_OVERFLOW)
4560 msg(
M_INFO,
"GetPerAdapterInfo #1 failed (status=%u) : %s",
4566 pi = (PIP_PER_ADAPTER_INFO)
gc_malloc(size,
false,
gc);
4567 if ((
status = GetPerAdapterInfo((ULONG)index, pi, &size)) == ERROR_SUCCESS)
4573 msg(
M_INFO,
"GetPerAdapterInfo #2 failed (status=%u) : %s",
4582static const IP_INTERFACE_INFO *
4586 IP_INTERFACE_INFO *ii = NULL;
4589 if ((
status = GetInterfaceInfo(NULL, &size)) != ERROR_INSUFFICIENT_BUFFER)
4591 msg(
M_INFO,
"GetInterfaceInfo #1 failed (status=%u) : %s",
4597 ii = (PIP_INTERFACE_INFO)
gc_malloc(size,
false,
gc);
4598 if ((
status = GetInterfaceInfo(ii, &size)) == NO_ERROR)
4604 msg(
M_INFO,
"GetInterfaceInfo #2 failed (status=%u) : %s",
4612static const IP_ADAPTER_INDEX_MAP *
4619 for (i = 0; i < list->NumAdapters; ++i)
4621 const IP_ADAPTER_INDEX_MAP *inter = &list->Adapter[i];
4622 if (index == inter->Index)
4636const IP_ADAPTER_INFO *
4641 const IP_ADAPTER_INFO *a;
4644 for (a = ai; a != NULL; a = a->Next)
4646 if (a->Index == index)
4655const IP_ADAPTER_INFO *
4667 const IP_ADDR_STRING *ip = &ai->IpAddressList;
4691 const IP_ADDR_STRING *iplist = &ai->IpAddressList;
4701 iplist = iplist->Next;
4707 const char *ip_str = iplist->IpAddress.String;
4708 const char *netmask_str = iplist->IpMask.String;
4709 bool succeed1 =
false;
4710 bool succeed2 =
false;
4712 if (ip_str && netmask_str && strlen(ip_str) && strlen(netmask_str))
4714 *ip =
getaddr(getaddr_flags, ip_str, 0, &succeed1, NULL);
4715 *netmask =
getaddr(getaddr_flags, netmask_str, 0, &succeed2, NULL);
4716 ret = (succeed1 ==
true && succeed2 ==
true);
4729 in_addr_t ip_adapter = 0;
4730 in_addr_t netmask_adapter = 0;
4732 return (
status && ip_adapter == ip && netmask_adapter == netmask);
4740const IP_ADAPTER_INFO *
4766 for (i = 0; i < n; ++i)
4768 in_addr_t ip, netmask;
4804 if (highest_netmask)
4806 *highest_netmask = 0;
4812 for (i = 0; i < n; ++i)
4814 in_addr_t adapter_ip, adapter_netmask;
4817 if (adapter_ip && adapter_netmask && (ip & adapter_netmask) == (adapter_ip & adapter_netmask))
4819 if (highest_netmask && adapter_netmask > *highest_netmask)
4821 *highest_netmask = adapter_netmask;
4839 in_addr_t highest_netmask = 0;
4840 int lowest_metric = INT_MAX;
4855 if (first || hn > highest_netmask)
4857 highest_netmask = hn;
4860 lowest_metric = metric;
4869 else if (hn == highest_netmask)
4875 if (metric >= 0 && metric < lowest_metric)
4878 lowest_metric = metric;
4885 dmsg(
D_ROUTE_DEBUG,
"DEBUG: IP Locate: ip=%s nm=%s index=%d count=%d metric=%d",
4889 count ? *count : -1,
4899 *netmask = highest_netmask;
4911#define DHCP_STATUS_UNDEF 0
4912#define DHCP_STATUS_ENABLED 1
4913#define DHCP_STATUS_DISABLED 2
4926 if (ai->DhcpEnabled)
4952 const IP_ADDR_STRING *ip = &a->IpAddressList;
4956 const DWORD
context = ip->Context;
4958 if ((
status = DeleteIPAddress((ULONG)
context)) == NO_ERROR)
4960 msg(
M_INFO,
"Successfully deleted previously set dynamic IP/netmask: %s/%s",
4961 ip->IpAddress.String,
4966 const char *empty =
"0.0.0.0";
4967 if (strcmp(ip->IpAddress.String, empty)
4968 || strcmp(ip->IpMask.String, empty))
4970 msg(
M_INFO,
"NOTE: could not delete previously set dynamic IP/netmask: %s/%s (status=%u)",
4971 ip->IpAddress.String,
4991 swprintf(wbuf,
SIZE(wbuf), L
"\\DEVICE\\TCPIP_%hs", guid);
4992 if (GetAdapterIndex(wbuf, &aindex) != NO_ERROR)
4998 index = (DWORD)aindex;
5013 if (!strcmp(guid,
list->AdapterName))
5015 index =
list->Index;
5036 msg(
M_INFO,
"NOTE: could not get adapter index for %s", guid);
5050 buf_printf(&out,
"%s", ip->IpAddress.String);
5051 if (
strlen(ip->IpMask.String))
5104 msg(msglev,
"SYSTEM ADAPTER LIST");
5107 const IP_ADAPTER_INFO *a;
5110 for (a = ai; a != NULL; a = a->Next)
5133 msg(
M_ERR,
"Error: init SA failed");
5136 status = SetKernelObjectSecurity(hand, DACL_SECURITY_INFORMATION, &
sa.sd);
5139 msg(
M_ERRNO,
"Error: SetKernelObjectSecurity failed on %s", device_path);
5153 const char *device_guid = NULL;
5155 uint8_t actual_buffer[256];
5156 char device_path[256];
5167 msg(
M_FATAL,
"TAP-Windows adapter '%s' not found", dev_node);
5171 snprintf(device_path,
sizeof(device_path),
"%s%s%s",
5182 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
5186 if (hand == INVALID_HANDLE_VALUE)
5188 msg(
M_ERR,
"CreateFile failed on TAP device: %s", device_path);
5196 int device_number = 0;
5203 sizeof(actual_buffer),
5215 snprintf(device_path,
sizeof(device_path),
"%s%s%s",
5226 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
5230 if (hand == INVALID_HANDLE_VALUE)
5232 msg(
M_WARN,
"CreateFile failed on TAP device: %s", device_path);
5258 DWORD
status = IpReleaseAddress((IP_ADAPTER_INDEX_MAP *)inter);
5266 msg(
M_WARN,
"NOTE: Release of DHCP-assigned IP address lease on TAP-Windows adapter failed: %s (code=%u)",
5298 DWORD
status = IpRenewAddress((IP_ADAPTER_INDEX_MAP *)inter);
5306 msg(
M_WARN,
"WARNING: Failed to renew DHCP IP address lease on TAP-Windows adapter: %s (code=%u)",
5332 for (i = 0; i < n; ++i)
5346 msg(msglevel,
"%s: command failed", prefix);
5359 const char err[] =
"ERROR: Windows ipconfig command failed";
5388 const char *ip_str = src->IpAddress.String;
5390 bool succeed =
false;
5396 if (!ip_str || !strlen(ip_str))
5401 ip =
getaddr(getaddr_flags, ip_str, 0, &succeed, NULL);
5415 msg(
M_INFO,
"ip_addr_string_to_array [%d]", *dest_len);
5416 for (i = 0; i < *dest_len; ++i)
5429 int a2len =
SIZE(a2);
5439 for (i = 0; i < a1len; ++i)
5457 for (i = 0; i < len; ++i)
5475 DWORD adapter_index)
5487 for (
int i = 0; i < addr_len; ++i)
5489 const char *fmt = (i == 0) ?
5490 "%s%s interface ipv6 set dns %lu static %s"
5491 :
"%s%s interface ipv6 add dns %lu %s";
5509 const in_addr_t *addr_list,
5511 const IP_ADDR_STRING *current,
5512 DWORD adapter_index,
5513 const bool test_first)
5517 bool delete_first =
false;
5518 bool is_dns = !strcmp(type,
"dns");
5525 delete_first =
true;
5530 delete_first =
true;
5548 for (i = 0; i < addr_len; ++i)
5552 const char *fmt = count ?
5553 "%s%s interface ip add %s %lu %s"
5554 :
"%s%s interface ip set %s %lu static %s";
5575 msg(
M_INFO,
"NETSH: %lu %s %s [already set]",
5595 dest[0].Next = NULL;
5600 dest[0].Next = &dest[1];
5601 dest[1].Next = NULL;
5607 DWORD adapter_index,
5609 const in_addr_t netmask,
5610 const unsigned int flags)
5614 const IP_ADAPTER_INFO *ai = NULL;
5615 const IP_PER_ADAPTER_INFO *pai = NULL;
5628 msg(
M_INFO,
"NETSH: %lu %s/%s [already set]",
5650 IP_ADDR_STRING wins[2];
5657 pai ? &pai->DnsServerList : NULL,
5660 if (ai && ai->HaveWins)
5684 "%s%s interface ip set address %lu dhcp",
5719 msg(
M_NONFATAL,
"TUN: enabling dhcp using service failed: %s [status=%u if_index=%d]",
5724 msg(
M_INFO,
"DHCP enabled on interface %d using service",
dhcp.iface.index);
5739 MIB_IPINTERFACE_ROW ipiface;
5740 InitializeIpInterfaceEntry(&ipiface);
5741 const char *family_name = (family == AF_INET6) ?
"IPv6" :
"IPv4";
5742 ipiface.Family = family;
5743 ipiface.InterfaceIndex = iface_index;
5744 if (family == AF_INET6 && mtu < 1280)
5746 msg(
M_INFO,
"NOTE: IPv6 interface MTU < 1280 conflicts with IETF standards and might not work");
5749 err = GetIpInterfaceEntry(&ipiface);
5750 if (err == NO_ERROR)
5752 if (family == AF_INET)
5754 ipiface.SitePrefixLength = 0;
5756 ipiface.NlMtu = mtu;
5757 err = SetIpInterfaceEntry(&ipiface);
5760 if (err != NO_ERROR)
5762 msg(
M_WARN,
"TUN: Setting %s mtu failed: %s [status=%lu if_index=%d]",
5767 msg(
M_INFO,
"%s MTU set to %d on interface %d using SetIpInterfaceEntry()", family_name, mtu, iface_index);
5805 return BSTR(&actual);
5819 tt->standby_iter = 0;
5831 msg(
M_INFO,
"NOTE: now trying netsh (this may take some time)");
5835 tt->adapter_netmask,
5857 msg(
M_WARN,
"write_dhcp_u8: buffer overflow building DHCP options");
5876 msg(
M_WARN,
"write_dhcp_u32_array: buffer overflow building DHCP options");
5882 msg(
M_WARN,
"write_dhcp_u32_array: size (%d) must be > 0 and <= 255", size);
5887 for (
i = 0;
i <
len; ++
i)
5901 msg(
M_WARN,
"write_dhcp_str: buffer overflow building DHCP options");
5907 msg(
M_WARN,
"write_dhcp_str: string '%s' must be > 0 bytes and <= 255 bytes",
str);
5939 msg(
M_WARN,
"write_dhcp_search_str: temp buffer overflow building DHCP options");
5951 if (*
ptr ==
'.' || *
ptr ==
'\0')
5969 msg(
M_WARN,
"write_search_dhcp_str: buffer overflow building DHCP options");
5975 msg(
M_WARN,
"write_dhcp_search_str: search domain string must be <= 255 bytes");
5993 if (
o->netbios_scope)
5998 if (
o->netbios_node_type)
6008 if (
o->domain_search_list_len > 0)
6011 o->domain_search_list_len,
6022 msg(
M_WARN,
"build_dhcp_options_string: buffer overflow building DHCP options");
6037 if (
tt->options.dhcp_pre_release ||
tt->options.dhcp_renew)
6045 if (
tt->options.dhcp_pre_release)
6049 if (
tt->options.dhcp_renew)
6063 HANDLE msg_channel =
tt->options.msg_channel;
6077 msg(
M_WARN,
"Register_dns failed using service: %s [status=0x%x]",
6083 msg(
M_INFO,
"Register_dns request sent to the service");
6116 msg(
M_NONFATAL,
"Register ring buffers failed using service: %s [status=0x%x]",
6122 msg(
M_INFO,
"Ring buffers registered via service");
6142 buf_printf(&
cmd,
"openvpn --verb %d --register-dns --rdns-internal", verb);
6156 dsa = (local | (~netmask)) + offset;
6160 dsa = (local & netmask) + offset;
6165 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));
6168 if ((local & netmask) != (dsa & netmask))
6170 msg(
M_FATAL,
"ERROR: --ip-win32 dynamic [offset] : offset is outside of --ifconfig subnet");
6183 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_VERSION,
6184 &info,
sizeof(info),
6185 &info,
sizeof(info), &len, NULL))
6190 (info[2] ?
"(DEBUG)" :
""));
6195 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.",
6204 && info[0] == 9 && info[1] < 8)
6206 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]);
6212 && info[0] == 9 && info[1] == 8)
6214 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]);
6223 if (DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_GET_MTU,
6225 &mtu,
sizeof(mtu), &len, NULL))
6233 const char *device_guid,
6234 bool dhcp_masq_post)
6255 .iface = {.index = index, .name =
"" }
6266 status = FlushIpNetTable(index);
6271 msg(
M_INFO,
"Successful ARP Flush on interface [%lu] %s",
6277 msg(
D_TUNTAP_INFO,
"NOTE: FlushIpNetTable failed on interface [%lu] %s (status=%lu) : %s",
6294 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'");
6316 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')";
6321 msg(
M_FATAL,
"ERROR: unable to get adapter index for interface %s -- %s",
6329 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'");
6343 msg(
M_INFO,
"Succeeded in adding a temporary IP/netmask of %s/%s to interface %s using the Win32 IP Helper API",
6351 msg(
M_FATAL,
"ERROR: AddIPAddress %s/%s failed on interface %s, index=%lu, status=%lu (windows error: '%s') -- %s",
6372 FILE_MAP_ALL_ACCESS,
6378 FILE_MAP_ALL_ACCESS,
6395 switch (GetLastError())
6397 case ERROR_ACCESS_DENIED:
6398 msg(
M_FATAL,
"ERROR: Wintun requires SYSTEM privileges and therefore "
6399 "should be used with interactive service. If you want to "
6400 "use openvpn from command line, you need to do SYSTEM "
6401 "elevation yourself (for example with psexec).");
6404 case ERROR_ALREADY_INITIALIZED:
6405 msg(
M_NONFATAL,
"Adapter %s is already in use", device_guid);
6423 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
6427 msg(
M_WARN,
"WARNING: The TAP-Windows driver rejected a TAP_WIN_IOCTL_SET_MEDIA_STATUS DeviceIoControl call.");
6433 msg(
M_INFO,
"Sleeping for %d seconds...", s);
6446 msg(
M_FATAL,
"ERROR: --dev tun also requires --ifconfig");
6457 ep[0] = htonl(tt->
local);
6461 status = DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_TUN,
6463 ep,
sizeof(ep), &len, NULL);
6471 status ?
"SUCCEEDED" :
"FAILED");
6476 status ?
"SUCCEEDED" :
"FAILED");
6482 ep[0] = htonl(tt->
local);
6485 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT,
6487 ep,
sizeof(ep), &len, NULL))
6489 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set Point-to-Point mode, which is required for --dev tun");
6504 ep[0] = htonl(tt->
local);
6530#ifndef SIMULATE_DHCP_FAILED
6531 if (!DeviceIoControl(tt->
hand, TAP_WIN_IOCTL_CONFIG_DHCP_MASQ,
6533 ep,
sizeof(ep), &len, NULL))
6535 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a DeviceIoControl call to set TAP_WIN_IOCTL_CONFIG_DHCP_MASQ mode");
6538 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]",
6557 msg(
M_FATAL,
"ERROR: The TAP-Windows driver rejected a TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT DeviceIoControl call");
6562 msg(
M_WARN,
"DHCP option string not set due to error");
6610 snprintf(tuntap_device_path,
sizeof(tuntap_device_path),
"%s%s%s",
6614 path = tuntap_device_path;
6619 tt->
hand = CreateFile(path,
6620 GENERIC_READ | GENERIC_WRITE,
6624 FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED,
6626 if (tt->
hand == INVALID_HANDLE_VALUE)
6637 msg(
D_TUNTAP_INFO,
"Failed to register %s adapter ring buffers", device_guid);
6638 CloseHandle(tt->
hand);
6654 uint8_t actual_buffer[256];
6668 msg(
M_FATAL,
"Adapter '%s' not found", dev_node);
6673 msg(
M_FATAL,
"Adapter '%s' is using %s driver, %s expected. If you want to use this device, adjust --windows-driver.",
6684 int device_number = 0;
6685 int adapters_created = 0;
6693 sizeof(actual_buffer),
6762 *dhcp_masq_post =
true;
6787 bool dhcp_masq =
false;
6788 bool dhcp_masq_post =
false;
6829open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt,
6835 msg(
M_WARN,
"Some --dhcp-option or --dns options require DHCP server,"
6836 " which is not supported by the selected %s driver. They will be"
6846 const char *device_guid = NULL;
6829open_tun(
const char *dev,
const char *dev_type,
const char *dev_node,
struct tuntap *tt, {
…}
6914 "%s%s interface %s delete dns %lu all",
6917 ipv6 ?
"ipv6" :
"ipv4",
6925 "%s%s interface ipv4 delete winsservers %lu all",
6951 "%s%s interface %s delete address %lu %s store=active",
6954 ipv6 ?
"ipv6" :
"ipv4",
6970 if (!CancelIo(tt->
hand))
6972 msg(
M_WARN |
M_ERRNO,
"Warning: CancelIO failed on %s adapter", adaptertype);
6976 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped read event on %s adapter", adaptertype);
6979 dmsg(
D_WIN32_IO_LOW,
"Attempting close of overlapped write event on %s adapter", adaptertype);
6985 if (!CloseHandle(tt->
hand))
6987 msg(
M_WARN |
M_ERRNO,
"Warning: CloseHandle failed on %s adapter", adaptertype);
7071 msg(
M_WARN,
"Warning: DeleteIPAddress[%u] failed on TAP-Windows adapter, status=%u : %s",
7127 return "[unknown --ip-win32 type]";
7156open_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)
#define TAP_WIN_MIN_MINOR
#define TAP_WIN_COMPONENT_ID
#define TAP_WIN_MIN_MAJOR
static int open_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx, const char *dev)
static void close_tun_dco(struct tuntap *tt, openvpn_net_ctx_t *ctx)
void env_set_destroy(struct env_set *es)
void setenv_int(struct env_set *es, const char *name, int value)
void setenv_str(struct env_set *es, const char *name, const char *value)
void env_set_add(struct env_set *es, const char *str)
struct env_set * env_set_create(struct gc_arena *gc)
void set_nonblock(socket_descriptor_t fd)
void set_cloexec(socket_descriptor_t fd)
static SERVICE_STATUS status
void management_set_state(struct management *man, const int state, const char *detail, const in_addr_t *tun_local_ip, const struct in6_addr *tun_local_ip6, const struct openvpn_sockaddr *local, const struct openvpn_sockaddr *remote)
void management_sleep(const int n)
A sleep function that services the management layer for n seconds rather than doing nothing.
#define OPENVPN_STATE_ASSIGN_IP
static void net_ctx_reset(openvpn_net_ctx_t *ctx)
static void net_ctx_free(openvpn_net_ctx_t *ctx)
@ msg_register_ring_buffers
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
const char * print_topology(const int topology)
const char * time_string(time_t t, long usec, bool show_usec, struct gc_arena *gc)
#define OPENVPN_IPH_GET_VER(v)
static bool register_ring_buffers(HANDLE device, struct tun_ring *send_ring, struct tun_ring *receive_ring, HANDLE send_tail_moved, HANDLE receive_tail_moved)
Registers ring buffers used to exchange data between userspace openvpn process and wintun kernel driv...
int netmask_to_netbits2(in_addr_t netmask)
bool add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
bool add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
void get_default_gateway(struct route_gateway_info *rgi, in_addr_t dest, openvpn_net_ctx_t *ctx)
Retrieves the best gateway for a given destination based on the routing table.
void delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, const struct env_set *es, openvpn_net_ctx_t *ctx)
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
#define RT_METRIC_DEFINED
#define RGI_NETMASK_DEFINED
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
int sockethandle_finalize(sockethandle_t sh, struct overlapped_io *io, struct buffer *buf, struct link_socket_actual *from)
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
in_addr_t getaddr(unsigned int flags, const char *hostname, int resolve_retry_seconds, bool *succeeded, struct signal_info *sig_info)
Translate an IPv4 addr or hostname from string form to in_addr_t.
#define GETADDR_HOST_ORDER
#define GETADDR_FATAL_ON_SIGNAL
Wrapper structure for dynamically allocated memory.
uint8_t * data
Pointer to the allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
int offset
Offset in bytes of the actual content within the allocated memory.
Contains all state information for one tunnel.
const char * device_interface
struct device_instance_id_interface * next
LPBYTE net_cfg_instance_id
Packet geometry parameters.
Garbage collection arena used to keep track of dynamically allocated memory.
struct gc_entry * list
First element of the linked list of gc_entry structures.
struct man_connection connection
struct route_gateway_address gateway
enum tun_driver_type windows_driver
Wintun ring buffer See https://github.com/WireGuard/wintun#ring-layout.
struct in6_addr dns6[N_DHCP_ADDR]
in_addr_t wins[N_DHCP_ADDR]
in_addr_t dns[N_DHCP_ADDR]
bool dhcp_masq_custom_offset
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.
HANDLE wintun_receive_ring_handle
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
struct tuntap_options options
struct in6_addr remote_ipv6
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
struct overlapped_io writes
in_addr_t adapter_netmask
struct tun_ring * wintun_receive_ring
struct overlapped_io reads
struct in6_addr local_ipv6
HANDLE wintun_send_ring_handle
struct tun_ring * wintun_send_ring
bool ipapi_context_defined
static const char * get_unspecified_device_guid(const int device_number, uint8_t *actual_name, int actual_name_size, const struct tap_reg *tap_reg_src, const struct panel_reg *panel_reg_src, enum tun_driver_type *windows_driver, struct gc_arena *gc)
void ipconfig_register_dns(const struct env_set *es)
void tun_show_debug(struct tuntap *tt)
static const struct tap_reg * get_tap_reg(struct gc_arena *gc)
static DWORD get_adapter_index_method_1(const char *guid)
static void tuntap_post_open(struct tuntap *tt, const char *device_guid)
static bool do_address_service(const bool add, const short family, const struct tuntap *tt)
static void clear_tuntap(struct tuntap *tuntap)
static const char * netsh_get_id(const char *dev_node, struct gc_arena *gc)
void open_tun(const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt, openvpn_net_ctx_t *ctx)
int dev_type_enum(const char *dev, const char *dev_type)
static const struct panel_reg * get_panel_reg(struct gc_arena *gc)
void close_tun_handle(struct tuntap *tt)
void fork_register_dns_action(struct tuntap *tt)
static bool test_adapter_ip_netmask(const IP_ADAPTER_INFO *ai, const in_addr_t ip, const in_addr_t netmask)
static void do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu, const struct env_set *es, openvpn_net_ctx_t *ctx)
do_ifconfig_ipv6 - perform platform specific ifconfig6 commands
static void netsh_enable_dhcp(DWORD adapter_index)
static const GUID GUID_DEVINTERFACE_NET
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 bool service_register_ring_buffers(const struct tuntap *tt)
static void netsh_set_dns6_servers(const struct in6_addr *addr_list, const int addr_len, DWORD adapter_index)
Set the ipv6 dns servers on the specified interface.
static const GUID GUID_DEVCLASS_NET
const char * print_tun_backend_driver(enum tun_driver_type driver)
Return a string representation of the tun backed driver type.
static void do_wins_service(bool add, const struct tuntap *tt)
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
static void do_dns_service(bool add, const short family, const struct tuntap *tt)
static bool wintun_register_ring_buffer(struct tuntap *tt, const char *device_guid)
void tun_open_device(struct tuntap *tt, const char *dev_node, const char **device_guid, struct gc_arena *gc)
void verify_255_255_255_252(in_addr_t local, in_addr_t remote)
static bool ip_addr_one_to_one(const in_addr_t *a1, const int a1len, const IP_ADDR_STRING *ias)
#define IPW32_SET_ADAPTIVE
#define DHCP_OPTIONS_DHCP_REQUIRED
#define 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
#define WINTUN_COMPONENT_ID
@ WINDOWS_DRIVER_UNSPECIFIED
@ DRIVER_UTUN
macOS internal tun driver
@ DRIVER_AFUNIX
using an AF_UNIX socket to pass packets from/to an external program.
@ WINDOWS_DRIVER_TAP_WINDOWS6
int read_tun(struct tuntap *tt, uint8_t *buf, int len)
int write_tun(struct tuntap *tt, uint8_t *buf, int len)
void tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options, openvpn_net_ctx_t *ctx)
int get_interface_metric(const NET_IFINDEX index, const ADDRESS_FAMILY family, int *is_auto)
Return interface metric value for the specified interface index.
void overlapped_io_init(struct overlapped_io *o, const struct frame *frame, BOOL event_state)
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