Consistently allocate device and iface variables on the heap.
[tinc] / src / bsd / device.c
index 045fc18..01b7071 100644 (file)
@@ -1,7 +1,7 @@
 /*
     device.c -- Interaction BSD tun/tap device
-    Copyright (C) 2001-2004 Ivo Timmermans <ivo@tinc-vpn.org>,
-                  2001-2004 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2001-2005 Ivo Timmermans,
+                  2001-2008 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
 #include "net.h"
 #include "route.h"
 #include "utils.h"
+#include "xalloc.h"
 
 #define DEFAULT_DEVICE "/dev/tun0"
 
@@ -37,31 +38,27 @@ typedef enum device_type {
 } device_type_t;
 
 int device_fd = -1;
-char *device;
-char *iface;
-char *device_info;
+char *device = NULL;
+char *iface = NULL;
+static char *device_info = NULL;
 static int device_total_in = 0;
 static int device_total_out = 0;
-#ifdef HAVE_OPENBSD
+#if defined(HAVE_OPENBSD) || defined(HAVE_FREEBSD)
 static device_type_t device_type = DEVICE_TYPE_TUNIFHEAD;
 #else
 static device_type_t device_type = DEVICE_TYPE_TUN;
 #endif
 
 bool setup_device(void) {
-#ifdef TUNSIFHEAD
-       const int zero = 0;
-       const int one = 1;
-#endif
        char *type;
 
        cp();
 
        if(!get_config_string(lookup_config(config_tree, "Device"), &device))
-               device = DEFAULT_DEVICE;
+               device = xstrdup(DEFAULT_DEVICE);
 
        if(!get_config_string(lookup_config(config_tree, "Interface"), &iface))
-               iface = rindex(device, '/') ? rindex(device, '/') + 1 : device;
+               iface = xstrdup(rindex(device, '/') ? rindex(device, '/') + 1 : device);
 
        if((device_fd = open(device, O_RDWR | O_NONBLOCK)) < 0) {
                logger(LOG_ERR, _("Could not open %s: %s"), device, strerror(errno));
@@ -82,7 +79,7 @@ bool setup_device(void) {
                        return false;
                }
        } else {
-               if(strstr(device, "tap"))
+               if(strstr(device, "tap") || routing_mode != RMODE_ROUTER)
                        device_type = DEVICE_TYPE_TAP;
        }
 
@@ -91,20 +88,40 @@ bool setup_device(void) {
                        device_type = DEVICE_TYPE_TUN;
                case DEVICE_TYPE_TUN:
 #ifdef TUNSIFHEAD
+               {       
+                       const int zero = 0;
                        if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) {
                                logger(LOG_ERR, _("System call `%s' failed: %s"), "ioctl", strerror(errno));
                                return false;
                        }
+               }
 #endif
+#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
+               {
+                       const int mode = IFF_BROADCAST | IFF_MULTICAST;
+                       ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode);
+               }
+#endif
+
                        device_info = _("Generic BSD tun device");
                        break;
                case DEVICE_TYPE_TUNIFHEAD:
 #ifdef TUNSIFHEAD
+               {
+                       const int one = 1;
                        if(ioctl(device_fd, TUNSIFHEAD, &one, sizeof one) == -1) {
                                logger(LOG_ERR, _("System call `%s' failed: %s"), "ioctl", strerror(errno));
                                return false;
                        }
+               }
+#endif
+#if defined(TUNSIFMODE) && defined(IFF_BROADCAST) && defined(IFF_MULTICAST)
+               {
+                               const int mode = IFF_BROADCAST | IFF_MULTICAST;
+                               ioctl(device_fd, TUNSIFMODE, &mode, sizeof mode);
+               }
 #endif
+
                        device_info = _("Generic BSD tun device");
                        break;
                case DEVICE_TYPE_TAP:
@@ -229,7 +246,7 @@ bool write_packet(vpn_packet_t *packet)
 
                case DEVICE_TYPE_TUNIFHEAD: {
                        u_int32_t type;
-                       struct iovec vector[2] = {{&type, sizeof(type)}, {packet->data + 14, MTU - 14}};
+                       struct iovec vector[2] = {{&type, sizeof(type)}, {packet->data + 14, packet->len - 14}};
                        int af;
                        
                        af = (packet->data[12] << 8) + packet->data[13];