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-2025 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 o->route_default_table_id);
123}
124
125static void
126verify_common_subnet(const char *opt, const in_addr_t a, const in_addr_t b, const in_addr_t subnet)
127{
128 struct gc_arena gc = gc_new();
129 if ((a & subnet) != (b & subnet))
130 {
131 msg(M_USAGE, "%s IP addresses %s and %s are not in the same %s subnet",
132 opt,
133 print_in_addr_t(a, 0, &gc),
134 print_in_addr_t(b, 0, &gc),
135 print_in_addr_t(subnet, 0, &gc));
136 }
137 gc_free(&gc);
138}
139
140
144void
146{
147 if (o->topology != TOP_UNDEF)
148 {
149 return;
150 }
151 int dev = dev_type_enum(o->dev, o->dev_type);
152 if (dev != DEV_TYPE_TUN)
153 {
154 return;
155 }
156 if (o->mode == MODE_SERVER)
157 {
158 o->topology = TOP_SUBNET;
159 }
160 else
161 {
162 o->topology = TOP_NET30;
163 }
164}
165
166
167/*
168 * Process server, server-bridge, and client helper
169 * directives after the parameters themselves have been
170 * parsed and placed in struct options.
171 */
172void
174{
175 struct gc_arena gc = gc_new();
176
177 /*
178 * Get tun/tap/null device type
179 */
180 const int dev = dev_type_enum(o->dev, o->dev_type);
181
182 /*
183 *
184 * HELPER DIRECTIVE for IPv6
185 *
186 * server-ipv6 2001:db8::/64
187 *
188 * EXPANDS TO:
189 *
190 * tun-ipv6
191 * push "tun-ipv6"
192 * ifconfig-ipv6 2001:db8::1 2001:db8::2
193 * if !nopool:
194 * ifconfig-ipv6-pool 2001:db8::1000/64
195 *
196 */
197 if (o->server_ipv6_defined)
198 {
199 if (o->client)
200 {
201 msg(M_USAGE, "--server-ipv6 and --client cannot be used together");
202 }
203
204 if (o->server_flags & SF_NOPOOL)
205 {
206 msg(M_USAGE, "--server-ipv6 is incompatible with 'nopool' option");
207 }
209 {
210 msg(M_USAGE, "--server-ipv6 already defines an ifconfig-ipv6-pool, so you can't also specify --ifconfig-pool explicitly");
211 }
212
213 o->mode = MODE_SERVER;
214 o->tls_server = true;
215
216 /* local ifconfig is "base address + 1" and "+2" */
222
223 /* basic sanity check */
224 ASSERT(o->server_netbits_ipv6 >= 64 && o->server_netbits_ipv6 <= 124);
225
227 /* For large enough pools we keep the original behaviour of adding
228 * 0x1000 when computing the base.
229 *
230 * Smaller pools can't get that far, therefore we just increase by 2
231 */
233 o->server_netbits_ipv6 < 112 ? 0x1000 : 2);
235
236 push_option(o, "tun-ipv6", M_USAGE);
237 }
238
239 /*
240 *
241 * HELPER DIRECTIVE:
242 *
243 * server 10.8.0.0 255.255.255.0
244 *
245 * EXPANDS TO:
246 *
247 * mode server
248 * tls-server
249 * push "topology [topology]"
250 *
251 * if tun AND (topology == net30 OR topology == p2p):
252 * ifconfig 10.8.0.1 10.8.0.2
253 * if !nopool:
254 * ifconfig-pool 10.8.0.4 10.8.0.251
255 * route 10.8.0.0 255.255.255.0
256 * if client-to-client:
257 * push "route 10.8.0.0 255.255.255.0"
258 * else if topology == net30:
259 * push "route 10.8.0.1"
260 *
261 * if tap OR (tun AND topology == subnet):
262 * ifconfig 10.8.0.1 255.255.255.0
263 * if !nopool:
264 * ifconfig-pool 10.8.0.2 10.8.0.254 255.255.255.0
265 * push "route-gateway 10.8.0.1"
266 * if route-gateway unset:
267 * route-gateway 10.8.0.2
268 */
269
270 if (o->server_defined)
271 {
272 int netbits = -2;
273 bool status = false;
274
275 if (o->client)
276 {
277 msg(M_USAGE, "--server and --client cannot be used together");
278 }
279
281 {
282 msg(M_USAGE, "--server and --server-bridge cannot be used together");
283 }
284
285 if (o->shared_secret_file)
286 {
287 msg(M_USAGE, "--server and --secret cannot be used together (you must use SSL/TLS keys)");
288 }
289
291 {
292 msg(M_USAGE, "--server already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");
293 }
294
295 if (!(dev == DEV_TYPE_TAP || dev == DEV_TYPE_TUN))
296 {
297 msg(M_USAGE, "--server directive only makes sense with --dev tun or --dev tap");
298 }
299
301 if (!status)
302 {
303 msg(M_USAGE, "--server directive network/netmask combination is invalid");
304 }
305
306 if (netbits < 0)
307 {
308 msg(M_USAGE, "--server directive netmask is invalid");
309 }
310
311 if (netbits < IFCONFIG_POOL_MIN_NETBITS)
312 {
313 msg(M_USAGE, "--server directive netmask allows for too many host addresses (subnet must be %s or higher)",
315 }
316
317 if (dev == DEV_TYPE_TUN)
318 {
319 int pool_end_reserve = 4;
320
321 if (netbits > 29)
322 {
323 msg(M_USAGE, "--server directive when used with --dev tun must define a subnet of %s or lower",
324 print_netmask(29, &gc));
325 }
326
327 if (netbits == 29)
328 {
329 pool_end_reserve = 0;
330 }
331
332 o->mode = MODE_SERVER;
333 o->tls_server = true;
334 /* Need to know topology now */
336
337 if (o->topology == TOP_NET30 || o->topology == TOP_P2P)
338 {
339 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
341
342 if (!(o->server_flags & SF_NOPOOL))
343 {
344 o->ifconfig_pool_defined = true;
346 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - pool_end_reserve;
348 }
349
351 if (o->enable_c2c)
352 {
354 }
355 else if (o->topology == TOP_NET30)
356 {
358 }
359 }
360 else if (o->topology == TOP_SUBNET)
361 {
362 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
364
365 if (!(o->server_flags & SF_NOPOOL))
366 {
367 o->ifconfig_pool_defined = true;
369 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
371 }
373
375 if (!o->route_default_gateway)
376 {
378 }
379 }
380 else
381 {
382 ASSERT(0);
383 }
384
386
387 if (o->topology == TOP_NET30 && !(o->server_flags & SF_NOPOOL))
388 {
389 msg(M_WARN, "WARNING: --topology net30 support for server "
390 "configs with IPv4 pools will be removed in a future "
391 "release. Please migrate to --topology subnet as soon "
392 "as possible.");
393 }
394 }
395 else if (dev == DEV_TYPE_TAP)
396 {
397 if (netbits > 30)
398 {
399 msg(M_USAGE, "--server directive when used with --dev tap must define a subnet of %s or lower",
400 print_netmask(30, &gc));
401 }
402
403 o->mode = MODE_SERVER;
404 o->tls_server = true;
405 o->ifconfig_local = print_in_addr_t(o->server_network + 1, 0, &o->gc);
407
408 if (!(o->server_flags & SF_NOPOOL))
409 {
410 o->ifconfig_pool_defined = true;
412 o->ifconfig_pool_end = (o->server_network | ~o->server_netmask) - 1;
414 }
416
418 }
419 else
420 {
421 ASSERT(0);
422 }
423
424 /* set push-ifconfig-constraint directive */
425 if ((dev == DEV_TYPE_TAP || o->topology == TOP_SUBNET))
426 {
430 }
431 }
432
433 /*
434 * HELPER DIRECTIVE:
435 *
436 * server-bridge 10.8.0.4 255.255.255.0 10.8.0.128 10.8.0.254
437 *
438 * EXPANDS TO:
439 *
440 * mode server
441 * tls-server
442 *
443 * ifconfig-pool 10.8.0.128 10.8.0.254 255.255.255.0
444 * push "route-gateway 10.8.0.4"
445 *
446 * OR
447 *
448 * server-bridge
449 *
450 * EXPANDS TO:
451 *
452 * mode server
453 * tls-server
454 *
455 * if !nogw:
456 * push "route-gateway dhcp"
457 */
459 {
460 if (o->client)
461 {
462 msg(M_USAGE, "--server-bridge and --client cannot be used together");
463 }
464
466 {
467 msg(M_USAGE, "--server-bridge already defines an ifconfig-pool, so you can't also specify --ifconfig-pool explicitly");
468 }
469
470 if (o->shared_secret_file)
471 {
472 msg(M_USAGE, "--server-bridge and --secret cannot be used together (you must use SSL/TLS keys)");
473 }
474
475 if (dev != DEV_TYPE_TAP)
476 {
477 msg(M_USAGE, "--server-bridge directive only makes sense with --dev tap");
478 }
479
481 {
485 }
486
487 o->mode = MODE_SERVER;
488 o->tls_server = true;
489
491 {
492 o->ifconfig_pool_defined = true;
498 }
500 {
502 }
503 }
504
505 /*
506 * HELPER DIRECTIVE:
507 *
508 * client
509 *
510 * EXPANDS TO:
511 *
512 * pull
513 * tls-client
514 */
515 else if (o->client)
516 {
517 o->pull = true;
518 o->tls_client = true;
519 }
520
521 gc_free(&gc);
522}
523
524/*
525 *
526 * HELPER DIRECTIVE:
527 *
528 * keepalive 10 60
529 *
530 * EXPANDS TO:
531 *
532 * if mode server:
533 * ping 10
534 * ping-restart 120
535 * push "ping 10"
536 * push "ping-restart 60"
537 * else
538 * ping 10
539 * ping-restart 60
540 */
541void
543{
545 {
546 /*
547 * Sanity checks.
548 */
549 if (o->keepalive_ping <= 0 || o->keepalive_timeout <= 0)
550 {
551 msg(M_USAGE, "--keepalive parameters must be > 0");
552 }
553 if (o->keepalive_ping * 2 > o->keepalive_timeout)
554 {
555 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.",
557 o->keepalive_ping);
558 }
560 {
561 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.");
562 }
563
564 /*
565 * Expand.
566 */
567 if (o->mode == MODE_POINT_TO_POINT)
568 {
572 }
573 else if (o->mode == MODE_SERVER)
574 {
578 push_option(o, print_str_int("ping", o->keepalive_ping, &o->gc), M_USAGE);
579 push_option(o, print_str_int("ping-restart", o->keepalive_timeout, &o->gc), M_USAGE);
580 }
581 else
582 {
583 ASSERT(0);
584 }
585 }
586}
587
588/*
589 *
590 * HELPER DIRECTIVE:
591 *
592 * tcp-nodelay
593 *
594 * EXPANDS TO:
595 *
596 * if mode server:
597 * socket-flags TCP_NODELAY
598 * push "socket-flags TCP_NODELAY"
599 */
600void
602{
604 {
605 if (o->mode == MODE_SERVER)
606 {
608 push_option(o, print_str("socket-flags TCP_NODELAY", &o->gc), M_USAGE);
609 }
610 else
611 {
613 }
614 }
615}
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:145
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:601
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:126
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:173
void helper_keepalive(struct options *o)
Definition helper.c:542
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:52
#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:1570
const char * print_topology(const int topology)
Definition options.c:4801
#define MODE_POINT_TO_POINT
Definition options.h:259
#define SF_TCP_NODELAY_HELPER
Definition options.h:477
#define MODE_SERVER
Definition options.h:260
#define SF_NOPOOL
Definition options.h:476
#define PING_RESTART
Definition options.h:355
#define SF_NO_PUSH_ROUTE_GATEWAY
Definition options.h:478
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:885
bool netmask_to_netbits(const in_addr_t network, const in_addr_t netmask, int *netbits)
Definition route.c:4117
void add_route_to_option_list(struct route_option_list *l, const char *network, const char *netmask, const char *gateway, const char *metric, int table_id)
Definition route.c:514
static in_addr_t netbits_to_netmask(const int netbits)
Definition route.h:401
struct in6_addr add_in6_addr(struct in6_addr base, uint32_t add)
Definition socket.c:3054
const char * print_in6_addr(struct in6_addr a6, unsigned int flags, struct gc_arena *gc)
Definition socket.c:3027
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Definition socket.c:3007
#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:326
in_addr_t push_ifconfig_constraint_network
Definition options.h:520
struct in6_addr server_network_ipv6
Definition options.h:473
in_addr_t server_network
Definition options.h:470
bool server_bridge_defined
Definition options.h:483
in_addr_t ifconfig_pool_netmask
Definition options.h:493
in_addr_t server_netmask
Definition options.h:471
bool server_bridge_proxy_dhcp
Definition options.h:481
const char * ifconfig_ipv6_local
Definition options.h:324
const char * dev_type
Definition options.h:318
bool ifconfig_pool_defined
Definition options.h:490
in_addr_t server_bridge_netmask
Definition options.h:485
in_addr_t ifconfig_pool_end
Definition options.h:492
int keepalive_timeout
Definition options.h:342
bool ifconfig_ipv6_pool_defined
Definition options.h:497
unsigned int server_flags
Definition options.h:479
bool server_defined
Definition options.h:469
const char * ifconfig_local
Definition options.h:322
const char * route_default_gateway
Definition options.h:428
int topology
Definition options.h:321
int mode
Definition options.h:261
bool tls_server
Definition options.h:594
bool client
Definition options.h:557
bool pull
Definition options.h:558
int ifconfig_ipv6_pool_netbits
Definition options.h:499
in_addr_t push_ifconfig_constraint_netmask
Definition options.h:521
bool tls_client
Definition options.h:595
int ping_rec_timeout_action
Definition options.h:356
struct gc_arena gc
Definition options.h:252
bool push_ifconfig_constraint_defined
Definition options.h:519
int ping_rec_timeout
Definition options.h:350
unsigned int sockflags
Definition options.h:423
int ping_send_timeout
Definition options.h:349
bool server_ipv6_defined
Definition options.h:472
int keepalive_ping
Definition options.h:341
in_addr_t server_bridge_pool_start
Definition options.h:486
const char * ifconfig_remote_netmask
Definition options.h:323
bool enable_c2c
Definition options.h:528
in_addr_t server_bridge_pool_end
Definition options.h:487
in_addr_t ifconfig_pool_start
Definition options.h:491
unsigned int server_netbits_ipv6
Definition options.h:474
in_addr_t server_bridge_ip
Definition options.h:484
const char * shared_secret_file
Definition options.h:571
const char * dev
Definition options.h:317
struct in6_addr ifconfig_ipv6_pool_base
Definition options.h:498
int ifconfig_ipv6_netbits
Definition options.h:325
struct gc_arena gc
Definition test_ssl.c:155
int dev_type_enum(const char *dev, const char *dev_type)
Definition tun.c:547