]> git.ipfire.org Git - thirdparty/openvpn.git/blame - src/openvpn/route.c
dev-tools: Simple tool which automates rebasing LZ4 compat library
[thirdparty/openvpn.git] / src / openvpn / route.c
CommitLineData
6fbf66fa
JY
1/*
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
6 * packet compression.
7 *
58716979 8 * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
6fbf66fa
JY
9 *
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.
13 *
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.
18 *
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
23 */
24
25/*
26 * Support routines for adding/deleting network routes.
27 */
28
c110b289
ABL
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#elif defined(_MSC_VER)
32#include "config-msvc.h"
33#endif
34
6fbf66fa
JY
35#include "syshead.h"
36
37#include "common.h"
38#include "error.h"
39#include "route.h"
40#include "misc.h"
41#include "socket.h"
42#include "manage.h"
5a2e9a25 43#include "win32.h"
1840c852 44#include "options.h"
6fbf66fa
JY
45
46#include "memdbg.h"
47
3128abcf 48#if defined(TARGET_LINUX) || defined(TARGET_ANDROID)
81d882d5 49#include <linux/rtnetlink.h> /* RTM_GETROUTE etc. */
3128abcf
GD
50#endif
51
445b192a 52#ifdef _WIN32
a24dd2e3
HH
53#include "openvpn-msg.h"
54
12e46092 55#define METRIC_NOT_USED ((DWORD)-1)
81d882d5
DS
56static bool add_route_service(const struct route_ipv4 *, const struct tuntap *);
57
58static bool del_route_service(const struct route_ipv4 *, const struct tuntap *);
59
60static bool add_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *);
61
62static bool del_route_ipv6_service(const struct route_ipv6 *, const struct tuntap *);
63
12e46092
ABL
64#endif
65
81d882d5 66static 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);
576dc96c 67
81d882d5 68static void get_bypass_addresses(struct route_bypass *rb, const unsigned int flags);
3c7f2f55
JY
69
70#ifdef ENABLE_DEBUG
71
72static void
81d882d5 73print_bypass_addresses(const struct route_bypass *rb)
3c7f2f55 74{
81d882d5
DS
75 struct gc_arena gc = gc_new();
76 int i;
77 for (i = 0; i < rb->n_bypass; ++i)
3c7f2f55 78 {
81d882d5
DS
79 msg(D_ROUTE, "ROUTE: bypass_host_route[%d]=%s",
80 i,
81 print_in_addr_t(rb->bypass[i], 0, &gc));
3c7f2f55 82 }
81d882d5 83 gc_free(&gc);
3c7f2f55
JY
84}
85
86#endif
87
d02a86d3 88static bool
81d882d5 89add_bypass_address(struct route_bypass *rb, const in_addr_t a)
d02a86d3 90{
81d882d5
DS
91 int i;
92 for (i = 0; i < rb->n_bypass; ++i)
d02a86d3 93 {
81d882d5
DS
94 if (a == rb->bypass[i]) /* avoid duplicates */
95 {
96 return true;
97 }
d02a86d3 98 }
81d882d5 99 if (rb->n_bypass < N_ROUTE_BYPASS)
d02a86d3 100 {
81d882d5
DS
101 rb->bypass[rb->n_bypass++] = a;
102 return true;
d02a86d3 103 }
81d882d5 104 else
d02a86d3 105 {
81d882d5 106 return false;
d02a86d3
JY
107 }
108}
109
6fbf66fa 110struct route_option_list *
81d882d5 111new_route_option_list(struct gc_arena *a)
6fbf66fa 112{
81d882d5
DS
113 struct route_option_list *ret;
114 ALLOC_OBJ_CLEAR_GC(ret, struct route_option_list, a);
115 ret->gc = a;
116 return ret;
6fbf66fa
JY
117}
118
512cda46 119struct route_ipv6_option_list *
81d882d5 120new_route_ipv6_option_list(struct gc_arena *a)
512cda46 121{
81d882d5
DS
122 struct route_ipv6_option_list *ret;
123 ALLOC_OBJ_CLEAR_GC(ret, struct route_ipv6_option_list, a);
124 ret->gc = a;
125 return ret;
512cda46
GD
126}
127
d0085293
HH
128/*
129 * NOTE: structs are cloned/copied shallow by design.
130 * The routes list from src will stay intact since it is allocated using
131 * the options->gc. The cloned/copied lists will share this common tail
132 * to avoid copying the data around between pulls. Pulled routes use
133 * the c2->gc so they get freed immediately after a reconnect.
134 */
673f583f 135struct route_option_list *
81d882d5 136clone_route_option_list(const struct route_option_list *src, struct gc_arena *a)
673f583f 137{
81d882d5
DS
138 struct route_option_list *ret;
139 ALLOC_OBJ_GC(ret, struct route_option_list, a);
140 *ret = *src;
141 return ret;
673f583f
JY
142}
143
91402236 144struct route_ipv6_option_list *
81d882d5 145clone_route_ipv6_option_list(const struct route_ipv6_option_list *src, struct gc_arena *a)
91402236 146{
81d882d5
DS
147 struct route_ipv6_option_list *ret;
148 ALLOC_OBJ_GC(ret, struct route_ipv6_option_list, a);
149 *ret = *src;
150 return ret;
91402236
GD
151}
152
673f583f 153void
81d882d5 154copy_route_option_list(struct route_option_list *dest, const struct route_option_list *src, struct gc_arena *a)
673f583f 155{
81d882d5
DS
156 *dest = *src;
157 dest->gc = a;
673f583f
JY
158}
159
91402236 160void
81d882d5
DS
161copy_route_ipv6_option_list(struct route_ipv6_option_list *dest,
162 const struct route_ipv6_option_list *src,
163 struct gc_arena *a)
512cda46 164{
81d882d5
DS
165 *dest = *src;
166 dest->gc = a;
512cda46
GD
167}
168
6fbf66fa 169static const char *
81d882d5 170route_string(const struct route_ipv4 *r, struct gc_arena *gc)
6fbf66fa 171{
81d882d5
DS
172 struct buffer out = alloc_buf_gc(256, gc);
173 buf_printf(&out, "ROUTE network %s netmask %s gateway %s",
174 print_in_addr_t(r->network, 0, gc),
175 print_in_addr_t(r->netmask, 0, gc),
176 print_in_addr_t(r->gateway, 0, gc)
177 );
178 if (r->flags & RT_METRIC_DEFINED)
179 {
180 buf_printf(&out, " metric %d", r->metric);
181 }
182 return BSTR(&out);
6fbf66fa
JY
183}
184
185static bool
81d882d5 186is_route_parm_defined(const char *parm)
6fbf66fa 187{
81d882d5
DS
188 if (!parm)
189 {
190 return false;
191 }
192 if (!strcmp(parm, "default"))
193 {
194 return false;
195 }
196 return true;
6fbf66fa
JY
197}
198
199static void
81d882d5 200setenv_route_addr(struct env_set *es, const char *key, const in_addr_t addr, int i)
6fbf66fa 201{
81d882d5
DS
202 struct gc_arena gc = gc_new();
203 struct buffer name = alloc_buf_gc(256, &gc);
204 if (i >= 0)
205 {
206 buf_printf(&name, "route_%s_%d", key, i);
207 }
208 else
209 {
210 buf_printf(&name, "route_%s", key);
211 }
212 setenv_str(es, BSTR(&name), print_in_addr_t(addr, 0, &gc));
213 gc_free(&gc);
6fbf66fa
JY
214}
215
216static bool
81d882d5
DS
217get_special_addr(const struct route_list *rl,
218 const char *string,
219 in_addr_t *out,
220 bool *status)
221{
222 if (status)
223 {
224 *status = true;
225 }
226 if (!strcmp(string, "vpn_gateway"))
227 {
228 if (rl)
229 {
230 if (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
231 {
232 *out = rl->spec.remote_endpoint;
233 }
234 else
235 {
236 msg(M_INFO, PACKAGE_NAME " ROUTE: vpn_gateway undefined");
237 if (status)
238 {
239 *status = false;
240 }
241 }
242 }
243 return true;
244 }
245 else if (!strcmp(string, "net_gateway"))
246 {
247 if (rl)
248 {
249 if (rl->rgi.flags & RGI_ADDR_DEFINED)
250 {
251 *out = rl->rgi.gateway.addr;
252 }
253 else
254 {
255 msg(M_INFO, PACKAGE_NAME " ROUTE: net_gateway undefined -- unable to get default gateway from system");
256 if (status)
257 {
258 *status = false;
259 }
260 }
261 }
262 return true;
263 }
264 else if (!strcmp(string, "remote_host"))
265 {
266 if (rl)
267 {
268 if (rl->spec.flags & RTSA_REMOTE_HOST)
269 {
270 *out = rl->spec.remote_host;
271 }
272 else
273 {
274 msg(M_INFO, PACKAGE_NAME " ROUTE: remote_host undefined");
275 if (status)
276 {
277 *status = false;
278 }
279 }
280 }
281 return true;
282 }
283 return false;
6fbf66fa
JY
284}
285
b4073a76 286bool
81d882d5 287is_special_addr(const char *addr_str)
b4073a76 288{
81d882d5
DS
289 if (addr_str)
290 {
291 return get_special_addr(NULL, addr_str, NULL, NULL);
292 }
293 else
294 {
295 return false;
296 }
b4073a76
JY
297}
298
6fbf66fa 299static bool
81d882d5
DS
300init_route(struct route_ipv4 *r,
301 struct addrinfo **network_list,
302 const struct route_option *ro,
303 const struct route_list *rl)
6fbf66fa 304{
81d882d5
DS
305 const in_addr_t default_netmask = IPV4_NETMASK_HOST;
306 bool status;
307 int ret;
308 struct in_addr special;
6fbf66fa 309
81d882d5
DS
310 CLEAR(*r);
311 r->option = ro;
6fbf66fa 312
81d882d5 313 /* network */
6fbf66fa 314
81d882d5 315 if (!is_route_parm_defined(ro->network))
6fbf66fa 316 {
81d882d5 317 goto fail;
6fbf66fa 318 }
f2d6f3bc
AS
319
320
81d882d5
DS
321 /* get_special_addr replaces specialaddr with a special ip addr
322 * like gw. getaddrinfo is called to convert a a addrinfo struct */
f2d6f3bc 323
81d882d5
DS
324 if (get_special_addr(rl, ro->network, (in_addr_t *) &special.s_addr, &status))
325 {
326 special.s_addr = htonl(special.s_addr);
327 ret = openvpn_getaddrinfo(0, inet_ntoa(special), NULL, 0, NULL,
328 AF_INET, network_list);
329 }
330 else
6fbf66fa 331 {
81d882d5
DS
332 ret = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL,
333 ro->network, NULL, 0, NULL, AF_INET, network_list);
6fbf66fa 334 }
f2d6f3bc 335
81d882d5 336 status = (ret == 0);
6fbf66fa 337
81d882d5
DS
338 if (!status)
339 {
340 goto fail;
341 }
6fbf66fa 342
81d882d5 343 /* netmask */
6fbf66fa 344
81d882d5
DS
345 if (is_route_parm_defined(ro->netmask))
346 {
347 r->netmask = getaddr(
348 GETADDR_HOST_ORDER
349 | GETADDR_WARN_ON_SIGNAL,
350 ro->netmask,
351 0,
352 &status,
353 NULL);
354 if (!status)
355 {
356 goto fail;
357 }
358 }
359 else
6fbf66fa 360 {
81d882d5 361 r->netmask = default_netmask;
6fbf66fa 362 }
6fbf66fa 363
81d882d5 364 /* gateway */
6fbf66fa 365
81d882d5 366 if (is_route_parm_defined(ro->gateway))
6fbf66fa 367 {
81d882d5
DS
368 if (!get_special_addr(rl, ro->gateway, &r->gateway, &status))
369 {
370 r->gateway = getaddr(
371 GETADDR_RESOLVE
372 | GETADDR_HOST_ORDER
373 | GETADDR_WARN_ON_SIGNAL,
374 ro->gateway,
375 0,
376 &status,
377 NULL);
378 }
379 if (!status)
380 {
381 goto fail;
382 }
6fbf66fa 383 }
81d882d5 384 else
6fbf66fa 385 {
81d882d5
DS
386 if (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
387 {
388 r->gateway = rl->spec.remote_endpoint;
389 }
390 else
391 {
392 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");
393 goto fail;
394 }
6fbf66fa
JY
395 }
396
81d882d5 397 /* metric */
6fbf66fa 398
81d882d5
DS
399 r->metric = 0;
400 if (is_route_parm_defined(ro->metric))
6fbf66fa 401 {
81d882d5
DS
402 r->metric = atoi(ro->metric);
403 if (r->metric < 0)
404 {
405 msg(M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
406 ro->network,
407 ro->metric);
408 goto fail;
409 }
410 r->flags |= RT_METRIC_DEFINED;
6fbf66fa 411 }
81d882d5 412 else if (rl->spec.flags & RTSA_DEFAULT_METRIC)
6fbf66fa 413 {
81d882d5
DS
414 r->metric = rl->spec.default_metric;
415 r->flags |= RT_METRIC_DEFINED;
6fbf66fa
JY
416 }
417
81d882d5 418 r->flags |= RT_DEFINED;
6fbf66fa 419
81d882d5 420 return true;
6fbf66fa 421
81d882d5
DS
422fail:
423 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
424 ro->network);
425 return false;
6fbf66fa
JY
426}
427
512cda46 428static bool
81d882d5
DS
429init_route_ipv6(struct route_ipv6 *r6,
430 const struct route_ipv6_option *r6o,
431 const struct route_ipv6_list *rl6 )
512cda46 432{
81d882d5 433 CLEAR(*r6);
512cda46 434
81d882d5
DS
435 if (!get_ipv6_addr( r6o->prefix, &r6->network, &r6->netbits, M_WARN ))
436 {
437 goto fail;
438 }
512cda46 439
81d882d5
DS
440 /* gateway */
441 if (is_route_parm_defined(r6o->gateway))
512cda46 442 {
81d882d5 443 if (inet_pton( AF_INET6, r6o->gateway, &r6->gateway ) != 1)
512cda46 444 {
81d882d5 445 msg( M_WARN, PACKAGE_NAME "ROUTE6: cannot parse gateway spec '%s'", r6o->gateway );
512cda46
GD
446 }
447 }
81d882d5 448 else if (rl6->spec_flags & RTSA_REMOTE_ENDPOINT)
512cda46 449 {
81d882d5 450 r6->gateway = rl6->remote_endpoint_ipv6;
512cda46 451 }
81d882d5 452 else
512cda46 453 {
81d882d5
DS
454 msg(M_WARN, PACKAGE_NAME " ROUTE6: " PACKAGE_NAME " needs a gateway parameter for a --route-ipv6 option and no default was specified by either --route-ipv6-gateway or --ifconfig-ipv6 options");
455 goto fail;
512cda46
GD
456 }
457
81d882d5 458 /* metric */
512cda46 459
81d882d5
DS
460 r6->metric = -1;
461 if (is_route_parm_defined(r6o->metric))
512cda46 462 {
81d882d5
DS
463 r6->metric = atoi(r6o->metric);
464 if (r6->metric < 0)
465 {
466 msg(M_WARN, PACKAGE_NAME " ROUTE: route metric for network %s (%s) must be >= 0",
467 r6o->prefix,
468 r6o->metric);
469 goto fail;
470 }
471 r6->flags |= RT_METRIC_DEFINED;
512cda46 472 }
81d882d5 473 else if (rl6->spec_flags & RTSA_DEFAULT_METRIC)
512cda46 474 {
81d882d5
DS
475 r6->metric = rl6->default_metric;
476 r6->flags |= RT_METRIC_DEFINED;
512cda46
GD
477 }
478
81d882d5 479 r6->flags |= RT_DEFINED;
512cda46 480
81d882d5 481 return true;
512cda46 482
81d882d5
DS
483fail:
484 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve route for host/network: %s",
485 r6o->prefix);
486 return false;
512cda46
GD
487}
488
6fbf66fa 489void
81d882d5
DS
490add_route_to_option_list(struct route_option_list *l,
491 const char *network,
492 const char *netmask,
493 const char *gateway,
494 const char *metric)
6fbf66fa 495{
81d882d5
DS
496 struct route_option *ro;
497 ALLOC_OBJ_GC(ro, struct route_option, l->gc);
498 ro->network = network;
499 ro->netmask = netmask;
500 ro->gateway = gateway;
501 ro->metric = metric;
502 ro->next = l->routes;
503 l->routes = ro;
d0085293 504
6fbf66fa
JY
505}
506
512cda46 507void
81d882d5
DS
508add_route_ipv6_to_option_list(struct route_ipv6_option_list *l,
509 const char *prefix,
510 const char *gateway,
511 const char *metric)
512cda46 512{
81d882d5
DS
513 struct route_ipv6_option *ro;
514 ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc);
515 ro->prefix = prefix;
516 ro->gateway = gateway;
517 ro->metric = metric;
518 ro->next = l->routes_ipv6;
519 l->routes_ipv6 = ro;
512cda46
GD
520}
521
6fbf66fa 522void
81d882d5 523clear_route_list(struct route_list *rl)
6fbf66fa 524{
81d882d5
DS
525 gc_free(&rl->gc);
526 CLEAR(*rl);
6fbf66fa
JY
527}
528
512cda46 529void
81d882d5 530clear_route_ipv6_list(struct route_ipv6_list *rl6)
512cda46 531{
81d882d5
DS
532 gc_free(&rl6->gc);
533 CLEAR(*rl6);
512cda46
GD
534}
535
03731db3 536void
81d882d5
DS
537route_list_add_vpn_gateway(struct route_list *rl,
538 struct env_set *es,
539 const in_addr_t addr)
03731db3 540{
81d882d5
DS
541 ASSERT(rl);
542 rl->spec.remote_endpoint = addr;
543 rl->spec.flags |= RTSA_REMOTE_ENDPOINT;
544 setenv_route_addr(es, "vpn_gateway", rl->spec.remote_endpoint, -1);
03731db3
JY
545}
546
7fb0e07e 547static void
81d882d5
DS
548add_block_local_item(struct route_list *rl,
549 const struct route_gateway_address *gateway,
550 in_addr_t target)
7fb0e07e 551{
81d882d5
DS
552 const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
553 if ((rl->rgi.flags & rgi_needed) == rgi_needed
554 && rl->rgi.gateway.netmask < 0xFFFFFFFF)
7fb0e07e 555 {
81d882d5
DS
556 struct route_ipv4 *r1, *r2;
557 unsigned int l2;
558
559 ALLOC_OBJ_GC(r1, struct route_ipv4, &rl->gc);
560 ALLOC_OBJ_GC(r2, struct route_ipv4, &rl->gc);
561
562 /* split a route into two smaller blocking routes, and direct them to target */
563 l2 = ((~gateway->netmask)+1)>>1;
564 r1->flags = RT_DEFINED;
565 r1->gateway = target;
566 r1->network = gateway->addr & gateway->netmask;
567 r1->netmask = ~(l2-1);
568 r1->next = rl->routes;
569 rl->routes = r1;
570
571 *r2 = *r1;
572 r2->network += l2;
573 r2->next = rl->routes;
574 rl->routes = r2;
7fb0e07e
JY
575 }
576}
577
578static void
81d882d5 579add_block_local(struct route_list *rl)
7fb0e07e 580{
81d882d5
DS
581 const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
582 if ((rl->flags & RG_BLOCK_LOCAL)
583 && (rl->rgi.flags & rgi_needed) == rgi_needed
584 && (rl->spec.flags & RTSA_REMOTE_ENDPOINT)
585 && rl->spec.remote_host_local != TLA_LOCAL)
7fb0e07e 586 {
81d882d5 587 size_t i;
7fb0e07e 588
ad80d677 589#ifndef TARGET_ANDROID
81d882d5
DS
590 /* add bypass for gateway addr */
591 add_bypass_address(&rl->spec.bypass, rl->rgi.gateway.addr);
ad80d677 592#endif
7fb0e07e 593
81d882d5
DS
594 /* block access to local subnet */
595 add_block_local_item(rl, &rl->rgi.gateway, rl->spec.remote_endpoint);
7fb0e07e 596
81d882d5
DS
597 /* process additional subnets on gateway interface */
598 for (i = 0; i < rl->rgi.n_addrs; ++i)
599 {
600 const struct route_gateway_address *gwa = &rl->rgi.addrs[i];
601 /* omit the add/subnet in &rl->rgi which we processed above */
602 if (!((rl->rgi.gateway.addr & rl->rgi.gateway.netmask) == (gwa->addr & gwa->netmask)
603 && rl->rgi.gateway.netmask == gwa->netmask))
604 {
605 add_block_local_item(rl, gwa, rl->spec.remote_endpoint);
606 }
607 }
7fb0e07e
JY
608 }
609}
610
6fbf66fa 611bool
81d882d5
DS
612init_route_list(struct route_list *rl,
613 const struct route_option_list *opt,
614 const char *remote_endpoint,
615 int default_metric,
616 in_addr_t remote_host,
617 struct env_set *es)
6fbf66fa 618{
81d882d5
DS
619 struct gc_arena gc = gc_new();
620 bool ret = true;
6fbf66fa 621
81d882d5 622 clear_route_list(rl);
6fbf66fa 623
81d882d5 624 rl->flags = opt->flags;
3c7f2f55 625
81d882d5 626 if (remote_host)
6fbf66fa 627 {
81d882d5
DS
628 rl->spec.remote_host = remote_host;
629 rl->spec.flags |= RTSA_REMOTE_HOST;
6fbf66fa
JY
630 }
631
81d882d5 632 if (default_metric)
40ac3d7a 633 {
81d882d5
DS
634 rl->spec.default_metric = default_metric;
635 rl->spec.flags |= RTSA_DEFAULT_METRIC;
40ac3d7a
JY
636 }
637
81d882d5
DS
638 get_default_gateway(&rl->rgi);
639 if (rl->rgi.flags & RGI_ADDR_DEFINED)
6fbf66fa 640 {
81d882d5 641 setenv_route_addr(es, "net_gateway", rl->rgi.gateway.addr, -1);
c29e08a2 642#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
81d882d5 643 print_default_gateway(D_ROUTE, &rl->rgi, NULL);
7fb0e07e 644#endif
3c7f2f55 645 }
81d882d5 646 else
03653f42 647 {
81d882d5 648 dmsg(D_ROUTE, "ROUTE: default_gateway=UNDEF");
03653f42 649 }
3c7f2f55 650
81d882d5 651 if (rl->spec.flags & RTSA_REMOTE_HOST)
6fbf66fa 652 {
81d882d5
DS
653 rl->spec.remote_host_local = test_local_addr(remote_host, &rl->rgi);
654 }
6fbf66fa 655
81d882d5
DS
656 if (is_route_parm_defined(remote_endpoint))
657 {
658 bool defined = false;
659 rl->spec.remote_endpoint = getaddr(
660 GETADDR_RESOLVE
661 | GETADDR_HOST_ORDER
662 | GETADDR_WARN_ON_SIGNAL,
663 remote_endpoint,
664 0,
665 &defined,
666 NULL);
667
668 if (defined)
669 {
670 setenv_route_addr(es, "vpn_gateway", rl->spec.remote_endpoint, -1);
671 rl->spec.flags |= RTSA_REMOTE_ENDPOINT;
672 }
673 else
674 {
675 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve default gateway: %s",
676 remote_endpoint);
677 ret = false;
678 }
6fbf66fa 679 }
7fb0e07e 680
81d882d5 681 if (rl->flags & RG_ENABLE)
7fb0e07e 682 {
81d882d5
DS
683 add_block_local(rl);
684 get_bypass_addresses(&rl->spec.bypass, rl->flags);
7fb0e07e 685#ifdef ENABLE_DEBUG
81d882d5 686 print_bypass_addresses(&rl->spec.bypass);
7fb0e07e
JY
687#endif
688 }
6fbf66fa 689
81d882d5
DS
690 /* parse the routes from opt to rl */
691 {
692 struct route_option *ro;
693 for (ro = opt->routes; ro; ro = ro->next)
694 {
695 struct addrinfo *netlist = NULL;
696 struct route_ipv4 r;
697
698 if (!init_route(&r, &netlist, ro, rl))
699 {
700 ret = false;
701 }
702 else
703 {
704 struct addrinfo *curele;
705 for (curele = netlist; curele; curele = curele->ai_next)
706 {
707 struct route_ipv4 *new;
708 ALLOC_OBJ_GC(new, struct route_ipv4, &rl->gc);
709 *new = r;
710 new->network = ntohl(((struct sockaddr_in *)curele->ai_addr)->sin_addr.s_addr);
711 new->next = rl->routes;
712 rl->routes = new;
713 }
714 }
715 if (netlist)
716 {
717 gc_addspecial(netlist, &gc_freeaddrinfo_callback, &gc);
718 }
719 }
720 }
721
722 gc_free(&gc);
723 return ret;
6fbf66fa
JY
724}
725
3ddb5643
GD
726/* check whether an IPv6 host address is covered by a given route_ipv6
727 * (not the most beautiful implementation in the world, but portable and
728 * "good enough")
729 */
730static bool
731route_ipv6_match_host( const struct route_ipv6 *r6,
81d882d5 732 const struct in6_addr *host )
3ddb5643
GD
733{
734 unsigned int bits = r6->netbits;
735 int i;
736 unsigned int mask;
737
81d882d5
DS
738 if (bits>128)
739 {
740 return false;
741 }
3ddb5643 742
81d882d5 743 for (i = 0; bits >= 8; i++, bits -= 8)
3ddb5643 744 {
81d882d5
DS
745 if (r6->network.s6_addr[i] != host->s6_addr[i])
746 {
747 return false;
748 }
3ddb5643
GD
749 }
750
81d882d5
DS
751 if (bits == 0)
752 {
753 return true;
754 }
3ddb5643
GD
755
756 mask = 0xff << (8-bits);
757
758 if ( (r6->network.s6_addr[i] & mask) == (host->s6_addr[i] & mask ))
81d882d5
DS
759 {
760 return true;
761 }
3ddb5643
GD
762
763 return false;
764}
765
512cda46 766bool
81d882d5
DS
767init_route_ipv6_list(struct route_ipv6_list *rl6,
768 const struct route_ipv6_option_list *opt6,
769 const char *remote_endpoint,
770 int default_metric,
771 const struct in6_addr *remote_host_ipv6,
772 struct env_set *es)
512cda46 773{
81d882d5
DS
774 struct gc_arena gc = gc_new();
775 bool ret = true;
776 bool need_remote_ipv6_route;
512cda46 777
81d882d5 778 clear_route_ipv6_list(rl6);
512cda46 779
81d882d5 780 rl6->flags = opt6->flags;
512cda46 781
81d882d5 782 if (remote_host_ipv6)
3ddb5643 783 {
81d882d5
DS
784 rl6->remote_host_ipv6 = *remote_host_ipv6;
785 rl6->spec_flags |= RTSA_REMOTE_HOST;
3ddb5643
GD
786 }
787
81d882d5 788 if (default_metric >= 0)
512cda46 789 {
81d882d5
DS
790 rl6->default_metric = default_metric;
791 rl6->spec_flags |= RTSA_DEFAULT_METRIC;
512cda46
GD
792 }
793
81d882d5
DS
794 msg(D_ROUTE, "GDG6: remote_host_ipv6=%s",
795 remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a" );
3ddb5643 796
81d882d5
DS
797 get_default_gateway_ipv6(&rl6->rgi6, remote_host_ipv6);
798 if (rl6->rgi6.flags & RGI_ADDR_DEFINED)
3ddb5643 799 {
81d882d5 800 setenv_str(es, "net_gateway_ipv6", print_in6_addr(rl6->rgi6.gateway.addr_ipv6, 0, &gc));
3ddb5643 801#if defined(ENABLE_DEBUG) && !defined(ENABLE_SMALL)
81d882d5 802 print_default_gateway(D_ROUTE, NULL, &rl6->rgi6);
3ddb5643
GD
803#endif
804 }
81d882d5 805 else
512cda46 806 {
81d882d5 807 dmsg(D_ROUTE, "ROUTE6: default_gateway=UNDEF");
512cda46
GD
808 }
809
81d882d5 810 if (is_route_parm_defined( remote_endpoint ))
512cda46 811 {
81d882d5
DS
812 if (inet_pton( AF_INET6, remote_endpoint,
813 &rl6->remote_endpoint_ipv6) == 1)
814 {
815 rl6->spec_flags |= RTSA_REMOTE_ENDPOINT;
816 }
817 else
512cda46 818 {
81d882d5
DS
819 msg(M_WARN, PACKAGE_NAME " ROUTE: failed to parse/resolve VPN endpoint: %s", remote_endpoint);
820 ret = false;
512cda46 821 }
512cda46 822 }
512cda46 823
81d882d5
DS
824 /* parse the routes from opt6 to rl6
825 * discovering potential overlaps with remote_host_ipv6 in the process
826 */
827 need_remote_ipv6_route = false;
3ddb5643 828
81d882d5
DS
829 {
830 struct route_ipv6_option *ro6;
831 for (ro6 = opt6->routes_ipv6; ro6; ro6 = ro6->next)
832 {
833 struct route_ipv6 *r6;
834 ALLOC_OBJ_GC(r6, struct route_ipv6, &rl6->gc);
835 if (!init_route_ipv6(r6, ro6, rl6))
836 {
837 ret = false;
838 }
839 else
840 {
841 r6->next = rl6->routes_ipv6;
842 rl6->routes_ipv6 = r6;
3ddb5643 843
1ff39cff 844#ifndef TARGET_ANDROID
81d882d5
DS
845 /* On Android the VPNService protect function call will take of
846 * avoiding routing loops, so ignore this part and let
847 * need_remote_ipv6_route always evaluate to false
848 */
849 if (remote_host_ipv6
850 && route_ipv6_match_host( r6, remote_host_ipv6 ) )
851 {
852 need_remote_ipv6_route = true;
853 msg(D_ROUTE, "ROUTE6: %s/%d overlaps IPv6 remote %s, adding host route to VPN endpoint",
854 print_in6_addr(r6->network, 0, &gc), r6->netbits,
855 print_in6_addr(*remote_host_ipv6, 0, &gc));
856 }
1ff39cff 857#endif
81d882d5
DS
858 }
859 }
860 }
512cda46 861
81d882d5
DS
862 /* add VPN server host route if needed */
863 if (need_remote_ipv6_route)
3ddb5643 864 {
81d882d5
DS
865 if ( (rl6->rgi6.flags & (RGI_ADDR_DEFINED|RGI_IFACE_DEFINED) ) ==
866 (RGI_ADDR_DEFINED|RGI_IFACE_DEFINED) )
3ddb5643 867 {
81d882d5
DS
868 struct route_ipv6 *r6;
869 ALLOC_OBJ_CLEAR_GC(r6, struct route_ipv6, &rl6->gc);
870
871 r6->network = *remote_host_ipv6;
872 r6->netbits = 128;
873 if (!(rl6->rgi6.flags & RGI_ON_LINK) )
874 {
875 r6->gateway = rl6->rgi6.gateway.addr_ipv6;
876 }
877 r6->metric = 1;
445b192a 878#ifdef _WIN32
81d882d5 879 r6->adapter_index = rl6->rgi6.adapter_index;
3ddb5643 880#else
81d882d5 881 r6->iface = rl6->rgi6.iface;
3ddb5643 882#endif
81d882d5 883 r6->flags = RT_DEFINED | RT_METRIC_DEFINED;
3ddb5643 884
81d882d5
DS
885 r6->next = rl6->routes_ipv6;
886 rl6->routes_ipv6 = r6;
887 }
888 else
3ddb5643 889 {
81d882d5
DS
890 msg(M_WARN, "ROUTE6: IPv6 route overlaps with IPv6 remote address, but could not determine IPv6 gateway address + interface, expect failure\n" );
891 }
3ddb5643
GD
892 }
893
81d882d5
DS
894 gc_free(&gc);
895 return ret;
512cda46
GD
896}
897
6fbf66fa 898static void
81d882d5
DS
899add_route3(in_addr_t network,
900 in_addr_t netmask,
901 in_addr_t gateway,
902 const struct tuntap *tt,
903 unsigned int flags,
904 const struct route_gateway_info *rgi,
905 const struct env_set *es)
906{
907 struct route_ipv4 r;
908 CLEAR(r);
909 r.flags = RT_DEFINED;
910 r.network = network;
911 r.netmask = netmask;
912 r.gateway = gateway;
913 add_route(&r, tt, flags, rgi, es);
6fbf66fa
JY
914}
915
916static void
81d882d5
DS
917del_route3(in_addr_t network,
918 in_addr_t netmask,
919 in_addr_t gateway,
920 const struct tuntap *tt,
921 unsigned int flags,
922 const struct route_gateway_info *rgi,
923 const struct env_set *es)
924{
925 struct route_ipv4 r;
926 CLEAR(r);
927 r.flags = RT_DEFINED|RT_ADDED;
928 r.network = network;
929 r.netmask = netmask;
930 r.gateway = gateway;
931 delete_route(&r, tt, flags, rgi, es);
6fbf66fa
JY
932}
933
3c7f2f55 934static void
81d882d5
DS
935add_bypass_routes(struct route_bypass *rb,
936 in_addr_t gateway,
937 const struct tuntap *tt,
938 unsigned int flags,
939 const struct route_gateway_info *rgi,
940 const struct env_set *es)
3c7f2f55 941{
81d882d5
DS
942 int i;
943 for (i = 0; i < rb->n_bypass; ++i)
3c7f2f55 944 {
81d882d5
DS
945 if (rb->bypass[i])
946 {
947 add_route3(rb->bypass[i],
948 IPV4_NETMASK_HOST,
949 gateway,
950 tt,
951 flags | ROUTE_REF_GW,
952 rgi,
953 es);
954 }
3c7f2f55
JY
955 }
956}
957
958static void
81d882d5
DS
959del_bypass_routes(struct route_bypass *rb,
960 in_addr_t gateway,
961 const struct tuntap *tt,
962 unsigned int flags,
963 const struct route_gateway_info *rgi,
964 const struct env_set *es)
3c7f2f55 965{
81d882d5
DS
966 int i;
967 for (i = 0; i < rb->n_bypass; ++i)
3c7f2f55 968 {
81d882d5
DS
969 if (rb->bypass[i])
970 {
971 del_route3(rb->bypass[i],
972 IPV4_NETMASK_HOST,
973 gateway,
974 tt,
975 flags | ROUTE_REF_GW,
976 rgi,
977 es);
978 }
3c7f2f55
JY
979 }
980}
981
6fbf66fa 982static void
81d882d5
DS
983redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
984{
985 const char err[] = "NOTE: unable to redirect default gateway --";
6fbf66fa 986
81d882d5
DS
987 if (rl && rl->flags & RG_ENABLE)
988 {
989 if (!(rl->spec.flags & RTSA_REMOTE_ENDPOINT) && (rl->flags & RG_REROUTE_GW))
990 {
991 msg(M_WARN, "%s VPN gateway parameter (--route-gateway or --ifconfig) is missing", err);
992 }
993 else if (!(rl->rgi.flags & RGI_ADDR_DEFINED))
994 {
995 msg(M_WARN, "%s Cannot read current default gateway from system", err);
996 }
997 else if (!(rl->spec.flags & RTSA_REMOTE_HOST))
998 {
999 msg(M_WARN, "%s Cannot obtain current remote host address", err);
1000 }
1001 else
1002 {
1003#ifndef TARGET_ANDROID
1004 bool local = BOOL_CAST(rl->flags & RG_LOCAL);
1005 if (rl->flags & RG_AUTO_LOCAL)
1006 {
1007 const int tla = rl->spec.remote_host_local;
1008 if (tla == TLA_NONLOCAL)
1009 {
1010 dmsg(D_ROUTE, "ROUTE remote_host is NOT LOCAL");
1011 local = false;
1012 }
1013 else if (tla == TLA_LOCAL)
1014 {
1015 dmsg(D_ROUTE, "ROUTE remote_host is LOCAL");
1016 local = true;
1017 }
1018 }
1019 if (!local)
1020 {
1021 /* route remote host to original default gateway */
1022 /* if remote_host is not ipv4 (ie: ipv6), just skip
1023 * adding this special /32 route */
1024 if (rl->spec.remote_host != IPV4_INVALID_ADDR)
1025 {
1026 add_route3(rl->spec.remote_host,
1027 IPV4_NETMASK_HOST,
1028 rl->rgi.gateway.addr,
1029 tt,
1030 flags | ROUTE_REF_GW,
1031 &rl->rgi,
1032 es);
1033 rl->iflags |= RL_DID_LOCAL;
1034 }
1035 else
1036 {
1037 dmsg(D_ROUTE, "ROUTE remote_host protocol differs from tunneled");
1038 }
1039 }
1040#endif /* ifndef TARGET_ANDROID */
1041
1042 /* route DHCP/DNS server traffic through original default gateway */
1043 add_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
1044
1045 if (rl->flags & RG_REROUTE_GW)
1046 {
1047 if (rl->flags & RG_DEF1)
1048 {
1049 /* add new default route (1st component) */
1050 add_route3(0x00000000,
1051 0x80000000,
1052 rl->spec.remote_endpoint,
1053 tt,
1054 flags,
1055 &rl->rgi,
1056 es);
1057
1058 /* add new default route (2nd component) */
1059 add_route3(0x80000000,
1060 0x80000000,
1061 rl->spec.remote_endpoint,
1062 tt,
1063 flags,
1064 &rl->rgi,
1065 es);
1066 }
1067 else
1068 {
1069 /* delete default route */
1070 del_route3(0,
1071 0,
1072 rl->rgi.gateway.addr,
1073 tt,
1074 flags | ROUTE_REF_GW,
1075 &rl->rgi,
1076 es);
1077
1078 /* add new default route */
1079 add_route3(0,
1080 0,
1081 rl->spec.remote_endpoint,
1082 tt,
1083 flags,
1084 &rl->rgi,
1085 es);
1086 }
1087 }
1088
1089 /* set a flag so we can undo later */
1090 rl->iflags |= RL_DID_REDIRECT_DEFAULT_GATEWAY;
1091 }
b723833b
JY
1092 }
1093}
1094
1095static void
81d882d5
DS
1096undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
1097{
1098 if (rl && rl->iflags & RL_DID_REDIRECT_DEFAULT_GATEWAY)
1099 {
1100 /* delete remote host route */
1101 if (rl->iflags & RL_DID_LOCAL)
1102 {
1103 del_route3(rl->spec.remote_host,
1104 IPV4_NETMASK_HOST,
1105 rl->rgi.gateway.addr,
1106 tt,
1107 flags | ROUTE_REF_GW,
1108 &rl->rgi,
1109 es);
1110 rl->iflags &= ~RL_DID_LOCAL;
1111 }
1112
1113 /* delete special DHCP/DNS bypass route */
1114 del_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
1115
1116 if (rl->flags & RG_REROUTE_GW)
1117 {
1118 if (rl->flags & RG_DEF1)
1119 {
1120 /* delete default route (1st component) */
1121 del_route3(0x00000000,
1122 0x80000000,
1123 rl->spec.remote_endpoint,
1124 tt,
1125 flags,
1126 &rl->rgi,
1127 es);
1128
1129 /* delete default route (2nd component) */
1130 del_route3(0x80000000,
1131 0x80000000,
1132 rl->spec.remote_endpoint,
1133 tt,
1134 flags,
1135 &rl->rgi,
1136 es);
1137 }
1138 else
1139 {
1140 /* delete default route */
1141 del_route3(0,
1142 0,
1143 rl->spec.remote_endpoint,
1144 tt,
1145 flags,
1146 &rl->rgi,
1147 es);
1148
1149 /* restore original default route */
1150 add_route3(0,
1151 0,
1152 rl->rgi.gateway.addr,
1153 tt,
1154 flags | ROUTE_REF_GW,
1155 &rl->rgi,
1156 es);
1157 }
1158 }
1159
1160 rl->iflags &= ~RL_DID_REDIRECT_DEFAULT_GATEWAY;
6fbf66fa
JY
1161 }
1162}
1163
1164void
81d882d5 1165add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
6fbf66fa 1166{
81d882d5
DS
1167 redirect_default_route_to_vpn(rl, tt, flags, es);
1168 if (rl && !(rl->iflags & RL_ROUTES_ADDED) )
6fbf66fa 1169 {
81d882d5 1170 struct route_ipv4 *r;
6fbf66fa
JY
1171
1172#ifdef ENABLE_MANAGEMENT
81d882d5
DS
1173 if (management && rl->routes)
1174 {
1175 management_set_state(management,
1176 OPENVPN_STATE_ADD_ROUTES,
1177 NULL,
1178 NULL,
1179 NULL,
1180 NULL,
1181 NULL);
1182 }
6fbf66fa 1183#endif
d0085293 1184
81d882d5
DS
1185 for (r = rl->routes; r; r = r->next)
1186 {
1187 check_subnet_conflict(r->network, r->netmask, "route");
1188 if (flags & ROUTE_DELETE_FIRST)
1189 {
1190 delete_route(r, tt, flags, &rl->rgi, es);
1191 }
1192 add_route(r, tt, flags, &rl->rgi, es);
1193 }
1194 rl->iflags |= RL_ROUTES_ADDED;
6fbf66fa 1195 }
81d882d5 1196 if (rl6 && !(rl6->iflags & RL_ROUTES_ADDED) )
512cda46 1197 {
81d882d5 1198 struct route_ipv6 *r;
2b7650e7
AQ
1199
1200 if (!tt->did_ifconfig_ipv6_setup)
1201 {
1202 msg(M_INFO, "WARNING: OpenVPN was configured to add an IPv6 "
1203 "route over %s. However, no IPv6 has been configured for "
1204 "this interface, therefore the route installation may "
1205 "fail or may not work as expected.", tt->actual_name);
1206 }
1207
81d882d5
DS
1208 for (r = rl6->routes_ipv6; r; r = r->next)
1209 {
1210 if (flags & ROUTE_DELETE_FIRST)
1211 {
1212 delete_route_ipv6(r, tt, flags, es);
1213 }
1214 add_route_ipv6(r, tt, flags, es);
1215 }
1216 rl6->iflags |= RL_ROUTES_ADDED;
512cda46 1217 }
6fbf66fa
JY
1218}
1219
1220void
81d882d5
DS
1221delete_routes(struct route_list *rl, struct route_ipv6_list *rl6,
1222 const struct tuntap *tt, unsigned int flags, const struct env_set *es)
6fbf66fa 1223{
81d882d5 1224 if (rl && rl->iflags & RL_ROUTES_ADDED)
6fbf66fa 1225 {
81d882d5
DS
1226 struct route_ipv4 *r;
1227 for (r = rl->routes; r; r = r->next)
1228 {
1229 delete_route(r, tt, flags, &rl->rgi, es);
1230 }
1231 rl->iflags &= ~RL_ROUTES_ADDED;
6fbf66fa 1232 }
6fbf66fa 1233
81d882d5 1234 undo_redirect_default_route_to_vpn(rl, tt, flags, es);
f0257abb 1235
81d882d5 1236 if (rl)
f0257abb 1237 {
81d882d5 1238 clear_route_list(rl);
f0257abb 1239 }
512cda46 1240
81d882d5 1241 if (rl6 && (rl6->iflags & RL_ROUTES_ADDED) )
512cda46 1242 {
81d882d5
DS
1243 struct route_ipv6 *r6;
1244 for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
1245 {
1246 delete_route_ipv6(r6, tt, flags, es);
1247 }
1248 rl6->iflags &= ~RL_ROUTES_ADDED;
512cda46
GD
1249 }
1250
81d882d5 1251 if (rl6)
512cda46 1252 {
81d882d5 1253 clear_route_ipv6_list(rl6);
512cda46 1254 }
6fbf66fa
JY
1255}
1256
6c61d0dd 1257#ifndef ENABLE_SMALL
6fbf66fa
JY
1258
1259static const char *
81d882d5 1260show_opt(const char *option)
6fbf66fa 1261{
81d882d5
DS
1262 if (!option)
1263 {
1264 return "default (not set)";
1265 }
1266 else
1267 {
1268 return option;
1269 }
6fbf66fa
JY
1270}
1271
1272static void
81d882d5 1273print_route_option(const struct route_option *ro, int level)
6fbf66fa 1274{
81d882d5
DS
1275 msg(level, " route %s/%s/%s/%s",
1276 show_opt(ro->network),
1277 show_opt(ro->netmask),
1278 show_opt(ro->gateway),
1279 show_opt(ro->metric));
6fbf66fa
JY
1280}
1281
1282void
81d882d5
DS
1283print_route_options(const struct route_option_list *rol,
1284 int level)
6fbf66fa 1285{
81d882d5
DS
1286 struct route_option *ro;
1287 if (rol->flags & RG_ENABLE)
1288 {
1289 msg(level, " [redirect_default_gateway local=%d]",
1290 (rol->flags & RG_LOCAL) != 0);
1291 }
1292 for (ro = rol->routes; ro; ro = ro->next)
4cd4899e 1293 {
81d882d5 1294 print_route_option(ro, level);
4cd4899e 1295 }
6fbf66fa
JY
1296}
1297
7fb0e07e 1298void
d8a8656f 1299print_default_gateway(const int msglevel,
81d882d5
DS
1300 const struct route_gateway_info *rgi,
1301 const struct route_ipv6_gateway_info *rgi6)
1302{
1303 struct gc_arena gc = gc_new();
1304 if (rgi && (rgi->flags & RGI_ADDR_DEFINED))
1305 {
1306 struct buffer out = alloc_buf_gc(256, &gc);
1307 buf_printf(&out, "ROUTE_GATEWAY");
1308 if (rgi->flags & RGI_ON_LINK)
1309 {
1310 buf_printf(&out, " ON_LINK");
1311 }
1312 else
1313 {
1314 buf_printf(&out, " %s", print_in_addr_t(rgi->gateway.addr, 0, &gc));
1315 }
1316 if (rgi->flags & RGI_NETMASK_DEFINED)
1317 {
1318 buf_printf(&out, "/%s", print_in_addr_t(rgi->gateway.netmask, 0, &gc));
1319 }
445b192a 1320#ifdef _WIN32
81d882d5
DS
1321 if (rgi->flags & RGI_IFACE_DEFINED)
1322 {
1323 buf_printf(&out, " I=%u", (unsigned int)rgi->adapter_index);
1324 }
7fb0e07e 1325#else
81d882d5
DS
1326 if (rgi->flags & RGI_IFACE_DEFINED)
1327 {
1328 buf_printf(&out, " IFACE=%s", rgi->iface);
1329 }
7fb0e07e 1330#endif
81d882d5
DS
1331 if (rgi->flags & RGI_HWADDR_DEFINED)
1332 {
1333 buf_printf(&out, " HWADDR=%s", format_hex_ex(rgi->hwaddr, 6, 0, 1, ":", &gc));
1334 }
1335 msg(msglevel, "%s", BSTR(&out));
7fb0e07e 1336 }
d8a8656f 1337
81d882d5 1338 if (rgi6 && (rgi6->flags & RGI_ADDR_DEFINED))
d8a8656f 1339 {
81d882d5
DS
1340 struct buffer out = alloc_buf_gc(256, &gc);
1341 buf_printf(&out, "ROUTE6_GATEWAY");
1342 buf_printf(&out, " %s", print_in6_addr(rgi6->gateway.addr_ipv6, 0, &gc));
1343 if (rgi6->flags & RGI_ON_LINK)
1344 {
1345 buf_printf(&out, " ON_LINK");
1346 }
1347 if (rgi6->flags & RGI_NETMASK_DEFINED)
1348 {
1349 buf_printf(&out, "/%d", rgi6->gateway.netbits_ipv6);
1350 }
445b192a 1351#ifdef _WIN32
81d882d5
DS
1352 if (rgi6->flags & RGI_IFACE_DEFINED)
1353 {
1354 buf_printf(&out, " I=%u", (unsigned int)rgi6->adapter_index);
1355 }
d8a8656f 1356#else
81d882d5
DS
1357 if (rgi6->flags & RGI_IFACE_DEFINED)
1358 {
1359 buf_printf(&out, " IFACE=%s", rgi6->iface);
1360 }
d8a8656f 1361#endif
81d882d5
DS
1362 if (rgi6->flags & RGI_HWADDR_DEFINED)
1363 {
1364 buf_printf(&out, " HWADDR=%s", format_hex_ex(rgi6->hwaddr, 6, 0, 1, ":", &gc));
1365 }
1366 msg(msglevel, "%s", BSTR(&out));
d8a8656f 1367 }
81d882d5 1368 gc_free(&gc);
7fb0e07e
JY
1369}
1370
81d882d5 1371#endif /* ifndef ENABLE_SMALL */
6fbf66fa
JY
1372
1373static void
81d882d5 1374print_route(const struct route_ipv4 *r, int level)
6fbf66fa 1375{
81d882d5
DS
1376 struct gc_arena gc = gc_new();
1377 if (r->flags & RT_DEFINED)
1378 {
1379 msg(level, "%s", route_string(r, &gc));
1380 }
1381 gc_free(&gc);
6fbf66fa
JY
1382}
1383
1384void
81d882d5 1385print_routes(const struct route_list *rl, int level)
6fbf66fa 1386{
81d882d5
DS
1387 struct route_ipv4 *r;
1388 for (r = rl->routes; r; r = r->next)
4cd4899e 1389 {
81d882d5 1390 print_route(r, level);
4cd4899e 1391 }
6fbf66fa
JY
1392}
1393
1394static void
81d882d5 1395setenv_route(struct env_set *es, const struct route_ipv4 *r, int i)
6fbf66fa 1396{
81d882d5
DS
1397 struct gc_arena gc = gc_new();
1398 if (r->flags & RT_DEFINED)
6fbf66fa 1399 {
81d882d5
DS
1400 setenv_route_addr(es, "network", r->network, i);
1401 setenv_route_addr(es, "netmask", r->netmask, i);
1402 setenv_route_addr(es, "gateway", r->gateway, i);
6fbf66fa 1403
81d882d5
DS
1404 if (r->flags & RT_METRIC_DEFINED)
1405 {
1406 struct buffer name = alloc_buf_gc(256, &gc);
1407 buf_printf(&name, "route_metric_%d", i);
1408 setenv_int(es, BSTR(&name), r->metric);
1409 }
6fbf66fa 1410 }
81d882d5 1411 gc_free(&gc);
6fbf66fa
JY
1412}
1413
1414void
81d882d5 1415setenv_routes(struct env_set *es, const struct route_list *rl)
6fbf66fa 1416{
81d882d5
DS
1417 int i = 1;
1418 struct route_ipv4 *r;
1419 for (r = rl->routes; r; r = r->next)
4cd4899e 1420 {
81d882d5 1421 setenv_route(es, r, i++);
4cd4899e 1422 }
6fbf66fa
JY
1423}
1424
512cda46 1425static void
81d882d5 1426setenv_route_ipv6(struct env_set *es, const struct route_ipv6 *r6, int i)
512cda46 1427{
81d882d5
DS
1428 struct gc_arena gc = gc_new();
1429 if (r6->flags & RT_DEFINED)
512cda46 1430 {
81d882d5
DS
1431 struct buffer name1 = alloc_buf_gc( 256, &gc );
1432 struct buffer val = alloc_buf_gc( 256, &gc );
1433 struct buffer name2 = alloc_buf_gc( 256, &gc );
512cda46 1434
81d882d5
DS
1435 buf_printf( &name1, "route_ipv6_network_%d", i );
1436 buf_printf( &val, "%s/%d", print_in6_addr( r6->network, 0, &gc ),
1437 r6->netbits );
1438 setenv_str( es, BSTR(&name1), BSTR(&val) );
512cda46 1439
81d882d5
DS
1440 buf_printf( &name2, "route_ipv6_gateway_%d", i );
1441 setenv_str( es, BSTR(&name2), print_in6_addr( r6->gateway, 0, &gc ));
512cda46 1442 }
81d882d5 1443 gc_free(&gc);
512cda46
GD
1444}
1445void
81d882d5 1446setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6)
512cda46 1447{
81d882d5
DS
1448 int i = 1;
1449 struct route_ipv6 *r6;
1450 for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
4cd4899e 1451 {
81d882d5 1452 setenv_route_ipv6(es, r6, i++);
4cd4899e 1453 }
512cda46
GD
1454}
1455
7fb0e07e
JY
1456/*
1457 * local_route() determines whether the gateway of a provided host
1458 * route is on the same interface that owns the default gateway.
1459 * It uses the data structure
1460 * returned by get_default_gateway() (struct route_gateway_info)
1461 * to determine this. If the route is local, LR_MATCH is returned.
1462 * When adding routes into the kernel, if LR_MATCH is defined for
1463 * a given route, the route should explicitly reference the default
1464 * gateway interface as the route destination. For example, here
1465 * is an example on Linux that uses LR_MATCH:
1466 *
576dc96c 1467 * route add -net 10.10.0.1 netmask 255.255.255.255 dev eth0
7fb0e07e
JY
1468 *
1469 * This capability is needed by the "default-gateway block-local"
1470 * directive, to allow client access to the local subnet to be
1471 * blocked but still allow access to the local default gateway.
1472 */
1473
1474/* local_route() return values */
1475#define LR_NOMATCH 0 /* route is not local */
1476#define LR_MATCH 1 /* route is local */
1477#define LR_ERROR 2 /* caller should abort adding route */
1478
1479static int
81d882d5
DS
1480local_route(in_addr_t network,
1481 in_addr_t netmask,
1482 in_addr_t gateway,
1483 const struct route_gateway_info *rgi)
1484{
1485 /* set LR_MATCH on local host routes */
1486 const int rgi_needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED|RGI_IFACE_DEFINED);
1487 if (rgi
1488 && (rgi->flags & rgi_needed) == rgi_needed
1489 && gateway == rgi->gateway.addr
1490 && netmask == 0xFFFFFFFF)
1491 {
1492 if (((network ^ rgi->gateway.addr) & rgi->gateway.netmask) == 0)
1493 {
1494 return LR_MATCH;
1495 }
1496 else
1497 {
1498 /* examine additional subnets on gateway interface */
1499 size_t i;
1500 for (i = 0; i < rgi->n_addrs; ++i)
1501 {
1502 const struct route_gateway_address *gwa = &rgi->addrs[i];
1503 if (((network ^ gwa->addr) & gwa->netmask) == 0)
1504 {
1505 return LR_MATCH;
1506 }
1507 }
1508 }
7fb0e07e
JY
1509 }
1510 return LR_NOMATCH;
1511}
1512
8fc83a2d 1513/* Return true if the "on-link" form of the route should be used. This is when the gateway for a
81d882d5 1514 * a route is specified as an interface rather than an address. */
8fc83a2d 1515static inline bool
81d882d5 1516is_on_link(const int is_local_route, const unsigned int flags, const struct route_gateway_info *rgi)
8fc83a2d 1517{
81d882d5 1518 return rgi && (is_local_route == LR_MATCH || ((flags & ROUTE_REF_GW) && (rgi->flags & RGI_ON_LINK)));
8fc83a2d
JY
1519}
1520
6d5d1010 1521void
81d882d5
DS
1522add_route(struct route_ipv4 *r,
1523 const struct tuntap *tt,
1524 unsigned int flags,
1525 const struct route_gateway_info *rgi, /* may be NULL */
1526 const struct env_set *es)
6fbf66fa 1527{
81d882d5
DS
1528 struct gc_arena gc;
1529 struct argv argv = argv_new();
1530 const char *network;
1531 const char *netmask;
1532 const char *gateway;
1533 bool status = false;
1534 int is_local_route;
1535
1536 if (!(r->flags & RT_DEFINED))
1537 {
1538 return;
1539 }
6fbf66fa 1540
81d882d5 1541 gc_init(&gc);
6fbf66fa 1542
81d882d5
DS
1543 network = print_in_addr_t(r->network, 0, &gc);
1544 netmask = print_in_addr_t(r->netmask, 0, &gc);
1545 gateway = print_in_addr_t(r->gateway, 0, &gc);
6fbf66fa 1546
81d882d5
DS
1547 is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
1548 if (is_local_route == LR_ERROR)
1549 {
1550 goto done;
1551 }
6fbf66fa
JY
1552
1553#if defined(TARGET_LINUX)
51bd56f4 1554#ifdef ENABLE_IPROUTE
81d882d5
DS
1555 argv_printf(&argv, "%s route add %s/%d",
1556 iproute_path,
1557 network,
1558 netmask_to_netbits2(r->netmask));
1559
1560 if (r->flags & RT_METRIC_DEFINED)
1561 {
1562 argv_printf_cat(&argv, "metric %d", r->metric);
1563 }
1564
1565 if (is_on_link(is_local_route, flags, rgi))
1566 {
1567 argv_printf_cat(&argv, "dev %s", rgi->iface);
1568 }
1569 else
1570 {
1571 argv_printf_cat(&argv, "via %s", gateway);
1572 }
1573#else /* ifdef ENABLE_IPROUTE */
1574 argv_printf(&argv, "%s add -net %s netmask %s",
1575 ROUTE_PATH,
1576 network,
1577 netmask);
1578 if (r->flags & RT_METRIC_DEFINED)
1579 {
1580 argv_printf_cat(&argv, "metric %d", r->metric);
1581 }
1582 if (is_on_link(is_local_route, flags, rgi))
1583 {
1584 argv_printf_cat(&argv, "dev %s", rgi->iface);
1585 }
1586 else
1587 {
1588 argv_printf_cat(&argv, "gw %s", gateway);
1589 }
7fb0e07e 1590
51bd56f4 1591#endif /*ENABLE_IPROUTE*/
81d882d5
DS
1592 argv_msg(D_ROUTE, &argv);
1593 status = openvpn_execve_check(&argv, es, 0, "ERROR: Linux route add command failed");
6fbf66fa 1594
a55b3cdb 1595#elif defined (TARGET_ANDROID)
81d882d5 1596 struct buffer out = alloc_buf_gc(128, &gc);
a55b3cdb 1597
81d882d5
DS
1598 if (rgi)
1599 {
1600 buf_printf(&out, "%s %s %s dev %s", network, netmask, gateway, rgi->iface);
1601 }
1602 else
1603 {
1604 buf_printf(&out, "%s %s %s", network, netmask, gateway);
1605 }
1606 management_android_control(management, "ROUTE", buf_bptr(&out));
a55b3cdb 1607
445b192a 1608#elif defined (_WIN32)
81d882d5
DS
1609 {
1610 DWORD ai = TUN_ADAPTER_INDEX_INVALID;
1611 argv_printf(&argv, "%s%sc ADD %s MASK %s %s",
1612 get_win_sys_path(),
1613 WIN_ROUTE_PATH_SUFFIX,
1614 network,
1615 netmask,
1616 gateway);
1617 if (r->flags & RT_METRIC_DEFINED)
1618 {
1619 argv_printf_cat(&argv, "METRIC %d", r->metric);
1620 }
1621 if (is_on_link(is_local_route, flags, rgi))
1622 {
1623 ai = rgi->adapter_index;
1624 argv_printf_cat(&argv, "IF %u", (unsigned int)ai);
1625 }
6fbf66fa 1626
81d882d5 1627 argv_msg(D_ROUTE, &argv);
6fbf66fa 1628
81d882d5
DS
1629 if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_SERVICE)
1630 {
1631 status = add_route_service(r, tt);
1632 msg(D_ROUTE, "Route addition via service %s", status ? "succeeded" : "failed");
1633 }
1634 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
1635 {
1636 status = add_route_ipapi(r, tt, ai);
1637 msg(D_ROUTE, "Route addition via IPAPI %s", status ? "succeeded" : "failed");
1638 }
1639 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
1640 {
1641 netcmd_semaphore_lock();
1642 status = openvpn_execve_check(&argv, es, 0, "ERROR: Windows route add command failed");
1643 netcmd_semaphore_release();
1644 }
1645 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
1646 {
1647 status = add_route_ipapi(r, tt, ai);
1648 msg(D_ROUTE, "Route addition via IPAPI %s [adaptive]", status ? "succeeded" : "failed");
1649 if (!status)
1650 {
1651 msg(D_ROUTE, "Route addition fallback to route.exe");
1652 netcmd_semaphore_lock();
1653 status = openvpn_execve_check(&argv, es, 0, "ERROR: Windows route add command failed [adaptive]");
1654 netcmd_semaphore_release();
1655 }
1656 }
1657 else
1658 {
1659 ASSERT(0);
1660 }
1661 }
6fbf66fa
JY
1662
1663#elif defined (TARGET_SOLARIS)
1664
81d882d5 1665 /* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
6fbf66fa 1666
81d882d5
DS
1667 argv_printf(&argv, "%s add",
1668 ROUTE_PATH);
6fbf66fa 1669
81d882d5
DS
1670 argv_printf_cat(&argv, "%s -netmask %s %s",
1671 network,
1672 netmask,
1673 gateway);
6fbf66fa 1674
81d882d5
DS
1675 /* Solaris can only distinguish between "metric 0" == "on-link on the
1676 * interface where the IP address given is configured" and "metric > 0"
1677 * == "use gateway specified" (no finer-grained route metrics available)
1678 *
1679 * More recent versions of Solaris can also do "-interface", but that
1680 * would break backwards compatibility with older versions for no gain.
1681 */
1682 if (r->flags & RT_METRIC_DEFINED)
1683 {
1684 argv_printf_cat(&argv, "%d", r->metric);
1685 }
f0eac1a5 1686
81d882d5
DS
1687 argv_msg(D_ROUTE, &argv);
1688 status = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add command failed");
6fbf66fa
JY
1689
1690#elif defined(TARGET_FREEBSD)
1691
81d882d5
DS
1692 argv_printf(&argv, "%s add",
1693 ROUTE_PATH);
6fbf66fa
JY
1694
1695#if 0
81d882d5
DS
1696 if (r->flags & RT_METRIC_DEFINED)
1697 {
1698 argv_printf_cat(&argv, "-rtt %d", r->metric);
1699 }
6fbf66fa
JY
1700#endif
1701
81d882d5
DS
1702 argv_printf_cat(&argv, "-net %s %s %s",
1703 network,
1704 gateway,
1705 netmask);
6fbf66fa 1706
81d882d5 1707 /* FIXME -- add on-link support for FreeBSD */
7fb0e07e 1708
81d882d5
DS
1709 argv_msg(D_ROUTE, &argv);
1710 status = openvpn_execve_check(&argv, es, 0, "ERROR: FreeBSD route add command failed");
6fbf66fa 1711
1bda73a7
JY
1712#elif defined(TARGET_DRAGONFLY)
1713
81d882d5
DS
1714 argv_printf(&argv, "%s add",
1715 ROUTE_PATH);
1bda73a7
JY
1716
1717#if 0
81d882d5
DS
1718 if (r->flags & RT_METRIC_DEFINED)
1719 {
1720 argv_printf_cat(&argv, "-rtt %d", r->metric);
1721 }
1bda73a7
JY
1722#endif
1723
81d882d5
DS
1724 argv_printf_cat(&argv, "-net %s %s %s",
1725 network,
1726 gateway,
1727 netmask);
1bda73a7 1728
81d882d5 1729 /* FIXME -- add on-link support for Dragonfly */
7fb0e07e 1730
81d882d5
DS
1731 argv_msg(D_ROUTE, &argv);
1732 status = openvpn_execve_check(&argv, es, 0, "ERROR: DragonFly route add command failed");
1bda73a7 1733
6fbf66fa
JY
1734#elif defined(TARGET_DARWIN)
1735
81d882d5
DS
1736 argv_printf(&argv, "%s add",
1737 ROUTE_PATH);
6fbf66fa
JY
1738
1739#if 0
81d882d5
DS
1740 if (r->flags & RT_METRIC_DEFINED)
1741 {
1742 argv_printf_cat(&argv, "-rtt %d", r->metric);
1743 }
6fbf66fa
JY
1744#endif
1745
81d882d5 1746 if (is_on_link(is_local_route, flags, rgi))
7fb0e07e 1747 {
81d882d5
DS
1748 /* Mac OS X route syntax for ON_LINK:
1749 * route add -cloning -net 10.10.0.1 -netmask 255.255.255.255 -interface en0 */
1750 argv_printf_cat(&argv, "-cloning -net %s -netmask %s -interface %s",
1751 network,
1752 netmask,
1753 rgi->iface);
7fb0e07e 1754 }
81d882d5 1755 else
7fb0e07e 1756 {
81d882d5
DS
1757 argv_printf_cat(&argv, "-net %s %s %s",
1758 network,
1759 gateway,
1760 netmask);
7fb0e07e 1761 }
6fbf66fa 1762
81d882d5
DS
1763 argv_msg(D_ROUTE, &argv);
1764 status = openvpn_execve_check(&argv, es, 0, "ERROR: OS X route add command failed");
6fbf66fa
JY
1765
1766#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
1767
81d882d5
DS
1768 argv_printf(&argv, "%s add",
1769 ROUTE_PATH);
6fbf66fa
JY
1770
1771#if 0
81d882d5
DS
1772 if (r->flags & RT_METRIC_DEFINED)
1773 {
1774 argv_printf_cat(&argv, "-rtt %d", r->metric);
1775 }
6fbf66fa
JY
1776#endif
1777
81d882d5
DS
1778 argv_printf_cat(&argv, "-net %s %s -netmask %s",
1779 network,
1780 gateway,
1781 netmask);
6fbf66fa 1782
81d882d5 1783 /* FIXME -- add on-link support for OpenBSD/NetBSD */
7fb0e07e 1784
81d882d5
DS
1785 argv_msg(D_ROUTE, &argv);
1786 status = openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed");
6fbf66fa 1787
b4b92ae5
GD
1788#elif defined(TARGET_AIX)
1789
81d882d5
DS
1790 {
1791 int netbits = netmask_to_netbits2(r->netmask);
1792 argv_printf(&argv, "%s add -net %s/%d %s",
1793 ROUTE_PATH,
1794 network, netbits, gateway);
1795 argv_msg(D_ROUTE, &argv);
1796 status = openvpn_execve_check(&argv, es, 0, "ERROR: AIX route add command failed");
1797 }
b4b92ae5 1798
81d882d5
DS
1799#else /* if defined(TARGET_LINUX) */
1800 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");
1801#endif /* if defined(TARGET_LINUX) */
6fbf66fa 1802
81d882d5
DS
1803done:
1804 if (status)
1805 {
1806 r->flags |= RT_ADDED;
1807 }
1808 else
1809 {
1810 r->flags &= ~RT_ADDED;
1811 }
1812 argv_reset(&argv);
1813 gc_free(&gc);
6fbf66fa
JY
1814}
1815
b55e49bd 1816
a24dd2e3
HH
1817static void
1818route_ipv6_clear_host_bits( struct route_ipv6 *r6 )
b55e49bd 1819{
81d882d5
DS
1820 /* clear host bit parts of route
1821 * (needed if routes are specified improperly, or if we need to
1822 * explicitely setup/clear the "connected" network routes on some OSes)
1823 */
1824 int byte = 15;
1825 int bits_to_clear = 128 - r6->netbits;
b55e49bd 1826
81d882d5 1827 while (byte >= 0 && bits_to_clear > 0)
b55e49bd 1828 {
81d882d5
DS
1829 if (bits_to_clear >= 8)
1830 {
1831 r6->network.s6_addr[byte--] = 0; bits_to_clear -= 8;
1832 }
1833 else
1834 {
1835 r6->network.s6_addr[byte--] &= (0xff << bits_to_clear); bits_to_clear = 0;
1836 }
b55e49bd 1837 }
b55e49bd
GD
1838}
1839
512cda46 1840void
81d882d5 1841add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
512cda46 1842{
81d882d5
DS
1843 struct gc_arena gc;
1844 struct argv argv = argv_new();
512cda46 1845
81d882d5
DS
1846 const char *network;
1847 const char *gateway;
1848 bool status = false;
1849 const char *device = tt->actual_name;
512cda46 1850
81d882d5 1851 bool gateway_needed = false;
ff9c39b6 1852
81d882d5
DS
1853 if (!(r6->flags & RT_DEFINED) )
1854 {
1855 return;
1856 }
512cda46 1857
445b192a 1858#ifndef _WIN32
81d882d5 1859 if (r6->iface != NULL) /* vpn server special route */
3ddb5643 1860 {
81d882d5
DS
1861 device = r6->iface;
1862 if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) )
1863 {
1864 gateway_needed = true;
1865 }
3ddb5643
GD
1866 }
1867#endif
1868
81d882d5 1869 gc_init(&gc);
512cda46 1870
81d882d5 1871 route_ipv6_clear_host_bits(r6);
a24dd2e3 1872
81d882d5
DS
1873 network = print_in6_addr( r6->network, 0, &gc);
1874 gateway = print_in6_addr( r6->gateway, 0, &gc);
512cda46 1875
81d882d5
DS
1876#if defined(TARGET_DARWIN) \
1877 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
1878 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2ff366f7 1879
81d882d5
DS
1880 /* the BSD platforms cannot specify gateway and interface independently,
1881 * but for link-local destinations, we MUST specify the interface, so
1882 * we build a combined "$gateway%$interface" gateway string
1883 */
1884 if (r6->iface != NULL && gateway_needed
1885 && IN6_IS_ADDR_LINKLOCAL(&r6->gateway) ) /* fe80::...%intf */
2ff366f7 1886 {
81d882d5
DS
1887 int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
1888 char *tmp = gc_malloc( len, true, &gc );
1889 snprintf( tmp, len, "%s%%%s", gateway, r6->iface );
1890 gateway = tmp;
2ff366f7
GD
1891 }
1892#endif
1893
81d882d5
DS
1894 msg( M_INFO, "add_route_ipv6(%s/%d -> %s metric %d) dev %s",
1895 network, r6->netbits, gateway, r6->metric, device );
512cda46 1896
81d882d5
DS
1897 /*
1898 * Filter out routes which are essentially no-ops
1899 * (not currently done for IPv6)
1900 */
512cda46 1901
81d882d5
DS
1902 /* On "tun" interface, we never set a gateway if the operating system
1903 * can do "route to interface" - it does not add value, as the target
1904 * dev already fully qualifies the route destination on point-to-point
1905 * interfaces. OTOH, on "tap" interface, we must always set the
1906 * gateway unless the route is to be an on-link network
1907 */
1908 if (tt->type == DEV_TYPE_TAP
1909 && !( (r6->flags & RT_METRIC_DEFINED) && r6->metric == 0 ) )
ff9c39b6 1910 {
81d882d5 1911 gateway_needed = true;
ff9c39b6
GD
1912 }
1913
512cda46 1914#if defined(TARGET_LINUX)
51bd56f4 1915#ifdef ENABLE_IPROUTE
81d882d5
DS
1916 argv_printf(&argv, "%s -6 route add %s/%d dev %s",
1917 iproute_path,
1918 network,
1919 r6->netbits,
1920 device);
1921 if (gateway_needed)
1922 {
1923 argv_printf_cat(&argv, "via %s", gateway);
1924 }
1925 if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0)
1926 {
1927 argv_printf_cat(&argv, " metric %d", r6->metric);
1928 }
512cda46 1929
81d882d5
DS
1930#else /* ifdef ENABLE_IPROUTE */
1931 argv_printf(&argv, "%s -A inet6 add %s/%d dev %s",
1932 ROUTE_PATH,
1933 network,
1934 r6->netbits,
1935 device);
1936 if (gateway_needed)
1937 {
1938 argv_printf_cat(&argv, "gw %s", gateway);
1939 }
1940 if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0)
1941 {
1942 argv_printf_cat(&argv, " metric %d", r6->metric);
1943 }
51bd56f4 1944#endif /*ENABLE_IPROUTE*/
81d882d5
DS
1945 argv_msg(D_ROUTE, &argv);
1946 status = openvpn_execve_check(&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
512cda46 1947
a55b3cdb 1948#elif defined (TARGET_ANDROID)
81d882d5 1949 struct buffer out = alloc_buf_gc(64, &gc);
a55b3cdb 1950
81d882d5 1951 buf_printf(&out, "%s/%d %s", network, r6->netbits, device);
a55b3cdb 1952
81d882d5 1953 management_android_control(management, "ROUTE6", buf_bptr(&out));
a55b3cdb 1954
445b192a 1955#elif defined (_WIN32)
512cda46 1956
81d882d5
DS
1957 if (tt->options.msg_channel)
1958 {
1959 status = add_route_ipv6_service(r6, tt);
1960 }
1961 else
1962 {
1963 struct buffer out = alloc_buf_gc(64, &gc);
1964 if (r6->adapter_index) /* vpn server special route */
1965 {
1966 buf_printf(&out, "interface=%d", r6->adapter_index );
1967 gateway_needed = true;
1968 }
1969 else
1970 {
1971 buf_printf(&out, "interface=%d", tt->adapter_index );
1972 }
1973 device = buf_bptr(&out);
1974
1975 /* netsh interface ipv6 add route 2001:db8::/32 MyTunDevice */
1976 argv_printf(&argv, "%s%sc interface ipv6 add route %s/%d %s",
1977 get_win_sys_path(),
1978 NETSH_PATH_SUFFIX,
1979 network,
1980 r6->netbits,
1981 device);
1982
1983 /* next-hop depends on TUN or TAP mode:
1984 * - in TAP mode, we use the "real" next-hop
1985 * - in TUN mode we use a special-case link-local address that the tapdrvr
1986 * knows about and will answer ND (neighbor discovery) packets for
1987 */
1988 if (tt->type == DEV_TYPE_TUN && !gateway_needed)
1989 {
1990 argv_printf_cat( &argv, " %s", "fe80::8" );
1991 }
1992 else if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) )
1993 {
1994 argv_printf_cat( &argv, " %s", gateway );
1995 }
a9557fcb 1996
6607def8 1997#if 0
81d882d5
DS
1998 if (r6->flags & RT_METRIC_DEFINED)
1999 {
2000 argv_printf_cat(&argv, " METRIC %d", r->metric);
2001 }
6607def8
GD
2002#endif
2003
81d882d5
DS
2004 /* in some versions of Windows, routes are persistent across reboots by
2005 * default, unless "store=active" is set (pointed out by Tony Lim, thanks)
2006 */
2007 argv_printf_cat( &argv, " store=active" );
b55e49bd 2008
81d882d5 2009 argv_msg(D_ROUTE, &argv);
6607def8 2010
81d882d5
DS
2011 netcmd_semaphore_lock();
2012 status = openvpn_execve_check(&argv, es, 0, "ERROR: Windows route add ipv6 command failed");
2013 netcmd_semaphore_release();
a24dd2e3 2014 }
512cda46
GD
2015
2016#elif defined (TARGET_SOLARIS)
2017
81d882d5
DS
2018 /* example: route add -inet6 2001:db8::/32 somegateway 0 */
2019
2020 /* for some reason, routes to tun/tap do not work for me unless I set
2021 * "metric 0" - otherwise, the routes will be nicely installed, but
2022 * packets will just disappear somewhere. So we always use "0" now,
2023 * unless the route points to "gateway on other interface"...
2024 *
2025 * (Note: OpenSolaris can not specify host%interface gateways, so we just
2026 * use the GW addresses - it seems to still work for fe80:: addresses,
2027 * however this is done internally. NUD maybe?)
2028 */
2029 argv_printf(&argv, "%s add -inet6 %s/%d %s",
2030 ROUTE_PATH,
2031 network,
2032 r6->netbits,
2033 gateway );
2034
2035 /* on tun/tap, not "elsewhere"? -> metric 0 */
2036 if (!r6->iface)
2037 {
2038 argv_printf_cat(&argv, "0");
2039 }
2040
2041 argv_msg(D_ROUTE, &argv);
2042 status = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add -inet6 command failed");
512cda46
GD
2043
2044#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2045
81d882d5
DS
2046 argv_printf(&argv, "%s add -inet6 %s/%d",
2047 ROUTE_PATH,
2048 network,
2049 r6->netbits);
ff9c39b6 2050
81d882d5
DS
2051 if (gateway_needed)
2052 {
2053 argv_printf_cat(&argv, "%s", gateway);
2054 }
2055 else
2056 {
2057 argv_printf_cat(&argv, "-iface %s", device);
2058 }
512cda46 2059
81d882d5
DS
2060 argv_msg(D_ROUTE, &argv);
2061 status = openvpn_execve_check(&argv, es, 0, "ERROR: *BSD route add -inet6 command failed");
512cda46 2062
81d882d5 2063#elif defined(TARGET_DARWIN)
512cda46 2064
81d882d5
DS
2065 argv_printf(&argv, "%s add -inet6 %s -prefixlen %d",
2066 ROUTE_PATH,
2067 network, r6->netbits );
ff9c39b6 2068
81d882d5
DS
2069 if (gateway_needed)
2070 {
2071 argv_printf_cat(&argv, "%s", gateway);
2072 }
2073 else
2074 {
2075 argv_printf_cat(&argv, "-iface %s", device);
2076 }
512cda46 2077
81d882d5
DS
2078 argv_msg(D_ROUTE, &argv);
2079 status = openvpn_execve_check(&argv, es, 0, "ERROR: MacOS X route add -inet6 command failed");
512cda46 2080
ada9769e 2081#elif defined(TARGET_OPENBSD)
512cda46 2082
81d882d5
DS
2083 argv_printf(&argv, "%s add -inet6 %s -prefixlen %d %s",
2084 ROUTE_PATH,
2085 network, r6->netbits, gateway );
ada9769e 2086
81d882d5
DS
2087 argv_msg(D_ROUTE, &argv);
2088 status = openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD route add -inet6 command failed");
ada9769e
GD
2089
2090#elif defined(TARGET_NETBSD)
512cda46 2091
81d882d5
DS
2092 argv_printf(&argv, "%s add -inet6 %s/%d %s",
2093 ROUTE_PATH,
2094 network, r6->netbits, gateway );
512cda46 2095
81d882d5
DS
2096 argv_msg(D_ROUTE, &argv);
2097 status = openvpn_execve_check(&argv, es, 0, "ERROR: NetBSD route add -inet6 command failed");
512cda46 2098
b4b92ae5
GD
2099#elif defined(TARGET_AIX)
2100
81d882d5
DS
2101 argv_printf(&argv, "%s add -inet6 %s/%d %s",
2102 ROUTE_PATH,
2103 network, r6->netbits, gateway);
2104 argv_msg(D_ROUTE, &argv);
2105 status = openvpn_execve_check(&argv, es, 0, "ERROR: AIX route add command failed");
b4b92ae5 2106
81d882d5
DS
2107#else /* if defined(TARGET_LINUX) */
2108 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");
2109#endif /* if defined(TARGET_LINUX) */
512cda46 2110
81d882d5
DS
2111 if (status)
2112 {
2113 r6->flags |= RT_ADDED;
2114 }
2115 else
2116 {
2117 r6->flags &= ~RT_ADDED;
2118 }
2119 argv_reset(&argv);
2120 gc_free(&gc);
512cda46
GD
2121}
2122
6fbf66fa 2123static void
81d882d5
DS
2124delete_route(struct route_ipv4 *r,
2125 const struct tuntap *tt,
2126 unsigned int flags,
2127 const struct route_gateway_info *rgi,
2128 const struct env_set *es)
6fbf66fa 2129{
81d882d5
DS
2130 struct gc_arena gc;
2131 struct argv argv = argv_new();
2132 const char *network;
2133 const char *netmask;
2134 const char *gateway;
2135 int is_local_route;
2136
2137 if ((r->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED))
2138 {
2139 return;
2140 }
6fbf66fa 2141
81d882d5 2142 gc_init(&gc);
6fbf66fa 2143
81d882d5
DS
2144 network = print_in_addr_t(r->network, 0, &gc);
2145 netmask = print_in_addr_t(r->netmask, 0, &gc);
2146 gateway = print_in_addr_t(r->gateway, 0, &gc);
6fbf66fa 2147
81d882d5
DS
2148 is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
2149 if (is_local_route == LR_ERROR)
2150 {
2151 goto done;
2152 }
7fb0e07e 2153
6fbf66fa 2154#if defined(TARGET_LINUX)
51bd56f4 2155#ifdef ENABLE_IPROUTE
81d882d5
DS
2156 argv_printf(&argv, "%s route del %s/%d",
2157 iproute_path,
2158 network,
2159 netmask_to_netbits2(r->netmask));
6fbf66fa 2160#else
81d882d5
DS
2161 argv_printf(&argv, "%s del -net %s netmask %s",
2162 ROUTE_PATH,
2163 network,
2164 netmask);
51bd56f4 2165#endif /*ENABLE_IPROUTE*/
81d882d5
DS
2166 if (r->flags & RT_METRIC_DEFINED)
2167 {
2168 argv_printf_cat(&argv, "metric %d", r->metric);
2169 }
2170 argv_msg(D_ROUTE, &argv);
2171 openvpn_execve_check(&argv, es, 0, "ERROR: Linux route delete command failed");
6fbf66fa 2172
445b192a 2173#elif defined (_WIN32)
6fbf66fa 2174
81d882d5
DS
2175 argv_printf(&argv, "%s%sc DELETE %s MASK %s %s",
2176 get_win_sys_path(),
2177 WIN_ROUTE_PATH_SUFFIX,
2178 network,
2179 netmask,
2180 gateway);
2181
2182 argv_msg(D_ROUTE, &argv);
6fbf66fa 2183
81d882d5 2184 if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_SERVICE)
a24dd2e3 2185 {
81d882d5
DS
2186 const bool status = del_route_service(r, tt);
2187 msg(D_ROUTE, "Route deletion via service %s", status ? "succeeded" : "failed");
a24dd2e3 2188 }
81d882d5 2189 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
6fbf66fa 2190 {
81d882d5
DS
2191 const bool status = del_route_ipapi(r, tt);
2192 msg(D_ROUTE, "Route deletion via IPAPI %s", status ? "succeeded" : "failed");
6fbf66fa 2193 }
81d882d5 2194 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
6fbf66fa 2195 {
81d882d5
DS
2196 netcmd_semaphore_lock();
2197 openvpn_execve_check(&argv, es, 0, "ERROR: Windows route delete command failed");
2198 netcmd_semaphore_release();
6fbf66fa 2199 }
81d882d5 2200 else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
6215931b 2201 {
81d882d5
DS
2202 const bool status = del_route_ipapi(r, tt);
2203 msg(D_ROUTE, "Route deletion via IPAPI %s [adaptive]", status ? "succeeded" : "failed");
2204 if (!status)
2205 {
2206 msg(D_ROUTE, "Route deletion fallback to route.exe");
2207 netcmd_semaphore_lock();
2208 openvpn_execve_check(&argv, es, 0, "ERROR: Windows route delete command failed [adaptive]");
2209 netcmd_semaphore_release();
2210 }
6215931b 2211 }
81d882d5 2212 else
6fbf66fa 2213 {
81d882d5 2214 ASSERT(0);
6fbf66fa
JY
2215 }
2216
2217#elif defined (TARGET_SOLARIS)
2218
81d882d5
DS
2219 argv_printf(&argv, "%s delete %s -netmask %s %s",
2220 ROUTE_PATH,
2221 network,
2222 netmask,
2223 gateway);
6fbf66fa 2224
81d882d5
DS
2225 argv_msg(D_ROUTE, &argv);
2226 openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete command failed");
6fbf66fa
JY
2227
2228#elif defined(TARGET_FREEBSD)
2229
81d882d5
DS
2230 argv_printf(&argv, "%s delete -net %s %s %s",
2231 ROUTE_PATH,
2232 network,
2233 gateway,
2234 netmask);
6fbf66fa 2235
81d882d5
DS
2236 argv_msg(D_ROUTE, &argv);
2237 openvpn_execve_check(&argv, es, 0, "ERROR: FreeBSD route delete command failed");
6fbf66fa 2238
1bda73a7
JY
2239#elif defined(TARGET_DRAGONFLY)
2240
81d882d5
DS
2241 argv_printf(&argv, "%s delete -net %s %s %s",
2242 ROUTE_PATH,
2243 network,
2244 gateway,
2245 netmask);
1bda73a7 2246
81d882d5
DS
2247 argv_msg(D_ROUTE, &argv);
2248 openvpn_execve_check(&argv, es, 0, "ERROR: DragonFly route delete command failed");
1bda73a7 2249
6fbf66fa
JY
2250#elif defined(TARGET_DARWIN)
2251
81d882d5 2252 if (is_on_link(is_local_route, flags, rgi))
7fb0e07e 2253 {
81d882d5
DS
2254 argv_printf(&argv, "%s delete -cloning -net %s -netmask %s -interface %s",
2255 ROUTE_PATH,
2256 network,
2257 netmask,
2258 rgi->iface);
7fb0e07e 2259 }
81d882d5 2260 else
7fb0e07e 2261 {
81d882d5
DS
2262 argv_printf(&argv, "%s delete -net %s %s %s",
2263 ROUTE_PATH,
2264 network,
2265 gateway,
2266 netmask);
7fb0e07e 2267 }
6fbf66fa 2268
81d882d5
DS
2269 argv_msg(D_ROUTE, &argv);
2270 openvpn_execve_check(&argv, es, 0, "ERROR: OS X route delete command failed");
6fbf66fa
JY
2271
2272#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2273
81d882d5
DS
2274 argv_printf(&argv, "%s delete -net %s %s -netmask %s",
2275 ROUTE_PATH,
2276 network,
2277 gateway,
2278 netmask);
6fbf66fa 2279
81d882d5
DS
2280 argv_msg(D_ROUTE, &argv);
2281 openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
b4b92ae5 2282
a55b3cdb 2283#elif defined(TARGET_ANDROID)
81d882d5 2284 msg(M_NONFATAL, "Sorry, deleting routes on Android is not possible. The VpnService API allows routes to be set on connect only.");
b4b92ae5
GD
2285
2286#elif defined(TARGET_AIX)
2287
81d882d5
DS
2288 {
2289 int netbits = netmask_to_netbits2(r->netmask);
2290 argv_printf(&argv, "%s delete -net %s/%d %s",
2291 ROUTE_PATH,
2292 network, netbits, gateway);
2293 argv_msg(D_ROUTE, &argv);
2294 openvpn_execve_check(&argv, es, 0, "ERROR: AIX route delete command failed");
2295 }
b4b92ae5 2296
81d882d5
DS
2297#else /* if defined(TARGET_LINUX) */
2298 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");
2299#endif /* if defined(TARGET_LINUX) */
6fbf66fa 2300
81d882d5
DS
2301done:
2302 r->flags &= ~RT_ADDED;
2303 argv_reset(&argv);
2304 gc_free(&gc);
6fbf66fa
JY
2305}
2306
b55e49bd 2307void
81d882d5 2308delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
512cda46 2309{
81d882d5
DS
2310 struct gc_arena gc;
2311 struct argv argv = argv_new();
2312 const char *network;
2313 const char *gateway;
2314 const char *device = tt->actual_name;
2315 bool gateway_needed = false;
2316
2317 if ((r6->flags & (RT_DEFINED|RT_ADDED)) != (RT_DEFINED|RT_ADDED))
2318 {
2319 return;
2320 }
512cda46 2321
445b192a 2322#ifndef _WIN32
81d882d5 2323 if (r6->iface != NULL) /* vpn server special route */
3ddb5643 2324 {
81d882d5
DS
2325 device = r6->iface;
2326 gateway_needed = true;
3ddb5643
GD
2327 }
2328#endif
2329
81d882d5 2330 gc_init(&gc);
512cda46 2331
81d882d5
DS
2332 network = print_in6_addr( r6->network, 0, &gc);
2333 gateway = print_in6_addr( r6->gateway, 0, &gc);
512cda46 2334
81d882d5
DS
2335#if defined(TARGET_DARWIN) \
2336 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
2337 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
2ff366f7 2338
81d882d5
DS
2339 /* the BSD platforms cannot specify gateway and interface independently,
2340 * but for link-local destinations, we MUST specify the interface, so
2341 * we build a combined "$gateway%$interface" gateway string
2342 */
2343 if (r6->iface != NULL && gateway_needed
2344 && IN6_IS_ADDR_LINKLOCAL(&r6->gateway) ) /* fe80::...%intf */
2ff366f7 2345 {
81d882d5
DS
2346 int len = strlen(gateway) + 1 + strlen(r6->iface)+1;
2347 char *tmp = gc_malloc( len, true, &gc );
2348 snprintf( tmp, len, "%s%%%s", gateway, r6->iface );
2349 gateway = tmp;
2ff366f7
GD
2350 }
2351#endif
2352
81d882d5 2353 msg( M_INFO, "delete_route_ipv6(%s/%d)", network, r6->netbits );
512cda46 2354
81d882d5
DS
2355 /* if we used a gateway on "add route", we also need to specify it on
2356 * delete, otherwise some OSes will refuse to delete the route
2357 */
2358 if (tt->type == DEV_TYPE_TAP
2359 && !( (r6->flags & RT_METRIC_DEFINED) && r6->metric == 0 ) )
ff9c39b6 2360 {
81d882d5 2361 gateway_needed = true;
ff9c39b6
GD
2362 }
2363
2364
512cda46 2365#if defined(TARGET_LINUX)
51bd56f4 2366#ifdef ENABLE_IPROUTE
81d882d5
DS
2367 argv_printf(&argv, "%s -6 route del %s/%d dev %s",
2368 iproute_path,
2369 network,
2370 r6->netbits,
2371 device);
2372 if (gateway_needed)
2373 {
2374 argv_printf_cat(&argv, "via %s", gateway);
2375 }
2376#else /* ifdef ENABLE_IPROUTE */
2377 argv_printf(&argv, "%s -A inet6 del %s/%d dev %s",
2378 ROUTE_PATH,
2379 network,
2380 r6->netbits,
2381 device);
2382 if (gateway_needed)
2383 {
2384 argv_printf_cat(&argv, "gw %s", gateway);
2385 }
2386 if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0)
2387 {
2388 argv_printf_cat(&argv, " metric %d", r6->metric);
2389 }
51bd56f4 2390#endif /*ENABLE_IPROUTE*/
81d882d5
DS
2391 argv_msg(D_ROUTE, &argv);
2392 openvpn_execve_check(&argv, es, 0, "ERROR: Linux route -6/-A inet6 del command failed");
512cda46 2393
445b192a 2394#elif defined (_WIN32)
512cda46 2395
81d882d5
DS
2396 if (tt->options.msg_channel)
2397 {
2398 del_route_ipv6_service(r6, tt);
2399 }
2400 else
2401 {
2402 struct buffer out = alloc_buf_gc(64, &gc);
2403 if (r6->adapter_index) /* vpn server special route */
2404 {
2405 buf_printf(&out, "interface=%d", r6->adapter_index );
2406 gateway_needed = true;
2407 }
2408 else
2409 {
2410 buf_printf(&out, "interface=%d", tt->adapter_index );
2411 }
2412 device = buf_bptr(&out);
2413
2414 /* netsh interface ipv6 delete route 2001:db8::/32 MyTunDevice */
2415 argv_printf(&argv, "%s%sc interface ipv6 delete route %s/%d %s",
2416 get_win_sys_path(),
2417 NETSH_PATH_SUFFIX,
2418 network,
2419 r6->netbits,
2420 device);
2421
2422 /* next-hop depends on TUN or TAP mode:
2423 * - in TAP mode, we use the "real" next-hop
2424 * - in TUN mode we use a special-case link-local address that the tapdrvr
2425 * knows about and will answer ND (neighbor discovery) packets for
2426 * (and "route deletion without specifying next-hop" does not work...)
2427 */
2428 if (tt->type == DEV_TYPE_TUN && !gateway_needed)
2429 {
2430 argv_printf_cat( &argv, " %s", "fe80::8" );
2431 }
2432 else if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) )
2433 {
2434 argv_printf_cat( &argv, " %s", gateway );
2435 }
94d50a17 2436
6607def8 2437#if 0
81d882d5
DS
2438 if (r6->flags & RT_METRIC_DEFINED)
2439 {
2440 argv_printf_cat(&argv, "METRIC %d", r->metric);
2441 }
6607def8
GD
2442#endif
2443
81d882d5
DS
2444 /* Windows XP to 7 "just delete" routes, wherever they came from, but
2445 * in Windows 8(.1?), if you create them with "store=active", this is
2446 * how you should delete them as well (pointed out by Cedric Tabary)
2447 */
2448 argv_printf_cat( &argv, " store=active" );
4b4fac91 2449
81d882d5 2450 argv_msg(D_ROUTE, &argv);
6607def8 2451
81d882d5
DS
2452 netcmd_semaphore_lock();
2453 openvpn_execve_check(&argv, es, 0, "ERROR: Windows route delete ipv6 command failed");
2454 netcmd_semaphore_release();
a24dd2e3 2455 }
512cda46
GD
2456
2457#elif defined (TARGET_SOLARIS)
2458
81d882d5 2459 /* example: route delete -inet6 2001:db8::/32 somegateway */
512cda46 2460
81d882d5
DS
2461 argv_printf(&argv, "%s delete -inet6 %s/%d %s",
2462 ROUTE_PATH,
2463 network,
2464 r6->netbits,
2465 gateway );
512cda46 2466
81d882d5
DS
2467 argv_msg(D_ROUTE, &argv);
2468 openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete -inet6 command failed");
512cda46
GD
2469
2470#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
2471
81d882d5
DS
2472 argv_printf(&argv, "%s delete -inet6 %s/%d",
2473 ROUTE_PATH,
2474 network,
2475 r6->netbits );
ff9c39b6 2476
81d882d5
DS
2477 if (gateway_needed)
2478 {
2479 argv_printf_cat(&argv, "%s", gateway);
2480 }
2481 else
2482 {
2483 argv_printf_cat(&argv, "-iface %s", device);
2484 }
512cda46 2485
81d882d5
DS
2486 argv_msg(D_ROUTE, &argv);
2487 openvpn_execve_check(&argv, es, 0, "ERROR: *BSD route delete -inet6 command failed");
512cda46 2488
81d882d5 2489#elif defined(TARGET_DARWIN)
512cda46 2490
81d882d5
DS
2491 argv_printf(&argv, "%s delete -inet6 %s -prefixlen %d",
2492 ROUTE_PATH,
2493 network, r6->netbits );
ff9c39b6 2494
81d882d5
DS
2495 if (gateway_needed)
2496 {
2497 argv_printf_cat(&argv, "%s", gateway);
2498 }
2499 else
2500 {
2501 argv_printf_cat(&argv, "-iface %s", device);
2502 }
512cda46 2503
81d882d5
DS
2504 argv_msg(D_ROUTE, &argv);
2505 openvpn_execve_check(&argv, es, 0, "ERROR: MacOS X route delete -inet6 command failed");
512cda46 2506
ada9769e 2507#elif defined(TARGET_OPENBSD)
512cda46 2508
81d882d5
DS
2509 argv_printf(&argv, "%s delete -inet6 %s -prefixlen %d %s",
2510 ROUTE_PATH,
2511 network, r6->netbits, gateway );
ada9769e 2512
81d882d5
DS
2513 argv_msg(D_ROUTE, &argv);
2514 openvpn_execve_check(&argv, es, 0, "ERROR: OpenBSD route delete -inet6 command failed");
ada9769e
GD
2515
2516#elif defined(TARGET_NETBSD)
512cda46 2517
81d882d5
DS
2518 argv_printf(&argv, "%s delete -inet6 %s/%d %s",
2519 ROUTE_PATH,
2520 network, r6->netbits, gateway );
512cda46 2521
81d882d5
DS
2522 argv_msg(D_ROUTE, &argv);
2523 openvpn_execve_check(&argv, es, 0, "ERROR: NetBSD route delete -inet6 command failed");
512cda46 2524
b4b92ae5
GD
2525#elif defined(TARGET_AIX)
2526
81d882d5
DS
2527 argv_printf(&argv, "%s delete -inet6 %s/%d %s",
2528 ROUTE_PATH,
2529 network, r6->netbits, gateway);
2530 argv_msg(D_ROUTE, &argv);
2531 openvpn_execve_check(&argv, es, 0, "ERROR: AIX route add command failed");
b4b92ae5 2532
81d882d5
DS
2533#else /* if defined(TARGET_LINUX) */
2534 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");
2535#endif /* if defined(TARGET_LINUX) */
512cda46 2536
81d882d5
DS
2537 argv_reset(&argv);
2538 gc_free(&gc);
512cda46
GD
2539}
2540
6fbf66fa
JY
2541/*
2542 * The --redirect-gateway option requires OS-specific code below
2543 * to get the current default gateway.
2544 */
2545
445b192a 2546#if defined(_WIN32)
6fbf66fa
JY
2547
2548static const MIB_IPFORWARDTABLE *
81d882d5 2549get_windows_routing_table(struct gc_arena *gc)
6fbf66fa 2550{
81d882d5
DS
2551 ULONG size = 0;
2552 PMIB_IPFORWARDTABLE rt = NULL;
2553 DWORD status;
6fbf66fa 2554
81d882d5
DS
2555 status = GetIpForwardTable(NULL, &size, TRUE);
2556 if (status == ERROR_INSUFFICIENT_BUFFER)
6fbf66fa 2557 {
81d882d5
DS
2558 rt = (PMIB_IPFORWARDTABLE) gc_malloc(size, false, gc);
2559 status = GetIpForwardTable(rt, &size, TRUE);
2560 if (status != NO_ERROR)
2561 {
2562 msg(D_ROUTE, "NOTE: GetIpForwardTable returned error: %s (code=%u)",
2563 strerror_win32(status, gc),
2564 (unsigned int)status);
2565 rt = NULL;
2566 }
6fbf66fa 2567 }
81d882d5 2568 return rt;
6fbf66fa
JY
2569}
2570
2571static int
81d882d5
DS
2572test_route(const IP_ADAPTER_INFO *adapters,
2573 const in_addr_t gateway,
2574 DWORD *index)
6fbf66fa 2575{
81d882d5
DS
2576 int count = 0;
2577 DWORD i = adapter_index_of_ip(adapters, gateway, &count, NULL);
2578 if (index)
2579 {
2580 *index = i;
2581 }
2582 return count;
6fbf66fa
JY
2583}
2584
2585static void
81d882d5
DS
2586test_route_helper(bool *ret,
2587 int *count,
2588 int *good,
2589 int *ambig,
2590 const IP_ADAPTER_INFO *adapters,
2591 const in_addr_t gateway)
6fbf66fa 2592{
81d882d5 2593 int c;
6fbf66fa 2594
81d882d5
DS
2595 ++*count;
2596 c = test_route(adapters, gateway, NULL);
2597 if (c == 0)
2598 {
2599 *ret = false;
2600 }
2601 else
2602 {
2603 ++*good;
2604 }
2605 if (c > 1)
2606 {
2607 ++*ambig;
2608 }
6fbf66fa
JY
2609}
2610
2611/*
2612 * If we tried to add routes now, would we succeed?
2613 */
2614bool
81d882d5 2615test_routes(const struct route_list *rl, const struct tuntap *tt)
6fbf66fa 2616{
81d882d5
DS
2617 struct gc_arena gc = gc_new();
2618 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2619 bool ret = false;
2620 int count = 0;
2621 int good = 0;
2622 int ambig = 0;
2623 int len = -1;
2624 bool adapter_up = false;
2625
2626 if (is_adapter_up(tt, adapters))
6fbf66fa 2627 {
81d882d5
DS
2628 ret = true;
2629 adapter_up = true;
6fbf66fa 2630
81d882d5
DS
2631 if (rl)
2632 {
2633 struct route_ipv4 *r;
2634 for (r = rl->routes, len = 0; r; r = r->next, ++len)
4cd4899e 2635 {
81d882d5 2636 test_route_helper(&ret, &count, &good, &ambig, adapters, r->gateway);
4cd4899e 2637 }
81d882d5
DS
2638
2639 if ((rl->flags & RG_ENABLE) && (rl->spec.flags & RTSA_REMOTE_ENDPOINT))
2640 {
2641 test_route_helper(&ret, &count, &good, &ambig, adapters, rl->spec.remote_endpoint);
2642 }
2643 }
6fbf66fa
JY
2644 }
2645
81d882d5
DS
2646 msg(D_ROUTE, "TEST ROUTES: %d/%d succeeded len=%d ret=%d a=%d u/d=%s",
2647 good,
2648 count,
2649 len,
2650 (int)ret,
2651 ambig,
2652 adapter_up ? "up" : "down");
6fbf66fa 2653
81d882d5
DS
2654 gc_free(&gc);
2655 return ret;
6fbf66fa
JY
2656}
2657
3c7f2f55 2658static const MIB_IPFORWARDROW *
81d882d5 2659get_default_gateway_row(const MIB_IPFORWARDTABLE *routes)
6fbf66fa 2660{
81d882d5
DS
2661 struct gc_arena gc = gc_new();
2662 DWORD lowest_metric = MAXDWORD;
2663 const MIB_IPFORWARDROW *ret = NULL;
2664 int i;
2665 int best = -1;
6fbf66fa 2666
81d882d5 2667 if (routes)
6fbf66fa 2668 {
81d882d5
DS
2669 for (i = 0; i < routes->dwNumEntries; ++i)
2670 {
2671 const MIB_IPFORWARDROW *row = &routes->table[i];
2672 const in_addr_t net = ntohl(row->dwForwardDest);
2673 const in_addr_t mask = ntohl(row->dwForwardMask);
2674 const DWORD index = row->dwForwardIfIndex;
2675 const DWORD metric = row->dwForwardMetric1;
2676
2677 dmsg(D_ROUTE_DEBUG, "GDGR: route[%d] %s/%s i=%d m=%d",
2678 i,
2679 print_in_addr_t((in_addr_t) net, 0, &gc),
2680 print_in_addr_t((in_addr_t) mask, 0, &gc),
2681 (int)index,
2682 (int)metric);
2683
2684 if (!net && !mask && metric < lowest_metric)
2685 {
2686 ret = row;
2687 lowest_metric = metric;
2688 best = i;
2689 }
2690 }
6fbf66fa 2691 }
348fb443 2692
81d882d5 2693 dmsg(D_ROUTE_DEBUG, "GDGR: best=%d lm=%u", best, (unsigned int)lowest_metric);
348fb443 2694
81d882d5
DS
2695 gc_free(&gc);
2696 return ret;
3c7f2f55
JY
2697}
2698
7fb0e07e 2699void
81d882d5 2700get_default_gateway(struct route_gateway_info *rgi)
3c7f2f55 2701{
81d882d5 2702 struct gc_arena gc = gc_new();
3c7f2f55 2703
81d882d5
DS
2704 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2705 const MIB_IPFORWARDTABLE *routes = get_windows_routing_table(&gc);
2706 const MIB_IPFORWARDROW *row = get_default_gateway_row(routes);
2707 DWORD a_index;
2708 const IP_ADAPTER_INFO *ai;
7fb0e07e 2709
81d882d5 2710 CLEAR(*rgi);
3c7f2f55 2711
81d882d5 2712 if (row)
3c7f2f55 2713 {
81d882d5
DS
2714 rgi->gateway.addr = ntohl(row->dwForwardNextHop);
2715 if (rgi->gateway.addr)
2716 {
2717 rgi->flags |= RGI_ADDR_DEFINED;
2718 a_index = adapter_index_of_ip(adapters, rgi->gateway.addr, NULL, &rgi->gateway.netmask);
2719 if (a_index != TUN_ADAPTER_INDEX_INVALID)
2720 {
2721 rgi->adapter_index = a_index;
2722 rgi->flags |= (RGI_IFACE_DEFINED|RGI_NETMASK_DEFINED);
2723 ai = get_adapter(adapters, a_index);
2724 if (ai)
2725 {
2726 memcpy(rgi->hwaddr, ai->Address, 6);
2727 rgi->flags |= RGI_HWADDR_DEFINED;
2728 }
2729 }
2730 }
3c7f2f55
JY
2731 }
2732
81d882d5 2733 gc_free(&gc);
6fbf66fa
JY
2734}
2735
2736static DWORD
81d882d5 2737windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt)
6fbf66fa 2738{
81d882d5
DS
2739 struct gc_arena gc = gc_new();
2740 DWORD ret = TUN_ADAPTER_INDEX_INVALID;
2741 int count = 0;
2742 const IP_ADAPTER_INFO *adapters = get_adapter_info_list(&gc);
2743 const IP_ADAPTER_INFO *tun_adapter = get_tun_adapter(tt, adapters);
2744 bool on_tun = false;
2745
2746 /* first test on tun interface */
2747 if (is_ip_in_adapter_subnet(tun_adapter, r->gateway, NULL))
6fbf66fa 2748 {
81d882d5
DS
2749 ret = tun_adapter->Index;
2750 count = 1;
2751 on_tun = true;
6fbf66fa 2752 }
81d882d5 2753 else /* test on other interfaces */
6fbf66fa 2754 {
81d882d5 2755 count = test_route(adapters, r->gateway, &ret);
6fbf66fa
JY
2756 }
2757
81d882d5 2758 if (count == 0)
6fbf66fa 2759 {
81d882d5
DS
2760 msg(M_WARN, "Warning: route gateway is not reachable on any active network adapters: %s",
2761 print_in_addr_t(r->gateway, 0, &gc));
2762 ret = TUN_ADAPTER_INDEX_INVALID;
6fbf66fa 2763 }
81d882d5 2764 else if (count > 1)
6fbf66fa 2765 {
81d882d5
DS
2766 msg(M_WARN, "Warning: route gateway is ambiguous: %s (%d matches)",
2767 print_in_addr_t(r->gateway, 0, &gc),
2768 count);
2769 ret = TUN_ADAPTER_INDEX_INVALID;
6fbf66fa
JY
2770 }
2771
81d882d5
DS
2772 dmsg(D_ROUTE_DEBUG, "DEBUG: route find if: on_tun=%d count=%d index=%d",
2773 on_tun,
2774 count,
2775 (int)ret);
6fbf66fa 2776
81d882d5
DS
2777 gc_free(&gc);
2778 return ret;
6fbf66fa
JY
2779}
2780
5fcd4933
GD
2781/* IPv6 implementation using GetBestRoute2()
2782 * (TBD: dynamic linking so the binary can still run on XP?)
2783 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa365922(v=vs.85).aspx
2784 * https://msdn.microsoft.com/en-us/library/windows/desktop/aa814411(v=vs.85).aspx
d8a8656f
GD
2785 */
2786void
2787get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
81d882d5 2788 const struct in6_addr *dest)
d8a8656f 2789{
81d882d5 2790 struct gc_arena gc = gc_new();
5fcd4933
GD
2791 MIB_IPFORWARD_ROW2 BestRoute;
2792 SOCKADDR_INET DestinationAddress, BestSourceAddress;
2793 DWORD BestIfIndex;
2794 DWORD status;
2795 NET_LUID InterfaceLuid;
2796
d8a8656f 2797 CLEAR(*rgi6);
81d882d5 2798 CLEAR(InterfaceLuid); /* cleared = not used for lookup */
5fcd4933
GD
2799 CLEAR(DestinationAddress);
2800
2801 DestinationAddress.si_family = AF_INET6;
81d882d5 2802 if (dest)
5fcd4933
GD
2803 {
2804 DestinationAddress.Ipv6.sin6_addr = *dest;
2805 }
2806
2807 status = GetBestInterfaceEx( &DestinationAddress, &BestIfIndex );
2808
2809 if (status != NO_ERROR)
2810 {
81d882d5
DS
2811 msg(D_ROUTE, "NOTE: GetBestInterfaceEx returned error: %s (code=%u)",
2812 strerror_win32(status, &gc),
2813 (unsigned int)status);
2814 goto done;
5fcd4933
GD
2815 }
2816
2817 msg( D_ROUTE, "GetBestInterfaceEx() returned if=%d", (int) BestIfIndex );
2818
2819 status = GetBestRoute2( &InterfaceLuid, BestIfIndex, NULL,
2820 &DestinationAddress, 0,
2821 &BestRoute, &BestSourceAddress );
2822
2823 if (status != NO_ERROR)
2824 {
81d882d5
DS
2825 msg(D_ROUTE, "NOTE: GetIpForwardEntry2 returned error: %s (code=%u)",
2826 strerror_win32(status, &gc),
2827 (unsigned int)status);
2828 goto done;
5fcd4933
GD
2829 }
2830
2831 msg( D_ROUTE, "GDG6: II=%d DP=%s/%d NH=%s",
81d882d5
DS
2832 BestRoute.InterfaceIndex,
2833 print_in6_addr( BestRoute.DestinationPrefix.Prefix.Ipv6.sin6_addr, 0, &gc),
2834 BestRoute.DestinationPrefix.PrefixLength,
2835 print_in6_addr( BestRoute.NextHop.Ipv6.sin6_addr, 0, &gc) );
5fcd4933 2836 msg( D_ROUTE, "GDG6: Metric=%d, Loopback=%d, AA=%d, I=%d",
81d882d5
DS
2837 (int) BestRoute.Metric,
2838 (int) BestRoute.Loopback,
2839 (int) BestRoute.AutoconfigureAddress,
2840 (int) BestRoute.Immortal );
5fcd4933
GD
2841
2842 rgi6->gateway.addr_ipv6 = BestRoute.NextHop.Ipv6.sin6_addr;
2843 rgi6->adapter_index = BestRoute.InterfaceIndex;
2844 rgi6->flags |= RGI_ADDR_DEFINED | RGI_IFACE_DEFINED;
2845
2846 /* on-link is signalled by receiving an empty (::) NextHop */
81d882d5
DS
2847 if (IN6_IS_ADDR_UNSPECIFIED(&BestRoute.NextHop.Ipv6.sin6_addr) )
2848 {
2849 rgi6->flags |= RGI_ON_LINK;
2850 }
5fcd4933 2851
81d882d5
DS
2852done:
2853 gc_free(&gc);
d8a8656f
GD
2854}
2855
6fbf66fa 2856bool
81d882d5
DS
2857add_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt, DWORD adapter_index)
2858{
2859 struct gc_arena gc = gc_new();
2860 bool ret = false;
2861 DWORD status;
2862 const DWORD if_index = (adapter_index == TUN_ADAPTER_INDEX_INVALID) ? windows_route_find_if_index(r, tt) : adapter_index;
2863
2864 if (if_index != TUN_ADAPTER_INDEX_INVALID)
2865 {
2866 MIB_IPFORWARDROW fr;
2867 CLEAR(fr);
2868 fr.dwForwardDest = htonl(r->network);
2869 fr.dwForwardMask = htonl(r->netmask);
2870 fr.dwForwardPolicy = 0;
2871 fr.dwForwardNextHop = htonl(r->gateway);
2872 fr.dwForwardIfIndex = if_index;
2873 fr.dwForwardType = 4; /* the next hop is not the final dest */
2874 fr.dwForwardProto = 3; /* PROTO_IP_NETMGMT */
2875 fr.dwForwardAge = 0;
2876 fr.dwForwardNextHopAS = 0;
2877 fr.dwForwardMetric1 = (r->flags & RT_METRIC_DEFINED) ? r->metric : 1;
2878 fr.dwForwardMetric2 = METRIC_NOT_USED;
2879 fr.dwForwardMetric3 = METRIC_NOT_USED;
2880 fr.dwForwardMetric4 = METRIC_NOT_USED;
2881 fr.dwForwardMetric5 = METRIC_NOT_USED;
2882
2883 if ((r->network & r->netmask) != r->network)
2884 {
2885 msg(M_WARN, "Warning: address %s is not a network address in relation to netmask %s",
2886 print_in_addr_t(r->network, 0, &gc),
2887 print_in_addr_t(r->netmask, 0, &gc));
2888 }
2889
2890 status = CreateIpForwardEntry(&fr);
2891
2892 if (status == NO_ERROR)
2893 {
2894 ret = true;
2895 }
2896 else
2897 {
2898 /* failed, try increasing the metric to work around Vista issue */
2899 const unsigned int forward_metric_limit = 2048; /* iteratively retry higher metrics up to this limit */
2900
2901 for (; fr.dwForwardMetric1 <= forward_metric_limit; ++fr.dwForwardMetric1)
2902 {
2903 /* try a different forward type=3 ("the next hop is the final dest") in addition to 4.
2904 * --redirect-gateway over RRAS seems to need this. */
2905 for (fr.dwForwardType = 4; fr.dwForwardType >= 3; --fr.dwForwardType)
2906 {
2907 status = CreateIpForwardEntry(&fr);
2908 if (status == NO_ERROR)
2909 {
2910 msg(D_ROUTE, "ROUTE: CreateIpForwardEntry succeeded with dwForwardMetric1=%u and dwForwardType=%u",
2911 (unsigned int)fr.dwForwardMetric1,
2912 (unsigned int)fr.dwForwardType);
2913 ret = true;
2914 goto doublebreak;
2915 }
2916 else if (status != ERROR_BAD_ARGUMENTS)
2917 {
2918 goto doublebreak;
2919 }
2920 }
2921 }
2922
2923doublebreak:
2924 if (status != NO_ERROR)
2925 {
2926 msg(M_WARN, "ROUTE: route addition failed using CreateIpForwardEntry: %s [status=%u if_index=%u]",
2927 strerror_win32(status, &gc),
2928 (unsigned int)status,
2929 (unsigned int)if_index);
2930 }
2931 }
2932 }
2933
2934 gc_free(&gc);
2935 return ret;
6fbf66fa
JY
2936}
2937
2938bool
81d882d5 2939del_route_ipapi(const struct route_ipv4 *r, const struct tuntap *tt)
6fbf66fa 2940{
81d882d5
DS
2941 struct gc_arena gc = gc_new();
2942 bool ret = false;
2943 DWORD status;
2944 const DWORD if_index = windows_route_find_if_index(r, tt);
6fbf66fa 2945
81d882d5 2946 if (if_index != TUN_ADAPTER_INDEX_INVALID)
6fbf66fa 2947 {
81d882d5
DS
2948 MIB_IPFORWARDROW fr;
2949 CLEAR(fr);
6fbf66fa 2950
81d882d5
DS
2951 fr.dwForwardDest = htonl(r->network);
2952 fr.dwForwardMask = htonl(r->netmask);
2953 fr.dwForwardPolicy = 0;
2954 fr.dwForwardNextHop = htonl(r->gateway);
2955 fr.dwForwardIfIndex = if_index;
6fbf66fa 2956
81d882d5 2957 status = DeleteIpForwardEntry(&fr);
6fbf66fa 2958
81d882d5
DS
2959 if (status == NO_ERROR)
2960 {
2961 ret = true;
2962 }
2963 else
2964 {
2965 msg(M_WARN, "ROUTE: route deletion failed using DeleteIpForwardEntry: %s",
2966 strerror_win32(status, &gc));
2967 }
6fbf66fa
JY
2968 }
2969
81d882d5
DS
2970 gc_free(&gc);
2971 return ret;
6fbf66fa
JY
2972}
2973
a24dd2e3 2974static bool
81d882d5 2975do_route_service(const bool add, const route_message_t *rt, const size_t size, HANDLE pipe)
a24dd2e3 2976{
81d882d5
DS
2977 DWORD len;
2978 bool ret = false;
2979 ack_message_t ack;
2980 struct gc_arena gc = gc_new();
a24dd2e3 2981
81d882d5
DS
2982 if (!WriteFile(pipe, rt, size, &len, NULL)
2983 || !ReadFile(pipe, &ack, sizeof(ack), &len, NULL))
a24dd2e3 2984 {
81d882d5
DS
2985 msg(M_WARN, "ROUTE: could not talk to service: %s [%lu]",
2986 strerror_win32(GetLastError(), &gc), GetLastError());
2987 goto out;
a24dd2e3
HH
2988 }
2989
81d882d5 2990 if (ack.error_number != NO_ERROR)
a24dd2e3 2991 {
81d882d5
DS
2992 msg(M_WARN, "ROUTE: route %s failed using service: %s [status=%u if_index=%lu]",
2993 (add ? "addition" : "deletion"), strerror_win32(ack.error_number, &gc),
2994 ack.error_number, rt->iface.index);
2995 goto out;
a24dd2e3
HH
2996 }
2997
81d882d5 2998 ret = true;
a24dd2e3
HH
2999
3000out:
81d882d5
DS
3001 gc_free(&gc);
3002 return ret;
a24dd2e3
HH
3003}
3004
3005static bool
81d882d5 3006do_route_ipv4_service(const bool add, const struct route_ipv4 *r, const struct tuntap *tt)
a24dd2e3 3007{
81d882d5
DS
3008 DWORD if_index = windows_route_find_if_index(r, tt);
3009 if (if_index == ~0)
3010 {
3011 return false;
3012 }
a24dd2e3 3013
81d882d5
DS
3014 route_message_t msg = {
3015 .header = {
3016 (add ? msg_add_route : msg_del_route),
3017 sizeof(route_message_t),
3018 0
3019 },
3020 .family = AF_INET,
3021 .prefix.ipv4.s_addr = htonl(r->network),
3022 .gateway.ipv4.s_addr = htonl(r->gateway),
3023 .iface = { .index = if_index, .name = "" },
3024 .metric = (r->flags & RT_METRIC_DEFINED ? r->metric : -1)
3025 };
3026
3027 netmask_to_netbits(r->network, r->netmask, &msg.prefix_len);
3028 if (msg.prefix_len == -1)
3029 {
3030 msg.prefix_len = 32;
3031 }
a24dd2e3 3032
81d882d5 3033 return do_route_service(add, &msg, sizeof(msg), tt->options.msg_channel);
a24dd2e3
HH
3034}
3035
3036static bool
81d882d5 3037do_route_ipv6_service(const bool add, const struct route_ipv6 *r, const struct tuntap *tt)
a24dd2e3 3038{
81d882d5
DS
3039 bool status;
3040 route_message_t msg = {
3041 .header = {
3042 (add ? msg_add_route : msg_del_route),
3043 sizeof(route_message_t),
3044 0
3045 },
3046 .family = AF_INET6,
3047 .prefix.ipv6 = r->network,
3048 .prefix_len = r->netbits,
3049 .gateway.ipv6 = r->gateway,
3050 .iface = { .index = tt->adapter_index, .name = "" },
3051 .metric = ( (r->flags & RT_METRIC_DEFINED) ? r->metric : -1)
3052 };
3053
3054 if (r->adapter_index) /* vpn server special route */
3055 {
3056 msg.iface.index = r->adapter_index;
3057 }
a24dd2e3 3058
81d882d5
DS
3059 /* In TUN mode we use a special link-local address as the next hop.
3060 * The tapdrvr knows about it and will answer neighbor discovery packets.
3061 */
3062 if (tt->type == DEV_TYPE_TUN)
3063 {
3064 inet_pton(AF_INET6, "fe80::8", &msg.gateway.ipv6);
3065 }
a24dd2e3 3066
81d882d5 3067 if (msg.iface.index == TUN_ADAPTER_INDEX_INVALID)
a24dd2e3 3068 {
81d882d5
DS
3069 strncpy(msg.iface.name, tt->actual_name, sizeof(msg.iface.name));
3070 msg.iface.name[sizeof(msg.iface.name) - 1] = '\0';
a24dd2e3
HH
3071 }
3072
81d882d5
DS
3073 status = do_route_service(add, &msg, sizeof(msg), tt->options.msg_channel);
3074 msg(D_ROUTE, "IPv6 route %s via service %s",
3075 add ? "addition" : "deletion",
3076 status ? "succeeded" : "failed");
3077 return status;
a24dd2e3
HH
3078}
3079
3080static bool
81d882d5 3081add_route_service(const struct route_ipv4 *r, const struct tuntap *tt)
a24dd2e3 3082{
81d882d5 3083 return do_route_ipv4_service(true, r, tt);
a24dd2e3
HH
3084}
3085
3086static bool
81d882d5 3087del_route_service(const struct route_ipv4 *r, const struct tuntap *tt)
a24dd2e3 3088{
81d882d5 3089 return do_route_ipv4_service(false, r, tt);
a24dd2e3
HH
3090}
3091
3092static bool
81d882d5 3093add_route_ipv6_service(const struct route_ipv6 *r, const struct tuntap *tt)
a24dd2e3 3094{
81d882d5 3095 return do_route_ipv6_service(true, r, tt);
a24dd2e3
HH
3096}
3097
3098static bool
81d882d5 3099del_route_ipv6_service(const struct route_ipv6 *r, const struct tuntap *tt)
a24dd2e3 3100{
81d882d5 3101 return do_route_ipv6_service(false, r, tt);
a24dd2e3
HH
3102}
3103
6fbf66fa 3104static const char *
81d882d5
DS
3105format_route_entry(const MIB_IPFORWARDROW *r, struct gc_arena *gc)
3106{
3107 struct buffer out = alloc_buf_gc(256, gc);
3108 buf_printf(&out, "%s %s %s p=%d i=%d t=%d pr=%d a=%d h=%d m=%d/%d/%d/%d/%d",
3109 print_in_addr_t(r->dwForwardDest, IA_NET_ORDER, gc),
3110 print_in_addr_t(r->dwForwardMask, IA_NET_ORDER, gc),
3111 print_in_addr_t(r->dwForwardNextHop, IA_NET_ORDER, gc),
3112 (int)r->dwForwardPolicy,
3113 (int)r->dwForwardIfIndex,
3114 (int)r->dwForwardType,
3115 (int)r->dwForwardProto,
3116 (int)r->dwForwardAge,
3117 (int)r->dwForwardNextHopAS,
3118 (int)r->dwForwardMetric1,
3119 (int)r->dwForwardMetric2,
3120 (int)r->dwForwardMetric3,
3121 (int)r->dwForwardMetric4,
3122 (int)r->dwForwardMetric5);
3123 return BSTR(&out);
6fbf66fa
JY
3124}
3125
3126/*
3127 * Show current routing table
3128 */
3129void
81d882d5 3130show_routes(int msglev)
6fbf66fa 3131{
81d882d5
DS
3132 struct gc_arena gc = gc_new();
3133 int i;
6fbf66fa 3134
81d882d5 3135 const MIB_IPFORWARDTABLE *rt = get_windows_routing_table(&gc);
6fbf66fa 3136
81d882d5
DS
3137 msg(msglev, "SYSTEM ROUTING TABLE");
3138 if (rt)
6fbf66fa 3139 {
81d882d5
DS
3140 for (i = 0; i < rt->dwNumEntries; ++i)
3141 {
3142 msg(msglev, "%s", format_route_entry(&rt->table[i], &gc));
3143 }
6fbf66fa 3144 }
81d882d5 3145 gc_free(&gc);
6fbf66fa
JY
3146}
3147
a55b3cdb 3148#elif defined(TARGET_LINUX) || defined(TARGET_ANDROID)
6fbf66fa 3149
7fb0e07e 3150void
81d882d5 3151get_default_gateway(struct route_gateway_info *rgi)
6fbf66fa 3152{
81d882d5
DS
3153 struct gc_arena gc = gc_new();
3154 int sd = -1;
3155 char best_name[16];
3156 best_name[0] = 0;
7fb0e07e 3157
81d882d5 3158 CLEAR(*rgi);
7fb0e07e 3159
429f0560 3160#ifndef TARGET_ANDROID
81d882d5
DS
3161 /* get default gateway IP addr */
3162 {
3163 FILE *fp = fopen("/proc/net/route", "r");
3164 if (fp)
3165 {
3166 char line[256];
3167 int count = 0;
3168 unsigned int lowest_metric = UINT_MAX;
3169 in_addr_t best_gw = 0;
3170 bool found = false;
3171 while (fgets(line, sizeof(line), fp) != NULL)
3172 {
3173 if (count)
3174 {
3175 unsigned int net_x = 0;
3176 unsigned int mask_x = 0;
3177 unsigned int gw_x = 0;
3178 unsigned int metric = 0;
3179 unsigned int flags = 0;
3180 char name[16];
3181 name[0] = 0;
3182 const int np = sscanf(line, "%15s\t%x\t%x\t%x\t%*s\t%*s\t%d\t%x",
3183 name,
3184 &net_x,
3185 &gw_x,
3186 &flags,
3187 &metric,
3188 &mask_x);
3189 if (np == 6 && (flags & IFF_UP))
3190 {
3191 const in_addr_t net = ntohl(net_x);
3192 const in_addr_t mask = ntohl(mask_x);
3193 const in_addr_t gw = ntohl(gw_x);
3194
3195 if (!net && !mask && metric < lowest_metric)
3196 {
3197 found = true;
3198 best_gw = gw;
3199 strcpy(best_name, name);
3200 lowest_metric = metric;
3201 }
3202 }
3203 }
3204 ++count;
3205 }
3206 fclose(fp);
3207
3208 if (found)
3209 {
3210 rgi->gateway.addr = best_gw;
3211 rgi->flags |= RGI_ADDR_DEFINED;
3212 if (!rgi->gateway.addr && best_name[0])
3213 {
3214 rgi->flags |= RGI_ON_LINK;
3215 }
3216 }
3217 }
3218 }
3219#else /* ifndef TARGET_ANDROID */
3220 /* Android, set some pseudo GW, addr is in host byte order,
3221 * Determining the default GW on Android 5.0+ is non trivial
3222 * and serves almost no purpose since OpenVPN only uses the
3223 * default GW address to add routes for networks that should
3224 * NOT be routed over the VPN. Using a well known address
3225 * (127.'d'.'g'.'w') for the default GW make detecting
3226 * these routes easier from the controlling app.
3227 */
3228 rgi->gateway.addr = 127 << 24 | 'd' << 16 | 'g' << 8 | 'w';
3229 rgi->flags |= RGI_ADDR_DEFINED;
3230 strcpy(best_name, "android-gw");
3231#endif /* ifndef TARGET_ANDROID */
3232
3233 /* scan adapter list */
3234 if (rgi->flags & RGI_ADDR_DEFINED)
3235 {
3236 struct ifreq *ifr, *ifend;
3237 in_addr_t addr, netmask;
3238 struct ifreq ifreq;
3239 struct ifconf ifc;
3240 struct ifreq ifs[20]; /* Maximum number of interfaces to scan */
3241
3242 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
3243 {
3244 msg(M_WARN, "GDG: socket() failed");
3245 goto done;
3246 }
3247 ifc.ifc_len = sizeof(ifs);
3248 ifc.ifc_req = ifs;
3249 if (ioctl(sd, SIOCGIFCONF, &ifc) < 0)
3250 {
3251 msg(M_WARN, "GDG: ioctl(SIOCGIFCONF) failed");
3252 goto done;
3253 }
7fb0e07e 3254
81d882d5
DS
3255 /* scan through interface list */
3256 ifend = ifs + (ifc.ifc_len / sizeof(struct ifreq));
3257 for (ifr = ifc.ifc_req; ifr < ifend; ifr++)
3258 {
3259 if (ifr->ifr_addr.sa_family == AF_INET)
3260 {
3261 /* get interface addr */
3262 addr = ntohl(((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr);
3263
3264 /* get interface name */
3265 strncpynt(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
3266
3267 /* check that the interface is up */
3268 if (ioctl(sd, SIOCGIFFLAGS, &ifreq) < 0)
3269 {
3270 continue;
3271 }
3272 if (!(ifreq.ifr_flags & IFF_UP))
3273 {
3274 continue;
3275 }
3276
3277 if (rgi->flags & RGI_ON_LINK)
3278 {
3279 /* check that interface name of current interface
3280 * matches interface name of best default route */
3281 if (strcmp(ifreq.ifr_name, best_name))
3282 {
3283 continue;
3284 }
8fc83a2d 3285#if 0
81d882d5
DS
3286 /* if point-to-point link, use remote addr as route gateway */
3287 if ((ifreq.ifr_flags & IFF_POINTOPOINT) && ioctl(sd, SIOCGIFDSTADDR, &ifreq) >= 0)
3288 {
3289 rgi->gateway.addr = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
3290 if (rgi->gateway.addr)
3291 {
3292 rgi->flags &= ~RGI_ON_LINK;
3293 }
3294 }
8fc83a2d 3295#endif
81d882d5
DS
3296 }
3297 else
3298 {
3299 /* get interface netmask */
3300 if (ioctl(sd, SIOCGIFNETMASK, &ifreq) < 0)
3301 {
3302 continue;
3303 }
3304 netmask = ntohl(((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr);
3305
3306 /* check that interface matches default route */
3307 if (((rgi->gateway.addr ^ addr) & netmask) != 0)
3308 {
3309 continue;
3310 }
3311
3312 /* save netmask */
3313 rgi->gateway.netmask = netmask;
3314 rgi->flags |= RGI_NETMASK_DEFINED;
3315 }
3316
3317 /* save iface name */
3318 strncpynt(rgi->iface, ifreq.ifr_name, sizeof(rgi->iface));
3319 rgi->flags |= RGI_IFACE_DEFINED;
3320
3321 /* now get the hardware address. */
3322 memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
3323 if (ioctl(sd, SIOCGIFHWADDR, &ifreq) < 0)
3324 {
3325 msg(M_WARN, "GDG: SIOCGIFHWADDR(%s) failed", ifreq.ifr_name);
3326 goto done;
3327 }
3328 memcpy(rgi->hwaddr, &ifreq.ifr_hwaddr.sa_data, 6);
3329 rgi->flags |= RGI_HWADDR_DEFINED;
3330
3331 break;
3332 }
3333 }
3334 }
3335
3336done:
3337 if (sd >= 0)
3338 {
3339 close(sd);
3340 }
3341 gc_free(&gc);
6fbf66fa
JY
3342}
3343
3128abcf
GD
3344/* IPv6 implementation using netlink
3345 * http://www.linuxjournal.com/article/7356
3346 * netlink(3), netlink(7), rtnetlink(7)
3347 * http://www.virtualbox.org/svn/vbox/trunk/src/VBox/NetworkServices/NAT/rtmon_linux.c
d8a8656f 3348 */
3128abcf 3349struct rtreq {
81d882d5
DS
3350 struct nlmsghdr nh;
3351 struct rtmsg rtm;
3352 char attrbuf[512];
3128abcf
GD
3353};
3354
d8a8656f
GD
3355void
3356get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
81d882d5 3357 const struct in6_addr *dest)
d8a8656f 3358{
3128abcf
GD
3359 int nls = -1;
3360 struct rtreq rtreq;
3361 struct rtattr *rta;
3362
3363 char rtbuf[2000];
3364 ssize_t ssize;
3365
d8a8656f 3366 CLEAR(*rgi6);
3128abcf
GD
3367
3368 nls = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE );
81d882d5
DS
3369 if (nls < 0)
3370 {
3371 msg(M_WARN|M_ERRNO, "GDG6: socket() failed" ); goto done;
3372 }
3128abcf
GD
3373
3374 /* bind() is not needed, no unsolicited msgs coming in */
3375
3376 /* request best matching route, see netlink(7) for explanations
3377 */
3378 CLEAR(rtreq);
3379 rtreq.nh.nlmsg_type = RTM_GETROUTE;
81d882d5 3380 rtreq.nh.nlmsg_flags = NLM_F_REQUEST; /* best match only */
3128abcf 3381 rtreq.rtm.rtm_family = AF_INET6;
81d882d5
DS
3382 rtreq.rtm.rtm_src_len = 0; /* not source dependent */
3383 rtreq.rtm.rtm_dst_len = 128; /* exact dst */
3128abcf
GD
3384 rtreq.rtm.rtm_table = RT_TABLE_MAIN;
3385 rtreq.rtm.rtm_protocol = RTPROT_UNSPEC;
3386 rtreq.nh.nlmsg_len = NLMSG_SPACE(sizeof(rtreq.rtm));
3387
3388 /* set RTA_DST for target IPv6 address we want */
3389 rta = (struct rtattr *)(((char *) &rtreq)+NLMSG_ALIGN(rtreq.nh.nlmsg_len));
3390 rta->rta_type = RTA_DST;
3391 rta->rta_len = RTA_LENGTH(16);
81d882d5
DS
3392 rtreq.nh.nlmsg_len = NLMSG_ALIGN(rtreq.nh.nlmsg_len)
3393 +RTA_LENGTH(16);
3128abcf 3394
81d882d5
DS
3395 if (dest == NULL) /* ::, unspecified */
3396 {
3397 memset( RTA_DATA(rta), 0, 16 ); /* :: = all-zero */
3398 }
3128abcf 3399 else
81d882d5
DS
3400 {
3401 memcpy( RTA_DATA(rta), (void *)dest, 16 );
3402 }
3128abcf
GD
3403
3404 /* send and receive reply */
81d882d5
DS
3405 if (send( nls, &rtreq, rtreq.nh.nlmsg_len, 0 ) < 0)
3406 {
3407 msg(M_WARN|M_ERRNO, "GDG6: send() failed" ); goto done;
3408 }
3128abcf
GD
3409
3410 ssize = recv(nls, rtbuf, sizeof(rtbuf), MSG_TRUNC);
3411
3412 if (ssize < 0)
81d882d5
DS
3413 {
3414 msg(M_WARN|M_ERRNO, "GDG6: recv() failed" ); goto done;
3415 }
3128abcf
GD
3416
3417 if (ssize > sizeof(rtbuf))
3418 {
81d882d5
DS
3419 msg(M_WARN, "get_default_gateway_ipv6: returned message too big for buffer (%d>%d)", (int)ssize, (int)sizeof(rtbuf) );
3420 goto done;
3128abcf
GD
3421 }
3422
3423 struct nlmsghdr *nh;
3424
3425 for (nh = (struct nlmsghdr *)rtbuf;
3426 NLMSG_OK(nh, ssize);
3427 nh = NLMSG_NEXT(nh, ssize))
3428 {
81d882d5
DS
3429 struct rtmsg *rtm;
3430 int attrlen;
3431
3432 if (nh->nlmsg_type == NLMSG_DONE)
3433 {
3434 break;
3435 }
3436
3437 if (nh->nlmsg_type == NLMSG_ERROR)
3438 {
3439 struct nlmsgerr *ne = (struct nlmsgerr *)NLMSG_DATA(nh);
3440 msg(M_WARN, "GDG6: NLSMG_ERROR: error %d\n", ne->error);
3441 break;
3442 }
3443
3444 if (nh->nlmsg_type != RTM_NEWROUTE)
3445 {
3446 /* shouldn't happen */
3447 msg(M_WARN, "GDG6: unexpected msg_type %d", nh->nlmsg_type );
3448 continue;
3449 }
3450
3451 rtm = (struct rtmsg *)NLMSG_DATA(nh);
3452 attrlen = RTM_PAYLOAD(nh);
3453
3454 /* we're only looking for routes in the main table, as "we have
3455 * no IPv6" will lead to a lookup result in "Local" (::/0 reject)
3456 */
3457 if (rtm->rtm_family != AF_INET6
3458 || rtm->rtm_table != RT_TABLE_MAIN)
3459 {
3460 continue;
3461 } /* we're not interested */
3462
3463 for (rta = RTM_RTA(rtm);
3464 RTA_OK(rta, attrlen);
3465 rta = RTA_NEXT(rta, attrlen))
3466 {
3467 if (rta->rta_type == RTA_GATEWAY)
3468 {
3469 if (RTA_PAYLOAD(rta) != sizeof(struct in6_addr) )
3470 {
3471 msg(M_WARN, "GDG6: RTA_GW size mismatch"); continue;
3472 }
3473 rgi6->gateway.addr_ipv6 = *(struct in6_addr *) RTA_DATA(rta);
3474 rgi6->flags |= RGI_ADDR_DEFINED;
3475 }
3476 else if (rta->rta_type == RTA_OIF)
3477 {
3478 char ifname[IF_NAMESIZE+1];
3479 int oif;
3480 if (RTA_PAYLOAD(rta) != sizeof(oif) )
3481 {
3482 msg(M_WARN, "GDG6: oif size mismatch"); continue;
3483 }
3484
3485 memcpy(&oif, RTA_DATA(rta), sizeof(oif));
3486 if_indextoname(oif,ifname);
3487 strncpy( rgi6->iface, ifname, sizeof(rgi6->iface)-1 );
3488 rgi6->flags |= RGI_IFACE_DEFINED;
3489 }
3490 }
3128abcf
GD
3491 }
3492
3493 /* if we have an interface but no gateway, the destination is on-link */
3494 if ( ( rgi6->flags & (RGI_IFACE_DEFINED|RGI_ADDR_DEFINED) ) ==
81d882d5 3495 RGI_IFACE_DEFINED)
3128abcf 3496 {
81d882d5
DS
3497 rgi6->flags |= (RGI_ADDR_DEFINED | RGI_ON_LINK);
3498 if (dest)
3499 {
3500 rgi6->gateway.addr_ipv6 = *dest;
3501 }
3128abcf
GD
3502 }
3503
81d882d5 3504done:
3128abcf 3505 if (nls >= 0)
81d882d5
DS
3506 {
3507 close(nls);
3508 }
d8a8656f
GD
3509}
3510
81d882d5
DS
3511#elif defined(TARGET_DARWIN) || defined(TARGET_SOLARIS) \
3512 || defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
3513 || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
6fbf66fa
JY
3514
3515#include <sys/types.h>
3516#include <sys/socket.h>
3517#include <netinet/in.h>
6a8ea970
JY
3518#include <net/route.h>
3519#include <net/if_dl.h>
6fbf66fa 3520
6a8ea970 3521struct rtmsg {
81d882d5
DS
3522 struct rt_msghdr m_rtm;
3523 char m_space[512];
6a8ea970 3524};
6fbf66fa 3525
cab6305b
GD
3526/* the route socket code is identical for all 4 supported BSDs and for
3527 * MacOS X (Darwin), with one crucial difference: when going from
3528 * 32 bit to 64 bit, the BSDs increased the structure size but kept
3529 * source code compatibility by keeping the use of "long", while
3530 * MacOS X decided to keep binary compatibility by *changing* the API
3531 * to use "uint32_t", thus 32 bit on all OS X variants
3532 *
3533 * We used to have a large amount of duplicate code here which really
3534 * differed only in this (long) vs. (uint32_t) - IMHO, worse than
3535 * having a combined block for all BSDs with this single #ifdef inside
3536 */
3537
3538#if defined(TARGET_DARWIN)
81d882d5
DS
3539#define ROUNDUP(a) \
3540 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
cab6305b 3541#else
81d882d5
DS
3542#define ROUNDUP(a) \
3543 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
cab6305b 3544#endif
6fbf66fa 3545
01bfdf3a
AP
3546#if defined(TARGET_SOLARIS)
3547#define NEXTADDR(w, u) \
81d882d5
DS
3548 if (rtm_addrs & (w)) { \
3549 l = ROUNDUP(sizeof(u)); memmove(cp, &(u), l); cp += l; \
3550 }
01bfdf3a
AP
3551
3552#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in)))
81d882d5 3553#else /* if defined(TARGET_SOLARIS) */
7fb0e07e 3554#define NEXTADDR(w, u) \
81d882d5
DS
3555 if (rtm_addrs & (w)) { \
3556 l = ROUNDUP( ((struct sockaddr *)&(u))->sa_len); memmove(cp, &(u), l); cp += l; \
3557 }
7fb0e07e
JY
3558
3559#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
01bfdf3a 3560#endif
7fb0e07e
JY
3561
3562#define max(a,b) ((a) > (b) ? (a) : (b))
3563
3564void
81d882d5 3565get_default_gateway(struct route_gateway_info *rgi)
6fbf66fa 3566{
81d882d5
DS
3567 struct gc_arena gc = gc_new();
3568 struct rtmsg m_rtmsg;
3569 int sockfd = -1;
3570 int seq, l, pid, rtm_addrs;
3571 unsigned int i;
3572 struct sockaddr so_dst, so_mask;
3573 char *cp = m_rtmsg.m_space;
3574 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
3575 struct rt_msghdr *rtm_aux;
6fbf66fa 3576
81d882d5 3577#define rtm m_rtmsg.m_rtm
6fbf66fa 3578
81d882d5 3579 CLEAR(*rgi);
6fbf66fa 3580
81d882d5
DS
3581 /* setup data to send to routing socket */
3582 pid = getpid();
3583 seq = 0;
3584 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
6fbf66fa 3585
81d882d5
DS
3586 bzero(&m_rtmsg, sizeof(m_rtmsg));
3587 bzero(&so_dst, sizeof(so_dst));
3588 bzero(&so_mask, sizeof(so_mask));
3589 bzero(&rtm, sizeof(struct rt_msghdr));
6fbf66fa 3590
81d882d5
DS
3591 rtm.rtm_type = RTM_GET;
3592 rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
3593 rtm.rtm_version = RTM_VERSION;
3594 rtm.rtm_seq = ++seq;
3595 rtm.rtm_addrs = rtm_addrs;
6fbf66fa 3596
81d882d5
DS
3597 so_dst.sa_family = AF_INET;
3598 so_mask.sa_family = AF_INET;
01bfdf3a
AP
3599
3600#ifndef TARGET_SOLARIS
81d882d5
DS
3601 so_dst.sa_len = sizeof(struct sockaddr_in);
3602 so_mask.sa_len = sizeof(struct sockaddr_in);
01bfdf3a 3603#endif
6fbf66fa 3604
81d882d5
DS
3605 NEXTADDR(RTA_DST, so_dst);
3606 NEXTADDR(RTA_NETMASK, so_mask);
3607
3608 rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
3609
3610 /* transact with routing socket */
3611 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
7fb0e07e 3612 if (sockfd < 0)
81d882d5
DS
3613 {
3614 msg(M_WARN, "GDG: socket #1 failed");
3615 goto done;
3616 }
3617 if (write(sockfd, (char *)&m_rtmsg, l) < 0)
3618 {
3619 msg(M_WARN, "GDG: problem writing to routing socket");
3620 goto done;
3621 }
4cd4899e
SK
3622 do
3623 {
81d882d5
DS
3624 l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg));
3625 } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
7fb0e07e
JY
3626 close(sockfd);
3627 sockfd = -1;
3628
81d882d5
DS
3629 /* extract return data from routing socket */
3630 rtm_aux = &rtm;
3631 cp = ((char *)(rtm_aux + 1));
3632 if (rtm_aux->rtm_addrs)
3633 {
3634 for (i = 1; i; i <<= 1)
3635 {
3636 if (i & rtm_aux->rtm_addrs)
3637 {
3638 sa = (struct sockaddr *)cp;
3639 if (i == RTA_GATEWAY)
3640 {
3641 gate = sa;
3642 }
3643 else if (i == RTA_IFP)
3644 {
3645 ifp = sa;
3646 }
3647 ADVANCE(cp, sa);
3648 }
3649 }
3650 }
3651 else
3652 {
3653 goto done;
3654 }
3655
3656 /* get gateway addr and interface name */
3657 if (gate != NULL)
3658 {
3659 /* get default gateway addr */
3660 rgi->gateway.addr = ntohl(((struct sockaddr_in *)gate)->sin_addr.s_addr);
3661 if (rgi->gateway.addr)
3662 {
3663 rgi->flags |= RGI_ADDR_DEFINED;
3664 }
3665
3666 if (ifp)
3667 {
3668 /* get interface name */
3669 const struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
3670 if (adl->sdl_nlen && adl->sdl_nlen < sizeof(rgi->iface))
3671 {
3672 memcpy(rgi->iface, adl->sdl_data, adl->sdl_nlen);
3673 rgi->iface[adl->sdl_nlen] = '\0';
3674 rgi->flags |= RGI_IFACE_DEFINED;
3675 }
3676 }
3677 }
3678
3679 /* get netmask of interface that owns default gateway */
3680 if (rgi->flags & RGI_IFACE_DEFINED)
3681 {
3682 struct ifreq ifr;
3683
3684 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3685 if (sockfd < 0)
3686 {
3687 msg(M_WARN, "GDG: socket #2 failed");
3688 goto done;
3689 }
3690
3691 CLEAR(ifr);
3692 ifr.ifr_addr.sa_family = AF_INET;
3693 strncpynt(ifr.ifr_name, rgi->iface, IFNAMSIZ);
3694
3695 if (ioctl(sockfd, SIOCGIFNETMASK, (char *)&ifr) < 0)
3696 {
3697 msg(M_WARN, "GDG: ioctl #1 failed");
3698 goto done;
3699 }
3700 close(sockfd);
3701 sockfd = -1;
3702
3703 rgi->gateway.netmask = ntohl(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr);
3704 rgi->flags |= RGI_NETMASK_DEFINED;
3705 }
3706
3707 /* try to read MAC addr associated with interface that owns default gateway */
3708 if (rgi->flags & RGI_IFACE_DEFINED)
3709 {
3710 struct ifconf ifc;
3711 struct ifreq *ifr;
3712 const int bufsize = 4096;
3713 char *buffer;
3714
3715 buffer = (char *) gc_malloc(bufsize, true, &gc);
3716 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
3717 if (sockfd < 0)
3718 {
3719 msg(M_WARN, "GDG: socket #3 failed");
3720 goto done;
3721 }
3722
3723 ifc.ifc_len = bufsize;
3724 ifc.ifc_buf = buffer;
3725
3726 if (ioctl(sockfd, SIOCGIFCONF, (char *)&ifc) < 0)
3727 {
3728 msg(M_WARN, "GDG: ioctl #2 failed");
3729 goto done;
3730 }
3731 close(sockfd);
3732 sockfd = -1;
3733
3734 for (cp = buffer; cp <= buffer + ifc.ifc_len - sizeof(struct ifreq); )
3735 {
3736 ifr = (struct ifreq *)cp;
01bfdf3a 3737#if defined(TARGET_SOLARIS)
81d882d5 3738 const size_t len = sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr);
01bfdf3a 3739#else
81d882d5 3740 const size_t len = sizeof(ifr->ifr_name) + max(sizeof(ifr->ifr_addr), ifr->ifr_addr.sa_len);
01bfdf3a
AP
3741#endif
3742
81d882d5
DS
3743 if (!ifr->ifr_addr.sa_family)
3744 {
3745 break;
3746 }
3747 if (!strncmp(ifr->ifr_name, rgi->iface, IFNAMSIZ))
3748 {
3749 if (ifr->ifr_addr.sa_family == AF_LINK)
3750 {
3751 struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
3752 memcpy(rgi->hwaddr, LLADDR(sdl), 6);
3753 rgi->flags |= RGI_HWADDR_DEFINED;
3754 }
3755 }
3756 cp += len;
3757 }
3758 }
3759
3760done:
3761 if (sockfd >= 0)
3762 {
3763 close(sockfd);
3764 }
3765 gc_free(&gc);
6a8ea970
JY
3766}
3767
2ff366f7
GD
3768/* BSD implementation using routing socket (as does IPv4)
3769 * (the code duplication is somewhat unavoidable if we want this to
3770 * work on OpenSolaris as well. *sigh*)
d8a8656f 3771 */
2ff366f7
GD
3772
3773/* Solaris has no length field - this is ugly, but less #ifdef in total
3774 */
3775#if defined(TARGET_SOLARIS)
81d882d5
DS
3776#undef ADVANCE
3777#define ADVANCE(x, n) (x += ROUNDUP(sizeof(struct sockaddr_in6)))
2ff366f7
GD
3778#endif
3779
d8a8656f
GD
3780void
3781get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
81d882d5 3782 const struct in6_addr *dest)
d8a8656f 3783{
2ff366f7
GD
3784
3785 struct rtmsg m_rtmsg;
3786 int sockfd = -1;
d4d5d925
MM
3787 int seq, l, pid, rtm_addrs;
3788 unsigned int i;
2ff366f7
GD
3789 struct sockaddr_in6 so_dst, so_mask;
3790 char *cp = m_rtmsg.m_space;
3791 struct sockaddr *gate = NULL, *ifp = NULL, *sa;
3792 struct rt_msghdr *rtm_aux;
3793
d8a8656f 3794 CLEAR(*rgi6);
2ff366f7
GD
3795
3796 /* setup data to send to routing socket */
3797 pid = getpid();
3798 seq = 0;
3799 rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP;
3800
3801 bzero(&m_rtmsg, sizeof(m_rtmsg));
3802 bzero(&so_dst, sizeof(so_dst));
3803 bzero(&so_mask, sizeof(so_mask));
3804 bzero(&rtm, sizeof(struct rt_msghdr));
3805
3806 rtm.rtm_type = RTM_GET;
3807 rtm.rtm_flags = RTF_UP;
3808 rtm.rtm_version = RTM_VERSION;
3809 rtm.rtm_seq = ++seq;
3810
3811 so_dst.sin6_family = AF_INET6;
3812 so_mask.sin6_family = AF_INET6;
3813
81d882d5
DS
3814 if (dest != NULL /* specific host? */
3815 && !IN6_IS_ADDR_UNSPECIFIED(dest) )
2ff366f7 3816 {
81d882d5
DS
3817 so_dst.sin6_addr = *dest;
3818 /* :: needs /0 "netmask", host route wants "no netmask */
3819 rtm_addrs &= ~RTA_NETMASK;
2ff366f7
GD
3820 }
3821
3822 rtm.rtm_addrs = rtm_addrs;
3823
3824#ifndef TARGET_SOLARIS
3825 so_dst.sin6_len = sizeof(struct sockaddr_in6);
3826 so_mask.sin6_len = sizeof(struct sockaddr_in6);
3827#endif
3828
3829 NEXTADDR(RTA_DST, so_dst);
3830 NEXTADDR(RTA_NETMASK, so_mask);
3831
3832 rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
3833
3834 /* transact with routing socket */
3835 sockfd = socket(PF_ROUTE, SOCK_RAW, 0);
3836 if (sockfd < 0)
3837 {
81d882d5
DS
3838 msg(M_WARN, "GDG6: socket #1 failed");
3839 goto done;
2ff366f7
GD
3840 }
3841 if (write(sockfd, (char *)&m_rtmsg, l) < 0)
3842 {
81d882d5
DS
3843 msg(M_WARN, "GDG6: problem writing to routing socket");
3844 goto done;
2ff366f7
GD
3845 }
3846
3847 do
3848 {
81d882d5 3849 l = read(sockfd, (char *)&m_rtmsg, sizeof(m_rtmsg));
2ff366f7
GD
3850 }
3851 while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
3852
3853 close(sockfd);
3854 sockfd = -1;
3855
3856 /* extract return data from routing socket */
3857 rtm_aux = &rtm;
3858 cp = ((char *)(rtm_aux + 1));
3859 if (rtm_aux->rtm_addrs)
3860 {
81d882d5
DS
3861 for (i = 1; i; i <<= 1)
3862 {
3863 if (i & rtm_aux->rtm_addrs)
3864 {
3865 sa = (struct sockaddr *)cp;
3866 if (i == RTA_GATEWAY)
3867 {
3868 gate = sa;
3869 }
3870 else if (i == RTA_IFP)
3871 {
3872 ifp = sa;
3873 }
3874 ADVANCE(cp, sa);
3875 }
3876 }
2ff366f7
GD
3877 }
3878 else
81d882d5
DS
3879 {
3880 goto done;
3881 }
2ff366f7
GD
3882
3883 /* get gateway addr and interface name */
81d882d5 3884 if (gate != NULL)
2ff366f7 3885 {
81d882d5
DS
3886 struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)gate;
3887 struct in6_addr gw = s6->sin6_addr;
2ff366f7
GD
3888
3889#ifndef TARGET_SOLARIS
81d882d5
DS
3890 /* You do not really want to know... from FreeBSD's route.c
3891 * (KAME encodes the 16 bit scope_id in s6_addr[2] + [3],
3892 * but for a correct link-local address these must be :0000: )
3893 */
3894 if (gate->sa_len == sizeof(struct sockaddr_in6)
3895 && IN6_IS_ADDR_LINKLOCAL(&gw) )
3896 {
3897 gw.s6_addr[2] = gw.s6_addr[3] = 0;
3898 }
3899
3900 if (gate->sa_len != sizeof(struct sockaddr_in6)
3901 || IN6_IS_ADDR_UNSPECIFIED(&gw) )
3902 {
3903 rgi6->flags |= RGI_ON_LINK;
3904 }
3905 else
2ff366f7
GD
3906#endif
3907
81d882d5
DS
3908 rgi6->gateway.addr_ipv6 = gw;
3909 rgi6->flags |= RGI_ADDR_DEFINED;
2ff366f7 3910
81d882d5
DS
3911 if (ifp)
3912 {
3913 /* get interface name */
3914 const struct sockaddr_dl *adl = (struct sockaddr_dl *) ifp;
3915 if (adl->sdl_nlen && adl->sdl_nlen < sizeof(rgi6->iface))
3916 {
3917 memcpy(rgi6->iface, adl->sdl_data, adl->sdl_nlen);
3918 rgi6->flags |= RGI_IFACE_DEFINED;
3919 }
3920 }
2ff366f7
GD
3921 }
3922
81d882d5 3923done:
2ff366f7 3924 if (sockfd >= 0)
81d882d5
DS
3925 {
3926 close(sockfd);
3927 }
d8a8656f
GD
3928}
3929
7fb0e07e
JY
3930#undef max
3931
81d882d5 3932#else /* if defined(_WIN32) */
6fbf66fa 3933
7fb0e07e
JY
3934/*
3935 * This is a platform-specific method that returns data about
3936 * the current default gateway. Return data is placed into
3937 * a struct route_gateway_info object provided by caller. The
3938 * implementation should CLEAR the structure before adding
3939 * data to it.
3940 *
3941 * Data returned includes:
3942 * 1. default gateway address (rgi->gateway.addr)
3943 * 2. netmask of interface that owns default gateway
3944 * (rgi->gateway.netmask)
3945 * 3. hardware address (i.e. MAC address) of interface that owns
3946 * default gateway (rgi->hwaddr)
3947 * 4. interface name (or adapter index on Windows) that owns default
3948 * gateway (rgi->iface or rgi->adapter_index)
3949 * 5. an array of additional address/netmask pairs defined by
3950 * interface that owns default gateway (rgi->addrs with length
3951 * given in rgi->n_addrs)
3952 *
3953 * The flags RGI_x_DEFINED may be used to indicate which of the data
3954 * members were successfully returned (set in rgi->flags). All of
3955 * the data members are optional, however certain OpenVPN functionality
3956 * may be disabled by missing items.
3957 */
3958void
81d882d5 3959get_default_gateway(struct route_gateway_info *rgi)
6fbf66fa 3960{
81d882d5 3961 CLEAR(*rgi);
6fbf66fa 3962}
d8a8656f
GD
3963void
3964get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
81d882d5 3965 const struct in6_addr *dest)
d8a8656f
GD
3966{
3967 msg(D_ROUTE, "no support for get_default_gateway_ipv6() on this system");
3968 CLEAR(*rgi6);
3969}
6fbf66fa 3970
81d882d5 3971#endif /* if defined(_WIN32) */
6fbf66fa
JY
3972
3973bool
81d882d5 3974netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
6fbf66fa 3975{
81d882d5
DS
3976 int i;
3977 const int addrlen = sizeof(in_addr_t) * 8;
6fbf66fa 3978
81d882d5 3979 if ((network & netmask) == network)
6fbf66fa 3980 {
81d882d5
DS
3981 for (i = 0; i <= addrlen; ++i)
3982 {
3983 in_addr_t mask = netbits_to_netmask(i);
3984 if (mask == netmask)
3985 {
3986 if (i == addrlen)
3987 {
3988 *netbits = -1;
3989 }
3990 else
3991 {
3992 *netbits = i;
3993 }
3994 return true;
3995 }
3996 }
6fbf66fa 3997 }
81d882d5 3998 return false;
6fbf66fa 3999}
3c7f2f55 4000
b4b92ae5
GD
4001/* similar to netmask_to_netbits(), but don't mess with base address
4002 * etc., just convert to netbits - non-mappable masks are returned as "-1"
4003 */
81d882d5
DS
4004int
4005netmask_to_netbits2(in_addr_t netmask)
b4b92ae5 4006{
81d882d5
DS
4007 int i;
4008 const int addrlen = sizeof(in_addr_t) * 8;
b4b92ae5 4009
81d882d5 4010 for (i = 0; i <= addrlen; ++i)
b4b92ae5 4011 {
81d882d5
DS
4012 in_addr_t mask = netbits_to_netmask(i);
4013 if (mask == netmask)
4014 {
4015 return i;
4016 }
b4b92ae5 4017 }
81d882d5 4018 return -1;
b4b92ae5
GD
4019}
4020
4021
3c7f2f55
JY
4022/*
4023 * get_bypass_addresses() is used by the redirect-gateway bypass-x
4024 * functions to build a route bypass to selected DHCP/DNS servers,
4025 * so that outgoing packets to these servers don't end up in the tunnel.
4026 */
4027
445b192a 4028#if defined(_WIN32)
3c7f2f55
JY
4029
4030static void
81d882d5 4031add_host_route_if_nonlocal(struct route_bypass *rb, const in_addr_t addr)
3c7f2f55 4032{
81d882d5
DS
4033 if (test_local_addr(addr, NULL) == TLA_NONLOCAL && addr != 0 && addr != IPV4_NETMASK_HOST)
4034 {
4035 add_bypass_address(rb, addr);
4036 }
3c7f2f55
JY
4037}
4038
4039static void
81d882d5 4040add_host_route_array(struct route_bypass *rb, const IP_ADDR_STRING *iplist)
3c7f2f55 4041{
81d882d5 4042 while (iplist)
3c7f2f55 4043 {
81d882d5
DS
4044 bool succeed = false;
4045 const in_addr_t ip = getaddr(GETADDR_HOST_ORDER, iplist->IpAddress.String, 0, &succeed, NULL);
4046 if (succeed)
4047 {
4048 add_host_route_if_nonlocal(rb, ip);
4049 }
4050 iplist = iplist->Next;
3c7f2f55
JY
4051 }
4052}
4053
4054static void
81d882d5 4055get_bypass_addresses(struct route_bypass *rb, const unsigned int flags)
3c7f2f55 4056{
81d882d5
DS
4057 struct gc_arena gc = gc_new();
4058 /*bool ret_bool = false;*/
3c7f2f55 4059
81d882d5
DS
4060 /* get full routing table */
4061 const MIB_IPFORWARDTABLE *routes = get_windows_routing_table(&gc);
3c7f2f55 4062
81d882d5
DS
4063 /* get the route which represents the default gateway */
4064 const MIB_IPFORWARDROW *row = get_default_gateway_row(routes);
3c7f2f55 4065
81d882d5 4066 if (row)
3c7f2f55 4067 {
81d882d5
DS
4068 /* get the adapter which the default gateway is associated with */
4069 const IP_ADAPTER_INFO *dgi = get_adapter_info(row->dwForwardIfIndex, &gc);
3c7f2f55 4070
81d882d5
DS
4071 /* get extra adapter info, such as DNS addresses */
4072 const IP_PER_ADAPTER_INFO *pai = get_per_adapter_info(row->dwForwardIfIndex, &gc);
3c7f2f55 4073
81d882d5
DS
4074 /* Bypass DHCP server address */
4075 if ((flags & RG_BYPASS_DHCP) && dgi && dgi->DhcpEnabled)
4076 {
4077 add_host_route_array(rb, &dgi->DhcpServer);
4078 }
3c7f2f55 4079
81d882d5
DS
4080 /* Bypass DNS server addresses */
4081 if ((flags & RG_BYPASS_DNS) && pai)
4082 {
4083 add_host_route_array(rb, &pai->DnsServerList);
4084 }
3c7f2f55
JY
4085 }
4086
81d882d5 4087 gc_free(&gc);
3c7f2f55
JY
4088}
4089
81d882d5 4090#else /* if defined(_WIN32) */
3c7f2f55
JY
4091
4092static void
81d882d5 4093get_bypass_addresses(struct route_bypass *rb, const unsigned int flags) /* PLATFORM-SPECIFIC */
3c7f2f55
JY
4094{
4095}
4096
81d882d5 4097#endif /* if defined(_WIN32) */
5f31881e 4098
775a6ac2
JY
4099/*
4100 * Test if addr is reachable via a local interface (return ILA_LOCAL),
4101 * or if it needs to be routed via the default gateway (return
4102 * ILA_NONLOCAL). If the target platform doesn't implement this
4103 * function, return ILA_NOT_IMPLEMENTED.
4104 *
4105 * Used by redirect-gateway autolocal feature
4106 */
4107
445b192a 4108#if defined(_WIN32)
775a6ac2
JY
4109
4110int
81d882d5 4111test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi)
775a6ac2 4112{
81d882d5
DS
4113 struct gc_arena gc = gc_new();
4114 const in_addr_t nonlocal_netmask = 0x80000000L; /* routes with netmask <= to this are considered non-local */
4115 int ret = TLA_NONLOCAL;
775a6ac2 4116
81d882d5
DS
4117 /* get full routing table */
4118 const MIB_IPFORWARDTABLE *rt = get_windows_routing_table(&gc);
4119 if (rt)
775a6ac2 4120 {
81d882d5
DS
4121 int i;
4122 for (i = 0; i < rt->dwNumEntries; ++i)
4123 {
4124 const MIB_IPFORWARDROW *row = &rt->table[i];
4125 const in_addr_t net = ntohl(row->dwForwardDest);
4126 const in_addr_t mask = ntohl(row->dwForwardMask);
4127 if (mask > nonlocal_netmask && (addr & mask) == net)
4128 {
4129 ret = TLA_LOCAL;
4130 break;
4131 }
4132 }
775a6ac2
JY
4133 }
4134
81d882d5
DS
4135 gc_free(&gc);
4136 return ret;
775a6ac2
JY
4137}
4138
81d882d5 4139#else /* if defined(_WIN32) */
775a6ac2 4140
775a6ac2 4141int
81d882d5 4142test_local_addr(const in_addr_t addr, const struct route_gateway_info *rgi) /* PLATFORM-SPECIFIC */
775a6ac2 4143{
81d882d5 4144 if (rgi)
7fb0e07e 4145 {
81d882d5
DS
4146 if (local_route(addr, 0xFFFFFFFF, rgi->gateway.addr, rgi))
4147 {
4148 return TLA_LOCAL;
4149 }
4150 else
4151 {
4152 return TLA_NONLOCAL;
4153 }
7fb0e07e 4154 }
81d882d5 4155 return TLA_NOT_IMPLEMENTED;
775a6ac2
JY
4156}
4157
81d882d5 4158#endif /* if defined(_WIN32) */