Changed options
diff --git a/examples/sgsnemu.conf b/examples/sgsnemu.conf
index f2c97d7..be8f8e6 100644
--- a/examples/sgsnemu.conf
+++ b/examples/sgsnemu.conf
@@ -4,11 +4,6 @@
 #
 ##############################################################################
 
-# TAG: fg
-# Include this flag if process is to run in the foreground
-#
-fg
-
 # TAG: debug
 # Include this flag to include debug information.
 #debug
@@ -37,13 +32,14 @@
 
 # TAG: listen
 # Specifies the local IP address to listen to
-listen 10.0.0.217
+#listen 10.0.0.217
 
 # TAG: remote
 # Specifies the remote IP address to connect to
 # If DNS is setup correctly it should be possible to specify the 
 # access point name (APN) as the remote address.
-remote 10.0.0.240
+#remote 10.0.0.240
+
 
 # TAG: contexts
 # Number of contexts to establish from the emulator to the ggsn.
@@ -102,6 +98,7 @@
 # Executed with the following parameters: <devicename> <ip address>
 #ipdown /etc/sgsnemu/ip-down
 
+
 # TAG: pinghost
 # Ping a remote host through a PDP context by using ICMP echo messages.
 # If more than one PDP context has been established the ICMP messages will
diff --git a/sgsnemu/cmdline.c b/sgsnemu/cmdline.c
index 2240c56..f6f044f 100644
--- a/sgsnemu/cmdline.c
+++ b/sgsnemu/cmdline.c
@@ -44,7 +44,6 @@
   "Usage: %s [OPTIONS]...\n", PACKAGE);
   printf("   -h         --help             Print help and exit\n");
   printf("   -V         --version          Print version and exit\n");
-  printf("   -f         --fg               Run in foreground (default=off)\n");
   printf("   -d         --debug            Run in debug mode (default=off)\n");
   printf("   -cSTRING   --conf=STRING      Read configuration file\n");
   printf("              --pidfile=STRING   Filename of process id file (default='./sgsnemu.pid')\n");
@@ -94,7 +93,6 @@
 
   args_info->help_given = 0 ;
   args_info->version_given = 0 ;
-  args_info->fg_given = 0 ;
   args_info->debug_given = 0 ;
   args_info->conf_given = 0 ;
   args_info->pidfile_given = 0 ;
@@ -120,7 +118,6 @@
   args_info->pingcount_given = 0 ;
   args_info->pingquiet_given = 0 ;
 #define clear_args() { \
-  args_info->fg_flag = 0;\
   args_info->debug_flag = 0;\
   args_info->conf_arg = NULL; \
   args_info->pidfile_arg = strdup("./sgsnemu.pid") ;\
@@ -161,7 +158,6 @@
       static struct option long_options[] = {
         { "help",	0, NULL, 'h' },
         { "version",	0, NULL, 'V' },
-        { "fg",	0, NULL, 'f' },
         { "debug",	0, NULL, 'd' },
         { "conf",	1, NULL, 'c' },
         { "pidfile",	1, NULL, 0 },
@@ -189,7 +185,7 @@
         { NULL,	0, NULL, 0 }
       };
 
-      c = getopt_long (argc, argv, "hVfdc:l:r:a:i:m:q:u:p:", long_options, &option_index);
+      c = getopt_long (argc, argv, "hVdc:l:r:a:i:m:q:u:p:", long_options, &option_index);
 
       if (c == -1) break;	/* Exit from `while (1)' loop.  */
 
@@ -205,17 +201,6 @@
           cmdline_parser_print_version ();
           exit (EXIT_SUCCESS);
 
-        case 'f':	/* Run in foreground.  */
-          if (args_info->fg_given)
-            {
-              fprintf (stderr, "%s: `--fg' (`-f') option given more than once\n", PACKAGE);
-              clear_args ();
-              exit (EXIT_FAILURE);
-            }
-          args_info->fg_given = 1;
-          args_info->fg_flag = !(args_info->fg_flag);
-          break;
-
         case 'd':	/* Run in debug mode.  */
           if (args_info->debug_given)
             {
@@ -583,15 +568,6 @@
                 }
               continue;
             }
