/* 
 * TUN interface functions.
 * Copyright (C) 2002, 2003, 2004 Mondru AB.
 * 
 * The contents of this file may be used under the terms of the GNU
 * General Public License Version 2, provided that the above copyright
 * notice and this permission notice is included in all copies or
 * substantial portions of the software.
 * 
 */

/*
 * tun.c: Contains all TUN functionality. Is able to handle multiple
 * tunnels in the same program. Each tunnel is identified by the struct,
 * which is passed to functions.
 *
 */


#include <syslog.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <errno.h>
#include <net/route.h>

#if defined(__linux__)
#include <linux/if.h>
#include <linux/if_tun.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>

#elif defined (__FreeBSD__)
#include <net/if.h>
#include <net/if_tun.h>

#elif defined (__APPLE__)
#include <net/if.h>

#elif defined (__sun__)
#include <stropts.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <net/if_tun.h>
/*#include "sun_if_tun.h"*/

#else
#error  "Unknown platform!"
#endif


#include "tun.h"
#include "syserr.h"


#if defined(__linux__)

int tun_nlattr(struct nlmsghdr *n, int nsize, int type, void *d, int dlen)
{
  int len = RTA_LENGTH(dlen);
  int alen = NLMSG_ALIGN(n->nlmsg_len);
  struct rtattr *rta = (struct rtattr*) (((void*)n) + alen);
  if (alen + len > nsize)
    return -1;
  rta->rta_len = len;
  rta->rta_type = type;
  memcpy(RTA_DATA(rta), d, dlen);
  n->nlmsg_len = alen + len;
  return 0;
}

int tun_gifindex(struct tun_t *this, __u32 *index) {
  struct ifreq ifr;
  int fd;

  memset (&ifr, '\0', sizeof (ifr));
  ifr.ifr_addr.sa_family = AF_INET;
  ifr.ifr_dstaddr.sa_family = AF_INET;
  ifr.ifr_netmask.sa_family = AF_INET;
  strncpy(ifr.ifr_name, this->devname, IFNAMSIZ);
  ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "socket() failed");
  }
  if (ioctl(fd, SIOCGIFINDEX, &ifr)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "ioctl() failed");
    close(fd);
    return -1;
  }
  close(fd);
  *index = ifr.ifr_ifindex;
  return 0;
}
#endif

int tun_sifflags(struct tun_t *this, int flags) {
  struct ifreq ifr;
  int fd;

  memset (&ifr, '\0', sizeof (ifr));
  ifr.ifr_flags = flags;
  strncpy(ifr.ifr_name, this->devname, IFNAMSIZ);
  ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */
  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "socket() failed");
  }
  if (ioctl(fd, SIOCSIFFLAGS, &ifr)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "ioctl(SIOCSIFFLAGS) failed");
    close(fd);
    return -1;
  }
  close(fd);
  return 0;
}


