62e7e84b8e216f529f2075acea090798640807e9
[tinc] / src / bsd / device.c
1 /*
2     device.c -- Interaction BSD tun/tap device
3     Copyright (C) 2001-2005 Ivo Timmermans,
4                   2001-2016 Guus Sliepen <guus@tinc-vpn.org>
5                   2009      Grzegorz Dymarek <gregd72002@googlemail.com>
6
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include "../system.h"
23
24 #include "../conf.h"
25 #include "../device.h"
26 #include "../logger.h"
27 #include "../net.h"
28 #include "../route.h"
29 #include "../utils.h"
30 #include "../xalloc.h"
31
32 #ifdef ENABLE_TUNEMU
33 #include "tunemu.h"
34 #endif
35
36 #ifdef HAVE_NET_IF_UTUN_H
37 #include <sys/sys_domain.h>
38 #include <sys/kern_control.h>
39 #include <net/if_utun.h>
40 #endif
41
42 #define DEFAULT_TUN_DEVICE "/dev/tun0"
43 #define DEFAULT_TAP_DEVICE "/dev/tap0"
44
45 typedef enum device_type {
46         DEVICE_TYPE_TUN,
47         DEVICE_TYPE_TUNIFHEAD,
48         DEVICE_TYPE_TAP,
49 #ifdef ENABLE_TUNEMU
50         DEVICE_TYPE_TUNEMU,
51 #endif
52         DEVICE_TYPE_UTUN,
53 } device_type_t;
54
55 int device_fd = -1;
56 char *device = NULL;
57 char *iface = NULL;
58 static char *device_info = NULL;
59 static uint64_t device_total_in = 0;
60 static uint64_t device_total_out = 0;
61 #if defined(ENABLE_TUNEMU)
62 static device_type_t device_type = DEVICE_TYPE_TUNEMU;
63 #elif defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD) || defined(HAVE_DRAGONFLY)
64 static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD;
65 #else
66 static device_type_t device_type = DEVICE_TYPE_TUN;
67 #endif
68
69 #ifdef HAVE_NET_IF_UTUN_H
70 static bool setup_utun(void) {
71         device_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
72
73         if(device_fd == -1) {
74                 logger(LOG_ERR, "Could not open PF_SYSTEM socket: %s\n", strerror(errno));
75                 return false;
76         }
77
78         struct ctl_info info = {};
79
80         strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name));
81
82         if(ioctl(device_fd, CTLIOCGINFO, &info) == -1) {
83                 logger(LOG_ERR, "ioctl(CTLIOCGINFO) failed: %s", strerror(errno));
84                 return false;
85         }
86
87         int unit = -1;
88         char *p = strstr(device, "utun"), *e = NULL;
89
90         if(p) {
91                 unit = strtol(p + 4, &e, 10);
92
93                 if(!e) {
94                         unit = -1;
95                 }
96         }
97
98         struct sockaddr_ctl sc = {
99                 .sc_id = info.ctl_id,
100                 .sc_len = sizeof(sc),
101                 .sc_family = AF_SYSTEM,
102                 .ss_sysaddr = AF_SYS_CONTROL,
103                 .sc_unit = unit + 1,
104         };
105
106         if(connect(device_fd, (struct sockaddr *)&sc, sizeof(sc)) == -1) {
107                 logger(LOG_ERR, "Could not connect utun socket: %s\n", strerror(errno));
108                 return false;
109         }
110
111         char name[64] = "";
112         socklen_t len = sizeof(name);
113
114         if(getsockopt(device_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
115                 iface = xstrdup(device);
116         } else {
117                 iface = xstrdup(name);
118         }
119
120         device_info = "OS X utun device";
121
122         logger(LOG_INFO, "%s is a %s", device, device_info);
123
124         return true;
125 }
126 #endif
127
128 static bool setup_device(void) {
129         // Find out which device file to open
130
131         if(!get_config_string(lookup_config(config_tree, "Device"), &device)) {
132                 if(routing_mode == RMODE_ROUTER) {
133                         device = xstrdup(DEFAULT_TUN_DEVICE);
134                 } else {
135                         device = xstrdup(DEFAULT_TAP_DEVICE);
136                 }
137         }
138
139         // Find out if it's supposed to be a tun or a tap device
140
141         char *type;
142
143         if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
144                 if(!strcasecmp(type, "tun"))
145                         /* use default */;
146
147 #ifdef ENABLE_TUNEMU
148                 else if(!strcasecmp(type, "tunemu")) {
149                         device_type = DEVICE_TYPE_TUNEMU;
150                 }
151
152 #endif
153 #ifdef HAVE_NET_IF_UTUN_H
154                 else if(!strcasecmp(type, "utun")) {
155                         device_type = DEVICE_TYPE_UTUN;
156                 }
157
158 #endif
159                 else if(!strcasecmp(type, "tunnohead")) {
160                         device_type = DEVICE_TYPE_TUN;
161                 } else if(!strcasecmp(type, "tunifhead")) {
162                         device_type = DEVICE_TYPE_TUNIFHEAD;
163                 } else if(!strcasecmp(type, "tap")) {
164                         device_type = DEVICE_TYPE_TAP;
165                 } else {
166                         logger(LOG_ERR, "Unknown device type %s!", type);
167                         return false;
168                 }
169         } else {
170 #ifdef HAVE_NET_IF_UTUN_H
171
172                 if(strncmp(device, "utun", 4) == 0 || strncmp(device, "/dev/utun", 9) == 0) {
173                         device_type = DEVICE_TYPE_UTUN;
174                 } else
175 #endif
176                         if(strstr(device, "tap") || routing_mode != RMODE_ROUTER) {
177                                 device_type = DEVICE_TYPE_TAP;
178                         }
179         }
180
181         if(routing_mode == RMODE_SWITCH && device_type != DEVICE_TYPE_TAP) {
182                 logger(LOG_ERR, "Only tap devices support switch mode!");
183                 return false;
184         }
185
186         // Open the device
187
188         switch(device_type) {
189 #ifdef ENABLE_TUNEMU
190
191         case DEVICE_TYPE_TUNEMU: {
192                 char dynamic_name[256] = "";
193                 device_fd = tunemu_open(dynamic_name);
194         }
195         break;
196 #endif
197 #ifdef HAVE_NET_IF_UTUN_H
198
199         case DEVICE_TYPE_UTUN:
200                 return setup_utun();
201 #endif
202
203         default:
204                 device_fd = open(device, O_RDWR | O_NONBLOCK);
205         }
206
207         if(device_fd < 0) {
208                 logger(LOG_ERR, "Could not open %s: %s", device, strerror(errno));
209                 return false;
210         }
211
212 #ifdef FD_CLOEXEC
213         fcntl(device_fd, F_SETFD, FD_CLOEXEC);
214 #endif
215
216         // Guess what the corresponding interface is called
217
218         char *realname = NULL;
219
220 #if defined(HAVE_FDEVNAME)
221         realname = fdevname(device_fd);
222 #elif defined(HAVE_DEVNAME)
223         struct stat buf;
224
225         if(!fstat(device_fd, &buf)) {
226                 realname = devname(buf.st_rdev, S_IFCHR);
227         }
228
229 #endif
230
231         if(!realname) {
232                 realname = device;
233         }
234
235         if(!get_config_string(lookup_config(config_tree, "Interface"), &iface)) {
236                 iface = xstrdup(strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname);
237         } else if(strcmp(iface, strrchr(realname, '/') ? strrchr(realname, '/') + 1 : realname)) {
238                 logger(LOG_WARNING, "Warning: Interface does not match Device. $INTERFACE might be set incorrectly.");
239         }
240
241         // Configure the device as best as we can
242
243         switch(device_type) {
244         default:
245                 device_type = DEVICE_TYPE_TUN;
246
247         case DEVICE_TYPE_TUN:
248 #ifdef TUNSIFHEAD
249                 {
250                         const int zero = 0;
251
252                         if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof(zero)) == -1) {
253                                 logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
254                                 return false;
255                         }
256                 }
257
258 #endif
259 #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
260                 {
261                         const int mode = IFF_BROADCAST | IFF_MULTICAST;
262                         ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
263                 }
264 #endif
265
266                 device_info = "Generic BSD tun device";
267                 break;
268
269         case DEVICE_TYPE_TUNIFHEAD:
270 #ifdef TUNSIFHEAD
271                 {
272                         const int one = 1;
273
274                         if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof(one)) == -1) {
275                                 logger(LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
276                                 return false;
277                         }
278                 }
279
280 #endif
281 #if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
282                 {
283                         const int mode = IFF_BROADCAST | IFF_MULTICAST;
284                         ioctl(device_fd, TUNSIFMODE, &mode, sizeof(mode));
285                 }
286 #endif
287
288                 device_info = "Generic BSD tun device";
289                 break;
290
291         case DEVICE_TYPE_TAP:
292                 if(routing_mode == RMODE_ROUTER) {
293                         overwrite_mac = true;
294                 }
295
296                 device_info = "Generic BSD tap device";
297 #ifdef TAPGIFNAME
298                 {
299                         struct ifreq ifr;
300
301                         if(ioctl(device_fd, TAPGIFNAME, (void *)&ifr) == 0) {
302                                 if(iface) {
303                                         free(iface);
304                                 }
305
306                                 iface = xstrdup(ifr.ifr_name);
307                         }
308                 }
309
310 #endif
311                 break;
312 #ifdef ENABLE_TUNEMU
313
314         case DEVICE_TYPE_TUNEMU:
315                 device_info = "BSD tunemu device";
316                 break;
317 #endif
318         }
319
320 #ifdef SIOCGIFADDR
321
322         if(overwrite_mac) {
323                 ioctl(device_fd, SIOCGIFADDR, mymac.x);
324         }
325
326 #endif
327
328         logger(LOG_INFO, "%s is a %s", device, device_info);
329
330         return true;
331 }
332
333 static void close_device(void) {
334         switch(device_type) {
335 #ifdef ENABLE_TUNEMU
336
337         case DEVICE_TYPE_TUNEMU:
338                 tunemu_close(device_fd);
339                 break;
340 #endif
341
342         default:
343                 close(device_fd);
344         }
345
346         free(device);
347         free(iface);
348 }
349
350 static bool read_packet(vpn_packet_t *packet) {
351         int lenin;
352
353         switch(device_type) {
354         case DEVICE_TYPE_TUN:
355 #ifdef ENABLE_TUNEMU
356         case DEVICE_TYPE_TUNEMU:
357                 if(device_type == DEVICE_TYPE_TUNEMU) {
358                         lenin = tunemu_read(device_fd, packet->data + 14, MTU - 14);
359                 } else
360 #endif
361                         lenin = read(device_fd, packet->data + 14, MTU - 14);
362
363                 if(lenin <= 0) {
364                         logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
365                                device, strerror(errno));
366                         return false;
367                 }
368
369                 switch(packet->data[14] >> 4) {
370                 case 4:
371                         packet->data[12] = 0x08;
372                         packet->data[13] = 0x00;
373                         break;
374
375                 case 6:
376                         packet->data[12] = 0x86;
377                         packet->data[13] = 0xDD;
378                         break;
379
380                 default:
381                         ifdebug(TRAFFIC) logger(LOG_ERR,
382                                                 "Unknown IP version %d while reading packet from %s %s",
383                                                 packet->data[14] >> 4, device_info, device);
384                         return false;
385                 }
386
387                 memset(packet->data, 0, 12);
388                 packet->len = lenin + 14;
389                 break;
390
391         case DEVICE_TYPE_UTUN:
392         case DEVICE_TYPE_TUNIFHEAD: {
393                 if((lenin = read(device_fd, packet->data + 10, MTU - 10)) <= 0) {
394                         logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
395                                device, strerror(errno));
396                         return false;
397                 }
398
399                 switch(packet->data[14] >> 4) {
400                 case 4:
401                         packet->data[12] = 0x08;
402                         packet->data[13] = 0x00;
403                         break;
404
405                 case 6:
406                         packet->data[12] = 0x86;
407                         packet->data[13] = 0xDD;
408                         break;
409
410                 default:
411                         ifdebug(TRAFFIC) logger(LOG_ERR,
412                                                 "Unknown IP version %d while reading packet from %s %s",
413                                                 packet->data[14] >> 4, device_info, device);
414                         return false;
415                 }
416
417                 memset(packet->data, 0, 12);
418                 packet->len = lenin + 10;
419                 break;
420         }
421
422         case DEVICE_TYPE_TAP:
423                 if((lenin = read(device_fd, packet->data, MTU)) <= 0) {
424                         logger(LOG_ERR, "Error while reading from %s %s: %s", device_info,
425                                device, strerror(errno));
426                         return false;
427                 }
428
429                 packet->len = lenin;
430                 break;
431
432         default:
433                 return false;
434         }
435
436         device_total_in += packet->len;
437
438         ifdebug(TRAFFIC) logger(LOG_DEBUG, "Read packet of %d bytes from %s",
439                                 packet->len, device_info);
440
441         return true;
442 }
443
444 static bool write_packet(vpn_packet_t *packet) {
445         ifdebug(TRAFFIC) logger(LOG_DEBUG, "Writing packet of %d bytes to %s",
446                                 packet->len, device_info);
447
448         switch(device_type) {
449         case DEVICE_TYPE_TUN:
450                 if(write(device_fd, packet->data + 14, packet->len - 14) < 0) {
451                         logger(LOG_ERR, "Error while writing to %s %s: %s", device_info,
452                                device, strerror(errno));
453                         return false;
454                 }
455
456                 break;
457
458         case DEVICE_TYPE_UTUN:
459         case DEVICE_TYPE_TUNIFHEAD: {
460                 int af = (packet->data[12] << 8) + packet->data[13];
461                 uint32_t type;
462
463                 switch(af) {
464                 case 0x0800:
465                         type = htonl(AF_INET);
466                         break;
467
468                 case 0x86DD:
469                         type = htonl(AF_INET6);
470                         break;
471
472                 default:
473                         ifdebug(TRAFFIC) logger(LOG_ERR,
474                                                 "Unknown address family %x while writing packet to %s %s",
475                                                 af, device_info, device);
476                         return false;
477                 }
478
479                 memcpy(packet->data + 10, &type, sizeof(type));
480
481                 if(write(device_fd, packet->data + 10, packet->len - 10) < 0) {
482                         logger(LOG_ERR, "Can't write to %s %s: %s", device_info, device,
483                                strerror(errno));
484                         return false;
485                 }
486
487                 break;
488         }
489
490         case DEVICE_TYPE_TAP:
491                 if(write(device_fd, packet->data, packet->len) < 0) {
492                         logger(LOG_ERR, "Error while writing to %s %s: %s", device_info,
493                                device, strerror(errno));
494                         return false;
495                 }
496
497                 break;
498
499 #ifdef ENABLE_TUNEMU
500
501         case DEVICE_TYPE_TUNEMU:
502                 if(tunemu_write(device_fd, packet->data + 14, packet->len - 14) < 0) {
503                         logger(LOG_ERR, "Error while writing to %s %s: %s", device_info,
504                                device, strerror(errno));
505                         return false;
506                 }
507
508                 break;
509 #endif
510
511         default:
512                 return false;
513         }
514
515         device_total_out += packet->len;
516
517         return true;
518 }
519
520 static void dump_device_stats(void) {
521         logger(LOG_DEBUG, "Statistics for %s %s:", device_info, device);
522         logger(LOG_DEBUG, " total bytes in:  %10"PRIu64, device_total_in);
523         logger(LOG_DEBUG, " total bytes out: %10"PRIu64, device_total_out);
524 }
525
526 const devops_t os_devops = {
527         .setup = setup_device,
528         .close = close_device,
529         .read = read_packet,
530         .write = write_packet,
531         .dump_stats = dump_device_stats,
532 };