af7e57140f93c8e35393ac0a6a7136601da12c5f
[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 <errno.h>
20 #include <fcntl.h>
21 #include <netinet/in.h>
22 #include <string.h>
23 #include <sys/ioctl.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <net/if.h>
29
30 #ifdef __APPLE__
31 #include <net/if_utun.h>
32 #include <netinet/in_var.h>
33 #include <sys/kern_control.h>
34 #elif defined(__linux__)
35 #include <linux/if_tun.h>
36 #else
37 #include <net/if_tun.h>
38 #endif
39
40 #include "tun_device.h"
41
42 #include <library.h>
43 #include <utils/debug.h>
44 #include <threading/thread.h>
45
46 #define TUN_DEFAULT_MTU 1500
47
48 typedef struct private_tun_device_t private_tun_device_t;
49
50 struct private_tun_device_t {
51
52 /**
53 * Public interface
54 */
55 tun_device_t public;
56
57 /**
58 * The TUN device's file descriptor
59 */
60 int tunfd;
61
62 /**
63 * Name of the TUN device
64 */
65 char if_name[IFNAMSIZ];
66
67 /**
68 * Socket used for ioctl() to set interface addr, ...
69 */
70 int sock;
71
72 /**
73 * The current MTU
74 */
75 int mtu;
76
77 /**
78 * Associated address
79 */
80 host_t *address;
81
82 /**
83 * Netmask for address
84 */
85 u_int8_t netmask;
86 };
87
88 METHOD(tun_device_t, set_address, bool,
89 private_tun_device_t *this, host_t *addr, u_int8_t netmask)
90 {
91 struct ifreq ifr;
92 host_t *mask;
93
94 memset(&ifr, 0, sizeof(ifr));
95 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
96 memcpy(&ifr.ifr_addr, addr->get_sockaddr(addr),
97 *addr->get_sockaddr_len(addr));
98
99 if (ioctl(this->sock, SIOCSIFADDR, &ifr) < 0)
100 {
101 DBG1(DBG_LIB, "failed to set address on %s: %s",
102 this->if_name, strerror(errno));
103 return FALSE;
104 }
105 #ifdef __APPLE__
106 if (ioctl(this->sock, SIOCSIFDSTADDR, &ifr) < 0)
107 {
108 DBG1(DBG_LIB, "failed to set dest address on %s: %s",
109 this->if_name, strerror(errno));
110 return FALSE;
111 }
112 #endif /* __APPLE__ */
113
114 mask = host_create_netmask(addr->get_family(addr), netmask);
115 if (!mask)
116 {
117 DBG1(DBG_LIB, "invalid netmask: %d", netmask);
118 return FALSE;
119 }
120 memcpy(&ifr.ifr_addr, mask->get_sockaddr(mask),
121 *mask->get_sockaddr_len(mask));
122 mask->destroy(mask);
123
124 if (ioctl(this->sock, SIOCSIFNETMASK, &ifr) < 0)
125 {
126 DBG1(DBG_LIB, "failed to set netmask on %s: %s",
127 this->if_name, strerror(errno));
128 return FALSE;
129 }
130 this->address = addr->clone(addr);
131 this->netmask = netmask;
132 return TRUE;
133 }
134
135 METHOD(tun_device_t, get_address, host_t*,
136 private_tun_device_t *this, u_int8_t *netmask)
137 {
138 if (netmask && this->address)
139 {
140 *netmask = this->netmask;
141 }
142 return this->address;
143 }
144
145 METHOD(tun_device_t, up, bool,
146 private_tun_device_t *this)
147 {
148 struct ifreq ifr;
149
150 memset(&ifr, 0, sizeof(ifr));
151 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
152
153 if (ioctl(this->sock, SIOCGIFFLAGS, &ifr) < 0)
154 {
155 DBG1(DBG_LIB, "failed to get interface flags for %s: %s", this->if_name,
156 strerror(errno));
157 return FALSE;
158 }
159
160 ifr.ifr_flags |= IFF_RUNNING | IFF_UP;
161
162 if (ioctl(this->sock, SIOCSIFFLAGS, &ifr) < 0)
163 {
164 DBG1(DBG_LIB, "failed to set interface flags on %s: %s", this->if_name,
165 strerror(errno));
166 return FALSE;
167 }
168 return TRUE;
169 }
170
171 METHOD(tun_device_t, set_mtu, bool,
172 private_tun_device_t *this, int mtu)
173 {
174 struct ifreq ifr;
175
176 memset(&ifr, 0, sizeof(ifr));
177 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
178 ifr.ifr_mtu = mtu;
179
180 if (ioctl(this->sock, SIOCSIFMTU, &ifr) < 0)
181 {
182 DBG1(DBG_LIB, "failed to set MTU on %s: %s", this->if_name,
183 strerror(errno));
184 return FALSE;
185 }
186 this->mtu = mtu;
187 return TRUE;
188 }
189
190 METHOD(tun_device_t, get_mtu, int,
191 private_tun_device_t *this)
192 {
193 struct ifreq ifr;
194
195 if (this->mtu > 0)
196 {
197 return this->mtu;
198 }
199
200 memset(&ifr, 0, sizeof(ifr));
201 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
202 this->mtu = TUN_DEFAULT_MTU;
203
204 if (ioctl(this->sock, SIOCGIFMTU, &ifr) == 0)
205 {
206 this->mtu = ifr.ifr_mtu;
207 }
208 return this->mtu;
209 }
210
211 METHOD(tun_device_t, get_name, char*,
212 private_tun_device_t *this)
213 {
214 return this->if_name;
215 }
216
217 METHOD(tun_device_t, get_fd, int,
218 private_tun_device_t *this)
219 {
220 return this->tunfd;
221 }
222
223 METHOD(tun_device_t, write_packet, bool,
224 private_tun_device_t *this, chunk_t packet)
225 {
226 ssize_t s;
227
228 #ifdef __APPLE__
229 /* UTUN's expect the packets to be prepended by a 32-bit protocol number
230 * instead of parsing the packet again, we assume IPv4 for now */
231 u_int32_t proto = htonl(AF_INET);
232 packet = chunk_cata("cc", chunk_from_thing(proto), packet);
233 #endif
234 s = write(this->tunfd, packet.ptr, packet.len);
235 if (s < 0)
236 {
237 DBG1(DBG_LIB, "failed to write packet to TUN device %s: %s",
238 this->if_name, strerror(errno));
239 return FALSE;
240 }
241 else if (s != packet.len)
242 {
243 return FALSE;
244 }
245 return TRUE;
246 }
247
248 METHOD(tun_device_t, read_packet, bool,
249 private_tun_device_t *this, chunk_t *packet)
250 {
251 ssize_t len;
252 fd_set set;
253 bool old;
254
255 FD_ZERO(&set);
256 FD_SET(this->tunfd, &set);
257
258 old = thread_cancelability(TRUE);
259 len = select(this->tunfd + 1, &set, NULL, NULL, NULL);
260 thread_cancelability(old);
261
262 if (len < 0)
263 {
264 DBG1(DBG_LIB, "select on TUN device %s failed: %s", this->if_name,
265 strerror(errno));
266 return FALSE;
267 }
268 /* FIXME: this is quite expensive for lots of small packets, copy from
269 * local buffer instead? */
270 *packet = chunk_alloc(get_mtu(this));
271 len = read(this->tunfd, packet->ptr, packet->len);
272 if (len < 0)
273 {
274 DBG1(DBG_LIB, "reading from TUN device %s failed: %s", this->if_name,
275 strerror(errno));
276 chunk_free(packet);
277 return FALSE;
278 }
279 packet->len = len;
280 #ifdef __APPLE__
281 /* UTUN's prepend packets with a 32-bit protocol number */
282 packet->len -= sizeof(u_int32_t);
283 memmove(packet->ptr, packet->ptr + sizeof(u_int32_t), packet->len);
284 #endif
285 return TRUE;
286 }
287
288 METHOD(tun_device_t, destroy, void,
289 private_tun_device_t *this)
290 {
291 if (this->tunfd > 0)
292 {
293 close(this->tunfd);
294 #ifdef __FreeBSD__
295 /* tun(4) says the following: "These network interfaces persist until
296 * the if_tun.ko module is unloaded, or until removed with the
297 * ifconfig(8) command." So simply closing the FD is not enough. */
298 struct ifreq ifr;
299
300 memset(&ifr, 0, sizeof(ifr));
301 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
302 if (ioctl(this->sock, SIOCIFDESTROY, &ifr) < 0)
303 {
304 DBG1(DBG_LIB, "failed to destroy %s: %s", this->if_name,
305 strerror(errno));
306 }
307 #endif /* __FreeBSD__ */
308 }
309 if (this->sock > 0)
310 {
311 close(this->sock);
312 }
313 DESTROY_IF(this->address);
314 free(this);
315 }
316
317 /**
318 * Initialize the tun device
319 */
320 static bool init_tun(private_tun_device_t *this, const char *name_tmpl)
321 {
322 #ifdef __APPLE__
323
324 struct ctl_info info;
325 struct sockaddr_ctl addr;
326 socklen_t size = IFNAMSIZ;
327
328 memset(&info, 0, sizeof(info));
329 memset(&addr, 0, sizeof(addr));
330
331 this->tunfd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
332 if (this->tunfd < 0)
333 {
334 DBG1(DBG_LIB, "failed to open tundevice PF_SYSTEM socket: %s",
335 strerror(errno));
336 return FALSE;
337 }
338
339 /* get a control identifier for the utun kernel extension */
340 strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME));
341 if (ioctl(this->tunfd, CTLIOCGINFO, &info) < 0)
342 {
343 DBG1(DBG_LIB, "failed to ioctl tundevice: %s", strerror(errno));
344 close(this->tunfd);
345 return FALSE;
346 }
347
348 addr.sc_id = info.ctl_id;
349 addr.sc_len = sizeof(addr);
350 addr.sc_family = AF_SYSTEM;
351 addr.ss_sysaddr = AF_SYS_CONTROL;
352 /* allocate identifier dynamically */
353 addr.sc_unit = 0;
354
355 if (connect(this->tunfd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
356 {
357 DBG1(DBG_LIB, "failed to connect tundevice: %s", strerror(errno));
358 close(this->tunfd);
359 return FALSE;
360 }
361 if (getsockopt(this->tunfd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME,
362 this->if_name, &size) < 0)
363 {
364 DBG1(DBG_LIB, "getting tundevice name failed: %s", strerror(errno));
365 close(this->tunfd);
366 return FALSE;
367 }
368 return TRUE;
369
370 #elif defined(IFF_TUN)
371
372 struct ifreq ifr;
373
374 strncpy(this->if_name, name_tmpl ?: "tun%d", IFNAMSIZ);
375 this->if_name[IFNAMSIZ-1] = '\0';
376
377 this->tunfd = open("/dev/net/tun", O_RDWR);
378 if (this->tunfd < 0)
379 {
380 DBG1(DBG_LIB, "failed to open /dev/net/tun: %s", strerror(errno));
381 return FALSE;
382 }
383
384 memset(&ifr, 0, sizeof(ifr));
385
386 /* TUN device, no packet info */
387 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
388
389 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
390 if (ioctl(this->tunfd, TUNSETIFF, (void*)&ifr) < 0)
391 {
392 DBG1(DBG_LIB, "failed to configure TUN device: %s", strerror(errno));
393 close(this->tunfd);
394 return FALSE;
395 }
396 strncpy(this->if_name, ifr.ifr_name, IFNAMSIZ);
397 return TRUE;
398
399 #else /* !IFF_TUN */
400
401 /* this works on FreeBSD and might also work on Linux with older TUN
402 * driver versions (no IFF_TUN) */
403 char devname[IFNAMSIZ];
404 /* the same process is allowed to open a device again, but that's not what
405 * we want (unless we previously closed a device, which we don't know at
406 * this point). therefore, this counter is static so we don't accidentally
407 * open a device twice */
408 static int i = -1;
409
410 if (name_tmpl)
411 {
412 DBG1(DBG_LIB, "arbitrary naming of TUN devices is not supported");
413 }
414
415 for (; ++i < 256; )
416 {
417 snprintf(devname, IFNAMSIZ, "/dev/tun%d", i);
418 this->tunfd = open(devname, O_RDWR);
419 if (this->tunfd > 0)
420 { /* for ioctl(2) calls only the interface name is used */
421 snprintf(this->if_name, IFNAMSIZ, "tun%d", i);
422 break;
423 }
424 DBG1(DBG_LIB, "failed to open %s: %s", this->if_name, strerror(errno));
425 }
426 return this->tunfd > 0;
427
428 #endif /* !__APPLE__ */
429 }
430
431 /*
432 * Described in header
433 */
434 tun_device_t *tun_device_create(const char *name_tmpl)
435 {
436 private_tun_device_t *this;
437
438 INIT(this,
439 .public = {
440 .read_packet = _read_packet,
441 .write_packet = _write_packet,
442 .get_mtu = _get_mtu,
443 .set_mtu = _set_mtu,
444 .get_name = _get_name,
445 .get_fd = _get_fd,
446 .set_address = _set_address,
447 .get_address = _get_address,
448 .up = _up,
449 .destroy = _destroy,
450 },
451 .tunfd = -1,
452 .sock = -1,
453 );
454
455 if (!init_tun(this, name_tmpl))
456 {
457 free(this);
458 return NULL;
459 }
460 DBG1(DBG_LIB, "created TUN device: %s", this->if_name);
461
462 this->sock = socket(AF_INET, SOCK_DGRAM, 0);
463 if (this->sock < 0)
464 {
465 DBG1(DBG_LIB, "failed to open socket to configure TUN device");
466 destroy(this);
467 return NULL;
468 }
469 return &this->public;
470 }