/* Currently unused 
int tun_addroute2(struct tun_t *this,
		  struct in_addr *dst,
		  struct in_addr *gateway,
		  struct in_addr *mask) {
  
  struct {
    struct nlmsghdr 	n;
    struct rtmsg 	r;
    char buf[TUN_NLBUFSIZE];
  } req;
  
  struct sockaddr_nl local;
  int addr_len;
  int fd;
  int status;
  struct sockaddr_nl nladdr;
  struct iovec iov;
  struct msghdr msg;

  memset(&req, 0, sizeof(req));
  req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
  req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
  req.n.nlmsg_type = RTM_NEWROUTE;
  req.r.rtm_family = AF_INET;
  req.r.rtm_table  = RT_TABLE_MAIN;
  req.r.rtm_protocol = RTPROT_BOOT;
  req.r.rtm_scope  = RT_SCOPE_UNIVERSE;
  req.r.rtm_type  = RTN_UNICAST;
  tun_nlattr(&req.n, sizeof(req), RTA_DST, dst, 4);
  tun_nlattr(&req.n, sizeof(req), RTA_GATEWAY, gateway, 4);
  
  if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "socket() failed");
    return -1;
  }

  memset(&local, 0, sizeof(local));
  local.nl_family = AF_NETLINK;
  local.nl_groups = 0;
  
  if (bind(fd, (struct sockaddr*)&local, sizeof(local)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "bind() failed");
    close(fd);
    return -1;
  }

  addr_len = sizeof(local);
  if (getsockname(fd, (struct sockaddr*)&local, &addr_len) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "getsockname() failed");
    close(fd);
    return -1;
  }

  if (addr_len != sizeof(local)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Wrong address length %d", addr_len);
    close(fd);
    return -1;
  }

  if (local.nl_family != AF_NETLINK) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Wrong address family %d", local.nl_family);
    close(fd);
    return -1;
  }
  
  iov.iov_base = (void*)&req.n;
  iov.iov_len = req.n.nlmsg_len;

  msg.msg_name = (void*)&nladdr;
  msg.msg_namelen = sizeof(nladdr),
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_control = NULL;
  msg.msg_controllen = 0;
  msg.msg_flags = 0;

  memset(&nladdr, 0, sizeof(nladdr));
  nladdr.nl_family = AF_NETLINK;
  nladdr.nl_pid = 0;
  nladdr.nl_groups = 0;

  req.n.nlmsg_seq = 0;
  req.n.nlmsg_flags |= NLM_F_ACK;

  status = sendmsg(fd, &msg, 0);  * TODO: Error check *
  close(fd);
  return 0;
}
*/

int tun_addaddr(struct tun_t *this,
		struct in_addr *addr,
		struct in_addr *dstaddr,
		struct in_addr *netmask) {

#if defined(__linux__)
  struct {
    struct nlmsghdr 	n;
    struct ifaddrmsg 	i;
    char buf[TUN_NLBUFSIZE];
  } req;
  
  struct sockaddr_nl local;
  socklen_t addr_len;
  int fd;
  int status;
  
  struct sockaddr_nl nladdr;
  struct iovec iov;
  struct msghdr msg;

  if (!this->addrs) /* Use ioctl for first addr to make ping work */
    return tun_setaddr(this, addr, dstaddr, netmask);

  memset(&req, 0, sizeof(req));
  req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
  req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
  req.n.nlmsg_type = RTM_NEWADDR;
  req.i.ifa_family = AF_INET;
  req.i.ifa_prefixlen = 32; /* 32 FOR IPv4 */
  req.i.ifa_flags = 0;
  req.i.ifa_scope = RT_SCOPE_HOST; /* TODO or 0 */
  if (tun_gifindex(this, &req.i.ifa_index)) {
    return -1;
  }

  tun_nlattr(&req.n, sizeof(req), IFA_ADDRESS, addr, sizeof(addr));
  tun_nlattr(&req.n, sizeof(req), IFA_LOCAL, dstaddr, sizeof(dstaddr));

  if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "socket() failed");
    return -1;
  }

  memset(&local, 0, sizeof(local));
  local.nl_family = AF_NETLINK;
  local.nl_groups = 0;
  
  if (bind(fd, (struct sockaddr*)&local, sizeof(local)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "bind() failed");
    close(fd);
    return -1;
  }

  addr_len = sizeof(local);
  if (getsockname(fd, (struct sockaddr*)&local, &addr_len) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "getsockname() failed");
    close(fd);
    return -1;
  }

  if (addr_len != sizeof(local)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Wrong address length %d", addr_len);
    close(fd);
    return -1;
  }

  if (local.nl_family != AF_NETLINK) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0,
	    "Wrong address family %d", local.nl_family);
    close(fd);
    return -1;
  }
  
  iov.iov_base = (void*)&req.n;
  iov.iov_len = req.n.nlmsg_len;

  msg.msg_name = (void*)&nladdr;
  msg.msg_namelen = sizeof(nladdr),
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_control = NULL;
  msg.msg_controllen = 0;
  msg.msg_flags = 0;

  memset(&nladdr, 0, sizeof(nladdr));
  nladdr.nl_family = AF_NETLINK;
  nladdr.nl_pid = 0;
  nladdr.nl_groups = 0;

  req.n.nlmsg_seq = 0;
  req.n.nlmsg_flags |= NLM_F_ACK;

  status = sendmsg(fd, &msg, 0); /* TODO Error check */

  tun_sifflags(this, IFF_UP | IFF_RUNNING); /* TODO */
  close(fd);
  this->addrs++;
  return 0;

