blob: 7ece1e822ca7d77f9c2bda9b958b4db3ae696f1e [file] [log] [blame]
jjakoada9ffa2004-12-30 16:39:11 +00001/*
jjakoa7cd2492003-04-11 09:40:12 +00002 * IP address pool functions.
jjakoc3213962004-09-09 20:23:50 +00003 * Copyright (C) 2003, 2004 Mondru AB.
jjakoada9ffa2004-12-30 16:39:11 +00004 *
jjakoa7cd2492003-04-11 09:40:12 +00005 * The contents of this file may be used under the terms of the GNU
6 * General Public License Version 2, provided that the above copyright
7 * notice and this permission notice is included in all copies or
8 * substantial portions of the software.
9 *
jjakoa7cd2492003-04-11 09:40:12 +000010 */
11
jjako06e9f122004-01-19 18:37:58 +000012#include <sys/types.h>
Harald Weltebed35df2011-11-02 13:06:18 +010013#include <netinet/in.h> /* in_addr */
14#include <stdlib.h> /* calloc */
15#include <stdio.h> /* sscanf */
jjakoc3213962004-09-09 20:23:50 +000016#include <syslog.h>
17#include <string.h>
18#include <sys/socket.h>
19#include <arpa/inet.h>
jjakoc3213962004-09-09 20:23:50 +000020#include "syserr.h"
jjakoa7cd2492003-04-11 09:40:12 +000021#include "ippool.h"
jjakoada9ffa2004-12-30 16:39:11 +000022#include "lookup.h"
jjakoa7cd2492003-04-11 09:40:12 +000023
Harald Weltebed35df2011-11-02 13:06:18 +010024int ippool_printaddr(struct ippool_t *this)
25{
26 unsigned int n;
27 printf("ippool_printaddr\n");
28 printf("Firstdyn %d\n", this->firstdyn - this->member);
29 printf("Lastdyn %d\n", this->lastdyn - this->member);
30 printf("Firststat %d\n", this->firststat - this->member);
31 printf("Laststat %d\n", this->laststat - this->member);
32 printf("Listsize %d\n", this->listsize);
jjakoa7cd2492003-04-11 09:40:12 +000033
Harald Weltebed35df2011-11-02 13:06:18 +010034 for (n = 0; n < this->listsize; n++) {
35 printf("Unit %d inuse %d prev %d next %d addr %s %x\n",
36 n,
37 this->member[n].inuse,
38 this->member[n].prev - this->member,
39 this->member[n].next - this->member,
40 inet_ntoa(this->member[n].addr),
41 this->member[n].addr.s_addr);
42 }
43 return 0;
jjakoa7cd2492003-04-11 09:40:12 +000044}
45
Harald Weltebed35df2011-11-02 13:06:18 +010046int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member)
47{
48 uint32_t hash;
49 struct ippoolm_t *p;
50 struct ippoolm_t *p_prev = NULL;
jjako88c22162003-07-06 19:33:18 +000051
Harald Weltebed35df2011-11-02 13:06:18 +010052 /* Insert into hash table */
53 hash = ippool_hash4(&member->addr) & this->hashmask;
54 for (p = this->hash[hash]; p; p = p->nexthash)
55 p_prev = p;
56 if (!p_prev)
57 this->hash[hash] = member;
58 else
59 p_prev->nexthash = member;
60 return 0; /* Always OK to insert */
jjako88c22162003-07-06 19:33:18 +000061}
62
Harald Weltebed35df2011-11-02 13:06:18 +010063int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member)
64{
65 uint32_t hash;
66 struct ippoolm_t *p;
67 struct ippoolm_t *p_prev = NULL;
jjako88c22162003-07-06 19:33:18 +000068
Harald Weltebed35df2011-11-02 13:06:18 +010069 /* Find in hash table */
70 hash = ippool_hash4(&member->addr) & this->hashmask;
71 for (p = this->hash[hash]; p; p = p->nexthash) {
72 if (p == member) {
73 break;
74 }
75 p_prev = p;
76 }
jjako88c22162003-07-06 19:33:18 +000077
Harald Weltebed35df2011-11-02 13:06:18 +010078 if (p != member) {
79 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
80 "ippool_hashdel: Tried to delete member not in hash table");
81 return -1;
82 }
jjako88c22162003-07-06 19:33:18 +000083
Harald Weltebed35df2011-11-02 13:06:18 +010084 if (!p_prev)
85 this->hash[hash] = p->nexthash;
86 else
87 p_prev->nexthash = p->nexthash;
jjako88c22162003-07-06 19:33:18 +000088
Harald Weltebed35df2011-11-02 13:06:18 +010089 return 0;
jjako88c22162003-07-06 19:33:18 +000090}
91
Harald Weltebed35df2011-11-02 13:06:18 +010092unsigned long int ippool_hash4(struct in_addr *addr)
93{
94 return lookup((unsigned char *)&addr->s_addr, sizeof(addr->s_addr), 0);
jjakoa7cd2492003-04-11 09:40:12 +000095}
96
97#ifndef IPPOOL_NOIP6
Harald Weltebed35df2011-11-02 13:06:18 +010098unsigned long int ippool_hash6(struct in6_addr *addr)
99{
100 return lookup((unsigned char *)addr->u6_addr8, sizeof(addr->u6_addr8),
101 0);
jjakoa7cd2492003-04-11 09:40:12 +0000102}
103#endif
104
jjakoa7cd2492003-04-11 09:40:12 +0000105/* Get IP address and mask */
106int ippool_aton(struct in_addr *addr, struct in_addr *mask,
Harald Weltebed35df2011-11-02 13:06:18 +0100107 char *pool, int number)
108{
jjakoa7cd2492003-04-11 09:40:12 +0000109
Harald Weltebed35df2011-11-02 13:06:18 +0100110 /* Parse only first instance of network for now */
111 /* Eventually "number" will indicate the token which we want to parse */
jjakoa7cd2492003-04-11 09:40:12 +0000112
Harald Weltebed35df2011-11-02 13:06:18 +0100113 unsigned int a1, a2, a3, a4;
114 unsigned int m1, m2, m3, m4;
115 int c;
116 int m;
117 int masklog;
jjakoa7cd2492003-04-11 09:40:12 +0000118
Harald Weltebed35df2011-11-02 13:06:18 +0100119 c = sscanf(pool, "%u.%u.%u.%u/%u.%u.%u.%u",
120 &a1, &a2, &a3, &a4, &m1, &m2, &m3, &m4);
121 switch (c) {
122 case 4:
123 mask->s_addr = 0xffffffff;
124 break;
125 case 5:
126 if (m1 > 32) {
127 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
128 return -1; /* Invalid mask */
129 }
130 mask->s_addr = htonl(0xffffffff << (32 - m1));
131 break;
132 case 8:
133 if (m1 >= 256 || m2 >= 256 || m3 >= 256 || m4 >= 256) {
134 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
135 return -1; /* Wrong mask format */
136 }
137 m = m1 * 0x1000000 + m2 * 0x10000 + m3 * 0x100 + m4;
138 for (masklog = 0; ((1 << masklog) < ((~m) + 1)); masklog++) ;
139 if (((~m) + 1) != (1 << masklog)) {
140 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
141 return -1; /* Wrong mask format (not all ones followed by all zeros) */
142 }
143 mask->s_addr = htonl(m);
144 break;
145 default:
146 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
147 return -1; /* Invalid mask */
148 }
jjakoa7cd2492003-04-11 09:40:12 +0000149
Harald Weltebed35df2011-11-02 13:06:18 +0100150 if (a1 >= 256 || a2 >= 256 || a3 >= 256 || a4 >= 256) {
151 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
152 "Wrong IP address format");
153 return -1;
154 } else
155 addr->s_addr =
156 htonl(a1 * 0x1000000 + a2 * 0x10000 + a3 * 0x100 + a4);
jjakoa7cd2492003-04-11 09:40:12 +0000157
Harald Weltebed35df2011-11-02 13:06:18 +0100158 return 0;
jjakoa7cd2492003-04-11 09:40:12 +0000159}
160
161/* Create new address pool */
Harald Weltebed35df2011-11-02 13:06:18 +0100162int ippool_new(struct ippool_t **this, char *dyn, char *stat,
163 int allowdyn, int allowstat, int flags)
164{
jjakoa7cd2492003-04-11 09:40:12 +0000165
Harald Weltebed35df2011-11-02 13:06:18 +0100166 /* Parse only first instance of pool for now */
jjakoa7cd2492003-04-11 09:40:12 +0000167
Harald Weltebed35df2011-11-02 13:06:18 +0100168 int i;
169 struct in_addr addr;
170 struct in_addr mask;
171 struct in_addr stataddr;
172 struct in_addr statmask;
173 unsigned int m;
174 int listsize;
175 int dynsize;
176 unsigned int statsize;
jjakoa7cd2492003-04-11 09:40:12 +0000177
Harald Weltebed35df2011-11-02 13:06:18 +0100178 if (!allowdyn) {
179 dynsize = 0;
180 } else {
181 if (ippool_aton(&addr, &mask, dyn, 0)) {
182 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
183 "Failed to parse dynamic pool");
184 return -1;
185 }
jjakoc6762cf2004-04-28 14:52:58 +0000186
Harald Weltebed35df2011-11-02 13:06:18 +0100187 /* Set IPPOOL_NONETWORK if IPPOOL_NOGATEWAY is set */
188 if (flags & IPPOOL_NOGATEWAY) {
189 flags |= IPPOOL_NONETWORK;
190 }
jjakoa7cd2492003-04-11 09:40:12 +0000191
Harald Weltebed35df2011-11-02 13:06:18 +0100192 m = ntohl(mask.s_addr);
193 dynsize = ((~m) + 1);
194 if (flags & IPPOOL_NONETWORK) /* Exclude network address from pool */
195 dynsize--;
196 if (flags & IPPOOL_NOGATEWAY) /* Exclude gateway address from pool */
197 dynsize--;
198 if (flags & IPPOOL_NOBROADCAST) /* Exclude broadcast address from pool */
199 dynsize--;
200 }
jjakoc3213962004-09-09 20:23:50 +0000201
Harald Weltebed35df2011-11-02 13:06:18 +0100202 if (!allowstat) {
203 statsize = 0;
204 stataddr.s_addr = 0;
205 statmask.s_addr = 0;
206 } else {
207 if (ippool_aton(&stataddr, &statmask, stat, 0)) {
208 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
209 "Failed to parse static range");
210 return -1;
211 }
jjako88c22162003-07-06 19:33:18 +0000212
Harald Weltebed35df2011-11-02 13:06:18 +0100213 m = ntohl(statmask.s_addr);
214 statsize = ((~m) + 1);
215 if (statsize > IPPOOL_STATSIZE)
216 statsize = IPPOOL_STATSIZE;
217 }
jjakoa7cd2492003-04-11 09:40:12 +0000218
Harald Weltebed35df2011-11-02 13:06:18 +0100219 listsize = dynsize + statsize; /* Allocate space for static IP addresses */
jjako88c22162003-07-06 19:33:18 +0000220
Harald Weltebed35df2011-11-02 13:06:18 +0100221 if (!(*this = calloc(sizeof(struct ippool_t), 1))) {
222 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
223 "Failed to allocate memory for ippool");
224 return -1;
225 }
jjakoa7cd2492003-04-11 09:40:12 +0000226
Harald Weltebed35df2011-11-02 13:06:18 +0100227 (*this)->allowdyn = allowdyn;
228 (*this)->allowstat = allowstat;
229 (*this)->stataddr = stataddr;
230 (*this)->statmask = statmask;
jjakoa7cd2492003-04-11 09:40:12 +0000231
Harald Weltebed35df2011-11-02 13:06:18 +0100232 (*this)->listsize += listsize;
233 if (!((*this)->member = calloc(sizeof(struct ippoolm_t), listsize))) {
234 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
235 "Failed to allocate memory for members in ippool");
236 return -1;
237 }
jjakoa7cd2492003-04-11 09:40:12 +0000238
Harald Weltebed35df2011-11-02 13:06:18 +0100239 for ((*this)->hashlog = 0;
240 ((1 << (*this)->hashlog) < listsize); (*this)->hashlog++) ;
jjakoa7cd2492003-04-11 09:40:12 +0000241
Harald Weltebed35df2011-11-02 13:06:18 +0100242 /* printf ("Hashlog %d %d %d\n", (*this)->hashlog, listsize, (1 << (*this)->hashlog)); */
jjakoa7cd2492003-04-11 09:40:12 +0000243
Harald Weltebed35df2011-11-02 13:06:18 +0100244 /* Determine hashsize */
245 (*this)->hashsize = 1 << (*this)->hashlog; /* Fails if mask=0: All Internet */
246 (*this)->hashmask = (*this)->hashsize - 1;
jjako88c22162003-07-06 19:33:18 +0000247
Harald Weltebed35df2011-11-02 13:06:18 +0100248 /* Allocate hash table */
249 if (!
250 ((*this)->hash =
251 calloc(sizeof(struct ippoolm_t), (*this)->hashsize))) {
252 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
253 "Failed to allocate memory for hash members in ippool");
254 return -1;
255 }
jjako88c22162003-07-06 19:33:18 +0000256
Harald Weltebed35df2011-11-02 13:06:18 +0100257 (*this)->firstdyn = NULL;
258 (*this)->lastdyn = NULL;
259 for (i = 0; i < dynsize; i++) {
jjako88c22162003-07-06 19:33:18 +0000260
Harald Weltebed35df2011-11-02 13:06:18 +0100261 if (flags & IPPOOL_NOGATEWAY)
262 (*this)->member[i].addr.s_addr =
263 htonl(ntohl(addr.s_addr) + i + 2);
264 else if (flags & IPPOOL_NONETWORK)
265 (*this)->member[i].addr.s_addr =
266 htonl(ntohl(addr.s_addr) + i + 1);
267 else
268 (*this)->member[i].addr.s_addr =
269 htonl(ntohl(addr.s_addr) + i);
jjako88c22162003-07-06 19:33:18 +0000270
Harald Weltebed35df2011-11-02 13:06:18 +0100271 (*this)->member[i].inuse = 0;
272
273 /* Insert into list of unused */
274 (*this)->member[i].prev = (*this)->lastdyn;
275 if ((*this)->lastdyn) {
276 (*this)->lastdyn->next = &((*this)->member[i]);
277 } else {
278 (*this)->firstdyn = &((*this)->member[i]);
279 }
280 (*this)->lastdyn = &((*this)->member[i]);
281 (*this)->member[i].next = NULL; /* Redundant */
282
283 (void)ippool_hashadd(*this, &(*this)->member[i]);
284 }
285
286 (*this)->firststat = NULL;
287 (*this)->laststat = NULL;
288 for (i = dynsize; i < listsize; i++) {
289
290 (*this)->member[i].addr.s_addr = 0;
291 (*this)->member[i].inuse = 0;
292
293 /* Insert into list of unused */
294 (*this)->member[i].prev = (*this)->laststat;
295 if ((*this)->laststat) {
296 (*this)->laststat->next = &((*this)->member[i]);
297 } else {
298 (*this)->firststat = &((*this)->member[i]);
299 }
300 (*this)->laststat = &((*this)->member[i]);
301 (*this)->member[i].next = NULL; /* Redundant */
302 }
303
304 if (0)
305 (void)ippool_printaddr(*this);
306 return 0;
jjakoa7cd2492003-04-11 09:40:12 +0000307}
308
309/* Delete existing address pool */
Harald Weltebed35df2011-11-02 13:06:18 +0100310int ippool_free(struct ippool_t *this)
311{
312 free(this->hash);
313 free(this->member);
314 free(this);
315 return 0; /* Always OK */
jjakoa7cd2492003-04-11 09:40:12 +0000316}
317
318/* Find an IP address in the pool */
319int ippool_getip(struct ippool_t *this, struct ippoolm_t **member,
Harald Weltebed35df2011-11-02 13:06:18 +0100320 struct in_addr *addr)
321{
322 struct ippoolm_t *p;
323 uint32_t hash;
jjakoa7cd2492003-04-11 09:40:12 +0000324
Harald Weltebed35df2011-11-02 13:06:18 +0100325 /* Find in hash table */
326 hash = ippool_hash4(addr) & this->hashmask;
327 for (p = this->hash[hash]; p; p = p->nexthash) {
328 if ((p->addr.s_addr == addr->s_addr) && (p->inuse)) {
329 if (member)
330 *member = p;
331 return 0;
332 }
333 }
334 if (member)
335 *member = NULL;
336 /*sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address could not be found"); */
337 return -1;
jjakoa7cd2492003-04-11 09:40:12 +0000338}
339
jjako88c22162003-07-06 19:33:18 +0000340/**
341 * ippool_newip
342 * Get an IP address. If addr = 0.0.0.0 get a dynamic IP address. Otherwise
343 * check to see if the given address is available. If available within
344 * dynamic address space allocate it there, otherwise allocate within static
345 * address space.
346**/
jjakoa7cd2492003-04-11 09:40:12 +0000347int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
Harald Weltebed35df2011-11-02 13:06:18 +0100348 struct in_addr *addr, int statip)
349{
350 struct ippoolm_t *p;
351 struct ippoolm_t *p2 = NULL;
352 uint32_t hash;
jjakoa7cd2492003-04-11 09:40:12 +0000353
Harald Weltebed35df2011-11-02 13:06:18 +0100354 /* If static:
355 * Look in dynaddr.
356 * If found remove from firstdyn/lastdyn linked list.
357 * Else allocate from stataddr.
358 * Remove from firststat/laststat linked list.
359 * Insert into hash table.
360 *
361 * If dynamic
362 * Remove from firstdyn/lastdyn linked list.
363 *
364 */
jjako88c22162003-07-06 19:33:18 +0000365
Harald Weltebed35df2011-11-02 13:06:18 +0100366 if (0)
367 (void)ippool_printaddr(this);
jjako88c22162003-07-06 19:33:18 +0000368
Harald Weltebed35df2011-11-02 13:06:18 +0100369 /* First check to see if this type of address is allowed */
370 if ((addr) && (addr->s_addr) && statip) { /* IP address given */
371 if (!this->allowstat) {
372 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
373 "Static IP address not allowed");
374 return -1;
375 }
376 if ((addr->s_addr & this->statmask.s_addr) !=
377 this->stataddr.s_addr) {
378 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
379 "Static out of range");
380 return -1;
381 }
382 } else {
383 if (!this->allowdyn) {
384 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
385 "Dynamic IP address not allowed");
386 return -1;
387 }
388 }
jjakoa7cd2492003-04-11 09:40:12 +0000389
Harald Weltebed35df2011-11-02 13:06:18 +0100390 /* If IP address given try to find it in dynamic address pool */
391 if ((addr) && (addr->s_addr)) { /* IP address given */
392 /* Find in hash table */
393 hash = ippool_hash4(addr) & this->hashmask;
394 for (p = this->hash[hash]; p; p = p->nexthash) {
395 if ((p->addr.s_addr == addr->s_addr)) {
396 p2 = p;
397 break;
398 }
399 }
400 }
jjakoada9ffa2004-12-30 16:39:11 +0000401
Harald Weltebed35df2011-11-02 13:06:18 +0100402 /* If IP was already allocated we can not use it */
403 if ((!statip) && (p2) && (p2->inuse)) {
404 p2 = NULL;
405 }
jjakoada9ffa2004-12-30 16:39:11 +0000406
Harald Weltebed35df2011-11-02 13:06:18 +0100407 /* If not found yet and dynamic IP then allocate dynamic IP */
408 if ((!p2) && (!statip)) {
409 if (!this->firstdyn) {
410 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
411 "No more IP addresses available");
412 return -1;
413 } else
414 p2 = this->firstdyn;
415 }
jjakoc3213962004-09-09 20:23:50 +0000416
Harald Weltebed35df2011-11-02 13:06:18 +0100417 if (p2) { /* Was allocated from dynamic address pool */
418 if (p2->inuse) {
419 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
420 "IP address allready in use");
421 return -1; /* Allready in use / Should not happen */
422 }
jjako88c22162003-07-06 19:33:18 +0000423
Harald Weltebed35df2011-11-02 13:06:18 +0100424 /* Remove from linked list of free dynamic addresses */
425 if (p2->prev)
426 p2->prev->next = p2->next;
427 else
428 this->firstdyn = p2->next;
429 if (p2->next)
430 p2->next->prev = p2->prev;
431 else
432 this->lastdyn = p2->prev;
433 p2->next = NULL;
434 p2->prev = NULL;
435 p2->inuse = 1; /* Dynamic address in use */
jjako88c22162003-07-06 19:33:18 +0000436
Harald Weltebed35df2011-11-02 13:06:18 +0100437 *member = p2;
438 if (0)
439 (void)ippool_printaddr(this);
440 return 0; /* Success */
441 }
jjako88c22162003-07-06 19:33:18 +0000442
Harald Weltebed35df2011-11-02 13:06:18 +0100443 /* It was not possible to allocate from dynamic address pool */
444 /* Try to allocate from static address space */
jjako88c22162003-07-06 19:33:18 +0000445
Harald Weltebed35df2011-11-02 13:06:18 +0100446 if ((addr) && (addr->s_addr) && (statip)) { /* IP address given */
447 if (!this->firststat) {
448 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
449 "No more IP addresses available");
450 return -1; /* No more available */
451 } else
452 p2 = this->firststat;
453
454 /* Remove from linked list of free static addresses */
455 if (p2->prev)
456 p2->prev->next = p2->next;
457 else
458 this->firststat = p2->next;
459 if (p2->next)
460 p2->next->prev = p2->prev;
461 else
462 this->laststat = p2->prev;
463 p2->next = NULL;
464 p2->prev = NULL;
465 p2->inuse = 2; /* Static address in use */
466 memcpy(&p2->addr, addr, sizeof(addr));
467 *member = p2;
468 (void)ippool_hashadd(this, *member);
469 if (0)
470 (void)ippool_printaddr(this);
471 return 0; /* Success */
472 }
473
474 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
475 "Could not allocate IP address");
476 return -1; /* Should never get here. TODO: Bad code */
jjakoa7cd2492003-04-11 09:40:12 +0000477}
478
Harald Weltebed35df2011-11-02 13:06:18 +0100479int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member)
480{
jjakoa7cd2492003-04-11 09:40:12 +0000481
Harald Weltebed35df2011-11-02 13:06:18 +0100482 if (0)
483 (void)ippool_printaddr(this);
jjakoa7cd2492003-04-11 09:40:12 +0000484
Harald Weltebed35df2011-11-02 13:06:18 +0100485 if (!member->inuse) {
486 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address not in use");
487 return -1; /* Not in use: Should not happen */
488 }
jjakoa7cd2492003-04-11 09:40:12 +0000489
Harald Weltebed35df2011-11-02 13:06:18 +0100490 switch (member->inuse) {
491 case 0: /* Not in use: Should not happen */
492 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address not in use");
493 return -1;
494 case 1: /* Allocated from dynamic address space */
495 /* Insert into list of unused */
496 member->prev = this->lastdyn;
497 if (this->lastdyn) {
498 this->lastdyn->next = member;
499 } else {
500 this->firstdyn = member;
501 }
502 this->lastdyn = member;
503
504 member->inuse = 0;
505 member->peer = NULL;
506 if (0)
507 (void)ippool_printaddr(this);
508 return 0;
509 case 2: /* Allocated from static address space */
510 if (ippool_hashdel(this, member))
511 return -1;
512 /* Insert into list of unused */
513 member->prev = this->laststat;
514 if (this->laststat) {
515 this->laststat->next = member;
516 } else {
517 this->firststat = member;
518 }
519 this->laststat = member;
520
521 member->inuse = 0;
522 member->addr.s_addr = 0;
523 member->peer = NULL;
524 member->nexthash = NULL;
525 if (0)
526 (void)ippool_printaddr(this);
527 return 0;
528 default: /* Should not happen */
529 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
530 "Could not free IP address");
531 return -1;
532 }
jjakoa7cd2492003-04-11 09:40:12 +0000533}
534
jjakoa7cd2492003-04-11 09:40:12 +0000535#ifndef IPPOOL_NOIP6
536extern unsigned long int ippool_hash6(struct in6_addr *addr);
537extern int ippool_getip6(struct ippool_t *this, struct in6_addr *addr);
538extern int ippool_returnip6(struct ippool_t *this, struct in6_addr *addr);
539#endif