· 5 years ago · May 23, 2020, 11:56 AM
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-2018 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#ifndef TUN_H
25#define TUN_H
26
27#ifdef _WIN32
28#include <winioctl.h>
29#include <tap-windows.h>
30#endif
31
32#include "buffer.h"
33#include "error.h"
34#include "mtu.h"
35#include "win32.h"
36#include "event.h"
37#include "proto.h"
38#include "misc.h"
39
40#if defined(_WIN32) || defined(TARGET_ANDROID)
41
42#define TUN_ADAPTER_INDEX_INVALID ((DWORD)-1)
43
44/* time constants for --ip-win32 adaptive */
45#define IPW32_SET_ADAPTIVE_DELAY_WINDOW 300
46#define IPW32_SET_ADAPTIVE_TRY_NETSH 20
47
48struct tuntap_options {
49 /* --ip-win32 options */
50 bool ip_win32_defined;
51
52#define IPW32_SET_MANUAL 0 /* "--ip-win32 manual" */
53#define IPW32_SET_NETSH 1 /* "--ip-win32 netsh" */
54#define IPW32_SET_IPAPI 2 /* "--ip-win32 ipapi" */
55#define IPW32_SET_DHCP_MASQ 3 /* "--ip-win32 dynamic" */
56#define IPW32_SET_ADAPTIVE 4 /* "--ip-win32 adaptive" */
57#define IPW32_SET_N 5
58 int ip_win32_type;
59
60#ifdef _WIN32
61 HANDLE msg_channel;
62#endif
63
64 /* --ip-win32 dynamic options */
65 bool dhcp_masq_custom_offset;
66 int dhcp_masq_offset;
67 int dhcp_lease_time;
68
69 /* --tap-sleep option */
70 int tap_sleep;
71
72 /* --dhcp-option options */
73
74 bool dhcp_options;
75
76 const char *domain; /* DOMAIN (15) */
77
78 const char *netbios_scope; /* NBS (47) */
79
80 int netbios_node_type; /* NBT 1,2,4,8 (46) */
81
82#define N_DHCP_ADDR 4 /* Max # of addresses allowed for
83 * DNS, WINS, etc. */
84
85 /* DNS (6) */
86 in_addr_t dns[N_DHCP_ADDR];
87 int dns_len;
88
89 /* WINS (44) */
90 in_addr_t wins[N_DHCP_ADDR];
91 int wins_len;
92
93 /* NTP (42) */
94 in_addr_t ntp[N_DHCP_ADDR];
95 int ntp_len;
96
97 /* NBDD (45) */
98 in_addr_t nbdd[N_DHCP_ADDR];
99 int nbdd_len;
100
101 /* DISABLE_NBT (43, Vendor option 001) */
102 bool disable_nbt;
103
104 bool dhcp_renew;
105 bool dhcp_pre_release;
106
107 bool register_dns;
108
109 struct in6_addr dns6[N_DHCP_ADDR];
110 int dns6_len;
111};
112
113#elif TARGET_LINUX
114
115struct tuntap_options {
116 int txqueuelen;
117};
118
119#else /* if defined(_WIN32) || defined(TARGET_ANDROID) */
120
121struct tuntap_options {
122 int dummy; /* not used */
123};
124
125#endif /* if defined(_WIN32) || defined(TARGET_ANDROID) */
126
127/*
128 * Define a TUN/TAP dev.
129 */
130
131struct tuntap
132{
133#define TUNNEL_TYPE(tt) ((tt) ? ((tt)->type) : DEV_TYPE_UNDEF)
134 int type; /* DEV_TYPE_x as defined in proto.h */
135
136#define TUNNEL_TOPOLOGY(tt) ((tt) ? ((tt)->topology) : TOP_UNDEF)
137 int topology; /* one of the TOP_x values */
138
139 bool did_ifconfig_setup;
140 bool did_ifconfig_ipv6_setup;
141 bool did_ifconfig;
142
143 bool persistent_if; /* if existed before, keep on program end */
144
145 struct tuntap_options options; /* options set on command line */
146
147 char *actual_name; /* actual name of TUN/TAP dev, usually including unit number */
148
149 /* number of TX buffers */
150 int txqueuelen;
151
152 /* ifconfig parameters */
153 in_addr_t local;
154 in_addr_t remote_netmask;
155 in_addr_t broadcast;
156
157 struct in6_addr local_ipv6;
158 struct in6_addr remote_ipv6;
159 int netbits_ipv6;
160
161#ifdef _WIN32
162 HANDLE hand;
163 struct overlapped_io reads;
164 struct overlapped_io writes;
165 struct rw_handle rw_handle;
166
167 /* used for setting interface address via IP Helper API
168 * or DHCP masquerade */
169 bool ipapi_context_defined;
170 ULONG ipapi_context;
171 ULONG ipapi_instance;
172 in_addr_t adapter_netmask;
173
174 /* Windows adapter index for TAP-Windows adapter,
175 * ~0 if undefined */
176 DWORD adapter_index;
177
178 int standby_iter;
179#else /* ifdef _WIN32 */
180 int fd; /* file descriptor for TUN/TAP dev */
181#endif
182
183#ifdef TARGET_SOLARIS
184 int ip_fd;
185#endif
186
187#ifdef HAVE_NET_IF_UTUN_H
188 bool is_utun;
189#endif
190 /* used for printing status info only */
191 unsigned int rwflags_debug;
192
193 /* Some TUN/TAP drivers like to be ioctled for mtu
194 * after open */
195 int post_open_mtu;
196};
197
198static inline bool
199tuntap_defined(const struct tuntap *tt)
200{
201#ifdef _WIN32
202 return tt && tt->hand != NULL;
203#else
204 return tt && tt->fd >= 0;
205#endif
206}
207
208/*
209 * Function prototypes
210 */
211
212void open_tun(const char *dev, const char *dev_type, const char *dev_node,
213 struct tuntap *tt);
214
215void close_tun(struct tuntap *tt);
216
217int write_tun(struct tuntap *tt, uint8_t *buf, int len);
218
219int read_tun(struct tuntap *tt, uint8_t *buf, int len);
220
221void tuncfg(const char *dev, const char *dev_type, const char *dev_node,
222 int persist_mode, const char *username,
223 const char *groupname, const struct tuntap_options *options);
224
225const char *guess_tuntap_dev(const char *dev,
226 const char *dev_type,
227 const char *dev_node,
228 struct gc_arena *gc);
229
230struct tuntap *init_tun(const char *dev, /* --dev option */
231 const char *dev_type, /* --dev-type option */
232 int topology, /* one of the TOP_x values */
233 const char *ifconfig_local_parm, /* --ifconfig parm 1 */
234 const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */
235 const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 / IPv6 */
236 int ifconfig_ipv6_netbits_parm, /* --ifconfig parm 1 / bits */
237 const char *ifconfig_ipv6_remote_parm, /* --ifconfig parm 2 / IPv6 */
238 struct addrinfo *local_public,
239 struct addrinfo *remote_public,
240 const bool strict_warn,
241 struct env_set *es);
242
243void init_tun_post(struct tuntap *tt,
244 const struct frame *frame,
245 const struct tuntap_options *options);
246
247void do_ifconfig_setenv(const struct tuntap *tt,
248 struct env_set *es);
249
250void do_ifconfig(struct tuntap *tt,
251 const char *actual, /* actual device name */
252 int tun_mtu,
253 const struct env_set *es);
254
255bool is_dev_type(const char *dev, const char *dev_type, const char *match_type);
256
257int dev_type_enum(const char *dev, const char *dev_type);
258
259const char *dev_type_string(const char *dev, const char *dev_type);
260
261const char *ifconfig_options_string(const struct tuntap *tt, bool remote, bool disable, struct gc_arena *gc);
262
263bool is_tun_p2p(const struct tuntap *tt);
264
265void check_subnet_conflict(const in_addr_t ip,
266 const in_addr_t netmask,
267 const char *prefix);
268
269void warn_on_use_of_common_subnets(void);
270
271/*
272 * Inline functions
273 */
274
275static inline void
276tun_adjust_frame_parameters(struct frame *frame, int size)
277{
278 frame_add_to_extra_tun(frame, size);
279}
280
281/*
282 * Should ifconfig be called before or after
283 * tun dev open?
284 */
285
286#define IFCONFIG_BEFORE_TUN_OPEN 0
287#define IFCONFIG_AFTER_TUN_OPEN 1
288
289#define IFCONFIG_DEFAULT IFCONFIG_AFTER_TUN_OPEN
290
291static inline int
292ifconfig_order(void)
293{
294#if defined(TARGET_LINUX)
295 return IFCONFIG_AFTER_TUN_OPEN;
296#elif defined(TARGET_SOLARIS)
297 return IFCONFIG_AFTER_TUN_OPEN;
298#elif defined(TARGET_OPENBSD)
299 return IFCONFIG_AFTER_TUN_OPEN;
300#elif defined(TARGET_DARWIN)
301 return IFCONFIG_AFTER_TUN_OPEN;
302#elif defined(TARGET_NETBSD)
303 return IFCONFIG_AFTER_TUN_OPEN;
304#elif defined(_WIN32)
305 return IFCONFIG_AFTER_TUN_OPEN;
306#elif defined(TARGET_ANDROID)
307 return IFCONFIG_BEFORE_TUN_OPEN;
308#else /* if defined(TARGET_LINUX) */
309 return IFCONFIG_DEFAULT;
310#endif
311}
312
313#define ROUTE_BEFORE_TUN 0
314#define ROUTE_AFTER_TUN 1
315#define ROUTE_ORDER_DEFAULT ROUTE_AFTER_TUN
316
317static inline int
318route_order(void)
319{
320#if defined(TARGET_ANDROID)
321 return ROUTE_BEFORE_TUN;
322#else
323 return ROUTE_ORDER_DEFAULT;
324#endif
325}
326
327
328#ifdef _WIN32
329
330#define TUN_PASS_BUFFER
331
332struct tap_reg
333{
334 const char *guid;
335 struct tap_reg *next;
336};
337
338struct panel_reg
339{
340 const char *name;
341 const char *guid;
342 struct panel_reg *next;
343};
344
345int ascii2ipset(const char *name);
346
347const char *ipset2ascii(int index);
348
349const char *ipset2ascii_all(struct gc_arena *gc);
350
351void verify_255_255_255_252(in_addr_t local, in_addr_t remote);
352
353const IP_ADAPTER_INFO *get_adapter_info_list(struct gc_arena *gc);
354
355const IP_ADAPTER_INFO *get_tun_adapter(const struct tuntap *tt, const IP_ADAPTER_INFO *list);
356
357const IP_ADAPTER_INFO *get_adapter_info(DWORD index, struct gc_arena *gc);
358
359const IP_PER_ADAPTER_INFO *get_per_adapter_info(const DWORD index, struct gc_arena *gc);
360
361const IP_ADAPTER_INFO *get_adapter(const IP_ADAPTER_INFO *ai, DWORD index);
362
363bool is_adapter_up(const struct tuntap *tt, const IP_ADAPTER_INFO *list);
364
365bool is_ip_in_adapter_subnet(const IP_ADAPTER_INFO *ai, const in_addr_t ip, in_addr_t *highest_netmask);
366
367DWORD adapter_index_of_ip(const IP_ADAPTER_INFO *list,
368 const in_addr_t ip,
369 int *count,
370 in_addr_t *netmask);
371
372void show_tap_win_adapters(int msglev, int warnlev);
373
374void show_adapters(int msglev);
375
376void tap_allow_nonadmin_access(const char *dev_node);
377
378void show_valid_win32_tun_subnets(void);
379
380const char *tap_win_getinfo(const struct tuntap *tt, struct gc_arena *gc);
381
382void tun_show_debug(struct tuntap *tt);
383
384bool dhcp_release_by_adapter_index(const DWORD adapter_index);
385
386bool dhcp_renew_by_adapter_index(const DWORD adapter_index);
387
388void fork_register_dns_action(struct tuntap *tt);
389
390void ipconfig_register_dns(const struct env_set *es);
391
392void tun_standby_init(struct tuntap *tt);
393
394bool tun_standby(struct tuntap *tt);
395
396int tun_read_queue(struct tuntap *tt, int maxsize);
397
398int tun_write_queue(struct tuntap *tt, struct buffer *buf);
399
400int tun_finalize(HANDLE h, struct overlapped_io *io, struct buffer *buf);
401
402static inline bool
403tuntap_stop(int status)
404{
405 /*
406 * This corresponds to the STATUS_NO_SUCH_DEVICE
407 * error in tapdrvr.c.
408 */
409 if (status < 0)
410 {
411 return openvpn_errno() == ERROR_FILE_NOT_FOUND;
412 }
413 return false;
414}
415
416static inline bool
417tuntap_abort(int status)
418{
419 /*
420 * Typically generated when driver is halted.
421 */
422 if (status < 0)
423 {
424 return openvpn_errno() == ERROR_OPERATION_ABORTED;
425 }
426 return false;
427}
428
429static inline int
430tun_write_win32(struct tuntap *tt, struct buffer *buf)
431{
432 int err = 0;
433 int status = 0;
434 if (overlapped_io_active(&tt->writes))
435 {
436 status = tun_finalize(tt->hand, &tt->writes, NULL);
437 if (status < 0)
438 {
439 err = GetLastError();
440 }
441 }
442 tun_write_queue(tt, buf);
443 if (status < 0)
444 {
445 SetLastError(err);
446 return status;
447 }
448 else
449 {
450 return BLEN(buf);
451 }
452}
453
454static inline int
455read_tun_buffered(struct tuntap *tt, struct buffer *buf)
456{
457 return tun_finalize(tt->hand, &tt->reads, buf);
458}
459
460static inline int
461write_tun_buffered(struct tuntap *tt, struct buffer *buf)
462{
463 return tun_write_win32(tt, buf);
464}
465
466#else /* ifdef _WIN32 */
467
468static inline bool
469tuntap_stop(int status)
470{
471 return false;
472}
473
474static inline bool
475tuntap_abort(int status)
476{
477 return false;
478}
479
480static inline void
481tun_standby_init(struct tuntap *tt)
482{
483}
484
485static inline bool
486tun_standby(struct tuntap *tt)
487{
488 return true;
489}
490
491#endif /* ifdef _WIN32 */
492
493/*
494 * TUN/TAP I/O wait functions
495 */
496
497static inline event_t
498tun_event_handle(const struct tuntap *tt)
499{
500#ifdef _WIN32
501 return &tt->rw_handle;
502#else
503 return tt->fd;
504#endif
505}
506
507static inline unsigned int
508tun_set(struct tuntap *tt,
509 struct event_set *es,
510 unsigned int rwflags,
511 void *arg,
512 unsigned int *persistent)
513{
514 if (tuntap_defined(tt))
515 {
516 /* if persistent is defined, call event_ctl only if rwflags has changed since last call */
517 if (!persistent || *persistent != rwflags)
518 {
519 event_ctl(es, tun_event_handle(tt), rwflags, arg);
520 if (persistent)
521 {
522 *persistent = rwflags;
523 }
524 }
525#ifdef _WIN32
526 if (rwflags & EVENT_READ)
527 {
528 tun_read_queue(tt, 0);
529 }
530#endif
531 tt->rwflags_debug = rwflags;
532 }
533 return rwflags;
534}
535
536const char *tun_stat(const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc);
537
538#endif /* TUN_H */