53d1f2653099671e0c827de755efe62a77c1d353
[strongswan.git] / src / libstrongswan / utils / 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
29 #ifdef __APPLE__
30 #include <net/if.h>
31 #include <net/if_utun.h>
32 #include <netinet/in_var.h>
33 #include <sys/kern_control.h>
34 #else /* !__APPLE__ */
35 #include <linux/if.h>
36 #include <linux/if_tun.h>
37 #endif /* !__APPLE__ */
38
39 #include "tun_device.h"
40
41 #include <library.h>
42 #include <debug.h>
43 #include <threading/thread.h>
44
45 #define TUN_DEFAULT_MTU 1500
46
47 typedef struct private_tun_device_t private_tun_device_t;
48
49 struct private_tun_device_t {
50
51 /**
52 * Public interface
53 */
54 tun_device_t public;
55
56 /**
57 * The TUN device's file descriptor
58 */
59 int tunfd;
60
61 /**
62 * Name of the TUN device
63 */
64 char if_name[IFNAMSIZ];
65
66 /**
67 * Socket used for ioctl() to set interface addr, ...
68 */
69 int sock;
70
71 /**
72 * The current MTU
73 */
74 int mtu;
75 };
76
77 /**
78 * Set the sockaddr_t from the given netmask
79 */
80 static void set_netmask(struct ifreq *ifr, int family, u_int8_t netmask)
81 {
82 int len, bytes, bits;
83 char *target;
84
85 switch (family)
86 {
87 case AF_INET:
88 {
89 struct sockaddr_in *addr = (struct sockaddr_in*)&ifr->ifr_addr;
90 addr->sin_family = AF_INET;
91 target = (char*)&addr->sin_addr;
92 len = 4;
93 break;
94 }
95 case AF_INET6:
96 {
97 struct sockaddr_in6 *addr = (struct sockaddr_in6*)&ifr->ifr_addr;
98 addr->sin6_family = AF_INET6;
99 target = (char*)&addr->sin6_addr;
100 len = 16;
101 break;
102 }
103 default:
104 return;
105 }
106
107 bytes = (netmask + 7) / 8;
108 bits = (bytes * 8) - netmask;
109
110 memset(target, 0xff, bytes);
111 memset(target + bytes, 0x00, len - bytes);
112 target[bytes - 1] = bits ? (u_int8_t)(0xff << bits) : 0xff;
113 }
114
115 METHOD(tun_device_t, set_address, bool,
116 private_tun_device_t *this, host_t *addr, u_int8_t netmask)
117 {
118 struct ifreq ifr;
119 int family;
120
121 family = addr->get_family(addr);
122 if ((netmask > 32 && family == AF_INET) || netmask > 128)
123 {
124 DBG1(DBG_LIB, "failed to set address on %s: invalid netmask",
125 this->if_name);
126 return FALSE;
127 }
128
129 memset(&ifr, 0, sizeof(ifr));
130 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
131 memcpy(&ifr.ifr_addr, addr->get_sockaddr(addr), sizeof(sockaddr_t));
132
133 if (ioctl(this->sock, SIOCSIFADDR, &ifr) < 0)
134 {
135 DBG1(DBG_LIB, "failed to set address on %s: %s",
136 this->if_name, strerror(errno));
137 return FALSE;
138 }
139 #ifdef __APPLE__
140 if (ioctl(this->sock, SIOCSIFDSTADDR, &ifr) < 0)
141 {
142 DBG1(DBG_LIB, "failed to set dest address on %s: %s",
143 this->if_name, strerror(errno));
144 return FALSE;
145 }
146 #endif /* __APPLE__ */
147
148 set_netmask(&ifr, family, netmask);
149
150 if (ioctl(this->sock, SIOCSIFNETMASK, &ifr) < 0)
151 {
152 DBG1(DBG_LIB, "failed to set netmask on %s: %s",
153 this->if_name, strerror(errno));
154 return FALSE;
155 }
156 return TRUE;
157 }
158
159 METHOD(tun_device_t, up, bool,
160 private_tun_device_t *this)
161 {
162 struct ifreq ifr;
163
164 memset(&ifr, 0, sizeof(ifr));
165 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
166
167 if (ioctl(this->sock, SIOCGIFFLAGS, &ifr) < 0)
168 {
169 DBG1(DBG_LIB, "failed to get interface flags for %s: %s", this->if_name,
170 strerror(errno));
171 return FALSE;
172 }
173
174 ifr.ifr_flags |= IFF_RUNNING | IFF_UP;
175
176 if (ioctl(this->sock, SIOCSIFFLAGS, &ifr) < 0)
177 {
178 DBG1(DBG_LIB, "failed to set interface flags on %s: %s", this->if_name,
179 strerror(errno));
180 return FALSE;
181 }
182 return TRUE;
183 }
184
185 METHOD(tun_device_t, set_mtu, bool,
186 private_tun_device_t *this, int mtu)
187 {
188 struct ifreq ifr;
189
190 memset(&ifr, 0, sizeof(ifr));
191 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
192 ifr.ifr_mtu = mtu;
193
194 if (ioctl(this->sock, SIOCSIFMTU, &ifr) < 0)
195 {
196 return FALSE;
197 }
198 this->mtu = mtu;
199 return TRUE;
200 }
201
202 METHOD(tun_device_t, get_mtu, int,
203 private_tun_device_t *this)
204 {
205 struct ifreq ifr;
206
207 if (this->mtu > 0)
208 {
209 return this->mtu;
210 }
211
212 memset(&ifr, 0, sizeof(ifr));
213 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
214 this->mtu = TUN_DEFAULT_MTU;
215
216 if (ioctl(this->sock, SIOCGIFMTU, &ifr) == 0)
217 {
218 this->mtu = ifr.ifr_mtu;
219 }
220 return this->mtu;
221 }
222
223 METHOD(tun_device_t, get_name, char*,
224 private_tun_device_t *this)
225 {
226 return this->if_name;
227 }
228
229 METHOD(tun_device_t, write_packet, bool,
230 private_tun_device_t *this, chunk_t packet)
231 {
232 ssize_t s;
233
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 return TRUE;
281 }
282
283 METHOD(tun_device_t, destroy, void,
284 private_tun_device_t *this)
285 {
286 if (this->tunfd > 0)
287 {
288 close(this->tunfd);
289 }
290 if (this->sock > 0)
291 {
292 close(this->sock);
293 }
294 free(this);
295 }
296
297 /**
298 * Initialize the tun device
299 */
300 static bool init_tun(private_tun_device_t *this, const char *name_tmpl)
301 {
302 #ifdef __APPLE__
303
304 struct ctl_info info;
305 struct sockaddr_ctl addr;
306 socklen_t size = IFNAMSIZ;
307
308 memset(&info, 0, sizeof(info));
309 memset(&addr, 0, sizeof(addr));
310
311 this->tunfd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
312 if (this->tunfd < 0)
313 {
314 DBG1(DBG_LIB, "failed to open tundevice PF_SYSTEM socket: %s",
315 strerror(errno));
316 return FALSE;
317 }
318
319 /* get a control identifier for the utun kernel extension */
320 strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME));
321 if (ioctl(this->tunfd, CTLIOCGINFO, &info) < 0)
322 {
323 DBG1(DBG_LIB, "failed to ioctl tundevice: %s", strerror(errno));
324 close(this->tunfd);
325 return FALSE;
326 }
327
328 addr.sc_id = info.ctl_id;
329 addr.sc_len = sizeof(addr);
330 addr.sc_family = AF_SYSTEM;
331 addr.ss_sysaddr = AF_SYS_CONTROL;
332 /* allocate identifier dynamically */
333 addr.sc_unit = 0;
334
335 if (connect(this->tunfd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
336 {
337 DBG1(DBG_LIB, "failed to connect tundevice: %s", strerror(errno));
338 close(this->tunfd);
339 return FALSE;
340 }
341 if (getsockopt(this->tunfd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME,
342 this->if_name, &size) < 0)
343 {
344 DBG1(DBG_LIB, "getting tundevice name failed: %s", strerror(errno));
345 close(this->tunfd);
346 return FALSE;
347 }
348 return TRUE;
349
350 #else /* !__APPLE__ */
351
352 struct ifreq ifr;
353
354 strncpy(this->if_name, name_tmpl ?: "tun%d", IFNAMSIZ);
355 this->if_name[IFNAMSIZ-1] = '\0';
356
357 this->tunfd = open("/dev/net/tun", O_RDWR);
358 if (this->tunfd < 0)
359 {
360 DBG1(DBG_LIB, "failed to open /dev/net/tun: %s", strerror(errno));
361 return FALSE;
362 }
363
364 memset(&ifr, 0, sizeof(ifr));
365
366 /* TUN device, no packet info */
367 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
368
369 strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
370 if (ioctl(this->tunfd, TUNSETIFF, (void*)&ifr) < 0)
371 {
372 DBG1(DBG_LIB, "failed to configure TUN device: %s", strerror(errno));
373 close(this->tunfd);
374 return FALSE;
375 }
376 strncpy(this->if_name, ifr.ifr_name, IFNAMSIZ);
377 return TRUE;
378
379 #endif /* !__APPLE__ */
380 }
381
382 /*
383 * Described in header
384 */
385 tun_device_t *tun_device_create(const char *name_tmpl)
386 {
387 private_tun_device_t *this;
388
389 INIT(this,
390 .public = {
391 .read_packet = _read_packet,
392 .write_packet = _write_packet,
393 .get_mtu = _get_mtu,
394 .set_mtu = _set_mtu,
395 .get_name = _get_name,
396 .set_address = _set_address,
397 .up = _up,
398 .destroy = _destroy,
399 },
400 .tunfd = -1,
401 .sock = -1,
402 );
403
404 if (!init_tun(this, name_tmpl))
405 {
406 free(this);
407 return NULL;
408 }
409 DBG1(DBG_LIB, "created TUN device: %s", this->if_name);
410
411 this->sock = socket(AF_INET, SOCK_DGRAM, 0);
412 if (this->sock < 0)
413 {
414 DBG1(DBG_LIB, "failed to open socket to configure TUN device");
415 destroy(this);
416 return NULL;
417 }
418 return &this->public;
419 }