openssl: OpenSSL 1.1.0 is thread-safe so we don't have to setup callbacks
[strongswan.git] / src / libstrongswan / networking / tun_device.c
1 /*
2 * Copyright (C) 2012 Tobias Brunner
3 * Copyright (C) 2012 Giuliano Grassi
4 * Copyright (C) 2012 Ralf Sager
5 * Hochschule fuer Technik Rapperswil
6 * Copyright (C) 2012 Martin Willi
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include "tun_device.h"
20
21 #include <utils/debug.h>
22 #include <threading/thread.h>
23
24 #if !defined(__APPLE__) && !defined(__linux__) && !defined(HAVE_NET_IF_TUN_H)
25
26 tun_device_t *tun_device_create(const char *name_tmpl)
27 {
28 DBG1(DBG_LIB, "TUN devices are not supported");
29 return NULL;
30 }
31
32 #else /* TUN devices supported */
33
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <netinet/in.h>
37 #include <string.h>
38 #include <sys/ioctl.h>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <sys/stat.h>
42 #include <unistd.h>
43 #include <net/if.h>
44
45 #ifdef __APPLE__
46 #include <net/if_utun.h>
47 #include <netinet/in_var.h>
48 #include <sys/kern_control.h>
49 #elif defined(__linux__)
50 #include <linux/types.h>
51 #include <linux/if_tun.h>
52 #elif __FreeBSD__ >= 10
53 #include <net/if_tun.h>
54 #include <net/if_var.h>
55 #include <netinet/in_var.h>
56 #else
57 #include <net/if_tun.h>
58 #endif
59
60 #define TUN_DEFAULT_MTU 1500
61
62 typedef struct private_tun_device_t private_tun_device_t;
63
64 struct private_tun_device_t {
65
66 /**
67 * Public interface
68 */
69 tun_device_t public;
70
71 /**
72 * The TUN device's file descriptor
73 */
74 int tunfd;
75
76 /**
77 * Name of the TUN device
78 */
79 char if_name[IFNAMSIZ];
80
81 /**
82 * Socket used for ioctl() to set interface addr, ...
83 */
84 int sock;
85
86 /**
87 * The current MTU
88 */
89 int mtu;
90
91 /**
92 * Associated address
93 */
94 host_t *address;
95
96 /**
97 * Netmask for address
98 */
99 uint8_t netmask;
100 };
101
102 /**
103 * FreeBSD 10 deprecated the SIOCSIFADDR etc. commands.
104 */
105 #if __FreeBSD__ >= 10
106
107 static bool set_address_and_mask(struct in_aliasreq *ifra, host_t *addr,
108 uint8_t netmask)
109 {
110 host_t *mask;
111
112 memcpy(&ifra->ifra_addr, addr->get_sockaddr(addr),
113 *addr->get_sockaddr_len(addr));
114 /* set the same address as destination address */
115 memcpy(&ifra->ifra_dstaddr, addr->get_sockaddr(addr),
116 *addr->get_sockaddr_len(addr));
117
118 mask = host_create_netmask(addr->get_family(addr), netmask);
119 if (!mask)
120 {
121 DBG1(DBG_LIB, "invalid netmask: %d", netmask);
122 return FALSE;
123 }
124 memcpy(&ifra->ifra_mask, mask->get_sockaddr(mask),
125 *mask->get_sockaddr_len(mask));
126 mask->destroy(mask);
127 return TRUE;
128 }
129
130 /**
131 * Set the address using the more flexible SIOCAIFADDR/SIOCDIFADDR commands
132 * on FreeBSD 10 an newer.
133 */
134 static bool set_address_impl(private_tun_device_t *this, host_t *addr,
135 uint8_t netmask)
136 {
137 struct in_aliasreq ifra;
138
139 memset(&ifra, 0, sizeof(ifra));
140 strncpy(ifra.ifra_name, this->if_name, IFNAMSIZ);
141
142 if (this->address)
143 { /* remove the existing address first */
144 if (!set_address_and_mask(&ifra, this->address, this->netmask))
145 {
146 return FALSE;
147 }
148 if (ioctl(this->sock, SIOCDIFADDR, &ifra) < 0)
149 {
150 DBG1(DBG_LIB, "failed to remove existing address on %s: %s",
151 this->if_name, strerror(errno));
152 return FALSE;
153 }
154 }
155 if (!set_address_and_mask(&ifra, addr, netmask))
156 {
157 return FALSE;
158 }
159 if (ioctl(this->sock, SIOCAIFADDR, &ifra) < 0)
160 {
161 DBG1(DBG_LIB, "failed to add address on %s: %s",
162 this->if_name, strerror(errno));
163 return FALSE;
164 }
165 return TRUE;
166 }
167
168 #else /* __FreeBSD__ */
169
170 /**
171 * Set the address using the classic SIOCSIFADDR etc. commands on other systems.
172 */
173 static bool set_address_impl(private_tun_device_t *this, host_t *addr,
174 uint8_t netmask)
175 {
176 struct ifreq ifr;
177 host_t *mask;
178
179 memset(&ifr, 0, sizeof(ifr));
180 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
181 memcpy(&ifr.ifr_addr, addr->get_sockaddr(addr),
182 *addr->get_sockaddr_len(addr));
183
184 if (ioctl(this->sock, SIOCSIFADDR, &ifr) < 0)
185 {
186 DBG1(DBG_LIB, "failed to set address on %s: %s",
187 this->if_name, strerror(errno));
188 return FALSE;
189 }
190 #ifdef __APPLE__
191 if (ioctl(this->sock, SIOCSIFDSTADDR, &ifr) < 0)
192 {
193 DBG1(DBG_LIB, "failed to set dest address on %s: %s",
194 this->if_name, strerror(errno));
195 return FALSE;
196 }
197 #endif /* __APPLE__ */
198
199 mask = host_create_netmask(addr->get_family(addr), netmask);
200 if (!mask)
201 {
202 DBG1(DBG_LIB, "invalid netmask: %d", netmask);
203 return FALSE;
204 }
205 memcpy(&ifr.ifr_addr, mask->get_sockaddr(mask),
206 *mask->get_sockaddr_len(mask));
207 mask->destroy(mask);
208
209 if (ioctl(this->sock, SIOCSIFNETMASK, &ifr) < 0)
210 {
211 DBG1(DBG_LIB, "failed to set netmask on %s: %s",
212 this->if_name, strerror(errno));
213 return FALSE;
214 }
215 return TRUE;
216 }
217
218 #endif /* __FreeBSD__ */
219
220 METHOD(tun_device_t, set_address, bool,
221 private_tun_device_t *this, host_t *addr, uint8_t netmask)
222 {
223 if (!set_address_impl(this, addr, netmask))
224 {
225 return FALSE;
226 }
227 DESTROY_IF(this->address);
228 this->address = addr->clone(addr);
229 this->netmask = netmask;
230 return TRUE;
231 }
232
233 METHOD(tun_device_t, get_address, host_t*,
234 private_tun_device_t *this, uint8_t *netmask)
235 {
236 if (netmask && this->address)
237 {
238 *netmask = this->netmask;
239 }
240 return this->address;
241 }
242
243 METHOD(tun_device_t, up, bool,
244 private_tun_device_t *this)
245 {
246 struct ifreq ifr;
247
248 memset(&ifr, 0, sizeof(ifr));
249 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
250
251 if (ioctl(this->sock, SIOCGIFFLAGS, &ifr) < 0)
252 {
253 DBG1(DBG_LIB, "failed to get interface flags for %s: %s", this->if_name,
254 strerror(errno));
255 return FALSE;
256 }
257
258 ifr.ifr_flags |= IFF_RUNNING | IFF_UP;
259
260 if (ioctl(this->sock, SIOCSIFFLAGS, &ifr) < 0)
261 {
262 DBG1(DBG_LIB, "failed to set interface flags on %s: %s", this->if_name,
263 strerror(errno));
264 return FALSE;
265 }
266 return TRUE;
267 }
268
269 METHOD(tun_device_t, set_mtu, bool,
270 private_tun_device_t *this, int mtu)
271 {
272 struct ifreq ifr;
273
274 memset(&ifr, 0, sizeof(ifr));
275 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
276 ifr.ifr_mtu = mtu;
277
278 if (ioctl(this->sock, SIOCSIFMTU, &ifr) < 0)
279 {
280 DBG1(DBG_LIB, "failed to set MTU on %s: %s", this->if_name,
281 strerror(errno));
282 return FALSE;
283 }
284 this->mtu = mtu;
285 return TRUE;
286 }
287
288 METHOD(tun_device_t, get_mtu, int,
289 private_tun_device_t *this)
290 {
291 struct ifreq ifr;
292
293 if (this->mtu > 0)
294 {
295 return this->mtu;
296 }
297
298 memset(&ifr, 0, sizeof(ifr));
299 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
300 this->mtu = TUN_DEFAULT_MTU;
301
302 if (ioctl(this->sock, SIOCGIFMTU, &ifr) == 0)
303 {
304 this->mtu = ifr.ifr_mtu;
305 }
306 return this->mtu;
307 }
308
309 METHOD(tun_device_t, get_name, char*,
310 private_tun_device_t *this)
311 {
312 return this->if_name;
313 }
314
315 METHOD(tun_device_t, get_fd, int,
316 private_tun_device_t *this)
317 {
318 return this->tunfd;
319 }
320
321 METHOD(tun_device_t, write_packet, bool,
322 private_tun_device_t *this, chunk_t packet)
323 {
324 ssize_t s;
325
326 #ifdef __APPLE__
327 /* UTUN's expect the packets to be prepended by a 32-bit protocol number
328 * instead of parsing the packet again, we assume IPv4 for now */
329 uint32_t proto = htonl(AF_INET);
330 packet = chunk_cata("cc", chunk_from_thing(proto), packet);
331 #endif
332 s = write(this->tunfd, packet.ptr, packet.len);
333 if (s < 0)
334 {
335 DBG1(DBG_LIB, "failed to write packet to TUN device %s: %s",
336 this->if_name, strerror(errno));
337 return FALSE;
338 }
339 else if (s != packet.len)
340 {
341 return FALSE;
342 }
343 return TRUE;
344 }
345
346 METHOD(tun_device_t, read_packet, bool,
347 private_tun_device_t *this, chunk_t *packet)
348 {
349 chunk_t data;
350 ssize_t len;
351 bool old;
352
353 data = chunk_alloca(get_mtu(this));
354
355 old = thread_cancelability(TRUE);
356 len = read(this->tunfd, data.ptr, data.len);
357 thread_cancelability(old);
358 if (len < 0)
359 {
360 DBG1(DBG_LIB, "reading from TUN device %s failed: %s", this->if_name,
361 strerror(errno));
362 return FALSE;
363 }
364 data.len = len;
365 #ifdef __APPLE__
366 /* UTUN's prepend packets with a 32-bit protocol number */
367 data = chunk_skip(data, sizeof(uint32_t));
368 #endif
369 *packet = chunk_clone(data);
370 return TRUE;
371 }
372
373 METHOD(tun_device_t, destroy, void,
374 private_tun_device_t *this)
375 {
376 if (this->tunfd > 0)
377 {
378 close(this->tunfd);
379 #ifdef __FreeBSD__
380 /* tun(4) says the following: "These network interfaces persist until
381 * the if_tun.ko module is unloaded, or until removed with the
382 * ifconfig(8) command." So simply closing the FD is not enough. */
383 struct ifreq ifr;
384
385 memset(&ifr, 0, sizeof(ifr));
386 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
387 if (ioctl(this->sock, SIOCIFDESTROY, &ifr) < 0)
388 {
389 DBG1(DBG_LIB, "failed to destroy %s: %s", this->if_name,
390 strerror(errno));
391 }
392 #endif /* __FreeBSD__ */
393 }
394 if (this->sock > 0)
395 {
396 close(this->sock);
397 }
398 DESTROY_IF(this->address);
399 free(this);
400 }
401
402 /**
403 * Initialize the tun device
404 */
405 static bool init_tun(private_tun_device_t *this, const char *name_tmpl)
406 {
407 #ifdef __APPLE__
408
409 struct ctl_info info;
410 struct sockaddr_ctl addr;
411 socklen_t size = IFNAMSIZ;
412
413 memset(&info, 0, sizeof(info));
414 memset(&addr, 0, sizeof(addr));
415
416 this->tunfd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
417 if (this->tunfd < 0)
418 {
419 DBG1(DBG_LIB, "failed to open tundevice PF_SYSTEM socket: %s",
420 strerror(errno));
421 return FALSE;
422 }
423
424 /* get a control identifier for the utun kernel extension */
425 strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME));
426 if (ioctl(this->tunfd, CTLIOCGINFO, &info) < 0)
427 {
428 DBG1(DBG_LIB, "failed to ioctl tundevice: %s", strerror(errno));
429 close(this->tunfd);
430 return FALSE;
431 }
432
433 addr.sc_id = info.ctl_id;
434 addr.sc_len = sizeof(addr);
435 addr.sc_family = AF_SYSTEM;
436 addr.ss_sysaddr = AF_SYS_CONTROL;
437 /* allocate identifier dynamically */
438 addr.sc_unit = 0;
439
440 if (connect(this->tunfd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
441 {
442 DBG1(DBG_LIB, "failed to connect tundevice: %s", strerror(errno));
443 close(this->tunfd);
444 return FALSE;
445 }
446 if (getsockopt(this->tunfd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME,
447 this->if_name, &size) < 0)
448 {
449 DBG1(DBG_LIB, "getting tundevice name failed: %s", strerror(errno));
450 close(this->tunfd);
451 return FALSE;
452 }
453 return TRUE;
454
455 #elif defined(IFF_TUN)
456
457 struct ifreq ifr;
458
459 strncpy(this->if_name, name_tmpl ?: "tun%d", IFNAMSIZ);
460 this->if_name[IFNAMSIZ-1] = '\0';
461
462 this->tunfd = open("/dev/net/tun", O_RDWR);
463 if (this->tunfd < 0)
464 {
465 DBG1(DBG_LIB, "failed to open /dev/net/tun: %s", strerror(errno));
466 return FALSE;
467 }
468
469 memset(&ifr, 0, sizeof(ifr));
470
471 /* TUN device, no packet info */
472 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
473
474 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
475 if (ioctl(this->tunfd, TUNSETIFF, (void*)&ifr) < 0)
476 {
477 DBG1(DBG_LIB, "failed to configure TUN device: %s", strerror(errno));
478 close(this->tunfd);
479 return FALSE;
480 }
481 strncpy(this->if_name, ifr.ifr_name, IFNAMSIZ);
482 return TRUE;
483
484 #else /* !IFF_TUN */
485
486 /* this works on FreeBSD and might also work on Linux with older TUN
487 * driver versions (no IFF_TUN) */
488 char devname[IFNAMSIZ];
489 /* the same process is allowed to open a device again, but that's not what
490 * we want (unless we previously closed a device, which we don't know at
491 * this point). therefore, this counter is static so we don't accidentally
492 * open a device twice */
493 static int i = -1;
494
495 if (name_tmpl)
496 {
497 DBG1(DBG_LIB, "arbitrary naming of TUN devices is not supported");
498 }
499
500 for (; ++i < 256; )
501 {
502 snprintf(devname, IFNAMSIZ, "/dev/tun%d", i);
503 this->tunfd = open(devname, O_RDWR);
504 if (this->tunfd > 0)
505 { /* for ioctl(2) calls only the interface name is used */
506 snprintf(this->if_name, IFNAMSIZ, "tun%d", i);
507 break;
508 }
509 DBG1(DBG_LIB, "failed to open %s: %s", this->if_name, strerror(errno));
510 }
511 return this->tunfd > 0;
512
513 #endif /* !__APPLE__ */
514 }
515
516 /*
517 * Described in header
518 */
519 tun_device_t *tun_device_create(const char *name_tmpl)
520 {
521 private_tun_device_t *this;
522
523 INIT(this,
524 .public = {
525 .read_packet = _read_packet,
526 .write_packet = _write_packet,
527 .get_mtu = _get_mtu,
528 .set_mtu = _set_mtu,
529 .get_name = _get_name,
530 .get_fd = _get_fd,
531 .set_address = _set_address,
532 .get_address = _get_address,
533 .up = _up,
534 .destroy = _destroy,
535 },
536 .tunfd = -1,
537 .sock = -1,
538 );
539
540 if (!init_tun(this, name_tmpl))
541 {
542 free(this);
543 return NULL;
544 }
545 DBG1(DBG_LIB, "created TUN device: %s", this->if_name);
546
547 this->sock = socket(AF_INET, SOCK_DGRAM, 0);
548 if (this->sock < 0)
549 {
550 DBG1(DBG_LIB, "failed to open socket to configure TUN device");
551 destroy(this);
552 return NULL;
553 }
554 return &this->public;
555 }
556
557 #endif /* TUN devices supported */