#elif defined (__FreeBSD__) || defined (__APPLE__)

  int fd;
  struct ifaliasreq      areq;

  /* TODO: Is this needed on FreeBSD? */
  if (!this->addrs) /* Use ioctl for first addr to make ping work */
    return tun_setaddr(this, addr, dstaddr, netmask); /* TODO dstaddr */

  memset(&areq, 0, sizeof(areq));

  /* Set up interface name */
  strncpy(areq.ifra_name, this->devname, IFNAMSIZ);
  areq.ifra_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */

  ((struct sockaddr_in*) &areq.ifra_addr)->sin_family = AF_INET;
  ((struct sockaddr_in*) &areq.ifra_addr)->sin_len = sizeof(areq.ifra_addr);
  ((struct sockaddr_in*) &areq.ifra_addr)->sin_addr.s_addr = addr->s_addr;

  ((struct sockaddr_in*) &areq.ifra_mask)->sin_family = AF_INET;
  ((struct sockaddr_in*) &areq.ifra_mask)->sin_len    = sizeof(areq.ifra_mask);
  ((struct sockaddr_in*) &areq.ifra_mask)->sin_addr.s_addr = netmask->s_addr;

  /* For some reason FreeBSD uses ifra_broadcast for specifying dstaddr */
  ((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_family = AF_INET;
  ((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_len = 
    sizeof(areq.ifra_broadaddr);
  ((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_addr.s_addr = 
    dstaddr->s_addr;

  /* Create a channel to the NET kernel. */
  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "socket() failed");
    return -1;
  }
  
  if (ioctl(fd, SIOCAIFADDR, (void *) &areq) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "ioctl(SIOCAIFADDR) failed");
    close(fd);
    return -1;
  }

  close(fd);
  this->addrs++;
  return 0;

#elif defined (__sun__)
  
  if (!this->addrs) /* Use ioctl for first addr to make ping work */
    return tun_setaddr(this, addr, dstaddr, netmask);
  
  sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	  "Setting multiple addresses not possible on Solaris");
  return -1;

#else
#error  "Unknown platform!"
#endif
  
}


int tun_setaddr(struct tun_t *this,
		struct in_addr *addr,
		struct in_addr *dstaddr,
		struct in_addr *netmask)
{
  struct ifreq   ifr;
  int fd;

  memset (&ifr, '\0', sizeof (ifr));
  ifr.ifr_addr.sa_family = AF_INET;
  ifr.ifr_dstaddr.sa_family = AF_INET;

#if defined(__linux__)
  ifr.ifr_netmask.sa_family = AF_INET;

#elif defined(__FreeBSD__) || defined (__APPLE__)
  ((struct sockaddr_in *) &ifr.ifr_addr)->sin_len = 
    sizeof (struct sockaddr_in);
  ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_len = 
    sizeof (struct sockaddr_in);
#endif

  strncpy(ifr.ifr_name, this->devname, IFNAMSIZ);
  ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */

  /* Create a channel to the NET kernel. */
  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "socket() failed");
    return -1;
  }

  if (addr) { /* Set the interface address */
    this->addr.s_addr = addr->s_addr;
    memcpy(&((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr, addr,
      sizeof(*addr));
    if (ioctl(fd, SIOCSIFADDR, (void *) &ifr) < 0) {
      if (errno != EEXIST) {
	sys_err(LOG_ERR, __FILE__, __LINE__, errno,
		"ioctl(SIOCSIFADDR) failed");
      }
      else {
	sys_err(LOG_WARNING, __FILE__, __LINE__, errno,
		"ioctl(SIOCSIFADDR): Address already exists");
      }
      close(fd);
      return -1;
    }
  }

  if (dstaddr) { /* Set the destination address */
    this->dstaddr.s_addr = dstaddr->s_addr;
    memcpy(&((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr,
      dstaddr, sizeof(*dstaddr));
    if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) {
      sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	      "ioctl(SIOCSIFDSTADDR) failed");
      close(fd);
      return -1; 
    }
  }

  if (netmask) { /* Set the netmask */
    this->netmask.s_addr = netmask->s_addr;
#if defined(__linux__)
    memcpy(&((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr, 
      netmask, sizeof(*netmask));

#elif defined(__FreeBSD__) || defined (__APPLE__)
    ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = 
      netmask->s_addr;

#elif defined(__sun__)
    ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = 
      netmask->s_addr;
#else
#error  "Unknown platform!"
#endif

    if (ioctl(fd, SIOCSIFNETMASK, (void *) &ifr) < 0) {
      sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	      "ioctl(SIOCSIFNETMASK) failed");
      close(fd);
      return -1;
    }
  }
  
  close(fd);
  this->addrs++;
  
  /* On linux the route to the interface is set automatically
     on FreeBSD we have to do this manually */

  /* TODO: How does it work on Solaris? */

  tun_sifflags(this, IFF_UP | IFF_RUNNING);

#if defined(__FreeBSD__) || defined (__APPLE__)
  tun_addroute(this, dstaddr, addr, netmask);
  this->routes = 1;
#endif

  return 0;
}

int tun_route(struct tun_t *this,
	      struct in_addr *dst,
	      struct in_addr *gateway,
	      struct in_addr *mask,
	      int delete)
{


  /* TODO: Learn how to set routing table on sun  */

#if defined(__linux__)

  struct rtentry r;
  int fd;

  memset (&r, '\0', sizeof (r));
  r.rt_flags = RTF_UP | RTF_GATEWAY; /* RTF_HOST not set */

  /* Create a channel to the NET kernel. */
  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "socket() failed");
    return -1;
  }

  r.rt_dst.sa_family     = AF_INET;
  r.rt_gateway.sa_family = AF_INET;
  r.rt_genmask.sa_family = AF_INET;
  memcpy(&((struct sockaddr_in *) &r.rt_dst)->sin_addr, dst, sizeof(*dst));
  memcpy(&((struct sockaddr_in *) &r.rt_gateway)->sin_addr, gateway,
    sizeof(*gateway));
  memcpy(&((struct sockaddr_in *) &r.rt_genmask)->sin_addr, mask,
    sizeof(*mask));
  
  if (delete) {
    if (ioctl(fd, SIOCDELRT, (void *) &r) < 0) {
      sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	      "ioctl(SIOCDELRT) failed");
      close(fd);
      return -1;
    }
  }
  else {
    if (ioctl(fd, SIOCADDRT, (void *) &r) < 0) {
      sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	      "ioctl(SIOCADDRT) failed");
      close(fd);
      return -1;
    }
  }
  close(fd);
  return 0;
  
