OpenVPN
helper.c
Go to the documentation of this file.
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 *
8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
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 along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "syshead.h"
29
30#include "forward.h"
31#include "helper.h"
32#include "pool.h"
33#include "push.h"
34
35#include "memdbg.h"
36
37
38static const char *
39print_netmask(int netbits, struct gc_arena *gc)
40{
41 struct buffer out = alloc_buf_gc(128, gc);
42 const in_addr_t netmask = netbits_to_netmask(netbits);
43
44 buf_printf(&out, "%s (/%d)", print_in_addr_t(netmask, 0, gc), netbits);
45
46 return BSTR(&out);
47}
48
49static const char *
51{
52 struct buffer out = alloc_buf_gc(128, gc);
54 buf_printf(&out, "route-gateway %s", print_in_addr_t(route_gateway, 0, gc));
55 return BSTR(&out);
56}
57
58static const char *
60{
61 struct buffer out = alloc_buf_gc(32, gc);
62 buf_printf(&out, "route-gateway dhcp");
63 return BSTR(&out);
64}
65
66static const char *
67print_opt_route(const in_addr_t network, const in_addr_t netmask, struct gc_arena *gc)
68{
69 struct buffer out = alloc_buf_gc(128, gc);
70 ASSERT(network);
71
72 if (netmask)
73 {
74 buf_printf(&out, "route %s %s",
75 print_in_addr_t(network, 0, gc),
76 print_in_addr_t(netmask, 0, gc));
77 }
78 else
79 {
80 buf_printf(&out, "route %s",
81 print_in_addr_t(network, 0, gc));
82 }
83
84 return BSTR(&out);
85}
86
87static const char *
88print_opt_topology(const int topology, struct gc_arena *gc)
89{
90 struct buffer out = alloc_buf_gc(128, gc);
91
92 buf_printf(&out, "topology %s", print_topology(topology));
93
94 return BSTR(&out);
95}
96
97static const char *
98print_str_int(const char *str, const int i, struct gc_arena *gc)
99{
100 struct buffer out = alloc_buf_gc(128, gc);
101 buf_printf(&out, "%s %d", str, i);
102 return BSTR(&out);
103}
104
105static const char *
106print_str(const char *str, struct gc_arena *gc)
107{
108 struct buffer out = alloc_buf_gc(128, gc);
109 buf_printf(&out, "%s", str);
110 return BSTR(&out);
111}
112
113static void
114helper_add_route(const in_addr_t network, const in_addr_t netmask, struct options *o)
115{
118 print_in_addr_t(network, 0, &o->gc),
119 print_in_addr_t(netmask, 0, &o->gc),
120 NULL,
121 NULL);
122}
123
124static void
125verify_common_subnet(const char *opt, const in_addr_t a, const in_addr_t b, const in_addr_t subnet)
126{
127 struct gc_arena gc = gc_new();
128 if ((a & subnet) != (b & subnet))
129 {
130 msg(M_USAGE, "%s IP addresses %s and %s are not in the same %s subnet",
131 opt,
132 print_in_addr_t(a, 0, &gc),
133 print_in_addr_t(b, 0, &gc),
134 print_in_addr_t(subnet, 0, &gc));
135 }
136 gc_free(&gc);
137}
138
139
143void
145{
146 if (o->topology != TOP_UNDEF)
147 {
148 return;
149 }
150 int dev = dev_type_enum(o->dev, o->dev_type);
151 if (dev != DEV_TYPE_TUN)
152 {
153 return;
154 }
155 if (o->mode == MODE_SERVER)
156 {
157 o->topology = TOP_SUBNET;
158 }
159 else
160 {
161 o->topology = TOP_NET30;
162 }
163}
164
165
166/*
167 * Process server, server-bridge, and client helper
168 * directives after the parameters themselves have been
169 * parsed and placed in struct options.
170 */
171void
173{
174 struct gc_arena gc = gc_new();
175
176 /*
177 * Get tun/tap/null device type
178 */
179 const int dev = dev_type_enum(o->dev, o->dev_type);
180
181 /*
182 *
183 * HELPER DIRECTIVE for IPv6
184 *
185 * server-ipv6 2001:db8::/64
186 *
187 * EXPANDS TO:
188 *
189 * tun-ipv6
190 * push "tun-ipv6"
191 * ifconfig-ipv6 2001:db8::1 2001:db8::2
192 * if !nopool:
193 * ifconfig-ipv6-pool 2001:db8::1000/64
194 *
195 */
196 if (o->server_ipv6_defined)
197 {
198 if (o->client)
199 {
200 msg(M_USAGE, "--server-ipv6 and --client cannot be used together");
201 }
202
203 if (o->server_flags & SF_NOPOOL)
204 {
205 msg(M_USAGE, "--server-ipv6 is incompatible with 'nopool' option");
206 }
208 {
209 msg(M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
210 }
211
212 o->mode = MODE_SERVER;
213 o->tls_server = true;
214
215 /* local ifconfig is "base address + 1" and "+2" */
221
222 /* basic sanity check */
223 ASSERT(o->server_netbits_ipv6 >= 64 && o->server_netbits_ipv6 <= 124);
224
226 /* For large enough pools we keep the original behaviour of adding
227 * 0x1000 when computing the base.
228 *
229 * Smaller pools can't get that far, therefore we just increase by 2
230 */
232 o->server_netbits_ipv6 < 112 ? 0x1000 : 2);
234
235 push_option(o, "tun-ipv6", M_USAGE);
236 }
237
238 /*
239 *
240 * HELPER DIRECTIVE:
241 *
242 * server 10.8.0.0 255.255.255.0
243 *
244 * EXPANDS TO:
245 *
246 * mode server
247 * tls-server
248 * push "topology [topology]"
249 *
250 * if tun AND (topology == net30 OR topology == p2p):
251 * ifconfig 10.8.0.1 10.8.0.2
252 * if !nopool:
253 * ifconfig-pool 10.8.0.4 10.8.0.251
254 * route 10.8.0.0 255.255.255.0
255 * if client-to-client:
256 * push "route 10.8.0.0 255.255.255.0"
257 * else if topology == net30:
258 * push "route 10.8.0.1"
259 *
260 * if tap OR (tun AND topology == subnet):
261 * ifconfig 10.8.0.1 255.255.255.0
262 * if !nopool:
263 * ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
264 * push "route-gateway 10.8.0.1"
265 * if route-gateway unset:
266 * route-gateway 10.8.0.2
267 */
268
269 if (o->server_defined)
270 {
271 int netbits = -2;
272 bool status = false;
273
274 if (o->client)
275 {
276 msg(M_USAGE, "--server and --client cannot be used together");
277 }
278
280 {
281 msg(M_USAGE, "--server and --server-bridge cannot be used together");
282 }
283
284 if (o->shared_secret_file)
285 {
286 msg(M_USAGE, "--server and --secret cannot be used together (you must use SSL/TLS keys)");
287 }
288
290 {
291 msg(M_USAGE, "--server already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");
292 }
293
294 if (!(dev == DEV_TYPE_TAP || dev == DEV_TYPE_TUN))
295 {
296 msg(M_USAGE, "--server directive only makes sense with --dev tun or --dev tap");
297 }
298
300 if (!status)
301 {
302 msg(M_USAGE, "--server directive network/netmask combination is invalid");
303 }
304
305 if (netbits < 0)
306 {
307 msg(M_USAGE, "--server directive netmask is invalid");
308 }
309
310 if (netbits < IFCONFIG_POOL_MIN_NETBITS)
311 {
312 msg(M_USAGE, "--server directive netmask allows for too many host addresses (subnet must be %s or higher)",
314 }
315
316 if (dev == DEV_TYPE_TUN)
317 {
318 int pool_end_reserve = 4;
319
320 if (netbits > 29)
321 {
322 msg(M_USAGE, "--server directive when used with --dev tun must define a subnet of %s or lower",
323 print_netmask(29, &gc));
324 }
325
326 if (netbits == 29)
327 {
328 pool_end_reserve = 0;
329 }
330
331 o->mode = MODE_SERVER;
332 o->tls_server = true;
333 /* Need to know topology now */
335
336 if (o->topology == TOP_NET30 || o->topology == TOP_P2P)
337 {
338 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
340
341 if (!(o->server_flags & SF_NOPOOL))
342 {
343 o->ifconfig_pool_defined = true;
345 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - pool_end_reserve;
347 }
348
350 if (o->enable_c2c)
351 {
353 }
354 else if (o->topology == TOP_NET30)
355 {
357 }
358 }
359 else if (o->topology == TOP_SUBNET)
360 {
361 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
363
364 if (!(o->server_flags & SF_NOPOOL))
365 {
366 o->ifconfig_pool_defined = true;
368 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
370 }
372
374 if (!o->route_default_gateway)
375 {
377 }
378 }
379 else
380 {
381 ASSERT(0);
382 }
383
385
386 if (o->topology == TOP_NET30 && !(o->server_flags & SF_NOPOOL))
387 {
388 msg(M_WARN, "WARNING: --topology net30 support for server "
389 "configs with IPv4 pools will be removed in a future "
390 "release. Please migrate to --topology subnet as soon "
391 "as possible.");
392 }
393 }
394 else if (dev == DEV_TYPE_TAP)
395 {
396 if (netbits > 30)
397 {
398 msg(M_USAGE, "--server directive when used with --dev tap must define a subnet of %s or lower",
399 print_netmask(30, &gc));
400 }
401
402 o->mode = MODE_SERVER;
403 o->tls_server = true;
404 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
406
407 if (!(o->server_flags & SF_NOPOOL))
408 {
409 o->ifconfig_pool_defined = true;
411 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
413 }
415
417 }
418 else
419 {
420 ASSERT(0);
421 }
422
423 /* set push-ifconfig-constraint directive */
424 if ((dev == DEV_TYPE_TAP || o->topology == TOP_SUBNET))
425 {
429 }
430 }
431
432 /*
433 * HELPER DIRECTIVE:
434 *
435 * server-bridge 10.8.0.4 255.255.255.0 10.8.0.128 10.8.0.254
436 *
437 * EXPANDS TO:
438 *
439 * mode server
440 * tls-server
441 *
442 * ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
443 * push "route-gateway 10.8.0.4"
444 *
445 * OR
446 *
447 * server-bridge
448 *
449 * EXPANDS TO:
450 *
451 * mode server
452 * tls-server
453 *
454 * if !nogw:
455 * push "route-gateway dhcp"
456 */
458 {
459 if (o->client)
460 {
461 msg(M_USAGE, "--server-bridge and --client cannot be used together");
462 }
463
465 {
466 msg(M_USAGE, "--server-bridge already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");
467 }
468
469 if (o->shared_secret_file)
470 {
471 msg(M_USAGE, "--server-bridge and --secret cannot be used together (you must use SSL/TLS keys)");
472 }
473
474 if (dev != DEV_TYPE_TAP)
475 {
476 msg(M_USAGE, "--server-bridge directive only makes sense with --dev tap");
477 }
478
480 {
484 }
485
486 o->mode = MODE_SERVER;
487 o->tls_server = true;
488
490 {
491 o->ifconfig_pool_defined = true;
497 }
499 {
501 }
502 }
503
504 /*
505 * HELPER DIRECTIVE:
506 *
507 * client
508 *
509 * EXPANDS TO:
510 *
511 * pull
512 * tls-client
513 */
514 else if (o->client)
515 {
516 o->pull = true;
517 o->tls_client = true;
518 }
519
520 gc_free(&gc);
521}
522
523/*
524 *
525 * HELPER DIRECTIVE:
526 *
527 * keepalive 10 60
528 *
529 * EXPANDS TO:
530 *
531 * if mode server:
532 * ping 10
533 * ping-restart 120
534 * push "ping 10"
535 * push "ping-restart 60"
536 * else
537 * ping 10
538 * ping-restart 60
539 */
540void
542{
544 {
545 /*
546 * Sanity checks.
547 */
548 if (o->keepalive_ping <= 0 || o->keepalive_timeout <= 0)
549 {
550 msg(M_USAGE, "--keepalive parameters must be > 0");
551 }
552 if (o->keepalive_ping * 2 > o->keepalive_timeout)
553 {
554 msg(M_USAGE, "the second parameter to --keepalive (restart timeout=%d) must be at least twice the value of the first parameter (ping interval=%d). A ratio of 1:5 or 1:6 would be even better. Recommended setting is --keepalive 10 60.",
556 o->keepalive_ping);
557 }
559 {
560 msg(M_USAGE, "--keepalive conflicts with --ping, --ping-exit, or --ping-restart. If you use --keepalive, you don't need any of the other --ping directives.");
561 }
562
563 /*
564 * Expand.
565 */
566 if (o->mode == MODE_POINT_TO_POINT)
567 {
571 }
572 else if (o->mode == MODE_SERVER)
573 {
577 push_option(o, print_str_int("ping", o->keepalive_ping, &o->gc), M_USAGE);
578 push_option(o, print_str_int("ping-restart", o->keepalive_timeout, &o->gc), M_USAGE);
579 }
580 else
581 {
582 ASSERT(0);
583 }
584 }
585}
586
587/*
588 *
589 * HELPER DIRECTIVE:
590 *
591 * tcp-nodelay
592 *
593 * EXPANDS TO:
594 *
595 * if mode server:
596 * socket-flags TCP_NODELAY
597 * push "socket-flags TCP_NODELAY"
598 */
599void
601{
603 {
604 if (o->mode == MODE_SERVER)
605 {
607 push_option(o, print_str("socket-flags TCP_NODELAY", &o->gc), M_USAGE);
608 }
609 else
610 {
612 }
613 }
614}
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
#define BSTR(buf)
Definition buffer.h:129
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
static struct gc_arena gc_new(void)
Definition buffer.h:1025
Interface functions to the internal and external multiplexers.
void helper_setdefault_topology(struct options *o)
Set –topology default depending on –mode.
Definition helper.c:144
static const char * print_opt_route_gateway_dhcp(struct gc_arena *gc)
Definition helper.c:59
void helper_tcp_nodelay(struct options *o)
Definition helper.c:600
static void verify_common_subnet(const char *opt, const in_addr_t a, const in_addr_t b, const in_addr_t subnet)
Definition helper.c:125
static void helper_add_route(const in_addr_t network, const in_addr_t netmask, struct options *o)
Definition helper.c:114
static const char * print_opt_route_gateway(const in_addr_t route_gateway, struct gc_arena *gc)
Definition helper.c:50
static const char * print_opt_route(const in_addr_t network, const in_addr_t netmask, struct gc_arena *gc)
Definition helper.c:67
static const char * print_str(const char *str, struct gc_arena *gc)
Definition helper.c:106
void helper_client_server(struct options *o)
Definition helper.c:172
void helper_keepalive(struct options *o)
Definition helper.c:541
static const char * print_str_int(const char *str, const int i, struct gc_arena *gc)
Definition helper.c:98
static const char * print_netmask(int netbits, struct gc_arena *gc)
Definition helper.c:39
static const char * print_opt_topology(const int topology, struct gc_arena *gc)
Definition helper.c:88
static SERVICE_STATUS status
Definition interactive.c:53
#define M_USAGE
Definition error.h:106
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
void rol_check_alloc(struct options *options)
Definition options.c:1712
const char * print_topology(const int topology)
Definition options.c:4855
#define MODE_POINT_TO_POINT
Definition options.h:258
#define SF_TCP_NODELAY_HELPER
Definition options.h:475
#define MODE_SERVER
Definition options.h:259
#define SF_NOPOOL
Definition options.h:474
#define PING_RESTART
Definition options.h:354
#define SF_NO_PUSH_ROUTE_GATEWAY
Definition options.h:476
bool ifconfig_pool_verify_range(const int msglevel, const in_addr_t start, const in_addr_t end)
Definition pool.c:121
#define IFCONFIG_POOL_MIN_NETBITS
Definition pool.h:33
#define DEV_TYPE_TAP
Definition proto.h:37
#define TOP_UNDEF
Definition proto.h:41
#define TOP_NET30
Definition proto.h:42
#define DEV_TYPE_TUN
Definition proto.h:36
#define TOP_P2P
Definition proto.h:43
#define TOP_SUBNET
Definition proto.h:44
void push_option(struct options *o, const char *opt, int msglevel)
Definition push.c:875
void add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask, const char *gateway, const char *metric)
Definition route.c:510
bool netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
Definition route.c:4108
static in_addr_t netbits_to_netmask(const int netbits)
Definition route.h:394
struct in6_addr add_in6_addr(struct in6_addr base, uint32_t add)
Definition socket.c:3025
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
Definition socket.c:2994
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Definition socket.c:2974
#define SF_TCP_NODELAY
Definition socket.h:222
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
const char * ifconfig_ipv6_remote
Definition options.h:325
in_addr_t push_ifconfig_constraint_network
Definition options.h:517
struct in6_addr server_network_ipv6
Definition options.h:471
in_addr_t server_network
Definition options.h:468
bool server_bridge_defined
Definition options.h:481
in_addr_t ifconfig_pool_netmask
Definition options.h:491
in_addr_t server_netmask
Definition options.h:469
bool server_bridge_proxy_dhcp
Definition options.h:479
const char * ifconfig_ipv6_local
Definition options.h:323
const char * dev_type
Definition options.h:317
bool ifconfig_pool_defined
Definition options.h:488
in_addr_t server_bridge_netmask
Definition options.h:483
in_addr_t ifconfig_pool_end
Definition options.h:490
int keepalive_timeout
Definition options.h:341
bool ifconfig_ipv6_pool_defined
Definition options.h:495
unsigned int server_flags
Definition options.h:477
bool server_defined
Definition options.h:467
const char * ifconfig_local
Definition options.h:321
const char * route_default_gateway
Definition options.h:427
int topology
Definition options.h:320
int mode
Definition options.h:260
bool tls_server
Definition options.h:591
bool client
Definition options.h:554
bool pull
Definition options.h:555
int ifconfig_ipv6_pool_netbits
Definition options.h:497
in_addr_t push_ifconfig_constraint_netmask
Definition options.h:518
bool tls_client
Definition options.h:592
int ping_rec_timeout_action
Definition options.h:355
struct gc_arena gc
Definition options.h:251
bool push_ifconfig_constraint_defined
Definition options.h:516
int ping_rec_timeout
Definition options.h:349
unsigned int sockflags
Definition options.h:422
int ping_send_timeout
Definition options.h:348
bool server_ipv6_defined
Definition options.h:470
int keepalive_ping
Definition options.h:340
in_addr_t server_bridge_pool_start
Definition options.h:484
const char * ifconfig_remote_netmask
Definition options.h:322
bool enable_c2c
Definition options.h:525
in_addr_t server_bridge_pool_end
Definition options.h:485
in_addr_t ifconfig_pool_start
Definition options.h:489
unsigned int server_netbits_ipv6
Definition options.h:472
in_addr_t server_bridge_ip
Definition options.h:482
const char * shared_secret_file
Definition options.h:568
const char * dev
Definition options.h:316
struct in6_addr ifconfig_ipv6_pool_base
Definition options.h:496
int ifconfig_ipv6_netbits
Definition options.h:324
struct gc_arena gc
Definition test_ssl.c:155
int dev_type_enum(const char *dev, const char *dev_type)
Definition tun.c:467