49#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
50#include <linux/rtnetlink.h>
53#if defined(TARGET_NETBSD)
60#define METRIC_NOT_USED ((DWORD)-1)
93 msg(
D_ROUTE,
"ROUTE: bypass_host_route[%d]=%s",
192 buf_printf(&out,
"ROUTE network %s netmask %s gateway %s",
245 if (!
strcmp(
string,
"vpn_gateway"))
251 *out =
rl->spec.remote_endpoint;
264 else if (!
strcmp(
string,
"net_gateway"))
270 *out =
rl->rgi.gateway.addr;
274 msg(
M_INFO,
PACKAGE_NAME " ROUTE: net_gateway undefined -- unable to get default gateway from system");
283 else if (!
strcmp(
string,
"remote_host"))
289 *out =
rl->spec.remote_host;
327 struct in_addr special = {0};
347 special.s_addr = htonl(special.s_addr);
348 char buf[INET_ADDRSTRLEN];
349 inet_ntop(AF_INET, &special, buf,
sizeof(buf));
351 AF_INET, network_list);
356 ro->
network, NULL, 0, NULL, AF_INET, network_list);
415 msg(
M_WARN, PACKAGE_NAME
" ROUTE: " PACKAGE_NAME
" needs a gateway parameter for a --route option and no default was specified by either --route-gateway or --ifconfig options");
428 msg(
M_WARN, PACKAGE_NAME
" ROUTE: route metric for network %s (%s) must be >= 0",
449 msg(
M_WARN, PACKAGE_NAME
" ROUTE: failed to parse/resolve route for host/network: %s",
471 msg(
M_WARN, PACKAGE_NAME
"ROUTE6: cannot parse gateway spec '%s'", r6o->
gateway );
487 msg(
M_WARN, PACKAGE_NAME
" ROUTE: route metric for network %s (%s) must be >= 0",
508 msg(
M_WARN, PACKAGE_NAME
" ROUTE: failed to parse/resolve route for host/network: %s",
567 const in_addr_t addr)
589 l2 = ((~gateway->netmask)+1)>>1;
607#ifndef TARGET_ANDROID
633 && (rl->
rgi.
flags & rgi_needed) == rgi_needed
641 const char *remote_endpoint,
643 in_addr_t remote_host,
670#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
686 bool defined =
false;
703 msg(
M_WARN, PACKAGE_NAME
" ROUTE: failed to parse/resolve default gateway: %s",
726 struct addrinfo *netlist = NULL;
735 struct addrinfo *curele;
736 for (curele = netlist; curele; curele = curele->ai_next)
741 new->
network = ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
763 const struct in6_addr *host )
765 unsigned int bits = r6->
netbits;
774 for (i = 0; bits >= 8; i++, bits -= 8)
776 if (r6->
network.s6_addr[i] != host->s6_addr[i])
787 mask = 0xff << (8-bits);
789 if ( (r6->
network.s6_addr[i] & mask) == (host->s6_addr[i] & mask ))
800 const char *remote_endpoint,
802 const struct in6_addr *remote_host_ipv6,
808 bool need_remote_ipv6_route;
814 if (remote_host_ipv6)
820 if (default_metric >= 0)
833#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
844 if (inet_pton( AF_INET6, remote_endpoint,
851 msg(
M_WARN, PACKAGE_NAME
" ROUTE: failed to parse/resolve VPN endpoint: %s", remote_endpoint);
859 need_remote_ipv6_route =
false;
876#ifndef TARGET_ANDROID
884 need_remote_ipv6_route =
true;
885 msg(
D_ROUTE,
"ROUTE6: %s/%d overlaps IPv6 remote %s, adding host route to VPN endpoint",
895 if (need_remote_ipv6_route)
903 r6->
network = *remote_host_ipv6;
913 r6->iface = rl6->
rgi6.iface;
922 msg(
M_WARN,
"ROUTE6: IPv6 route overlaps with IPv6 remote address, but could not determine IPv6 gateway address + interface, expect failure\n" );
978 for (
int i = 0; i < rb->
n_bypass; ++i)
1020 const char err[] =
"NOTE: unable to redirect IPv4 default gateway --";
1029 msg(
M_WARN,
"%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err);
1040 msg(
M_WARN,
"%s Cannot read current default gateway from system", err);
1045#ifndef TARGET_ANDROID
1078 dmsg(
D_ROUTE,
"ROUTE remote_host protocol differs from tunneled");
1085 &rl->
rgi,
es, ctx) && ret;
1141 rl->
iflags &= ~RL_DID_LOCAL;
1192 rl->
iflags &= ~RL_DID_REDIRECT_DEFAULT_GATEWAY;
1208 msg(
M_INFO,
"WARNING: OpenVPN was configured to add an IPv4 "
1209 "route. However, no IPv4 has been configured for %s, "
1210 "therefore the route installation may fail or may not work "
1214#ifdef ENABLE_MANAGEMENT
1243 msg(
M_INFO,
"WARNING: OpenVPN was configured to add an IPv6 "
1244 "route. However, no IPv6 has been configured for %s, "
1245 "therefore the route installation may fail or may not work "
1275 rl->
iflags &= ~RL_ROUTES_ADDED;
1292 rl6->
iflags &= ~RL_ROUTES_ADDED;
1308 return "default (not set)";
1319 msg(level,
" route %s/%s/%s/%s",
1333 msg(level,
" [redirect_default_gateway local=%d]",
1379 msg(msglevel,
"%s",
BSTR(&out));
1410 msg(msglevel,
"%s",
BSTR(&out));
1539 && (rgi->
flags & rgi_needed) == rgi_needed
1541 && netmask == 0xFFFFFFFF)
1551 for (i = 0; i < rgi->
n_addrs; ++i)
1566#if defined(TARGET_LINUX) || defined(_WIN32) || defined(TARGET_DARWIN)
1593#if !defined(TARGET_LINUX)
1595#if !defined(TARGET_AIX)
1607#if defined(TARGET_LINUX)
1608 const char *
iface = NULL;
1627 msg(
D_ROUTE,
"NOTE: Linux route add command failed because route exists");
1632 msg(
M_WARN,
"ERROR: Linux route add command failed");
1636#elif defined (TARGET_ANDROID)
1641 snprintf(out,
sizeof(out),
"%s %s %s dev %s", network, netmask, gateway, rgi->iface);
1645 snprintf(out,
sizeof(out),
"%s %s %s", network, netmask, gateway);
1647 bool ret = management_android_control(
management,
"ROUTE", out);
1650#elif defined (_WIN32)
1671 const char *method =
"service";
1685 "ERROR: Windows route add command failed");
1688 method =
"route.exe";
1693 method =
"ipapi [adaptive]";
1696 msg(
D_ROUTE,
"Route addition fallback to route.exe");
1699 "ERROR: Windows route add command failed [adaptive]");
1702 method =
"route.exe";
1711 msg(
D_ROUTE,
"Route addition via %s %s", method,
1716#elif defined (TARGET_SOLARIS)
1742 "ERROR: Solaris route add command failed");
1745#elif defined(TARGET_FREEBSD)
1766 "ERROR: FreeBSD route add command failed");
1769#elif defined(TARGET_DRAGONFLY)
1790 "ERROR: DragonFly route add command failed");
1793#elif defined(TARGET_DARWIN)
1824 "ERROR: OS X route add command failed");
1827#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1848 "ERROR: OpenBSD/NetBSD route add command failed");
1851#elif defined(TARGET_AIX)
1857 network, netbits, gateway);
1860 "ERROR: AIX route add command failed");
1864#elif defined(TARGET_HAIKU)
1875 "ERROR: Haiku inet route add command failed");
1879 msg(
M_FATAL,
"Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
1889 r->
flags &= ~RT_ADDED;
1908 int bits_to_clear = 128 - r6->
netbits;
1910 while (
byte >= 0 && bits_to_clear > 0)
1912 if (bits_to_clear >= 8)
1914 r6->
network.s6_addr[
byte--] = 0; bits_to_clear -= 8;
1918 r6->
network.s6_addr[
byte--] &= (0xff << bits_to_clear); bits_to_clear = 0;
1925 unsigned int flags,
const struct env_set *
es,
1929 bool gateway_needed =
false;
1941 if (r6->iface != NULL)
1944 if (!IN6_IS_ADDR_UNSPECIFIED(&r6->
gateway) )
1946 gateway_needed =
true;
1955#if defined(TARGET_DARWIN) \
1956 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1957 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1963 if (r6->iface != NULL && gateway_needed
1964 && IN6_IS_ADDR_LINKLOCAL(&r6->
gateway) )
1966 int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
1968 snprintf( tmp, len,
"%s%%%s", gateway, r6->iface );
1974 msg(
D_ROUTE,
"add_route_ipv6(%s/%d -> %s metric %d) dev %s",
1977 msg(
D_ROUTE,
"add_route_ipv6(%s/%d -> %s metric %d) IF %lu",
1996 gateway_needed =
true;
1999 if (gateway_needed && IN6_IS_ADDR_UNSPECIFIED(&r6->
gateway))
2001 msg(
M_WARN,
"ROUTE6 WARNING: " PACKAGE_NAME
" needs a gateway "
2002 "parameter for a --route-ipv6 option and no default was set via "
2003 "--ifconfig-ipv6 or --route-ipv6-gateway option. Not installing "
2004 "IPv6 route to %s/%d.", network, r6->
netbits);
2009#if defined(TARGET_LINUX)
2018 gateway_needed ? &r6->
gateway : NULL,
2022 msg(
D_ROUTE,
"NOTE: Linux route add command failed because route exists");
2027 msg(
M_WARN,
"ERROR: Linux route add command failed");
2031#elif defined (TARGET_ANDROID)
2034 snprintf(out,
sizeof(out),
"%s/%d %s", network, r6->
netbits, device);
2038#elif defined (_WIN32)
2048#elif defined (TARGET_SOLARIS)
2075 "ERROR: Solaris route add -inet6 command failed");
2078#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2096 "ERROR: *BSD route add -inet6 command failed");
2099#elif defined(TARGET_DARWIN)
2116 "ERROR: MacOS X route add -inet6 command failed");
2119#elif defined(TARGET_OPENBSD)
2123 network, r6->
netbits, gateway );
2127 "ERROR: OpenBSD route add -inet6 command failed");
2130#elif defined(TARGET_NETBSD)
2134 network, r6->
netbits, gateway );
2138 "ERROR: NetBSD route add -inet6 command failed");
2141#elif defined(TARGET_AIX)
2145 network, r6->
netbits, gateway);
2148 "ERROR: AIX route add command failed");
2151#elif defined(TARGET_HAIKU)
2162 "ERROR: Haiku inet6 route add command failed");
2166 msg(
M_FATAL,
"Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-up script");
2176 r6->
flags &= ~RT_ADDED;
2194#if !defined(TARGET_LINUX)
2195 const char *network;
2196#if !defined(TARGET_AIX)
2197 const char *netmask;
2199#if !defined(TARGET_ANDROID)
2200 const char *gateway;
2215#if !defined(TARGET_LINUX)
2217#if !defined(TARGET_AIX)
2220#if !defined(TARGET_ANDROID)
2231#if defined(TARGET_LINUX)
2241 msg(
M_WARN,
"ERROR: Linux route delete command failed");
2243#elif defined (_WIN32)
2257 msg(
D_ROUTE,
"Route deletion via service %s",
status ?
"succeeded" :
"failed");
2262 msg(
D_ROUTE,
"Route deletion via IPAPI %s",
status ?
"succeeded" :
"failed");
2273 msg(
D_ROUTE,
"Route deletion via IPAPI %s [adaptive]",
status ?
"succeeded" :
"failed");
2276 msg(
D_ROUTE,
"Route deletion fallback to route.exe");
2287#elif defined (TARGET_SOLARIS)
2298#elif defined(TARGET_FREEBSD)
2309#elif defined(TARGET_DRAGONFLY)
2320#elif defined(TARGET_DARWIN)
2324 argv_printf(&
argv,
"%s delete -cloning -net %s -netmask %s -interface %s",
2342#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2353#elif defined(TARGET_ANDROID)
2355 "needed. The VpnService API allows routes to be set "
2356 "on connect only and will clean up automatically.");
2357#elif defined(TARGET_AIX)
2363 network, netbits, gateway);
2368#elif defined(TARGET_HAIKU)
2381 msg(
M_FATAL,
"Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
2385 r->
flags &= ~RT_ADDED;
2397 const char *network;
2405#if !defined(TARGET_LINUX)
2406 const char *gateway;
2408#if !defined(TARGET_SOLARIS)
2409 bool gateway_needed =
false;
2411 if (r6->iface != NULL)
2414 gateway_needed =
true;
2423 gateway_needed =
true;
2432#if !defined(TARGET_LINUX) && !defined(_WIN32)
2436#if defined(TARGET_DARWIN) \
2437 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
2438 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2444 if (r6->iface != NULL && gateway_needed
2445 && IN6_IS_ADDR_LINKLOCAL(&r6->
gateway) )
2447 int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
2449 snprintf( tmp, len,
"%s%%%s", gateway, r6->iface );
2456#if defined(TARGET_LINUX)
2467 msg(
M_WARN,
"ERROR: Linux route v6 delete command failed");
2470#elif defined (_WIN32)
2480#elif defined (TARGET_SOLARIS)
2493#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2512#elif defined(TARGET_DARWIN)
2530#elif defined(TARGET_OPENBSD)
2534 network, r6->
netbits, gateway );
2539#elif defined(TARGET_NETBSD)
2543 network, r6->
netbits, gateway );
2548#elif defined(TARGET_AIX)
2552 network, r6->
netbits, gateway);
2556#elif defined(TARGET_ANDROID)
2558 "needed. The VpnService API allows routes to be set "
2559 "on connect only and will clean up automatically.");
2560#elif defined(TARGET_HAIKU)
2573 msg(
M_FATAL,
"Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-down script");
2589static const MIB_IPFORWARDTABLE *
2593 PMIB_IPFORWARDTABLE rt = NULL;
2596 status = GetIpForwardTable(NULL, &size, TRUE);
2597 if (
status == ERROR_INSUFFICIENT_BUFFER)
2599 rt = (PMIB_IPFORWARDTABLE)
gc_malloc(size,
false,
gc);
2600 status = GetIpForwardTable(rt, &size, TRUE);
2603 msg(
D_ROUTE,
"NOTE: GetIpForwardTable returned error: %s (code=%u)",
2614 const in_addr_t gateway,
2631 const IP_ADAPTER_INFO *adapters,
2632 const in_addr_t gateway)
2665 bool adapter_up =
false;
2679 for (r = rl->
routes, len = 0; r; r = r->
next, ++len)
2691 msg(
D_ROUTE,
"TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
2697 adapter_up ?
"up" :
"down");
2703static const MIB_IPFORWARDROW *
2707 DWORD lowest_metric = MAXDWORD;
2708 const MIB_IPFORWARDROW *ret = NULL;
2713 for (DWORD i = 0; i < routes->dwNumEntries; ++i)
2715 const MIB_IPFORWARDROW *row = &routes->table[i];
2716 const in_addr_t net = ntohl(row->dwForwardDest);
2717 const in_addr_t mask = ntohl(row->dwForwardMask);
2718 const DWORD index = row->dwForwardIfIndex;
2719 const DWORD metric = row->dwForwardMetric1;
2728 if (!net && !mask && metric < lowest_metric)
2731 lowest_metric = metric;
2757 DWORD best_if_index;
2763 status = GetBestInterfaceEx((
struct sockaddr *)dest, &best_if_index);
2766 msg(
D_ROUTE,
"NOTE: GetBestInterfaceEx returned error: %s (code=%u)",
2772 msg(
D_ROUTE_DEBUG,
"GetBestInterfaceEx() returned if=%d", (
int)best_if_index);
2777 SOCKADDR_INET best_src;
2779 status = GetBestRoute2(&luid, best_if_index, NULL,
2780 dest, 0, best_route, &best_src);
2783 msg(
D_ROUTE,
"NOTE: GetIpForwardEntry2 returned error: %s (code=%u)",
2803 sa.si_family = AF_INET;
2804 sa.Ipv4.sin_addr.s_addr = htonl(dest);
2807 MIB_IPFORWARD_ROW2 best_route;
2816 rgi->
gateway.
addr = ntohl(best_route.NextHop.Ipv4.sin_addr.S_un.S_addr);
2829 memcpy(rgi->
hwaddr, ai->Address, 6);
2833 in_addr_t nm = inet_addr(ai->IpAddressList.IpMask.String);
2853 bool on_tun =
false;
2858 ret = tun_adapter->Index;
2869 msg(
M_WARN,
"Warning: route gateway is not reachable on any active network adapters: %s",
2875 msg(
M_WARN,
"Warning: route gateway is ambiguous: %s (%d matches)",
2901 SOCKADDR_INET DestinationAddress;
2902 CLEAR(DestinationAddress);
2903 DestinationAddress.si_family = AF_INET6;
2906 DestinationAddress.Ipv6.sin6_addr = *dest;
2909 MIB_IPFORWARD_ROW2 BestRoute;
2919 BestRoute.InterfaceIndex,
2920 print_in6_addr( BestRoute.DestinationPrefix.Prefix.Ipv6.sin6_addr, 0, &
gc),
2921 BestRoute.DestinationPrefix.PrefixLength,
2923 msg(
D_ROUTE,
"GDG6: Metric=%d, Loopback=%d, AA=%d, I=%d",
2924 (
int) BestRoute.Metric,
2925 (
int) BestRoute.Loopback,
2926 (
int) BestRoute.AutoconfigureAddress,
2927 (
int) BestRoute.Immortal );
2934 if (IN6_IS_ADDR_UNSPECIFIED(&BestRoute.NextHop.Ipv6.sin6_addr) )
2954 MIB_IPFORWARDROW fr;
2956 fr.dwForwardDest = htonl(r->
network);
2957 fr.dwForwardMask = htonl(r->
netmask);
2958 fr.dwForwardPolicy = 0;
2959 fr.dwForwardNextHop = htonl(r->
gateway);
2960 fr.dwForwardIfIndex = if_index;
2961 fr.dwForwardType = 4;
2962 fr.dwForwardProto = 3;
2963 fr.dwForwardAge = 0;
2964 fr.dwForwardNextHopAS = 0;
2973 msg(
M_WARN,
"Warning: address %s is not a network address in relation to netmask %s",
2978 status = CreateIpForwardEntry(&fr);
2984 else if (
status == ERROR_OBJECT_ALREADY_EXISTS)
2991 const unsigned int forward_metric_limit = 2048;
2993 for (; fr.dwForwardMetric1 <= forward_metric_limit; ++fr.dwForwardMetric1)
2997 for (fr.dwForwardType = 4; fr.dwForwardType >= 3; --fr.dwForwardType)
2999 status = CreateIpForwardEntry(&fr);
3002 msg(
D_ROUTE,
"ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%u and dwForwardType=%u",
3003 (
unsigned int)fr.dwForwardMetric1,
3004 (
unsigned int)fr.dwForwardType);
3008 else if (
status != ERROR_BAD_ARGUMENTS)
3018 if (
status == ERROR_OBJECT_ALREADY_EXISTS)
3024 msg(
M_WARN,
"ERROR: route addition failed using CreateIpForwardEntry: "
3026 (
unsigned int)
status, (
unsigned int)if_index);
3046 MIB_IPFORWARDROW fr;
3049 fr.dwForwardDest = htonl(r->
network);
3050 fr.dwForwardMask = htonl(r->
netmask);
3051 fr.dwForwardPolicy = 0;
3052 fr.dwForwardNextHop = htonl(r->
gateway);
3053 fr.dwForwardIfIndex = if_index;
3055 status = DeleteIpForwardEntry(&fr);
3063 msg(
M_WARN,
"ERROR: route deletion failed using DeleteIpForwardEntry: %s",
3090 msg(
M_WARN,
"ERROR: route %s failed using service: %s [status=%u if_index=%d]",
3121 .prefix.ipv4.s_addr = htonl(r->
network),
3122 .gateway.ipv4.s_addr = htonl(r->
gateway),
3123 .iface = { .index = if_index, .name =
"" },
3128 if (
msg.prefix_len == -1)
3130 msg.prefix_len = 32;
3144 PMIB_IPFORWARD_ROW2 fwd_row;
3149 fwd_row->ValidLifetime = 0xffffffff;
3150 fwd_row->PreferredLifetime = 0xffffffff;
3151 fwd_row->Protocol = MIB_IPPROTO_NETMGMT;
3153 fwd_row->DestinationPrefix.Prefix.si_family = AF_INET6;
3154 fwd_row->DestinationPrefix.Prefix.Ipv6.sin6_addr = r->
network;
3155 fwd_row->DestinationPrefix.PrefixLength = (UINT8) r->
netbits;
3156 fwd_row->NextHop.si_family = AF_INET6;
3157 fwd_row->NextHop.Ipv6.sin6_addr = r->
gateway;
3166 inet_pton(AF_INET6,
"fe80::8", &fwd_row->NextHop.Ipv6.sin6_addr);
3174 if (err != NO_ERROR)
3178 fwd_row->InterfaceLuid = luid;
3179 fwd_row->InterfaceIndex = 0;
3184 err = CreateIpForwardEntry2(fwd_row);
3188 err = DeleteIpForwardEntry2(fwd_row);
3192 if (err != NO_ERROR)
3197 msg(
M_WARN,
"ERROR: route %s failed using ipapi: %s [status=%lu if_index=%lu]",
3199 fwd_row->InterfaceIndex);
3203 msg(
D_ROUTE,
"IPv6 route addition using ipapi failed because route exists");
3208 msg(
D_ROUTE,
"IPv6 route %s using ipapi", add ?
"added" :
"deleted");
3246 inet_pton(AF_INET6,
"fe80::8", &
msg.gateway.ipv6);
3252 msg.iface.name[
sizeof(
msg.iface.name) - 1] =
'\0';
3259 add ?
"addition" :
"deletion",
3295 buf_printf(&out,
"%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
3299 (
int)
r->dwForwardPolicy,
3300 (
int)
r->dwForwardIfIndex,
3301 (
int)
r->dwForwardType,
3302 (
int)
r->dwForwardProto,
3303 (
int)
r->dwForwardAge,
3304 (
int)
r->dwForwardNextHopAS,
3305 (
int)
r->dwForwardMetric1,
3306 (
int)
r->dwForwardMetric2,
3307 (
int)
r->dwForwardMetric3,
3308 (
int)
r->dwForwardMetric4,
3309 (
int)
r->dwForwardMetric5);
3323 msg(msglev,
"SYSTEM ROUTING TABLE");
3326 for (DWORD i = 0; i < rt->dwNumEntries; ++i)
3334#elif defined(TARGET_ANDROID)
3349 rgi->
gateway.
addr = 127 << 24 |
'd' << 16 |
'g' << 8 |
'w';
3351 strcpy(rgi->iface,
"android-gw");
3372 strcpy(rgi6->iface,
"android-gw");
3375#elif defined(TARGET_LINUX)
3382 char best_name[IFNAMSIZ];
3388 if (net_route_v4_best_gw(ctx, &dest, &rgi->
gateway.
addr, best_name) == 0)
3400 struct ifreq *ifr, *ifend;
3401 in_addr_t addr, netmask;
3404 struct ifreq ifs[20];
3406 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
3411 ifc.ifc_len =
sizeof(ifs);
3413 if (ioctl(sd, SIOCGIFCONF, &ifc) < 0)
3415 msg(
M_WARN,
"GDG: ioctl(SIOCGIFCONF) failed");
3420 ifend = ifs + (ifc.ifc_len /
sizeof(
struct ifreq));
3421 for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
3423 if (ifr->ifr_addr.sa_family == AF_INET)
3426 addr = ntohl(((
struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr);
3429 strncpynt(ifreq.ifr_name, ifr->ifr_name,
sizeof(ifreq.ifr_name));
3432 if (ioctl(sd, SIOCGIFFLAGS, &ifreq) < 0)
3436 if (!(ifreq.ifr_flags & IFF_UP))
3445 if (strcmp(ifreq.ifr_name, best_name))
3451 if ((ifreq.ifr_flags & IFF_POINTOPOINT) && ioctl(sd, SIOCGIFDSTADDR, &ifreq) >= 0)
3453 rgi->
gateway.
addr = ntohl(((
struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
3456 rgi->
flags &= ~RGI_ON_LINK;
3464 if (ioctl(sd, SIOCGIFNETMASK, &ifreq) < 0)
3468 netmask = ntohl(((
struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
3482 strncpynt(rgi->iface, ifreq.ifr_name,
sizeof(rgi->iface));
3486 memset(&ifreq.ifr_hwaddr, 0,
sizeof(
struct sockaddr));
3487 if (ioctl(sd, SIOCGIFHWADDR, &ifreq) < 0)
3489 msg(
M_WARN,
"GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
3492 memcpy(rgi->
hwaddr, &ifreq.ifr_hwaddr.sa_data, 6);
3535 if (strlen(rgi6->iface) > 0)
3553#elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) \
3554 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
3555 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
3557#include <sys/types.h>
3558#include <sys/socket.h>
3559#include <netinet/in.h>
3560#include <net/route.h>
3561#include <net/if_dl.h>
3562#if !defined(TARGET_SOLARIS)
3567 struct rt_msghdr m_rtm;
3587#if defined(TARGET_DARWIN)
3589 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
3590#elif defined(TARGET_NETBSD)
3591#define ROUNDUP(a) RT_ROUNDUP(a)
3594 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
3597#if defined(TARGET_SOLARIS)
3598#define NEXTADDR(w, u) \
3599 if (rtm_addrs & (w)) { \
3600 l = sizeof(u); memmove(cp, &(u), l); cp += ROUNDUP(l); \
3603#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in)))
3605#define NEXTADDR(w, u) \
3606 if (rtm_addrs & (w)) { \
3607 l = ((struct sockaddr *)&(u))->sa_len; memmove(cp, &(u), l); cp += ROUNDUP(l); \
3610#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
3613#define max(a, b) ((a) > (b) ? (a) : (b))
3619 struct rtmsg m_rtmsg;
3621 int seq, l, pid, rtm_addrs;
3623 struct sockaddr so_dst, so_mask;
3624 char *cp = m_rtmsg.m_space;
3625 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
3626 struct rt_msghdr *rtm_aux;
3628#define rtm m_rtmsg.m_rtm
3635#ifdef TARGET_OPENBSD
3636 rtm_addrs = RTA_DST | RTA_NETMASK;
3638 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
3641 bzero(&m_rtmsg,
sizeof(m_rtmsg));
3642 bzero(&so_dst,
sizeof(so_dst));
3643 bzero(&so_mask,
sizeof(so_mask));
3644 bzero(&rtm,
sizeof(
struct rt_msghdr));
3646 rtm.rtm_type = RTM_GET;
3647 rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
3648 rtm.rtm_version = RTM_VERSION;
3649 rtm.rtm_seq = ++seq;
3650#ifdef TARGET_OPENBSD
3651 rtm.rtm_tableid = getrtable();
3653 rtm.rtm_addrs = rtm_addrs;
3655 so_dst.sa_family = AF_INET;
3656 so_mask.sa_family = AF_INET;
3658#ifndef TARGET_SOLARIS
3659 so_dst.sa_len =
sizeof(
struct sockaddr_in);
3660 so_mask.sa_len =
sizeof(
struct sockaddr_in);
3663 NEXTADDR(RTA_DST, so_dst);
3664 NEXTADDR(RTA_NETMASK, so_mask);
3666 rtm.rtm_msglen = l = cp - (
char *)&m_rtmsg;
3669 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
3675 if (
write(sockfd, (
char *)&m_rtmsg, l) < 0)
3682 l =
read(sockfd, (
char *)&m_rtmsg,
sizeof(m_rtmsg));
3683 }
while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3689 cp = ((
char *)(rtm_aux + 1));
3690 if (rtm_aux->rtm_addrs)
3692 for (i = 1; i; i <<= 1)
3694 if (i & rtm_aux->rtm_addrs)
3696 sa = (
struct sockaddr *)cp;
3697 if (i == RTA_GATEWAY)
3701 else if (i == RTA_IFP)
3718 rgi->
gateway.
addr = ntohl(((
struct sockaddr_in *)gate)->sin_addr.s_addr);
3727 const struct sockaddr_dl *adl = (
struct sockaddr_dl *) ifp;
3728 if (adl->sdl_nlen && adl->sdl_nlen <
sizeof(rgi->iface))
3730 memcpy(rgi->iface, adl->sdl_data, adl->sdl_nlen);
3731 rgi->iface[adl->sdl_nlen] =
'\0';
3742 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3750 ifr.ifr_addr.sa_family = AF_INET;
3751 strncpynt(ifr.ifr_name, rgi->iface, IFNAMSIZ);
3753 if (ioctl(sockfd, SIOCGIFNETMASK, (
char *)&ifr) < 0)
3761 rgi->
gateway.
netmask = ntohl(((
struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
3768#if defined(TARGET_SOLARIS)
3770 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3777 struct ifreq ifreq = { 0 };
3780 strncpynt(ifreq.ifr_name, rgi->iface,
sizeof(ifreq.ifr_name));
3781 if (ioctl(sockfd, SIOCGIFHWADDR, &ifreq) < 0)
3783 msg(
M_WARN,
"GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
3787 memcpy(rgi->
hwaddr, &ifreq.ifr_addr.sa_data, 6);
3791 struct ifaddrs *ifap, *ifa;
3793 if (getifaddrs(&ifap) != 0)
3799 for (ifa = ifap; ifa; ifa = ifa->ifa_next)
3801 if (ifa->ifa_addr != NULL
3802 && ifa->ifa_addr->sa_family == AF_LINK
3803 && !strncmp(ifa->ifa_name, rgi->iface, IFNAMSIZ) )
3805 struct sockaddr_dl *sdl = (
struct sockaddr_dl *)ifa->ifa_addr;
3806 memcpy(rgi->
hwaddr, LLADDR(sdl), 6);
3830#if defined(TARGET_SOLARIS)
3832#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in6)))
3840 struct rtmsg m_rtmsg;
3842 int seq, l, pid, rtm_addrs;
3844 struct sockaddr_in6 so_dst, so_mask;
3845 char *cp = m_rtmsg.m_space;
3846 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
3847 struct rt_msghdr *rtm_aux;
3854#ifdef TARGET_OPENBSD
3855 rtm_addrs = RTA_DST | RTA_NETMASK;
3857 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
3860 bzero(&m_rtmsg,
sizeof(m_rtmsg));
3861 bzero(&so_dst,
sizeof(so_dst));
3862 bzero(&so_mask,
sizeof(so_mask));
3863 bzero(&rtm,
sizeof(
struct rt_msghdr));
3865 rtm.rtm_type = RTM_GET;
3866 rtm.rtm_flags = RTF_UP;
3867 rtm.rtm_version = RTM_VERSION;
3868 rtm.rtm_seq = ++seq;
3869#ifdef TARGET_OPENBSD
3870 rtm.rtm_tableid = getrtable();
3873 so_dst.sin6_family = AF_INET6;
3874 so_mask.sin6_family = AF_INET6;
3877 && !IN6_IS_ADDR_UNSPECIFIED(dest) )
3879 so_dst.sin6_addr = *dest;
3881 rtm_addrs &= ~RTA_NETMASK;
3884 rtm.rtm_addrs = rtm_addrs;
3886#ifndef TARGET_SOLARIS
3887 so_dst.sin6_len =
sizeof(
struct sockaddr_in6);
3888 so_mask.sin6_len =
sizeof(
struct sockaddr_in6);
3891 NEXTADDR(RTA_DST, so_dst);
3892 NEXTADDR(RTA_NETMASK, so_mask);
3894 rtm.rtm_msglen = l = cp - (
char *)&m_rtmsg;
3897 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
3903 if (
write(sockfd, (
char *)&m_rtmsg, l) < 0)
3911 l =
read(sockfd, (
char *)&m_rtmsg,
sizeof(m_rtmsg));
3913 while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3920 cp = ((
char *)(rtm_aux + 1));
3921 if (rtm_aux->rtm_addrs)
3923 for (i = 1; i; i <<= 1)
3925 if (i & rtm_aux->rtm_addrs)
3927 sa = (
struct sockaddr *)cp;
3928 if (i == RTA_GATEWAY)
3932 else if (i == RTA_IFP)
3948 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *)gate;
3949 struct in6_addr gw = s6->sin6_addr;
3951#ifndef TARGET_SOLARIS
3956 if (gate->sa_len ==
sizeof(
struct sockaddr_in6)
3957 && IN6_IS_ADDR_LINKLOCAL(&gw) )
3959 gw.s6_addr[2] = gw.s6_addr[3] = 0;
3962 if (gate->sa_len !=
sizeof(
struct sockaddr_in6)
3963 || IN6_IS_ADDR_UNSPECIFIED(&gw) )
3977 const struct sockaddr_dl *adl = (
struct sockaddr_dl *) ifp;
3978 if (adl->sdl_nlen && adl->sdl_nlen <
sizeof(rgi6->iface))
3980 memcpy(rgi6->iface, adl->sdl_data, adl->sdl_nlen);
3995#elif defined(TARGET_HAIKU)
4002 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
4005 msg(
M_ERRNO,
"%s: Error opening socket for AF_INET", __func__);
4009 struct ifconf config;
4010 config.ifc_len =
sizeof(config.ifc_value);
4011 if (ioctl(sockfd, SIOCGRTSIZE, &config,
sizeof(
struct ifconf)) < 0)
4013 msg(
M_ERRNO,
"%s: Error getting routing table size", __func__);
4017 uint32 size = (uint32)config.ifc_value;
4023 void *
buffer = malloc(size);
4026 config.ifc_len = size;
4028 if (ioctl(sockfd, SIOCGRTTABLE, &config,
sizeof(
struct ifconf)) < 0)
4034 struct ifreq *
interface = (struct ifreq *)
buffer;
4035 struct ifreq *end = (
struct ifreq *)((uint8 *)
buffer + size);
4037 while (interface < end)
4039 struct route_entry
route = interface->ifr_route;
4040 if ((
route.flags & RTF_GATEWAY) != 0 && (
route.flags & RTF_DEFAULT) != 0)
4042 rgi->
gateway.
addr = ntohl(((
struct sockaddr_in *)
route.gateway)->sin_addr.s_addr);
4044 strncpy(rgi->iface, interface->ifr_name,
sizeof(rgi->iface));
4047 int32 address_size = 0;
4048 if (
route.destination != NULL)
4050 address_size +=
route.destination->sa_len;
4052 if (
route.mask != NULL)
4054 address_size +=
route.mask->sa_len;
4056 if (
route.gateway != NULL)
4058 address_size +=
route.gateway->sa_len;
4061 interface = (struct ifreq *)((addr_t)
interface +
IF_NAMESIZE
4062 + sizeof(struct route_entry) + address_size);
4110 msg(
D_ROUTE,
"no support for get_default_gateway_ipv6() on this system");
4120 const int addrlen =
sizeof(in_addr_t) * 8;
4122 if ((network & netmask) == network)
4124 for (i = 0; i <= addrlen; ++i)
4127 if (mask == netmask)
4151 const int addrlen =
sizeof(in_addr_t) * 8;
4153 for (i = 0; i <= addrlen; ++i)
4156 if (mask == netmask)
4187 bool succeed =
false;
4193 iplist = iplist->Next;
4257 const in_addr_t nonlocal_netmask = 0x80000000L;
4264 for (DWORD i = 0; i < rt->dwNumEntries; ++i)
4266 const MIB_IPFORWARDROW *row = &rt->table[i];
4267 const in_addr_t net = ntohl(row->dwForwardDest);
4268 const in_addr_t mask = ntohl(row->dwForwardMask);
4269 if (mask > nonlocal_netmask && (addr & mask) == net)
void argv_msg(const int msglev, 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.
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.
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)
void gc_addspecial(void *addr, void(*free_function)(void *), struct gc_arena *a)
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
#define ALLOC_OBJ_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 void gc_freeaddrinfo_callback(void *addr)
static struct gc_arena gc_new(void)
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)
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)
#define OPENVPN_STATE_ADD_ROUTES
static void net_ctx_reset(openvpn_net_ctx_t *ctx)
#define IPV4_NETMASK_HOST
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
static void undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
static bool route_ipv6_match_host(const struct route_ipv6 *r6, const struct in6_addr *host)
static void add_host_route_if_nonlocal(struct route_bypass *rb, const in_addr_t addr)
bool add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
bool is_special_addr(const char *addr_str)
struct route_option_list * clone_route_option_list(const struct route_option_list *src, struct gc_arena *a)
void setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6)
static void clear_route_list(struct route_list *rl)
static void test_route_helper(bool *ret, int *count, int *good, int *ambig, const IP_ADAPTER_INFO *adapters, const in_addr_t gateway)
static void del_bypass_routes(struct route_bypass *rb, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
static bool del_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt)
static bool redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
static bool add_route3(in_addr_t network, in_addr_t netmask, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
static void add_host_route_array(struct route_bypass *rb, const IP_ADDR_STRING *iplist)
int netmask_to_netbits2(in_addr_t netmask)
struct route_ipv6_option_list * new_route_ipv6_option_list(struct gc_arena *a)
static bool init_route(struct route_ipv4 *r, struct addrinfo **network_list, const struct route_option *ro, const struct route_list *rl)
static const char * route_string(const struct route_ipv4 *r, struct gc_arena *gc)
static bool get_special_addr(const struct route_list *rl, const char *string, in_addr_t *out, bool *status)
bool test_routes(const struct route_list *rl, const struct tuntap *tt)
static void add_block_local_routes(struct route_list *rl)
bool block_local_needed(const struct route_list *rl)
Get the decision whether to block traffic to local networks while the VPN is connected.
void get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6, const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
static const MIB_IPFORWARDTABLE * get_windows_routing_table(struct gc_arena *gc)
static DWORD get_best_route(struct gc_arena *gc, SOCKADDR_INET *dest, MIB_IPFORWARD_ROW2 *best_route)
Determines the best route to a destination for both IPv4 and IPv6.
void show_routes(int msglev)
static const char * format_route_entry(const MIB_IPFORWARDROW *r, struct gc_arena *gc)
static void print_route_option(const struct route_option *ro, int level)
static int add_route_service(const struct route_ipv4 *, const struct tuntap *)
bool init_route_ipv6_list(struct route_ipv6_list *rl6, const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, const struct in6_addr *remote_host_ipv6, struct env_set *es, openvpn_net_ctx_t *ctx)
void print_route_options(const struct route_option_list *rol, int level)
static void delete_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)
static bool del_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *)
void route_list_add_vpn_gateway(struct route_list *rl, struct env_set *es, const in_addr_t addr)
void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, const char *metric, int table_id)
void print_default_gateway(const int msglevel, const struct route_gateway_info *rgi, const struct route_ipv6_gateway_info *rgi6)
void copy_route_option_list(struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a)
void copy_route_ipv6_option_list(struct route_ipv6_option_list *dest, const struct route_ipv6_option_list *src, struct gc_arena *a)
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)
static int test_route(const IP_ADAPTER_INFO *adapters, const in_addr_t gateway, DWORD *index)
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)
static void print_route(const struct route_ipv4 *r, int level)
static bool del_route_service(const struct route_ipv4 *, const struct tuntap *)
static int local_route(in_addr_t network, in_addr_t netmask, in_addr_t gateway, const struct route_gateway_info *rgi)
static int add_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *)
static bool is_on_link(const int is_local_route, const unsigned int flags, const struct route_gateway_info *rgi)
static const MIB_IPFORWARDROW * get_default_gateway_row(const MIB_IPFORWARDTABLE *routes)
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.
static int route_ipv6_ipapi(bool add, const struct route_ipv6 *, const struct tuntap *)
static void add_block_local_item(struct route_list *rl, const struct route_gateway_address *gateway, in_addr_t target)
struct route_ipv6_option_list * clone_route_ipv6_option_list(const struct route_ipv6_option_list *src, struct gc_arena *a)
static const char * show_opt(const char *option)
static bool init_route_ipv6(struct route_ipv6 *r6, const struct route_ipv6_option *r6o, const struct route_ipv6_list *rl6)
struct route_option_list * new_route_option_list(struct gc_arena *a)
int test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi)
bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx)
static int add_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index)
void delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, const struct env_set *es, openvpn_net_ctx_t *ctx)
static int do_route_ipv6_service(const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
static int do_route_service(const bool add, const route_message_t *rt, const size_t size, HANDLE pipe)
void route_ipv6_clear_host_bits(struct route_ipv6 *r6)
static void clear_route_ipv6_list(struct route_ipv6_list *rl6)
void delete_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx)
void print_routes(const struct route_list *rl, int level)
bool netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
static void setenv_route_addr(struct env_set *es, const char *key, const in_addr_t addr, int i)
static DWORD windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt)
static int do_route_ipv4_service(const bool add, const struct route_ipv4 *r, const struct tuntap *tt)
void setenv_routes(struct env_set *es, const struct route_list *rl)
static bool add_bypass_routes(struct route_bypass *rb, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
static void get_bypass_addresses(struct route_bypass *rb, const unsigned int flags)
static bool is_route_parm_defined(const char *parm)
static void setenv_route_ipv6(struct env_set *es, const struct route_ipv6 *r6, int i)
static bool add_bypass_address(struct route_bypass *rb, const in_addr_t a)
static void setenv_route(struct env_set *es, const struct route_ipv4 *r, int i)
void add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask, const char *gateway, const char *metric, int table_id)
static void del_route3(in_addr_t network, in_addr_t netmask, in_addr_t gateway, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es, openvpn_net_ctx_t *ctx)
#define RL_DID_REDIRECT_DEFAULT_GATEWAY
#define RTSA_REMOTE_ENDPOINT
#define RGI_HWADDR_DEFINED
static in_addr_t netbits_to_netmask(const int netbits)
#define ROUTE_METHOD_SERVICE
#define RGI_IFACE_DEFINED
#define ROUTE_METHOD_IPAPI
#define RT_METRIC_DEFINED
#define ROUTE_DELETE_FIRST
#define TLA_NOT_IMPLEMENTED
#define ROUTE_METHOD_ADAPTIVE
#define ROUTE_METHOD_MASK
#define RTSA_DEFAULT_METRIC
#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)
bool get_ipv6_addr(const char *hostname, struct in6_addr *network, unsigned int *netbits, int msglevel)
Translate an IPv6 addr or hostname from string form to in6_addr.
int openvpn_getaddrinfo(unsigned int flags, const char *hostname, const char *servname, int resolve_retry_seconds, struct signal_info *sig_info, int ai_family, struct addrinfo **res)
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 IPV4_INVALID_ADDR
#define GETADDR_HOST_ORDER
#define GETADDR_WARN_ON_SIGNAL
Wrapper structure for dynamically allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
Garbage collection arena used to keep track of dynamically allocated memory.
Container for unidirectional cipher and HMAC key material.
in_addr_t bypass[N_ROUTE_BYPASS]
struct route_gateway_address addrs[RGI_N_ADDRESSES]
struct route_gateway_address gateway
const struct route_option * option
struct in6_addr addr_ipv6
struct route_ipv6_gateway_address gateway
struct route_ipv6_gateway_address addrs[RGI_N_ADDRESSES]
struct route_ipv6_gateway_info rgi6
struct route_ipv6 * routes_ipv6
struct in6_addr remote_host_ipv6
struct in6_addr remote_endpoint_ipv6
struct route_ipv6_option * routes_ipv6
struct route_ipv6_option * next
struct route_gateway_info rgi
struct route_ipv4 * routes
struct route_special_addr spec
struct route_option * routes
struct route_option * next
struct route_bypass bypass
in_addr_t remote_endpoint
bool did_ifconfig_ipv6_setup
if the internal variables related to ifconfig-ipv6 of this struct have been set up.
struct tuntap_options options
bool did_ifconfig_setup
if the internal variables related to ifconfig of this struct have been set up.
const IP_ADAPTER_INFO * get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
bool is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list)
const IP_ADAPTER_INFO * get_adapter_info(DWORD index, struct gc_arena *gc)
const IP_PER_ADAPTER_INFO * get_per_adapter_info(const DWORD index, 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)
const IP_ADAPTER_INFO * get_adapter_info_list(struct gc_arena *gc)
const IP_ADAPTER_INFO * get_adapter(const IP_ADAPTER_INFO *ai, DWORD index)
DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list, const in_addr_t ip, int *count, in_addr_t *netmask)
#define TUN_ADAPTER_INDEX_INVALID
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
bool send_msg_iservice(HANDLE pipe, const void *data, size_t size, ack_message_t *ack, const char *context)
void netcmd_semaphore_release(void)
char * get_win_sys_path(void)
void netcmd_semaphore_lock(void)
#define WIN_ROUTE_PATH_SUFFIX