Added FreeBSD route capability
diff --git a/doc/Makefile b/doc/Makefile
index 62a896d..8db62bd 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -13,7 +13,7 @@
 # PARTICULAR PURPOSE.
 
 
-SHELL = /bin/sh
+SHELL = /usr/local/bin/bash
 
 srcdir = .
 top_srcdir = ..
@@ -38,10 +38,10 @@
 pkgincludedir = $(includedir)/openggsn
 top_builddir = ..
 
-ACLOCAL = ${SHELL} /home/jj/openggsn/missing --run aclocal-1.6
-AUTOCONF = ${SHELL} /home/jj/openggsn/missing --run autoconf
-AUTOMAKE = ${SHELL} /home/jj/openggsn/missing --run automake-1.6
-AUTOHEADER = ${SHELL} /home/jj/openggsn/missing --run autoheader
+ACLOCAL = ${SHELL} /usr/home/jj/openggsn/missing --run aclocal-1.6
+AUTOCONF = ${SHELL} /usr/home/jj/openggsn/missing --run autoconf
+AUTOMAKE = ${SHELL} /usr/home/jj/openggsn/missing --run automake-1.6
+AUTOHEADER = ${SHELL} /usr/home/jj/openggsn/missing --run autoheader
 
 am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
 INSTALL = /usr/bin/install -c
@@ -60,14 +60,14 @@
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
 host_alias = 
-host_triplet = i686-pc-linux-gnu
+host_triplet = i386-unknown-freebsd5.2
 
 EXEEXT = 
 OBJEXT = o
 PATH_SEPARATOR = :
-AMTAR = ${SHELL} /home/jj/openggsn/missing --run tar
+AMTAR = ${SHELL} /usr/home/jj/openggsn/missing --run tar
 AS = @AS@
-AWK = gawk
+AWK = nawk
 CC = gcc
 CPP = gcc -E
 CXX = g++
@@ -85,7 +85,7 @@
 VERSION = 0.81
 am__include = include
 am__quote = 
-install_sh = /home/jj/openggsn/install-sh
+install_sh = /usr/home/jj/openggsn/install-sh
 man_MANS = ggsn.8 sgsnemu.8
 man_aux = $(man_MANS:.1=.x)
 EXTRA_DIST = $(man_MANS)
diff --git a/ggsn/tun.c b/ggsn/tun.c
index 66ba4c4..a19fd5b 100644
--- a/ggsn/tun.c
+++ b/ggsn/tun.c
@@ -421,7 +421,17 @@
 
   close(fd);
   this->addrs++;
