2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * Support routines for adding/deleting network routes.
36 #define MAX_ROUTES_DEFAULT 100
40 * Windows route methods
42 #define ROUTE_METHOD_ADAPTIVE 0 /* try IP helper first then route.exe */
43 #define ROUTE_METHOD_IPAPI 1 /* use IP helper API */
44 #define ROUTE_METHOD_EXE 2 /* use route.exe */
45 #define ROUTE_METHOD_MASK 3
49 * Route add/delete flags (must stay clear of ROUTE_METHOD bits)
51 #define ROUTE_DELETE_FIRST (1<<2)
52 #define ROUTE_REF_GW (1<<3)
56 # define N_ROUTE_BYPASS 8
58 in_addr_t bypass
[N_ROUTE_BYPASS
];
61 struct route_special_addr
63 /* bits indicating which members below are defined */
64 # define RTSA_REMOTE_ENDPOINT (1<<0)
65 # define RTSA_REMOTE_HOST (1<<1)
66 # define RTSA_DEFAULT_METRIC (1<<2)
69 in_addr_t remote_endpoint
;
70 in_addr_t remote_host
;
71 int remote_host_local
; /* TLA_x value */
72 struct route_bypass bypass
;
83 /* redirect-gateway flags */
84 #define RG_ENABLE (1<<0)
85 #define RG_LOCAL (1<<1)
86 #define RG_DEF1 (1<<2)
87 #define RG_BYPASS_DHCP (1<<3)
88 #define RG_BYPASS_DNS (1<<4)
89 #define RG_REROUTE_GW (1<<5)
90 #define RG_AUTO_LOCAL (1<<6)
91 #define RG_BLOCK_LOCAL (1<<7)
93 struct route_option_list
{
94 unsigned int flags
; /* RG_x flags */
97 struct route_option routes
[EMPTY_ARRAY_SIZE
];
100 struct route_ipv6_option
{
101 const char *prefix
; /* e.g. "2001:db8:1::/64" */
102 const char *gateway
; /* e.g. "2001:db8:0::2" */
103 const char *metric
; /* e.g. "5" */
106 struct route_ipv6_option_list
{
110 struct route_ipv6_option routes_ipv6
[EMPTY_ARRAY_SIZE
];
114 # define RT_DEFINED (1<<0)
115 # define RT_ADDED (1<<1)
116 # define RT_METRIC_DEFINED (1<<2)
118 const struct route_option
*option
;
127 struct in6_addr network
;
128 unsigned int netbits
;
129 struct in6_addr gateway
;
134 struct route_ipv6_list
{
138 bool default_metric_defined
;
139 struct in6_addr remote_endpoint_ipv6
;
140 bool remote_endpoint_defined
;
141 bool did_redirect_default_gateway
; /* TODO (?) */
142 bool did_local
; /* TODO (?) */
145 struct route_ipv6 routes_ipv6
[EMPTY_ARRAY_SIZE
];
149 struct route_gateway_address
{
154 struct route_gateway_info
{
155 # define RGI_ADDR_DEFINED (1<<0) /* set if gateway.addr defined */
156 # define RGI_NETMASK_DEFINED (1<<1) /* set if gateway.netmask defined */
157 # define RGI_HWADDR_DEFINED (1<<2) /* set if hwaddr is defined */
158 # define RGI_IFACE_DEFINED (1<<3) /* set if iface is defined */
159 # define RGI_OVERFLOW (1<<4) /* set if more interface addresses than will fit in addrs */
160 # define RGI_ON_LINK (1<<5)
163 /* gateway interface */
165 DWORD adapter_index
; /* interface or ~0 if undefined */
167 char iface
[16]; /* interface name (null terminated), may be empty */
170 /* gateway interface hardware address */
173 /* gateway/router address */
174 struct route_gateway_address gateway
;
176 /* address/netmask pairs bound to interface */
177 # define RGI_N_ADDRESSES 8
178 int n_addrs
; /* len of addrs, may be 0 */
179 struct route_gateway_address addrs
[RGI_N_ADDRESSES
]; /* local addresses attached to iface */
183 # define RL_DID_REDIRECT_DEFAULT_GATEWAY (1<<0)
184 # define RL_DID_LOCAL (1<<1)
185 # define RL_ROUTES_ADDED (1<<2)
188 struct route_special_addr spec
;
189 struct route_gateway_info rgi
;
190 unsigned int flags
; /* RG_x flags */
193 struct route routes
[EMPTY_ARRAY_SIZE
];
197 /* internal OpenVPN route */
205 struct in6_addr network
;
206 unsigned int netbits
;
207 struct iroute_ipv6
*next
;
211 struct route_option_list
*new_route_option_list (const int max_routes
, struct gc_arena
*a
);
212 struct route_ipv6_option_list
*new_route_ipv6_option_list (const int max_routes
, struct gc_arena
*a
);
214 struct route_option_list
*clone_route_option_list (const struct route_option_list
*src
, struct gc_arena
*a
);
215 struct route_ipv6_option_list
*clone_route_ipv6_option_list (const struct route_ipv6_option_list
*src
, struct gc_arena
*a
);
216 void copy_route_option_list (struct route_option_list
*dest
, const struct route_option_list
*src
);
217 void copy_route_ipv6_option_list (struct route_ipv6_option_list
*dest
,
218 const struct route_ipv6_option_list
*src
);
220 struct route_list
*new_route_list (const int max_routes
, struct gc_arena
*a
);
221 struct route_ipv6_list
*new_route_ipv6_list (const int max_routes
, struct gc_arena
*a
);
223 void add_route_ipv6 (struct route_ipv6
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
);
224 void delete_route_ipv6 (const struct route_ipv6
*r
, const struct tuntap
*tt
, unsigned int flags
, const struct env_set
*es
);
226 void add_route (struct route
*r
,
227 const struct tuntap
*tt
,
229 const struct route_gateway_info
*rgi
,
230 const struct env_set
*es
);
232 void add_route_to_option_list (struct route_option_list
*l
,
238 void add_route_ipv6_to_option_list (struct route_ipv6_option_list
*l
,
243 bool init_route_list (struct route_list
*rl
,
244 const struct route_option_list
*opt
,
245 const char *remote_endpoint
,
247 in_addr_t remote_host
,
250 bool init_route_ipv6_list (struct route_ipv6_list
*rl6
,
251 const struct route_ipv6_option_list
*opt6
,
252 const char *remote_endpoint
,
256 void route_list_add_vpn_gateway (struct route_list
*rl
,
258 const in_addr_t addr
);
260 void add_routes (struct route_list
*rl
,
261 struct route_ipv6_list
*rl6
,
262 const struct tuntap
*tt
,
264 const struct env_set
*es
);
266 void delete_routes (struct route_list
*rl
,
267 struct route_ipv6_list
*rl6
,
268 const struct tuntap
*tt
,
270 const struct env_set
*es
);
272 void setenv_routes (struct env_set
*es
, const struct route_list
*rl
);
273 void setenv_routes_ipv6 (struct env_set
*es
, const struct route_ipv6_list
*rl6
);
277 bool is_special_addr (const char *addr_str
);
279 void get_default_gateway (struct route_gateway_info
*rgi
);
280 void print_default_gateway(const int msglevel
, const struct route_gateway_info
*rgi
);
283 * Test if addr is reachable via a local interface (return ILA_LOCAL),
284 * or if it needs to be routed via the default gateway (return
285 * ILA_NONLOCAL). If the current platform doesn't implement this
286 * function, return ILA_NOT_IMPLEMENTED.
288 #define TLA_NOT_IMPLEMENTED 0
289 #define TLA_NONLOCAL 1
291 int test_local_addr (const in_addr_t addr
, const struct route_gateway_info
*rgi
);
294 void print_route_options (const struct route_option_list
*rol
,
298 void print_routes (const struct route_list
*rl
, int level
);
302 void show_routes (int msglev
);
303 bool test_routes (const struct route_list
*rl
, const struct tuntap
*tt
);
304 bool add_route_ipapi (const struct route
*r
, const struct tuntap
*tt
, DWORD adapter_index
);
305 bool del_route_ipapi (const struct route
*r
, const struct tuntap
*tt
);
308 static inline bool test_routes (const struct route_list
*rl
, const struct tuntap
*tt
) { return true; }
311 bool netmask_to_netbits (const in_addr_t network
, const in_addr_t netmask
, int *netbits
);
313 static inline in_addr_t
314 netbits_to_netmask (const int netbits
)
316 const int addrlen
= sizeof (in_addr_t
) * 8;
318 if (netbits
> 0 && netbits
<= addrlen
)
319 mask
= IPV4_NETMASK_HOST
<< (addrlen
-netbits
);
324 route_list_vpn_gateway_needed (const struct route_list
*rl
)
329 return !(rl
->spec
.flags
& RTSA_REMOTE_ENDPOINT
);
333 route_did_redirect_default_gateway(const struct route_list
*rl
)
335 return rl
&& BOOL_CAST(rl
->iflags
& RL_DID_REDIRECT_DEFAULT_GATEWAY
);