Imported Upstream version 0.3.5
[debian/uanytun.git] / src / bsd / tun.c
index f193668..a469c58 100644 (file)
  *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
  *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
  *  ethernet, ip, arp ...). satp directly includes cryptography and
- *  message authentication based on the methodes used by SRTP.  It is
+ *  message authentication based on the methods used by SRTP.  It is
  *  intended to deliver a generic, scaleable and secure solution for
  *  tunneling and relaying of packets of any protocol.
- *  
  *
- *  Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org>
+ *
+ *  Copyright (C) 2007-2014 Christian Pointner <equinox@anytun.org>
  *
  *  This file is part of uAnytun.
  *
  *  uAnytun is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 3 as
- *  published by the Free Software Foundation.
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  any later version.
  *
  *  uAnytun is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  *  You should have received a copy of the GNU General Public License
  *  along with uAnytun. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *  In addition, as a special exception, the copyright holders give
+ *  permission to link the code of portions of this program with the
+ *  OpenSSL library under certain conditions as described in each
+ *  individual source file, and distribute linked combinations
+ *  including the two.
+ *  You must obey the GNU General Public License in all respects
+ *  for all of the code used other than OpenSSL.  If you modify
+ *  file(s) with this exception, you may extend this exception to your
+ *  version of the file(s), but you are not obligated to do so.  If you
+ *  do not wish to do so, delete this exception statement from your
+ *  version.  If you delete this exception statement from all source
+ *  files in the program, then also delete it here.
  */
 
 #include "datatypes.h"
@@ -57,9 +71,9 @@
 
 int tun_init(tun_device_t* dev, const char* dev_name, const char* dev_type, const char* ifcfg_addr, u_int16_t ifcfg_prefix)
 {
-  if(!dev) 
+  if(!dev)
     return -1;
+
   tun_conf(dev, dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400);
   dev->actual_name_ = NULL;
 
@@ -108,7 +122,7 @@ int tun_init(tun_device_t* dev, const char* dev_name, const char* dev_type, cons
         tun_close(dev);
         return -2;
       }
-        
+
       dev->fd_ = open(device_file_tmp, O_RDWR);
       free(device_file_tmp);
       if(dev->fd_ >= 0)
@@ -124,7 +138,7 @@ int tun_init(tun_device_t* dev, const char* dev_name, const char* dev_type, cons
       log_printf(ERROR, "can't open device file dynamically: no unused node left");
     else
       log_printf(ERROR, "can't open device file (%s): %s", device_file, strerror(errno));
-    
+
     tun_close(dev);
     return -1;
   }
@@ -163,18 +177,18 @@ int tun_init_post(tun_device_t* dev)
   dev->with_pi_ = 1;
   if(dev->type_ == TYPE_TAP)
     dev->with_pi_ = 0;
-  
-  struct tuninfo ti;  
+
+  struct tuninfo ti;
 
   if(ioctl(dev->fd_, TUNGIFINFO, &ti) < 0) {
     log_printf(ERROR, "can't enable multicast for interface: %s", strerror(errno));
     return -1;
-  }  
+  }
 
   ti.flags |= IFF_MULTICAST;
   if(dev->type_ == TYPE_TUN)
     ti.flags &= ~IFF_POINTOPOINT;
-  
+
   if(ioctl(dev->fd_, TUNSIFINFO, &ti) < 0) {
     log_printf(ERROR, "can't enable multicast for interface: %s", strerror(errno));
     return -1;
@@ -182,7 +196,7 @@ int tun_init_post(tun_device_t* dev)
   return 0;
 }
 
-#elif defined(__GNUC__) && defined(__FreeBSD__)
+#elif defined(__GNUC__) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
 
 int tun_init_post(tun_device_t* dev)
 {
@@ -198,20 +212,20 @@ int tun_init_post(tun_device_t* dev)
     if(ioctl(dev->fd_, TUNSLMODE, &arg) < 0) {
       log_printf(ERROR, "can't disable link-layer mode for interface: %s", strerror(errno));
       return -1;
-    }  
+    }
 
     arg = 1;
     if(ioctl(dev->fd_, TUNSIFHEAD, &arg) < 0) {
       log_printf(ERROR, "can't enable multi-af mode for interface: %s", strerror(errno));
       return -1;
-    }  
+    }
 
     arg = IFF_BROADCAST;
     arg |= IFF_MULTICAST;
     if(ioctl(dev->fd_, TUNSIFMODE, &arg) < 0) {
       log_printf(ERROR, "can't enable multicast for interface: %s", strerror(errno));
       return -1;
-    }  
+    }
   }
 
   return 0;
@@ -267,7 +281,7 @@ int tun_read(tun_device_t* dev, u_int8_t* buf, u_int32_t len)
   {
     struct iovec iov[2];
     u_int32_t type;
-    
+
     iov[0].iov_base = &type;
     iov[0].iov_len = sizeof(type);
     iov[1].iov_base = buf;
@@ -291,13 +305,13 @@ int tun_write(tun_device_t* dev, u_int8_t* buf, u_int32_t len)
     struct iovec iov[2];
     u_int32_t type;
     struct ip *hdr = (struct ip*)buf;
-    
+
     type = 0;
     if(hdr->ip_v == 4)
       type = htonl(AF_INET);
     else
       type = htonl(AF_INET6);
-    
+
     iov[0].iov_base = &type;
     iov[0].iov_len = sizeof(type);
     iov[1].iov_base = buf;
@@ -313,36 +327,31 @@ void tun_do_ifconfig(tun_device_t* dev)
   if(!dev || !dev->actual_name_ || !dev->net_addr_ || !dev->net_mask_)
     return;
 
-
-  char* command = NULL;
-  char* netmask;
   char* end;
   if(dev->type_ == TYPE_TAP) {
 #if defined(__GNUC__) && defined(__OpenBSD__)
-    end = " link0";
-#elif defined(__GNUC__) && defined(__FreeBSD__)
-    end = " up";
+    end = "link0";
+#elif defined(__GNUC__) && (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
+    end = "up";
 #elif defined(__GNUC__) && defined(__NetBSD__)
-    end = "";
+    end = NULL;
 #else
  #error This Device works just for OpenBSD, FreeBSD or NetBSD
 #endif
   }
   else
-    end = " up";
+    end = "up";
 
-  asprintf(&command, "/sbin/ifconfig %s %s netmask %s mtu %d%s", dev->actual_name_, dev->net_addr_,
-                                                                 dev->net_mask_, dev->mtu_, end);
-  if(!command) {
+  char* mtu_str = NULL;
+  asprintf(&mtu_str, "%d", dev->mtu_);
+  if(!mtu_str) {
     log_printf(ERROR, "Execution of ifconfig failed");
     return;
   }
 
-  int result = system(command);
-  if(result == -1)
-    log_printf(ERROR, "Execution of ifconfig failed");
-  else
-    log_printf(NOTICE, "ifconfig returned %d", WEXITSTATUS(result));
+  char* const argv[] = { "/sbin/ifconfig", dev->actual_name_, dev->net_addr_, "netmask", dev->net_mask_, "mtu", mtu_str, end, NULL };
+  char* const evp[] = { NULL };
+  uanytun_exec("/sbin/ifconfig", argv, evp);
 
-  free(command);
+  free(mtu_str);
 }