#elif defined(__FreeBSD__) || defined (__APPLE__)

struct {
  struct rt_msghdr rt;
  struct sockaddr_in dst;
  struct sockaddr_in gate;
  struct sockaddr_in mask;
} req;

 int fd;
 struct rt_msghdr *rtm;
 
 if((fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
   sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	   "socket() failed");
   return -1;
 }
 
 memset(&req, 0x00, sizeof(req));
 
 rtm  = &req.rt;
 
 rtm->rtm_msglen = sizeof(req);
 rtm->rtm_version = RTM_VERSION;
 if (delete) {
   rtm->rtm_type = RTM_DELETE;
 }
 else {
   rtm->rtm_type = RTM_ADD;
 }
 rtm->rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;  /* TODO */
 rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
 rtm->rtm_pid = getpid();      
 rtm->rtm_seq = 0044;                                 /* TODO */
 
 req.dst.sin_family       = AF_INET;
 req.dst.sin_len          = sizeof(req.dst);
 req.mask.sin_family      = AF_INET;
 req.mask.sin_len         = sizeof(req.mask);
 req.gate.sin_family      = AF_INET;
 req.gate.sin_len         = sizeof(req.gate);

 req.dst.sin_addr.s_addr  = dst->s_addr;
 req.mask.sin_addr.s_addr = mask->s_addr;
 req.gate.sin_addr.s_addr = gateway->s_addr;
 
 if(write(fd, rtm, rtm->rtm_msglen) < 0) {
   sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	   "write() failed");
   close(fd);
   return -1;
 }
 close(fd);
 return 0;

