QA on ippool
diff --git a/ggsn/ippool.c b/ggsn/ippool.c
index efd927e..35b14a3 100644
--- a/ggsn/ippool.c
+++ b/ggsn/ippool.c
@@ -1,7 +1,7 @@
-/*
+/*
* IP address pool functions.
* Copyright (C) 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
@@ -9,12 +9,6 @@
*
*/
-#include "../config.h"
-
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-#endif
-
#include <sys/types.h>
#include <netinet/in.h> /* in_addr */
#include <stdlib.h> /* calloc */
@@ -23,78 +17,9 @@
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
-
#include "syserr.h"
#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 static 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*/
-{
-
-#define mix(a,b,c) \
-{ \
- a -= b; a -= c; a ^= (c>>13); \
- b -= c; b -= a; b ^= (a<<8); \
- c -= a; c -= b; c ^= (b>>13); \
- a -= b; a -= c; a ^= (c>>12); \
- b -= c; b -= a; b ^= (a<<16); \
- c -= a; c -= b; c ^= (b>>5); \
- a -= b; a -= c; a ^= (c>>3); \
- b -= c; b -= a; b ^= (a<<10); \
- c -= a; c -= b; c ^= (b>>15); \
-}
-
- 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);
- /* 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;
-}
+#include "lookup.h"
int ippool_printaddr(struct ippool_t *this) {
@@ -119,7 +44,6 @@
return 0;
}
-
int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member) {
uint32_t hash;
struct ippoolm_t *p;
@@ -197,7 +121,7 @@
mask->s_addr = 0xffffffff;
break;
case 5:
- if (m1 < 0 || m1 > 32) {
+ if (m1 > 32) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
return -1; /* Invalid mask */
}
@@ -350,7 +274,7 @@
(*this)->lastdyn = &((*this)->member[i]);
(*this)->member[i].next = NULL; /* Redundant */
- ippool_hashadd(*this, &(*this)->member[i]);
+ ( void)ippool_hashadd(*this, &(*this)->member[i]);
}
(*this)->firststat = NULL;
@@ -372,10 +296,12 @@
(*this)->member[i].next = NULL; /* Redundant */
}
- if (0) ippool_printaddr(*this);
+ if (0) (void)ippool_printaddr(*this);
return 0;
}
+
+
/* Delete existing address pool */
int ippool_free(struct ippool_t *this) {
free(this->hash);
@@ -394,12 +320,12 @@
hash = ippool_hash4(addr) & this->hashmask;
for (p = this->hash[hash]; p; p = p->nexthash) {
if ((p->addr.s_addr == addr->s_addr) && (p->inuse)) {
- *member = p;
+ if (member) *member = p;
return 0;
}
}
- *member = NULL;
- sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address could not be found");
+ if (member) *member = NULL;
+ /*sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address could not be found");*/
return -1;
}
@@ -411,7 +337,7 @@
* address space.
**/
int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
- struct in_addr *addr) {
+ struct in_addr *addr, int statip) {
struct ippoolm_t *p;
struct ippoolm_t *p2 = NULL;
uint32_t hash;
@@ -428,10 +354,10 @@
*
*/
- if (0) ippool_printaddr(this);
+ if (0) (void)ippool_printaddr(this);
/* First check to see if this type of address is allowed */
- if ((addr) && (addr->s_addr)) { /* IP address given */
+ if ((addr) && (addr->s_addr) && statip) { /* IP address given */
if (!this->allowstat) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Static IP address not allowed");
return -1;
@@ -449,6 +375,7 @@
}
}
+ /* If IP address given try to find it in dynamic address pool */
if ((addr) && (addr->s_addr)) { /* IP address given */
/* Find in hash table */
hash = ippool_hash4(addr) & this->hashmask;
@@ -459,7 +386,14 @@
}
}
}
- else { /* No ip address given */
+
+ /* If IP was already allocated we can not use it */
+ if ((!statip) && (p2) && (p2->inuse)) {
+ p2 = NULL;
+ }
+
+ /* If not found yet and dynamic IP then allocate dynamic IP */
+ if ((!p2) && (!statip)) {
if (!this ->firstdyn) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"No more IP addresses available");
@@ -468,7 +402,7 @@
else
p2 = this ->firstdyn;
}
-
+
if (p2) { /* Was allocated from dynamic address pool */
if (p2->inuse) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
@@ -490,15 +424,15 @@
p2->inuse = 1; /* Dynamic address in use */
*member = p2;
- if (0) ippool_printaddr(this);
+ if (0) (void)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) {
+ if ((addr) && (addr->s_addr) && (statip)) { /* IP address given */
+ if (!this->firststat) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0,
"No more IP addresses available");
return -1; /* No more available */
@@ -517,12 +451,11 @@
this->laststat = p2->prev;
p2->next = NULL;
p2->prev = NULL;
- p2->inuse = 1; /* Static address in use */
-
+ p2->inuse = 2; /* Static address in use */
memcpy(&p2->addr, addr, sizeof(addr));
*member = p2;
- ippool_hashadd(this, *member);
- if (0) ippool_printaddr(this);
+ (void)ippool_hashadd(this, *member);
+ if (0) (void)ippool_printaddr(this);
return 0; /* Success */
}
@@ -534,7 +467,7 @@
int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member) {
- if (0) ippool_printaddr(this);
+ if (0) (void)ippool_printaddr(this);
if (!member->inuse) {
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address not in use");
@@ -558,7 +491,7 @@
member->inuse = 0;
member->peer = NULL;
- if (0) ippool_printaddr(this);
+ if (0) (void)ippool_printaddr(this);
return 0;
case 2: /* Allocated from static address space */
if (ippool_hashdel(this, member))
@@ -577,7 +510,7 @@
member->addr.s_addr = 0;
member->peer = NULL;
member->nexthash = NULL;
- if (0) ippool_printaddr(this);
+ if (0) (void)ippool_printaddr(this);
return 0;
default: /* Should not happen */
sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Could not free IP address");