-  return tun_sifflags(this, IFF_UP | IFF_RUNNING);
+
+  /* On linux the route to the interface is set automatically
+     on FreeBSD we have to do this manually */
+
+#if defined(__FreeBSD__)
+  tun_sifflags(this, IFF_UP | IFF_RUNNING); /* TODO */
+  return tun_addroute(this, addr, addr, netmask);
+#else
+  return tun_sifflags(this, IFF_UP | IFF_RUNNING); 
+#endif
+
 }
 
 int tun_addroute(struct tun_t *this,
@@ -430,7 +440,8 @@
 		 struct in_addr *mask)
 {
 
-  /* TODO: Learn how to set routing table on sun and FreeBSD */
+
+  /* TODO: Learn how to set routing table on sun  */
 #ifdef __linux__
 
   struct rtentry r;
@@ -463,67 +474,53 @@
 
 #elif defined(__FreeBSD__)
 
-struct my_rt
-{
-      struct rt_msghdr rt;
-      struct sockaddr_in dst;
-      struct sockaddr_in gate;
-      struct sockaddr_in mask;
-} my_rt;
+struct {
+  struct rt_msghdr rt;
+  struct sockaddr_in dst;
+  struct sockaddr_in gate;
+  struct sockaddr_in mask;
+} req;
 
- int s;
+ int fd;
  struct rt_msghdr *rtm;
- struct sockaddr_in *dst, *gate, *mask;
  
- if((s = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
-   {
-     sys_err(LOG_ERR, __FILE__, __LINE__, errno,
-	     "socket() failed");
-     return -1;
-   }
+ if((fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) {
+   sys_err(LOG_ERR, __FILE__, __LINE__, errno,
+	   "socket() failed");
+   return -1;
+ }
  
- memset(&my_rt, 0x00, sizeof(my_rt));
+ memset(&req, 0x00, sizeof(req));
  
- rtm  = &my_rt.rt;
+ rtm  = &req.rt;
  
- dst  = &my_rt.dst;
- gate = &my_rt.gate;
- mask = &my_rt.mask;
- 
+ rtm->rtm_msglen = sizeof(req);
+ rtm->rtm_version = RTM_VERSION;
  rtm->rtm_type = RTM_ADD;
  rtm->rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;  /* TODO */
- rtm->rtm_msglen = sizeof(my_rt);
- rtm->rtm_version = RTM_VERSION;
- rtm->rtm_seq = 1234;                                 /* TODO */
  rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK;
  rtm->rtm_pid = getpid();      
+ rtm->rtm_seq = 0044;                                 /* TODO */
  
- dst->sin_family = AF_INET;
- dst->sin_len    = sizeof(*dst);
- dst->sin_addr.s_addr = dst->s_addr;
+ 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;
  
- mask->sin_family = AF_INET;
- mask->sin_len    = sizeof(*mask);
- mask->sin_addr.s_addr = mask->s_addr;
- 
- gate->sin_family = AF_INET;
- gate->sin_len    = sizeof(*gate);
- gate->sin_addr.s_addr = gateway->s_addr;
- 
- AGAIN:
- if(write(s, rtm, rtm->rtm_msglen) < 0)
-   {
-     if(errno == EEXIST && rtm->rtm_type == RTM_ADD)
-       {
-	 rtm->rtm_type = RTM_CHANGE;
-	 goto AGAIN;
-       }
-     sys_err(LOG_ERR, __FILE__, __LINE__, errno,
-	     "write() failed");
-     return -1;
-   }
- return 0;
- 
+ if(write(fd, rtm, rtm->rtm_msglen) < 0) {
+   sys_err(LOG_ERR, __FILE__, __LINE__, errno,
+	   "write() failed");
+   close(fd);
+   return -1;
+ }
+ close(fd);
+
 #endif
 
   return 0;
@@ -636,6 +633,7 @@
 
   snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", devnum);
   (*tun)->devname[sizeof((*tun)->devname)] = 0;
+
 #endif
 
   return 0;
diff --git a/gtp/gtp.c b/gtp/gtp.c
index 9b1c5ad..af4bdba 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -2960,7 +2960,7 @@
     packet.gtp0.h.length = hton16(len);
     packet.gtp0.h.seq = hton16(pdp->gtpsntx++);
     packet.gtp0.h.flow = hton16(pdp->flru);
-    packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+    packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffffull) + ((uint64_t)pdp->nsapi << 60);
 
     if (len > sizeof (union gtp_packet) - sizeof(struct gtp0_header)) {
       gsn->err_memcpy++;
diff --git a/gtp/pdp.c b/gtp/pdp.c
index 130ba44..3a652b8 100644
--- a/gtp/pdp.c
+++ b/gtp/pdp.c
@@ -243,7 +243,7 @@
 
 int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) {
   return pdp_tidget(pdp, 
-		    (imsi & 0x0fffffffffffffff) + ((uint64_t)nsapi << 60));
+		    (imsi & 0x0fffffffffffffffull) + ((uint64_t)nsapi << 60));
 }
 
 /*
@@ -336,7 +336,7 @@
 }
 
 uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi) {
-  return (imsi & 0x0fffffffffffffff) + ((uint64_t)nsapi << 60);
+  return (imsi & 0x0fffffffffffffffull) + ((uint64_t)nsapi << 60);
 }
 
 int ulcpy(void* dst, void* src, size_t size) {
diff --git a/sgsnemu/tun.c b/sgsnemu/tun.c
index 06397d1..a19fd5b 100644
--- a/sgsnemu/tun.c
+++ b/sgsnemu/tun.c
@@ -421,7 +421,17 @@
 
   close(fd);
   this->addrs++;
-  return tun_sifflags(this, IFF_UP | IFF_RUNNING);
+
+  /* On linux the route to the interface is set automatically
+     on FreeBSD we have to do this manually */
+
+#if defined(__FreeBSD__)
+  tun_sifflags(this, IFF_UP | IFF_RUNNING); /* TODO */
+  return tun_addroute(this, addr, addr, netmask);
+#else
+  return tun_sifflags(this, IFF_UP | IFF_RUNNING); 
+#endif
+
 }
 
 int tun_addroute(struct tun_t *this,
@@ -430,7 +440,8 @@
 		 struct in_addr *mask)
 {
 
-  /* TODO: Learn how to set routing table on sun and FreeBSD */
+
+  /* TODO: Learn how to set routing table on sun  */
 #ifdef __linux__
 
   struct rtentry r;
@@ -461,6 +472,55 @@
   }
   close(fd);
 
+#elif defined(__FreeBSD__)
+
+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;
+ 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);
+
 #endif
 
   return 0;
@@ -573,6 +633,7 @@
 
   snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", devnum);
   (*tun)->devname[sizeof((*tun)->devname)] = 0;
+
 #endif
 
   return 0;