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};
349 special.s_addr = htonl(special.s_addr);
350 char buf[INET_ADDRSTRLEN];
351 inet_ntop(AF_INET, &special, buf,
sizeof(buf));
353 AF_INET, network_list);
358 ro->
network, NULL, 0, NULL, AF_INET, network_list);
417 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");
430 msg(
M_WARN, PACKAGE_NAME
" ROUTE: route metric for network %s (%s) must be >= 0",
448 msg(
M_WARN, PACKAGE_NAME
" ROUTE: failed to parse/resolve route for host/network: %s",
470 msg(
M_WARN, PACKAGE_NAME
"ROUTE6: cannot parse gateway spec '%s'", r6o->
gateway );
486 msg(
M_WARN, PACKAGE_NAME
" ROUTE: route metric for network %s (%s) must be >= 0",
504 msg(
M_WARN, PACKAGE_NAME
" ROUTE: failed to parse/resolve route for host/network: %s",
559 const in_addr_t addr)
581 l2 = ((~gateway->netmask)+1)>>1;
583 r1->gateway = target;
585 r1->netmask = ~(l2-1);
599#ifndef TARGET_ANDROID
625 && (rl->
rgi.
flags & rgi_needed) == rgi_needed
633 const char *remote_endpoint,
635 in_addr_t remote_host,
662#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
678 bool defined =
false;
695 msg(
M_WARN, PACKAGE_NAME
" ROUTE: failed to parse/resolve default gateway: %s",
718 struct addrinfo *netlist = NULL;
727 struct addrinfo *curele;
728 for (curele = netlist; curele; curele = curele->ai_next)
733 new->
network = ntohl(((
struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
755 const struct in6_addr *host )
757 unsigned int bits = r6->
netbits;
766 for (i = 0; bits >= 8; i++, bits -= 8)
768 if (r6->
network.s6_addr[i] != host->s6_addr[i])
779 mask = 0xff << (8-bits);
781 if ( (r6->
network.s6_addr[i] & mask) == (host->s6_addr[i] & mask ))
792 const char *remote_endpoint,
794 const struct in6_addr *remote_host_ipv6,
800 bool need_remote_ipv6_route;
806 if (remote_host_ipv6)
812 if (default_metric >= 0)
825#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
836 if (inet_pton( AF_INET6, remote_endpoint,
843 msg(
M_WARN, PACKAGE_NAME
" ROUTE: failed to parse/resolve VPN endpoint: %s", remote_endpoint);
851 need_remote_ipv6_route =
false;
868#ifndef TARGET_ANDROID
876 need_remote_ipv6_route =
true;
877 msg(
D_ROUTE,
"ROUTE6: %s/%d overlaps IPv6 remote %s, adding host route to VPN endpoint",
887 if (need_remote_ipv6_route)
895 r6->
network = *remote_host_ipv6;
905 r6->iface = rl6->
rgi6.iface;
914 msg(
M_WARN,
"ROUTE6: IPv6 route overlaps with IPv6 remote address, but could not determine IPv6 gateway address + interface, expect failure\n" );
970 for (
int i = 0; i < rb->
n_bypass; ++i)
1012 const char err[] =
"NOTE: unable to redirect IPv4 default gateway --";
1021 msg(
M_WARN,
"%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err);
1032 msg(
M_WARN,
"%s Cannot read current default gateway from system", err);
1037#ifndef TARGET_ANDROID
1070 dmsg(
D_ROUTE,
"ROUTE remote_host protocol differs from tunneled");
1077 &rl->
rgi,
es, ctx) && ret;
1133 rl->
iflags &= ~RL_DID_LOCAL;
1184 rl->
iflags &= ~RL_DID_REDIRECT_DEFAULT_GATEWAY;
1200 msg(
M_INFO,
"WARNING: OpenVPN was configured to add an IPv4 "
1201 "route. However, no IPv4 has been configured for %s, "
1202 "therefore the route installation may fail or may not work "
1206#ifdef ENABLE_MANAGEMENT
1235 msg(
M_INFO,
"WARNING: OpenVPN was configured to add an IPv6 "
1236 "route. However, no IPv6 has been configured for %s, "
1237 "therefore the route installation may fail or may not work "
1267 rl->
iflags &= ~RL_ROUTES_ADDED;
1284 rl6->
iflags &= ~RL_ROUTES_ADDED;
1300 return "default (not set)";
1311 msg(level,
" route %s/%s/%s/%s",
1325 msg(level,
" [redirect_default_gateway local=%d]",
1371 msg(msglevel,
"%s",
BSTR(&out));
1402 msg(msglevel,
"%s",
BSTR(&out));
1531 && (rgi->
flags & rgi_needed) == rgi_needed
1533 && netmask == 0xFFFFFFFF)
1543 for (i = 0; i < rgi->
n_addrs; ++i)
1558#if defined(TARGET_LINUX) || defined(_WIN32) || defined(TARGET_DARWIN)
1585#if !defined(TARGET_LINUX)
1587#if !defined(TARGET_AIX)
1599#if defined(TARGET_LINUX)
1600 const char *
iface = NULL;
1618 msg(
D_ROUTE,
"NOTE: Linux route add command failed because route exists");
1623 msg(
M_WARN,
"ERROR: Linux route add command failed");
1627#elif defined (TARGET_ANDROID)
1632 snprintf(out,
sizeof(out),
"%s %s %s dev %s", network, netmask, gateway, rgi->iface);
1636 snprintf(out,
sizeof(out),
"%s %s %s", network, netmask, gateway);
1638 bool ret = management_android_control(
management,
"ROUTE", out);
1641#elif defined (_WIN32)
1662 const char *method =
"service";
1676 "ERROR: Windows route add command failed");
1679 method =
"route.exe";
1684 method =
"ipapi [adaptive]";
1687 msg(
D_ROUTE,
"Route addition fallback to route.exe");
1690 "ERROR: Windows route add command failed [adaptive]");
1693 method =
"route.exe";
1702 msg(
D_ROUTE,
"Route addition via %s %s", method,
1707#elif defined (TARGET_SOLARIS)
1733 "ERROR: Solaris route add command failed");
1736#elif defined(TARGET_FREEBSD)
1757 "ERROR: FreeBSD route add command failed");
1760#elif defined(TARGET_DRAGONFLY)
1781 "ERROR: DragonFly route add command failed");
1784#elif defined(TARGET_DARWIN)
1815 "ERROR: OS X route add command failed");
1818#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1839 "ERROR: OpenBSD/NetBSD route add command failed");
1842#elif defined(TARGET_AIX)
1848 network, netbits, gateway);
1851 "ERROR: AIX route add command failed");
1855#elif defined(TARGET_HAIKU)
1866 "ERROR: Haiku inet route add command failed");
1870 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");
1880 r->
flags &= ~RT_ADDED;
1899 int bits_to_clear = 128 - r6->
netbits;
1901 while (
byte >= 0 && bits_to_clear > 0)
1903 if (bits_to_clear >= 8)
1905 r6->
network.s6_addr[
byte--] = 0; bits_to_clear -= 8;
1909 r6->
network.s6_addr[
byte--] &= (0xff << bits_to_clear); bits_to_clear = 0;
1916 unsigned int flags,
const struct env_set *
es,
1920 bool gateway_needed =
false;
1932 if (r6->iface != NULL)
1935 if (!IN6_IS_ADDR_UNSPECIFIED(&r6->
gateway) )
1937 gateway_needed =
true;
1946#if defined(TARGET_DARWIN) \
1947 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1948 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1954 if (r6->iface != NULL && gateway_needed
1955 && IN6_IS_ADDR_LINKLOCAL(&r6->
gateway) )
1957 int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
1959 snprintf( tmp, len,
"%s%%%s", gateway, r6->iface );
1965 msg(
D_ROUTE,
"add_route_ipv6(%s/%d -> %s metric %d) dev %s",
1968 msg(
D_ROUTE,
"add_route_ipv6(%s/%d -> %s metric %d) IF %lu",
1987 gateway_needed =
true;
1990 if (gateway_needed && IN6_IS_ADDR_UNSPECIFIED(&r6->
gateway))
1992 msg(
M_WARN,
"ROUTE6 WARNING: " PACKAGE_NAME
" needs a gateway "
1993 "parameter for a --route-ipv6 option and no default was set via "
1994 "--ifconfig-ipv6 or --route-ipv6-gateway option. Not installing "
1995 "IPv6 route to %s/%d.", network, r6->
netbits);
2000#if defined(TARGET_LINUX)
2009 gateway_needed ? &r6->
gateway : NULL,
2013 msg(
D_ROUTE,
"NOTE: Linux route add command failed because route exists");
2018 msg(
M_WARN,
"ERROR: Linux route add command failed");
2022#elif defined (TARGET_ANDROID)
2025 snprintf(out,
sizeof(out),
"%s/%d %s", network, r6->
netbits, device);
2029#elif defined (_WIN32)
2039#elif defined (TARGET_SOLARIS)
2066 "ERROR: Solaris route add -inet6 command failed");
2069#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2087 "ERROR: *BSD route add -inet6 command failed");
2090#elif defined(TARGET_DARWIN)
2107 "ERROR: MacOS X route add -inet6 command failed");
2110#elif defined(TARGET_OPENBSD)
2114 network, r6->
netbits, gateway );
2118 "ERROR: OpenBSD route add -inet6 command failed");
2121#elif defined(TARGET_NETBSD)
2125 network, r6->
netbits, gateway );
2129 "ERROR: NetBSD route add -inet6 command failed");
2132#elif defined(TARGET_AIX)
2136 network, r6->
netbits, gateway);
2139 "ERROR: AIX route add command failed");
2142#elif defined(TARGET_HAIKU)
2153 "ERROR: Haiku inet6 route add command failed");
2157 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");
2167 r6->
flags &= ~RT_ADDED;
2185#if !defined(TARGET_LINUX)
2186 const char *network;
2187#if !defined(TARGET_AIX)
2188 const char *netmask;
2190#if !defined(TARGET_ANDROID)
2191 const char *gateway;
2206#if !defined(TARGET_LINUX)
2208#if !defined(TARGET_AIX)
2211#if !defined(TARGET_ANDROID)
2222#if defined(TARGET_LINUX)
2230 &r->
gateway, NULL, 0, metric) < 0)
2232 msg(
M_WARN,
"ERROR: Linux route delete command failed");
2234#elif defined (_WIN32)
2248 msg(
D_ROUTE,
"Route deletion via service %s",
status ?
"succeeded" :
"failed");
2253 msg(
D_ROUTE,
"Route deletion via IPAPI %s",
status ?
"succeeded" :
"failed");
2264 msg(
D_ROUTE,
"Route deletion via IPAPI %s [adaptive]",
status ?
"succeeded" :
"failed");
2267 msg(
D_ROUTE,
"Route deletion fallback to route.exe");
2278#elif defined (TARGET_SOLARIS)
2289#elif defined(TARGET_FREEBSD)
2300#elif defined(TARGET_DRAGONFLY)
2311#elif defined(TARGET_DARWIN)
2315 argv_printf(&
argv,
"%s delete -cloning -net %s -netmask %s -interface %s",
2333#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2344#elif defined(TARGET_ANDROID)
2346 "needed. The VpnService API allows routes to be set "
2347 "on connect only and will clean up automatically.");
2348#elif defined(TARGET_AIX)
2354 network, netbits, gateway);
2359#elif defined(TARGET_HAIKU)
2372 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");
2376 r->
flags &= ~RT_ADDED;
2388 const char *network;
2396#if !defined(TARGET_LINUX)
2397 const char *gateway;
2399#if !defined(TARGET_SOLARIS)
2400 bool gateway_needed =
false;
2402 if (r6->iface != NULL)
2405 gateway_needed =
true;
2414 gateway_needed =
true;
2423#if !defined(TARGET_LINUX) && !defined(_WIN32)
2427#if defined(TARGET_DARWIN) \
2428 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
2429 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2435 if (r6->iface != NULL && gateway_needed
2436 && IN6_IS_ADDR_LINKLOCAL(&r6->
gateway) )
2438 int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
2440 snprintf( tmp, len,
"%s%%%s", gateway, r6->iface );
2447#if defined(TARGET_LINUX)
2455 gateway_needed ? &r6->
gateway : NULL, device, 0,
2458 msg(
M_WARN,
"ERROR: Linux route v6 delete command failed");
2461#elif defined (_WIN32)
2471#elif defined (TARGET_SOLARIS)
2484#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2503#elif defined(TARGET_DARWIN)
2521#elif defined(TARGET_OPENBSD)
2525 network, r6->
netbits, gateway );
2530#elif defined(TARGET_NETBSD)
2534 network, r6->
netbits, gateway );
2539#elif defined(TARGET_AIX)
2543 network, r6->
netbits, gateway);
2547#elif defined(TARGET_ANDROID)
2549 "needed. The VpnService API allows routes to be set "
2550 "on connect only and will clean up automatically.");
2551#elif defined(TARGET_HAIKU)
2564 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");
2580static const MIB_IPFORWARDTABLE *
2584 PMIB_IPFORWARDTABLE rt = NULL;
2587 status = GetIpForwardTable(NULL, &size, TRUE);
2588 if (
status == ERROR_INSUFFICIENT_BUFFER)
2590 rt = (PMIB_IPFORWARDTABLE)
gc_malloc(size,
false,
gc);
2591 status = GetIpForwardTable(rt, &size, TRUE);
2594 msg(
D_ROUTE,
"NOTE: GetIpForwardTable returned error: %s (code=%u)",
2605 const in_addr_t gateway,
2622 const IP_ADAPTER_INFO *adapters,
2623 const in_addr_t gateway)
2656 bool adapter_up =
false;
2670 for (r = rl->
routes, len = 0; r; r = r->
next, ++len)
2682 msg(
D_ROUTE,
"TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
2688 adapter_up ?
"up" :
"down");
2694static const MIB_IPFORWARDROW *
2698 DWORD lowest_metric = MAXDWORD;
2699 const MIB_IPFORWARDROW *ret = NULL;
2704 for (DWORD i = 0; i < routes->dwNumEntries; ++i)
2706 const MIB_IPFORWARDROW *row = &routes->table[i];
2707 const in_addr_t net = ntohl(row->dwForwardDest);
2708 const in_addr_t mask = ntohl(row->dwForwardMask);
2709 const DWORD index = row->dwForwardIfIndex;
2710 const DWORD metric = row->dwForwardMetric1;
2719 if (!net && !mask && metric < lowest_metric)
2722 lowest_metric = metric;
2748 DWORD best_if_index;
2754 status = GetBestInterfaceEx((
struct sockaddr *)dest, &best_if_index);
2757 msg(
D_ROUTE,
"NOTE: GetBestInterfaceEx returned error: %s (code=%u)",
2763 msg(
D_ROUTE_DEBUG,
"GetBestInterfaceEx() returned if=%d", (
int)best_if_index);
2768 SOCKADDR_INET best_src;
2770 status = GetBestRoute2(&luid, best_if_index, NULL,
2771 dest, 0, best_route, &best_src);
2774 msg(
D_ROUTE,
"NOTE: GetIpForwardEntry2 returned error: %s (code=%u)",
2794 sa.si_family = AF_INET;
2795 sa.Ipv4.sin_addr.s_addr = htonl(dest);
2798 MIB_IPFORWARD_ROW2 best_route;
2807 rgi->
gateway.
addr = ntohl(best_route.NextHop.Ipv4.sin_addr.S_un.S_addr);
2820 memcpy(rgi->
hwaddr, ai->Address, 6);
2824 in_addr_t nm = inet_addr(ai->IpAddressList.IpMask.String);
2844 bool on_tun =
false;
2849 ret = tun_adapter->Index;
2860 msg(
M_WARN,
"Warning: route gateway is not reachable on any active network adapters: %s",
2866 msg(
M_WARN,
"Warning: route gateway is ambiguous: %s (%d matches)",
2892 SOCKADDR_INET DestinationAddress;
2893 CLEAR(DestinationAddress);
2894 DestinationAddress.si_family = AF_INET6;
2897 DestinationAddress.Ipv6.sin6_addr = *dest;
2900 MIB_IPFORWARD_ROW2 BestRoute;
2910 BestRoute.InterfaceIndex,
2911 print_in6_addr( BestRoute.DestinationPrefix.Prefix.Ipv6.sin6_addr, 0, &
gc),
2912 BestRoute.DestinationPrefix.PrefixLength,
2914 msg(
D_ROUTE,
"GDG6: Metric=%d, Loopback=%d, AA=%d, I=%d",
2915 (
int) BestRoute.Metric,
2916 (
int) BestRoute.Loopback,
2917 (
int) BestRoute.AutoconfigureAddress,
2918 (
int) BestRoute.Immortal );
2925 if (IN6_IS_ADDR_UNSPECIFIED(&BestRoute.NextHop.Ipv6.sin6_addr) )
2945 MIB_IPFORWARDROW fr;
2947 fr.dwForwardDest = htonl(r->
network);
2948 fr.dwForwardMask = htonl(r->
netmask);
2949 fr.dwForwardPolicy = 0;
2950 fr.dwForwardNextHop = htonl(r->
gateway);
2951 fr.dwForwardIfIndex = if_index;
2952 fr.dwForwardType = 4;
2953 fr.dwForwardProto = 3;
2954 fr.dwForwardAge = 0;
2955 fr.dwForwardNextHopAS = 0;
2964 msg(
M_WARN,
"Warning: address %s is not a network address in relation to netmask %s",
2969 status = CreateIpForwardEntry(&fr);
2975 else if (
status == ERROR_OBJECT_ALREADY_EXISTS)
2982 const unsigned int forward_metric_limit = 2048;
2984 for (; fr.dwForwardMetric1 <= forward_metric_limit; ++fr.dwForwardMetric1)
2988 for (fr.dwForwardType = 4; fr.dwForwardType >= 3; --fr.dwForwardType)
2990 status = CreateIpForwardEntry(&fr);
2993 msg(
D_ROUTE,
"ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%u and dwForwardType=%u",
2994 (
unsigned int)fr.dwForwardMetric1,
2995 (
unsigned int)fr.dwForwardType);
2999 else if (
status != ERROR_BAD_ARGUMENTS)
3009 if (
status == ERROR_OBJECT_ALREADY_EXISTS)
3015 msg(
M_WARN,
"ERROR: route addition failed using CreateIpForwardEntry: "
3017 (
unsigned int)
status, (
unsigned int)if_index);
3037 MIB_IPFORWARDROW fr;
3040 fr.dwForwardDest = htonl(r->
network);
3041 fr.dwForwardMask = htonl(r->
netmask);
3042 fr.dwForwardPolicy = 0;
3043 fr.dwForwardNextHop = htonl(r->
gateway);
3044 fr.dwForwardIfIndex = if_index;
3046 status = DeleteIpForwardEntry(&fr);
3054 msg(
M_WARN,
"ERROR: route deletion failed using DeleteIpForwardEntry: %s",
3081 msg(
M_WARN,
"ERROR: route %s failed using service: %s [status=%u if_index=%d]",
3112 .prefix.ipv4.s_addr = htonl(r->
network),
3113 .gateway.ipv4.s_addr = htonl(r->
gateway),
3114 .iface = { .index = if_index, .name =
"" },
3119 if (
msg.prefix_len == -1)
3121 msg.prefix_len = 32;
3135 PMIB_IPFORWARD_ROW2 fwd_row;
3140 fwd_row->ValidLifetime = 0xffffffff;
3141 fwd_row->PreferredLifetime = 0xffffffff;
3142 fwd_row->Protocol = MIB_IPPROTO_NETMGMT;
3144 fwd_row->DestinationPrefix.Prefix.si_family = AF_INET6;
3145 fwd_row->DestinationPrefix.Prefix.Ipv6.sin6_addr = r->
network;
3146 fwd_row->DestinationPrefix.PrefixLength = (UINT8) r->
netbits;
3147 fwd_row->NextHop.si_family = AF_INET6;
3148 fwd_row->NextHop.Ipv6.sin6_addr = r->
gateway;
3157 inet_pton(AF_INET6,
"fe80::8", &fwd_row->NextHop.Ipv6.sin6_addr);
3165 if (err != NO_ERROR)
3169 fwd_row->InterfaceLuid = luid;
3170 fwd_row->InterfaceIndex = 0;
3175 err = CreateIpForwardEntry2(fwd_row);
3179 err = DeleteIpForwardEntry2(fwd_row);
3183 if (err != NO_ERROR)
3188 msg(
M_WARN,
"ERROR: route %s failed using ipapi: %s [status=%lu if_index=%lu]",
3190 fwd_row->InterfaceIndex);
3194 msg(
D_ROUTE,
"IPv6 route addition using ipapi failed because route exists");
3199 msg(
D_ROUTE,
"IPv6 route %s using ipapi", add ?
"added" :
"deleted");
3237 inet_pton(AF_INET6,
"fe80::8", &
msg.gateway.ipv6);
3243 msg.iface.name[
sizeof(
msg.iface.name) - 1] =
'\0';
3250 add ?
"addition" :
"deletion",
3286 buf_printf(&out,
"%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
3290 (
int)
r->dwForwardPolicy,
3291 (
int)
r->dwForwardIfIndex,
3292 (
int)
r->dwForwardType,
3293 (
int)
r->dwForwardProto,
3294 (
int)
r->dwForwardAge,
3295 (
int)
r->dwForwardNextHopAS,
3296 (
int)
r->dwForwardMetric1,
3297 (
int)
r->dwForwardMetric2,
3298 (
int)
r->dwForwardMetric3,
3299 (
int)
r->dwForwardMetric4,
3300 (
int)
r->dwForwardMetric5);
3314 msg(msglev,
"SYSTEM ROUTING TABLE");
3317 for (DWORD i = 0; i < rt->dwNumEntries; ++i)
3325#elif defined(TARGET_ANDROID)
3340 rgi->
gateway.
addr = 127 << 24 |
'd' << 16 |
'g' << 8 |
'w';
3342 strcpy(rgi->iface,
"android-gw");
3363 strcpy(rgi6->iface,
"android-gw");
3366#elif defined(TARGET_LINUX)
3373 char best_name[IFNAMSIZ];
3379 if (net_route_v4_best_gw(ctx, &dest, &rgi->
gateway.
addr, best_name) == 0)
3391 struct ifreq *ifr, *ifend;
3392 in_addr_t addr, netmask;
3395 struct ifreq ifs[20];
3397 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
3402 ifc.ifc_len =
sizeof(ifs);
3404 if (ioctl(sd, SIOCGIFCONF, &ifc) < 0)
3406 msg(
M_WARN,
"GDG: ioctl(SIOCGIFCONF) failed");
3411 ifend = ifs + (ifc.ifc_len /
sizeof(
struct ifreq));
3412 for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
3414 if (ifr->ifr_addr.sa_family == AF_INET)
3417 addr = ntohl(((
struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr);
3420 strncpynt(ifreq.ifr_name, ifr->ifr_name,
sizeof(ifreq.ifr_name));
3423 if (ioctl(sd, SIOCGIFFLAGS, &ifreq) < 0)
3427 if (!(ifreq.ifr_flags & IFF_UP))
3436 if (strcmp(ifreq.ifr_name, best_name))
3442 if ((ifreq.ifr_flags & IFF_POINTOPOINT) && ioctl(sd, SIOCGIFDSTADDR, &ifreq) >= 0)
3444 rgi->
gateway.
addr = ntohl(((
struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
3447 rgi->
flags &= ~RGI_ON_LINK;
3455 if (ioctl(sd, SIOCGIFNETMASK, &ifreq) < 0)
3459 netmask = ntohl(((
struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
3473 strncpynt(rgi->iface, ifreq.ifr_name,
sizeof(rgi->iface));
3477 memset(&ifreq.ifr_hwaddr, 0,
sizeof(
struct sockaddr));
3478 if (ioctl(sd, SIOCGIFHWADDR, &ifreq) < 0)
3480 msg(
M_WARN,
"GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
3483 memcpy(rgi->
hwaddr, &ifreq.ifr_hwaddr.sa_data, 6);
3526 if (strlen(rgi6->iface) > 0)
3544#elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) \
3545 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
3546 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
3548#include <sys/types.h>
3549#include <sys/socket.h>
3550#include <netinet/in.h>
3551#include <net/route.h>
3552#include <net/if_dl.h>
3553#if !defined(TARGET_SOLARIS)
3558 struct rt_msghdr m_rtm;
3578#if defined(TARGET_DARWIN)
3580 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
3581#elif defined(TARGET_NETBSD)
3582#define ROUNDUP(a) RT_ROUNDUP(a)
3585 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
3588#if defined(TARGET_SOLARIS)
3589#define NEXTADDR(w, u) \
3590 if (rtm_addrs & (w)) { \
3591 l = sizeof(u); memmove(cp, &(u), l); cp += ROUNDUP(l); \
3594#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in)))
3596#define NEXTADDR(w, u) \
3597 if (rtm_addrs & (w)) { \
3598 l = ((struct sockaddr *)&(u))->sa_len; memmove(cp, &(u), l); cp += ROUNDUP(l); \
3601#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
3604#define max(a, b) ((a) > (b) ? (a) : (b))
3610 struct rtmsg m_rtmsg;
3612 int seq, l, pid, rtm_addrs;
3614 struct sockaddr so_dst, so_mask;
3615 char *cp = m_rtmsg.m_space;
3616 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
3617 struct rt_msghdr *rtm_aux;
3619#define rtm m_rtmsg.m_rtm
3626#ifdef TARGET_OPENBSD
3627 rtm_addrs = RTA_DST | RTA_NETMASK;
3629 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
3632 bzero(&m_rtmsg,
sizeof(m_rtmsg));
3633 bzero(&so_dst,
sizeof(so_dst));
3634 bzero(&so_mask,
sizeof(so_mask));
3635 bzero(&rtm,
sizeof(
struct rt_msghdr));
3637 rtm.rtm_type = RTM_GET;
3638 rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
3639 rtm.rtm_version = RTM_VERSION;
3640 rtm.rtm_seq = ++seq;
3641#ifdef TARGET_OPENBSD
3642 rtm.rtm_tableid = getrtable();
3644 rtm.rtm_addrs = rtm_addrs;
3646 so_dst.sa_family = AF_INET;
3647 so_mask.sa_family = AF_INET;
3649#ifndef TARGET_SOLARIS
3650 so_dst.sa_len =
sizeof(
struct sockaddr_in);
3651 so_mask.sa_len =
sizeof(
struct sockaddr_in);
3654 NEXTADDR(RTA_DST, so_dst);
3655 NEXTADDR(RTA_NETMASK, so_mask);
3657 rtm.rtm_msglen = l = cp - (
char *)&m_rtmsg;
3660 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
3666 if (
write(sockfd, (
char *)&m_rtmsg, l) < 0)
3673 l =
read(sockfd, (
char *)&m_rtmsg,
sizeof(m_rtmsg));
3674 }
while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3680 cp = ((
char *)(rtm_aux + 1));
3681 if (rtm_aux->rtm_addrs)
3683 for (i = 1; i; i <<= 1)
3685 if (i & rtm_aux->rtm_addrs)
3687 sa = (
struct sockaddr *)cp;
3688 if (i == RTA_GATEWAY)
3692 else if (i == RTA_IFP)
3709 rgi->
gateway.
addr = ntohl(((
struct sockaddr_in *)gate)->sin_addr.s_addr);
3718 const struct sockaddr_dl *adl = (
struct sockaddr_dl *) ifp;
3719 if (adl->sdl_nlen && adl->sdl_nlen <
sizeof(rgi->iface))
3721 memcpy(rgi->iface, adl->sdl_data, adl->sdl_nlen);
3722 rgi->iface[adl->sdl_nlen] =
'\0';
3733 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3741 ifr.ifr_addr.sa_family = AF_INET;
3742 strncpynt(ifr.ifr_name, rgi->iface, IFNAMSIZ);
3744 if (ioctl(sockfd, SIOCGIFNETMASK, (
char *)&ifr) < 0)
3752 rgi->
gateway.
netmask = ntohl(((
struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
3759#if defined(TARGET_SOLARIS)
3761 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3768 struct ifreq ifreq = { 0 };
3771 strncpynt(ifreq.ifr_name, rgi->iface,
sizeof(ifreq.ifr_name));
3772 if (ioctl(sockfd, SIOCGIFHWADDR, &ifreq) < 0)
3774 msg(
M_WARN,
"GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
3778 memcpy(rgi->
hwaddr, &ifreq.ifr_addr.sa_data, 6);
3782 struct ifaddrs *ifap, *ifa;
3784 if (getifaddrs(&ifap) != 0)
3790 for (ifa = ifap; ifa; ifa = ifa->ifa_next)
3792 if (ifa->ifa_addr != NULL
3793 && ifa->ifa_addr->sa_family == AF_LINK
3794 && !strncmp(ifa->ifa_name, rgi->iface, IFNAMSIZ) )
3796 struct sockaddr_dl *sdl = (
struct sockaddr_dl *)ifa->ifa_addr;
3797 memcpy(rgi->
hwaddr, LLADDR(sdl), 6);
3821#if defined(TARGET_SOLARIS)
3823#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in6)))
3831 struct rtmsg m_rtmsg;
3833 int seq, l, pid, rtm_addrs;
3835 struct sockaddr_in6 so_dst, so_mask;
3836 char *cp = m_rtmsg.m_space;
3837 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
3838 struct rt_msghdr *rtm_aux;
3845#ifdef TARGET_OPENBSD
3846 rtm_addrs = RTA_DST | RTA_NETMASK;
3848 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
3851 bzero(&m_rtmsg,
sizeof(m_rtmsg));
3852 bzero(&so_dst,
sizeof(so_dst));
3853 bzero(&so_mask,
sizeof(so_mask));
3854 bzero(&rtm,
sizeof(
struct rt_msghdr));
3856 rtm.rtm_type = RTM_GET;
3857 rtm.rtm_flags = RTF_UP;
3858 rtm.rtm_version = RTM_VERSION;
3859 rtm.rtm_seq = ++seq;
3860#ifdef TARGET_OPENBSD
3861 rtm.rtm_tableid = getrtable();
3864 so_dst.sin6_family = AF_INET6;
3865 so_mask.sin6_family = AF_INET6;
3868 && !IN6_IS_ADDR_UNSPECIFIED(dest) )
3870 so_dst.sin6_addr = *dest;
3872 rtm_addrs &= ~RTA_NETMASK;
3875 rtm.rtm_addrs = rtm_addrs;
3877#ifndef TARGET_SOLARIS
3878 so_dst.sin6_len =
sizeof(
struct sockaddr_in6);
3879 so_mask.sin6_len =
sizeof(
struct sockaddr_in6);
3882 NEXTADDR(RTA_DST, so_dst);
3883 NEXTADDR(RTA_NETMASK, so_mask);
3885 rtm.rtm_msglen = l = cp - (
char *)&m_rtmsg;
3888 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
3894 if (
write(sockfd, (
char *)&m_rtmsg, l) < 0)
3902 l =
read(sockfd, (
char *)&m_rtmsg,
sizeof(m_rtmsg));
3904 while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3911 cp = ((
char *)(rtm_aux + 1));
3912 if (rtm_aux->rtm_addrs)
3914 for (i = 1; i; i <<= 1)
3916 if (i & rtm_aux->rtm_addrs)
3918 sa = (
struct sockaddr *)cp;
3919 if (i == RTA_GATEWAY)
3923 else if (i == RTA_IFP)
3939 struct sockaddr_in6 *s6 = (
struct sockaddr_in6 *)gate;
3940 struct in6_addr gw = s6->sin6_addr;
3942#ifndef TARGET_SOLARIS
3947 if (gate->sa_len ==
sizeof(
struct sockaddr_in6)
3948 && IN6_IS_ADDR_LINKLOCAL(&gw) )
3950 gw.s6_addr[2] = gw.s6_addr[3] = 0;
3953 if (gate->sa_len !=
sizeof(
struct sockaddr_in6)
3954 || IN6_IS_ADDR_UNSPECIFIED(&gw) )
3968 const struct sockaddr_dl *adl = (
struct sockaddr_dl *) ifp;
3969 if (adl->sdl_nlen && adl->sdl_nlen <
sizeof(rgi6->iface))
3971 memcpy(rgi6->iface, adl->sdl_data, adl->sdl_nlen);
3986#elif defined(TARGET_HAIKU)
3993 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3996 msg(
M_ERRNO,
"%s: Error opening socket for AF_INET", __func__);
4000 struct ifconf config;
4001 config.ifc_len =
sizeof(config.ifc_value);
4002 if (ioctl(sockfd, SIOCGRTSIZE, &config,
sizeof(
struct ifconf)) < 0)
4004 msg(
M_ERRNO,
"%s: Error getting routing table size", __func__);
4008 uint32 size = (uint32)config.ifc_value;
4014 void *
buffer = malloc(size);
4017 config.ifc_len = size;
4019 if (ioctl(sockfd, SIOCGRTTABLE, &config,
sizeof(
struct ifconf)) < 0)
4025 struct ifreq *
interface = (struct ifreq *)
buffer;
4026 struct ifreq *end = (
struct ifreq *)((uint8 *)
buffer + size);
4028 while (interface < end)
4030 struct route_entry
route = interface->ifr_route;
4031 if ((
route.flags & RTF_GATEWAY) != 0 && (
route.flags & RTF_DEFAULT) != 0)
4033 rgi->
gateway.
addr = ntohl(((
struct sockaddr_in *)
route.gateway)->sin_addr.s_addr);
4035 strncpy(rgi->iface, interface->ifr_name,
sizeof(rgi->iface));
4038 int32 address_size = 0;
4039 if (
route.destination != NULL)
4041 address_size +=
route.destination->sa_len;
4043 if (
route.mask != NULL)
4045 address_size +=
route.mask->sa_len;
4047 if (
route.gateway != NULL)
4049 address_size +=
route.gateway->sa_len;
4052 interface = (struct ifreq *)((addr_t)
interface +
IF_NAMESIZE
4053 + sizeof(struct route_entry) + address_size);
4101 msg(
D_ROUTE,
"no support for get_default_gateway_ipv6() on this system");
4111 const int addrlen =
sizeof(in_addr_t) * 8;
4113 if ((network & netmask) == network)
4115 for (i = 0; i <= addrlen; ++i)
4118 if (mask == netmask)
4142 const int addrlen =
sizeof(in_addr_t) * 8;
4144 for (i = 0; i <= addrlen; ++i)
4147 if (mask == netmask)
4178 bool succeed =
false;
4184 iplist = iplist->Next;
4248 const in_addr_t nonlocal_netmask = 0x80000000L;
4255 for (DWORD i = 0; i < rt->dwNumEntries; ++i)
4257 const MIB_IPFORWARDROW *row = &rt->table[i];
4258 const in_addr_t net = ntohl(row->dwForwardDest);
4259 const in_addr_t mask = ntohl(row->dwForwardMask);
4260 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)
void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, const char *metric)
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)
void add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask, const char *gateway, const char *metric)
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 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)
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