-          if (!strcmp(fopt, "fg"))
-            {
-              if (override || !args_info->fg_given)
-                {
-                  args_info->fg_given = 1;
-                  args_info->fg_flag = !(args_info->fg_flag);
-                }
-              continue;
-            }
           if (!strcmp(fopt, "debug"))
             {
               if (override || !args_info->debug_given)
diff --git a/sgsnemu/cmdline.ggo b/sgsnemu/cmdline.ggo
index 0b562ec..2c4f447 100644
--- a/sgsnemu/cmdline.ggo
+++ b/sgsnemu/cmdline.ggo
@@ -15,7 +15,6 @@
 # Use "gengetopt --conf-parser < cmdline.ggo" 
 # to generate cmdline.c and cmdline.h
 
-option  "fg"           f "Run in foreground"              flag   off
 option  "debug"        d "Run in debug mode"              flag   off
 
 option  "conf"         c "Read configuration file"        string no
diff --git a/sgsnemu/cmdline.h b/sgsnemu/cmdline.h
index 0c03629..636dcc3 100644
--- a/sgsnemu/cmdline.h
+++ b/sgsnemu/cmdline.h
@@ -20,7 +20,6 @@
 
 struct gengetopt_args_info
 {
-  int fg_flag;	/* Run in foreground (default=off).  */
   int debug_flag;	/* Run in debug mode (default=off).  */
   char * conf_arg;	/* Read configuration file.  */
   char * pidfile_arg;	/* Filename of process id file (default='./sgsnemu.pid').  */
@@ -48,7 +47,6 @@
 
   int help_given ;	/* Whether help was given.  */
   int version_given ;	/* Whether version was given.  */
-  int fg_given ;	/* Whether fg was given.  */
   int debug_given ;	/* Whether debug was given.  */
   int conf_given ;	/* Whether conf was given.  */
   int pidfile_given ;	/* Whether pidfile was given.  */
diff --git a/sgsnemu/ippool.c b/sgsnemu/ippool.c
index 3ad5c04..99842c5 100644
--- a/sgsnemu/ippool.c
+++ b/sgsnemu/ippool.c
@@ -20,34 +20,20 @@
 
 #include "ippool.h"
 
+/**
+ * lookup()
+ * Generates a 32 bit hash.
+ * Based on public domain code by Bob Jenkins
+ * It should be one of the best hash functions around in terms of both
+ * statistical properties and speed. It is NOT recommended for cryptographic
+ * purposes.
+ **/
+unsigned long int lookup( k, length, level)
+register unsigned char *k;         /* the key */
+register unsigned long int length; /* the length of the key */
+register unsigned long int level; /* the previous hash, or an arbitrary value*/
+{
 
-/*
---------------------------------------------------------------------
-Public domain by From Bob Jenkins, December 1996.
-mix -- mix 3 32-bit values reversibly.
-For every delta with one or two bit set, and the deltas of all three
-  high bits or all three low bits, whether the original value of a,b,c
-  is almost all zero or is uniformly distributed,
-* If mix() is run forward or backward, at least 32 bits in a,b,c
-  have at least 1/4 probability of changing.
-* If mix() is run forward, every bit of c will change between 1/3 and
-  2/3 of the time.  (Well, 22/100 and 78/100 for some 2-bit deltas.)
-mix() was built out of 36 single-cycle latency instructions in a 
-  structure that could supported 2x parallelism, like so:
-      a -= b; 
-      a -= c; x = (c>>13);
-      b -= c; a ^= x;
-      b -= a; x = (a<<8);
-      c -= a; b ^= x;
-      c -= b; x = (b>>13);
-      ...
-  Unfortunately, superscalar Pentiums and Sparcs can't take advantage 
-  of that parallelism.  They've also turned some of those single-cycle
-  latency instructions into multi-cycle latency instructions.  Still,
-  this is the fastest good hash I could find.  There were about 2^^68
-  to choose from.  I only looked at a billion or so.
---------------------------------------------------------------------
-*/
 #define mix(a,b,c) \
 { \
   a -= b; a -= c; a ^= (c>>13); \
@@ -60,89 +46,57 @@
   b -= c; b -= a; b ^= (a<<10); \
   c -= a; c -= b; c ^= (b>>15); \
 }
-/*
---------------------------------------------------------------------
-lookup() -- hash a variable-length key into a 32-bit value
-  k     : the key (the unaligned variable-length array of bytes)
-  len   : the length of the key, counting by bytes
-  level : can be any 4-byte value
-Returns a 32-bit value.  Every bit of the key affects every bit of
-the return value.  Every 1-bit and 2-bit delta achieves avalanche.
-About 6len+35 instructions.
 
-The best hash table sizes are powers of 2.  There is no need to do
-mod a prime (mod is sooo slow!).  If you need less than 32 bits,
-use a bitmask.  For example, if you need only 10 bits, do
-  h = (h & hashmask(10));
-In which case, the hash table should have hashsize(10) elements.
-
-If you are hashing n strings (ub1 **)k, do it like this:
-  for (i=0, h=0; i<n; ++i) h = lookup( k[i], len[i], h);
-
-By Bob Jenkins, 1996.  bob_jenkins@burtleburtle.net.  You may use this
-code any way you wish, private, educational, or commercial.
-
-See http://burtleburtle.net/bob/hash/evahash.html
-Use for hash table lookup, or anything where one collision in 2^32 is
-acceptable.  Do NOT use for cryptographic purposes.
---------------------------------------------------------------------
-*/
-
-unsigned long int lookup( k, length, level)
-register unsigned char *k;           /* the key */
-register unsigned long int length;   /* the length of the key */
-register unsigned long int level;    /* the previous hash, or an arbitrary value */
-{
-   register unsigned long int a,b,c,len;
-
-   /* Set up the internal state */
-   len = length;
-   a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
-   c = level;           /* the previous hash value */
-
-   /*---------------------------------------- handle most of the key */
-   while (len >= 12)
-   {
+  typedef  unsigned long  int  ub4;   /* unsigned 4-byte quantities */
+  typedef  unsigned       char ub1;   /* unsigned 1-byte quantities */
+  register unsigned long int a,b,c,len;
+  
+  /* Set up the internal state */
+  len = length;
+  a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
+  c = level;           /* the previous hash value */
+  
+  /*---------------------------------------- handle most of the key */
+  while (len >= 12)
+    {
       a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
       b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
       c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
       mix(a,b,c);
       k += 12; len -= 12;
-   }
-
-   /*------------------------------------- handle the last 11 bytes */
-   c += length;
-   switch(len)              /* all the case statements fall through */
-   {
-   case 11: c+=((ub4)k[10]<<24);
-   case 10: c+=((ub4)k[9]<<16);
-   case 9 : c+=((ub4)k[8]<<8);
+    }
+  
+  /*------------------------------------- handle the last 11 bytes */
+  c += length;
+  switch(len)              /* all the case statements fall through */
+    {
+    case 11: c+=((ub4)k[10]<<24);
+    case 10: c+=((ub4)k[9]<<16);
+    case 9 : c+=((ub4)k[8]<<8);
       /* the first byte of c is reserved for the length */
-   case 8 : b+=((ub4)k[7]<<24);
-   case 7 : b+=((ub4)k[6]<<16);
-   case 6 : b+=((ub4)k[5]<<8);
-   case 5 : b+=k[4];
-   case 4 : a+=((ub4)k[3]<<24);
-   case 3 : a+=((ub4)k[2]<<16);
-   case 2 : a+=((ub4)k[1]<<8);
-   case 1 : a+=k[0];
-     /* case 0: nothing left to add */
-   }
-   mix(a,b,c);
-   /*-------------------------------------------- report the result */
-   return c;
+    case 8 : b+=((ub4)k[7]<<24);
+    case 7 : b+=((ub4)k[6]<<16);
+    case 6 : b+=((ub4)k[5]<<8);
+    case 5 : b+=k[4];
+    case 4 : a+=((ub4)k[3]<<24);
+    case 3 : a+=((ub4)k[2]<<16);
+    case 2 : a+=((ub4)k[1]<<8);
+    case 1 : a+=k[0];
+      /* case 0: nothing left to add */
+    }
+  mix(a,b,c);
+  /*-------------------------------------------- report the result */
+  return c;
 }
 
-/*
-End of public domain code by From Bob Jenkins, December 1996.
---------------------------------------------------------------------
-*/
 
 int ippool_printaddr(struct ippool_t *this) {
   int n;
   printf("ippool_printaddr\n");
-  printf("First %d\n", this->first - this->member);
-  printf("Last %d\n",  this->last - this->member);
+  printf("Firstdyn %d\n", this->firstdyn - this->member);
+  printf("Lastdyn %d\n",  this->lastdyn - this->member);
+  printf("Firststat %d\n", this->firststat - this->member);
+  printf("Laststat %d\n",  this->laststat - this->member);
   printf("Listsize %d\n",  this->listsize);
 
   for (n=0; n<this->listsize; n++) {
@@ -158,6 +112,50 @@
 }
 
 
+int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member) {
+  uint32_t hash;
+  struct ippoolm_t *p;
+  struct ippoolm_t *p_prev = NULL; 
+
+  /* Insert into hash table */
+  hash = ippool_hash4(&member->addr) & this->hashmask;
+  for (p = this->hash[hash]; p; p = p->nexthash)
+    p_prev = p;
+  if (!p_prev)
+    this->hash[hash] = member;
+  else 
+    p_prev->nexthash = member;
+  return 0; /* Always OK to insert */
+}
+
+int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member) {
+  uint32_t hash;
+  struct ippoolm_t *p;
+  struct ippoolm_t *p_prev = NULL; 
+
+  /* Find in hash table */
+  hash = ippool_hash4(&member->addr) & this->hashmask;
+  for (p = this->hash[hash]; p; p = p->nexthash) {
+    if (p == member) {
+      break;
+    }
+    p_prev = p;
+  }
+
+  if (p!= member) {
+    printf("ippool_hashdel: Tried to delete member not in hash table\n");
+    return -1; /* Member was not in hash table !!! */
+  }
+
+  if (!p_prev)
+    this->hash[hash] = 0;
+  else
+    p_prev->nexthash = 0;
+
+  return 0;
+}
+
+
 unsigned long int ippool_hash4(struct in_addr *addr) {
   return lookup(&addr->s_addr, sizeof(addr->s_addr), 0);
 }
@@ -226,36 +224,64 @@
 }
 
 /* Create new address pool */
-int ippool_new(struct ippool_t **this, char *pool, int flags) {
+int ippool_new(struct ippool_t **this, char *dyn,  char *stat, 
+	       int allowdyn, int allowstat, int flags) {
 
-  /* Parse only first instance of network for now */
+  /* Parse only first instance of pool for now */
 
   int i;
-  struct ippoolm_t *p;
-  struct ippoolm_t *p_prev = NULL; 
-  uint32_t hash;
   struct in_addr addr;
   struct in_addr mask;
+  struct in_addr stataddr;
+  struct in_addr statmask;
   unsigned int m;
   unsigned int listsize;
+  unsigned int dynsize;
+  unsigned int statsize;
 
-  if (ippool_aton(&addr, &mask, pool, 0))
-    return 0; /* Failed to parse pool */
+  if (!allowdyn) {
+    dynsize = 0;
+  }
+  else {
+    if (ippool_aton(&addr, &mask, dyn, 0))
+      return -1; /* Failed to parse dynamic pool */
+    
+    m = ntohl(mask.s_addr);
+    dynsize = ((~m)+1);
+    if (flags & IPPOOL_NONETWORK)   /* Exclude network address from pool */
+      dynsize--;
+    if (flags & IPPOOL_NOBROADCAST) /* Exclude broadcast address from pool */
+      dynsize--;
+  }
 
-  m = ntohl(mask.s_addr);
-  listsize = ((~m)+1);
-  if (flags & IPPOOL_NONETWORK)   /* Exclude network address from pool */
-    listsize--;
-  if (flags & IPPOOL_NOBROADCAST) /* Exclude broadcast address from pool */
-    listsize--;
+  if (!allowstat) {
+    statsize = 0;
+    stataddr.s_addr = 0;
+    statmask.s_addr = 0;
+  }
+  else {
+    if (ippool_aton(&stataddr, &statmask, stat, 0))
+      return -1; /* Failed to parse static range */
+    
+    m = ntohl(statmask.s_addr);
+    statsize = ((~m)+1);
+    if (statsize > IPPOOL_STATSIZE) statsize = IPPOOL_STATSIZE;
+  }
+
+  listsize = dynsize + statsize; /* Allocate space for static IP addresses */
 
   if (!(*this = calloc(sizeof(struct ippool_t), 1))) {
     /* Failed to allocate memory for ippool */
     return -1;
   }
   
+  (*this)->allowdyn  = allowdyn;
+  (*this)->allowstat = allowstat;
+  (*this)->stataddr  = stataddr;
+  (*this)->statmask  = statmask;
+
   (*this)->listsize += listsize;
-  if (!((*this)->member = calloc(sizeof(struct ippoolm_t), (*this)->listsize))){
+  if (!((*this)->member = calloc(sizeof(struct ippoolm_t), listsize))){
     /* Failed to allocate memory for members in ippool */
     return -1;
   }
@@ -276,9 +302,9 @@
     return -1;
   }
   
-  (*this)->first = NULL;
-  (*this)->last = NULL;
-  for (i = 0; i<(*this)->listsize; i++) {
+  (*this)->firstdyn = NULL;
+  (*this)->lastdyn = NULL;
+  for (i = 0; i<dynsize; i++) {
 
     if (flags & IPPOOL_NONETWORK)
       (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 1);
@@ -286,29 +312,41 @@
       (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i);
 
     (*this)->member[i].inuse = 0;
-    (*this)->member[i].parent = *this;
 
     /* Insert into list of unused */
-    (*this)->member[i].prev = (*this)->last;
-    if ((*this)->last) {
-      (*this)->last->next = &((*this)->member[i]);
+    (*this)->member[i].prev = (*this)->lastdyn;
+    if ((*this)->lastdyn) {
+      (*this)->lastdyn->next = &((*this)->member[i]);
     }
     else {
-      (*this)->first = &((*this)->member[i]);
+      (*this)->firstdyn = &((*this)->member[i]);
     }
-    (*this)->last = &((*this)->member[i]);
+    (*this)->lastdyn = &((*this)->member[i]);
     (*this)->member[i].next = NULL; /* Redundant */
 
-    /* Insert into hash table */
-    hash = ippool_hash4(&(*this)->member[i].addr) & (*this)->hashmask;
-    for (p = (*this)->hash[hash]; p; p = p->nexthash)
-      p_prev = p;
-    if (!p_prev)
-      (*this)->hash[hash] = &((*this)->member[i]);
-    else 
-      p_prev->nexthash = &((*this)->member[i]);
+    ippool_hashadd(*this, &(*this)->member[i]);
   }
-  /*ippool_printaddr(*this);*/
+
+  (*this)->firststat = NULL;
+  (*this)->laststat = NULL;
+  for (i = dynsize; i<listsize; i++) {
+
+    (*this)->member[i].addr.s_addr = 0;
+    (*this)->member[i].inuse = 0;
+
+    /* Insert into list of unused */
+    (*this)->member[i].prev = (*this)->laststat;
+    if ((*this)->laststat) {
+      (*this)->laststat->next = &((*this)->member[i]);
+    }
+    else {
+      (*this)->firststat = &((*this)->member[i]);
+    }
+    (*this)->laststat = &((*this)->member[i]);
+    (*this)->member[i].next = NULL; /* Redundant */
+  }
+
+  if (0) ippool_printaddr(*this);
   return 0;
 }
 
@@ -338,16 +376,47 @@
   return -1; /* Address could not be found */
 }
 
-
-/* Get an IP address. If addr = 0.0.0.0 get a dynamic IP address. Otherwise
-   check to see if the given address is available */
+/**
+ * ippool_newip
+ * Get an IP address. If addr = 0.0.0.0 get a dynamic IP address. Otherwise
+ * check to see if the given address is available. If available within
+ * dynamic address space allocate it there, otherwise allocate within static
+ * address space.
+**/
 int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
 		 struct in_addr *addr) {
   struct ippoolm_t *p;
   struct ippoolm_t *p2 = NULL;
   uint32_t hash;
 
-  /*ippool_printaddr(this);*/
+  /* If static:
+   *   Look in dynaddr. 
+   *     If found remove from firstdyn/lastdyn linked list.
+   *   Else allocate from stataddr.
+   *    Remove from firststat/laststat linked list.
+   *    Insert into hash table.
+   *
+   * If dynamic
+   *   Remove from firstdyn/lastdyn linked list.
+   *
+   */
+
+  if (0) ippool_printaddr(this);
+
+  /* First check to see if this type of address is allowed */
+  if ((addr) && (addr->s_addr)) { /* IP address given */
+    if (!this->allowstat) {
+      return -1; /* Static not allowed */
+    }
+    if ((addr->s_addr & this->statmask.s_addr) != this->stataddr.s_addr) {
+      return -1; /* Static out of range */
+    }
+  }
+  else {
+    if (!this->allowdyn) {
+      return -1; /* Dynamic not allowed */
+    }
+  }
 
   if ((addr) && (addr->s_addr)) { /* IP address given */
     /* Find in hash table */
@@ -360,52 +429,110 @@
     }
   }
   else { /* No ip address given */
-    p2 = this -> first;
+    if (!this ->firstdyn)
+      return -1; /* No more available */
+    else
+      p2 = this ->firstdyn;
   }
 
-  if (!p2) return -1; /* Not found */
-  if (p2->inuse) return -1; /* Allready in use / Should not happen */
+  if (p2) { /* Was allocated from dynamic address pool */
+    if (p2->inuse) return -1; /* Allready in use / Should not happen */
   
-  /* Found new address. Remove from queue */
-  if (p2->prev) 
-    p2->prev->next = p2->next;
-  else
-    this->first = p2->next;
-  if (p2->next) 
-    p2->next->prev = p2->prev;
-  else
-    this->last = p2->prev;
-  p2->next = NULL;
-  p2->prev = NULL;
-  p2->inuse = 1;
-  
-  *member = p2;
-  /*ippool_printaddr(this);*/
-  return 0; /* Success */
+    /* Remove from linked list of free dynamic addresses */
+    if (p2->prev) 
+      p2->prev->next = p2->next;
+    else
+      this->firstdyn = p2->next;
+    if (p2->next) 
+      p2->next->prev = p2->prev;
+    else
+      this->lastdyn = p2->prev;
+    p2->next = NULL;
+    p2->prev = NULL;
+    p2->inuse = 1; /* Dynamic address in use */
+    
+    *member = p2;
+    if (0) ippool_printaddr(this);
+    return 0; /* Success */
+  }
+
+  /* It was not possible to allocate from dynamic address pool */
+  /* Try to allocate from static address space */
+
+  if ((addr) && (addr->s_addr)) { /* IP address given */
+    if (this->firststat)
+      return -1; /* No more available */
+    else
+      p2 = this ->firststat;
+
+    /* Remove from linked list of free static addresses */
+    if (p2->prev) 
+      p2->prev->next = p2->next;
+    else
+      this->firststat = p2->next;
+    if (p2->next) 
+      p2->next->prev = p2->prev;
+    else
+      this->laststat = p2->prev;
+    p2->next = NULL;
+    p2->prev = NULL;
+    p2->inuse = 1; /* Static address in use */
+
+    *member = p2;
+    if (0) ippool_printaddr(this);
+    return 0; /* Success */
+  }
+
+  return -1; /* Should never get here. TODO: Bad code */
 }
 
 
-int ippool_freeip(struct ippoolm_t *member) {
-  struct ippool_t *this = member->parent;
+int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member) {
   
-  /*ippool_printaddr(this);*/
+  if (0) ippool_printaddr(this);
 
   if (!member->inuse) return -1; /* Not in use: Should not happen */
 
-  /* Insert into list of unused */
-  member->prev = this->last;
-  if (this->last) {
-    this->last->next = member;
+  switch (member->inuse) {
+  case 0: /* Not in use: Should not happen */
+    return -1;
+  case 1: /* Allocated from dynamic address space */
+    /* Insert into list of unused */
+    member->prev = this->lastdyn;
+    if (this->lastdyn) {
+      this->lastdyn->next = member;
+    }
+    else {
+      this->firstdyn = member;
+    }
+    this->lastdyn = member;
+    
+    member->inuse = 0;
+    member->peer = NULL;
+    if (0) ippool_printaddr(this);
+    return 0;
+  case 2: /* Allocated from static address space */
+    if (ippool_hashdel(this, member))
+      return -1;
+    /* Insert into list of unused */
+    member->prev = this->laststat;
+    if (this->laststat) {
+      this->laststat->next = member;
+    }
+    else {
+      this->firststat = member;
+    }
+    this->laststat = member;
+    
+    member->inuse = 0;
+    member->addr.s_addr = 0;
+    member->peer = NULL;
+    member->nexthash = NULL;
+    if (0) ippool_printaddr(this);
+    return 0;
+  default: /* Should not happen */
+    return -1;
   }
-  else {
-    this->first = member;
-  }
-  this->last = member;
-
-  member->inuse = 0;
-  /*ippool_printaddr(this);*/
-  
-  return 0; /* Success */
 }
 
 
diff --git a/sgsnemu/ippool.h b/sgsnemu/ippool.h
index 2d3f575..1630a63 100644
--- a/sgsnemu/ippool.h
+++ b/sgsnemu/ippool.h
@@ -31,25 +31,30 @@
    in RFC2373.
 */
 
-typedef  unsigned long  int  ub4;   /* unsigned 4-byte quantities */
-typedef  unsigned       char ub1;
-
 #define IPPOOL_NOIP6
 
 #define IPPOOL_NONETWORK   0x01
 #define IPPOOL_NOBROADCAST 0x02
 
+#define IPPOOL_STATSIZE 0x10000
+
 struct ippoolm_t;                /* Forward declaration */
 
 struct ippool_t {
   int listsize;                  /* Total number of addresses */
+  int allowdyn;                  /* Allow dynamic IP address allocation */
+  int allowstat;                 /* Allow static IP address allocation */
+  struct in_addr stataddr;       /* Static address range network address */
+  struct in_addr statmask;       /* Static address range network mask */
   struct ippoolm_t *member;      /* Listsize array of members */
   int hashsize;                  /* Size of hash table */
   int hashlog;                   /* Log2 size of hash table */
   int hashmask;                  /* Bitmask for calculating hash */
   struct ippoolm_t **hash;       /* Hashsize array of pointer to member */
-  struct ippoolm_t *first;       /* Pointer to first available member */
-  struct ippoolm_t *last;        /* Pointer to last available member */
+  struct ippoolm_t *firstdyn;    /* Pointer to first free dynamic member */
+  struct ippoolm_t *lastdyn;     /* Pointer to last free dyanmic member */
+  struct ippoolm_t *firststat;   /* Pointer to first free static member */
+  struct ippoolm_t *laststat;    /* Pointer to last free static member */
 };
 
 struct ippoolm_t {
@@ -58,15 +63,13 @@
 #else
   struct in_addr addr;           /* IP address of this member */
 #endif
-  int inuse;                     /* 0=available; 1= inuse */
+  int inuse;                     /* 0=available; 1= dynamic; 2 = static */
   struct ippoolm_t *nexthash;    /* Linked list part of hash table */
-  struct ippoolm_t *prev, *next; /* Double linked list of available members */
-  struct ippool_t *parent;       /* Pointer to parent */
+  struct ippoolm_t *prev, *next; /* Linked list of free dynamic or static */
   void *peer;                    /* Pointer to peer protocol handler */
 };
 
-
-/* The above structures requires approximately 20+4 = 24 bytes for
+/* The above structures require approximately 20+4 = 24 bytes for
    each address (IPv4). For IPv6 the corresponding value is 32+4 = 36
    bytes for each address. */
 
@@ -74,7 +77,8 @@
 extern unsigned long int ippool_hash4(struct in_addr *addr);
 
 /* Create new address pool */
-extern int ippool_new(struct ippool_t **this, char *pool, int flags);
+extern int ippool_new(struct ippool_t **this, char *dyn,  char *stat, 
+		      int allowdyn, int allowstat, int flags);
 
 /* Delete existing address pool */
 extern int ippool_free(struct ippool_t *this);
@@ -89,7 +93,7 @@
 			struct in_addr *addr);
 
 /* Return a previously allocated IP address */
-extern int ippool_freeip(struct ippoolm_t *member);
+extern int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member);
 
 /* Get net and mask based on ascii string */
 extern int ippool_aton(struct in_addr *addr, struct in_addr *mask,
diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c
index 99f0366..ac0633b 100644
--- a/sgsnemu/sgsnemu.c
+++ b/sgsnemu/sgsnemu.c
@@ -76,6 +76,7 @@
 /* 1: Wait_connect               */
 /* 2: Connected                  */
 /* 3: Wait_disconnect            */
+/* 4: Disconnected               */
 int state = 0;                  
 
 struct gsn_t *gsn = NULL;       /* GSN instance */
@@ -217,7 +218,6 @@
     printf("remote: %s\n", args_info.remote_arg);
     printf("listen: %s\n", args_info.listen_arg);
     printf("conf: %s\n", args_info.conf_arg);
-    printf("fg: %d\n", args_info.fg_flag);
     printf("debug: %d\n", args_info.debug_flag);
     printf("imsi: %s\n", args_info.imsi_arg);
     printf("qos: %#08x\n", args_info.qos_arg);
@@ -251,7 +251,6 @@
       printf("remote: %s\n", args_info.remote_arg);
       printf("listen: %s\n", args_info.listen_arg);
       printf("conf: %s\n", args_info.conf_arg);
-      printf("fg: %d\n", args_info.fg_flag);
       printf("debug: %d\n", args_info.debug_flag);
       printf("imsi: %s\n", args_info.imsi_arg);
       printf("qos: %#08x\n", args_info.qos_arg);
@@ -279,18 +278,17 @@
   /* Handle each option */
 
   /* foreground                                                   */
-  /* If fg flag not given run as a daemon                            */
+  /* If fg flag not given run as a daemon                         */ 
+  /* Do not allow sgsnemu to run as deamon                        
   if (!args_info.fg_flag)
     {
       closelog(); 
-      /* Close the standard file descriptors. Why? */
       freopen("/dev/null", "w", stdout);
       freopen("/dev/null", "w", stderr);
       freopen("/dev/null", "r", stdin);
       daemon(0, 0);
-      /* Open log again. This time with new pid */
       openlog(PACKAGE, LOG_PID, LOG_DAEMON);
-    }
+    }                                                             */
 
   /* debug                                                        */
   options.debug = args_info.debug_flag;
@@ -750,6 +748,7 @@
 
   ipdel((struct iphash_t*) pdp->peer);
   memset(pdp->peer, 0, sizeof(struct iphash_t)); /* To be sure */
+  state = 4; /* Disconnected */
   return 0;
 }
 
@@ -867,7 +866,7 @@
     exit(1);
 
   printf("\nInitialising GTP library\n");
-  if (gtp_new(&gsn, options.statedir,  &options.listen)) {
+  if (gtp_new(&gsn, options.statedir,  &options.listen, GTP_MODE_SGSN)) {
     sys_err(LOG_ERR, __FILE__, __LINE__, 0,
 	    "Failed to create gtp");
     exit(1);