#elif defined(__sun__)
 sys_err(LOG_WARNING, __FILE__, __LINE__, errno,
	 "Could not set up routing on Solaris. Please add route manually.");
 return 0;
 
#else
#error  "Unknown platform!"
#endif

}

int tun_addroute(struct tun_t *this,
		 struct in_addr *dst,
		 struct in_addr *gateway,
		 struct in_addr *mask)
{
  return tun_route(this, dst, gateway, mask, 0);
}

int tun_delroute(struct tun_t *this,
		 struct in_addr *dst,
		 struct in_addr *gateway,
		 struct in_addr *mask)
{
  return tun_route(this, dst, gateway, mask, 1);
}


int tun_new(struct tun_t **tun)
{

#if defined(__linux__)
  struct ifreq ifr;

#elif defined(__FreeBSD__) || defined (__APPLE__)
  char devname[IFNAMSIZ+5]; /* "/dev/" + ifname */
  int devnum;
  struct ifaliasreq areq;
  int fd;

#elif defined(__sun__)
  int if_fd, ppa = -1;
  static int ip_fd = 0;
  int muxid;
  struct ifreq ifr;

#else
#error  "Unknown platform!"
#endif
  
  if (!(*tun = calloc(1, sizeof(struct tun_t)))) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "calloc() failed");
    return EOF;
  }
  
  (*tun)->cb_ind = NULL;
  (*tun)->addrs = 0;
  (*tun)->routes = 0;
  
#if defined(__linux__)
  /* Open the actual tun device */
  if (((*tun)->fd  = open("/dev/net/tun", O_RDWR)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "open() failed");
    return -1;
  }
  
  /* Set device flags. For some weird reason this is also the method
     used to obtain the network interface name */
  memset(&ifr, 0, sizeof(ifr));
  ifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* Tun device, no packet info */
  if (ioctl((*tun)->fd, TUNSETIFF, (void *) &ifr) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "ioctl() failed");
    close((*tun)->fd);
    return -1;
  } 
  
  strncpy((*tun)->devname, ifr.ifr_name, IFNAMSIZ);
  (*tun)->devname[IFNAMSIZ-1] = 0;
  
  ioctl((*tun)->fd, TUNSETNOCSUM, 1); /* Disable checksums */
  return 0;
  
#elif defined(__FreeBSD__) || defined (__APPLE__)

  /* Find suitable device */
  for (devnum = 0; devnum < 255; devnum++) { /* TODO 255 */ 
    snprintf(devname, sizeof(devname), "/dev/tun%d", devnum);
    devname[sizeof(devname)] = 0;
    if (((*tun)->fd = open(devname, O_RDWR)) >= 0) break;
    if (errno != EBUSY) break;
  } 
  if ((*tun)->fd < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't find tunnel device");
    return -1;
  }

  snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", devnum);
  (*tun)->devname[sizeof((*tun)->devname)] = 0;

  /* The tun device we found might have "old" IP addresses allocated */
  /* We need to delete those. This problem is not present on Linux */

  memset(&areq, 0, sizeof(areq));

  /* Set up interface name */
  strncpy(areq.ifra_name, (*tun)->devname, IFNAMSIZ);
  areq.ifra_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */

  /* Create a channel to the NET kernel. */
  if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno,
	    "socket() failed");
    return -1;
  }
  
  /* Delete any IP addresses until SIOCDIFADDR fails */
  while (ioctl(fd, SIOCDIFADDR, (void *) &areq) != -1);

  close(fd);
  return 0;

#elif defined(__sun__)

  if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/udp");
    return -1;
  }
  
  if( ((*tun)->fd = open("/dev/tun", O_RDWR, 0)) < 0){
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/tun");
    return -1;
  }
  
  /* Assign a new PPA and get its unit number. */
  if( (ppa = ioctl((*tun)->fd, TUNNEWPPA, -1)) < 0){
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't assign new interface");
    return -1;
  }
  
  if( (if_fd = open("/dev/tun", O_RDWR, 0)) < 0){
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/tun (2)");
    return -1;
  }
  if(ioctl(if_fd, I_PUSH, "ip") < 0){
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't push IP module");
    return -1;
  }
  
  /* Assign ppa according to the unit number returned by tun device */
  if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0){
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set PPA %d", ppa);
    return -1;
  }

  /* Link the two streams */
  if ((muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't link TUN device to IP");
    return -1;
  }

  close (if_fd);
  
  snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", ppa);
  (*tun)->devname[sizeof((*tun)->devname)] = 0;

  memset(&ifr, 0, sizeof(ifr));
  strcpy(ifr.ifr_name, (*tun)->devname);
  ifr.ifr_ip_muxid = muxid;
  
  if (ioctl(ip_fd, SIOCSIFMUXID, &ifr) < 0) {
    ioctl(ip_fd, I_PUNLINK, muxid);
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set multiplexor id");
    return -1;
  }
  
  /*  if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0)
      msg (M_ERR, "Set file descriptor to non-blocking failed"); */

  return 0;

#else
#error  "Unknown platform!"
#endif

}

int tun_free(struct tun_t *tun)
{

  if (tun->routes) {
    tun_delroute(tun, &tun->dstaddr, &tun->addr, &tun->netmask);
  }

  if (close(tun->fd)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "close() failed");
  }

  /* TODO: For solaris we need to unlink streams */

  free(tun);
  return 0;
}


int tun_set_cb_ind(struct tun_t *this, 
  int (*cb_ind) (struct tun_t *tun, void *pack, unsigned len)) {
  this->cb_ind = cb_ind;
  return 0;
}


int tun_decaps(struct tun_t *this)
{

#if defined(__linux__) || defined (__FreeBSD__) || defined (__APPLE__)

  unsigned char buffer[PACKET_MAX];
  int status;
  
  if ((status = read(this->fd, buffer, sizeof(buffer))) <= 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "read() failed");
    return -1;
  }
  
  if (this->cb_ind)
    return this->cb_ind(this, buffer, status);

  return 0;

#elif defined (__sun__)

  unsigned char buffer[PACKET_MAX];
  struct strbuf sbuf;
  int f = 0;
  
  sbuf.maxlen = PACKET_MAX;      
  sbuf.buf = buffer;
  if (getmsg(this->fd, NULL, &sbuf, &f) < 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "getmsg() failed");
    return -1;
  }

  if (this->cb_ind)
    return this->cb_ind(this, buffer, sbuf.len);

  return 0;
  
#endif

}


int tun_encaps(struct tun_t *tun, void *pack, unsigned len)
{

#if defined(__linux__) || defined (__FreeBSD__) || defined (__APPLE__)

  return write(tun->fd, pack, len);

#elif defined (__sun__)

  struct strbuf sbuf;
  sbuf.len = len;      
  sbuf.buf = pack;
  return putmsg(tun->fd, NULL, &sbuf, 0);

#endif
}

int tun_runscript(struct tun_t *tun, char* script) {
  
  char buf[TUN_SCRIPTSIZE];
  char snet[TUN_ADDRSIZE];
  char smask[TUN_ADDRSIZE];
  int rc;

  strncpy(snet, inet_ntoa(tun->addr), sizeof(snet));
  snet[sizeof(snet)-1] = 0;
  strncpy(smask, inet_ntoa(tun->netmask), sizeof(smask));
  smask[sizeof(smask)-1] = 0;
  
  /* system("ipup /dev/tun0 192.168.0.10 255.255.255.0"); */
  snprintf(buf, sizeof(buf), "%s %s %s %s",
	   script, tun->devname, snet, smask);
  buf[sizeof(buf)-1] = 0;
  rc = system(buf);
  if (rc == -1) {
    sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Error executing command %s",
      buf);
    return -1;
  }
  return 0;
}
