blob: 35b14a3efbe9222d6d7c7239773dd503550f8315 [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>
jjakoa7cd2492003-04-11 09:40:12 +000013#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
jjakoa7cd2492003-04-11 09:40:12 +000024
25int ippool_printaddr(struct ippool_t *this) {
26 int n;
27 printf("ippool_printaddr\n");
jjako88c22162003-07-06 19:33:18 +000028 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);
jjakoa7cd2492003-04-11 09:40:12 +000032 printf("Listsize %d\n", this->listsize);
33
34 for (n=0; n<this->listsize; n++) {
jjakoc3213962004-09-09 20:23:50 +000035 printf("Unit %d inuse %d prev %d next %d addr %s %x\n",
jjakoa7cd2492003-04-11 09:40:12 +000036 n,
37 this->member[n].inuse,
38 this->member[n].prev - this->member,
39 this->member[n].next - this->member,
jjakoc3213962004-09-09 20:23:50 +000040 inet_ntoa(this->member[n].addr),
jjakoa7cd2492003-04-11 09:40:12 +000041 this->member[n].addr.s_addr
42 );
43 }
44 return 0;
45}
46
jjako88c22162003-07-06 19:33:18 +000047int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member) {
48 uint32_t hash;
49 struct ippoolm_t *p;
50 struct ippoolm_t *p_prev = NULL;
51
52 /* 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 */
61}
62
63int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member) {
64 uint32_t hash;
65 struct ippoolm_t *p;
66 struct ippoolm_t *p_prev = NULL;
67
68 /* Find in hash table */
69 hash = ippool_hash4(&member->addr) & this->hashmask;
70 for (p = this->hash[hash]; p; p = p->nexthash) {
71 if (p == member) {
72 break;
73 }
74 p_prev = p;
75 }
76
77 if (p!= member) {
jjakoc3213962004-09-09 20:23:50 +000078 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
79 "ippool_hashdel: Tried to delete member not in hash table");
80 return -1;
jjako88c22162003-07-06 19:33:18 +000081 }
82
83 if (!p_prev)
jjakoc3213962004-09-09 20:23:50 +000084 this->hash[hash] = p->nexthash;
jjako88c22162003-07-06 19:33:18 +000085 else
jjakoc3213962004-09-09 20:23:50 +000086 p_prev->nexthash = p->nexthash;
jjako88c22162003-07-06 19:33:18 +000087
88 return 0;
89}
90
91
jjakoa7cd2492003-04-11 09:40:12 +000092unsigned long int ippool_hash4(struct in_addr *addr) {
jjakoc3213962004-09-09 20:23:50 +000093 return lookup((unsigned char*) &addr->s_addr, sizeof(addr->s_addr), 0);
jjakoa7cd2492003-04-11 09:40:12 +000094}
95
96#ifndef IPPOOL_NOIP6
97unsigned long int ippool_hash6(struct in6_addr *addr) {
jjakoc3213962004-09-09 20:23:50 +000098 return lookup((unsigned char*) addr->u6_addr8, sizeof(addr->u6_addr8), 0);
jjakoa7cd2492003-04-11 09:40:12 +000099}
100#endif
101
102
103/* Get IP address and mask */
104int ippool_aton(struct in_addr *addr, struct in_addr *mask,
105 char *pool, int number) {
106
107 /* Parse only first instance of network for now */
108 /* Eventually "number" will indicate the token which we want to parse */
109
110 unsigned int a1, a2, a3, a4;
111 unsigned int m1, m2, m3, m4;
112 int c;
113 unsigned int m;
114 int masklog;
115
116 c = sscanf(pool, "%u.%u.%u.%u/%u.%u.%u.%u",
117 &a1, &a2, &a3, &a4,
118 &m1, &m2, &m3, &m4);
119 switch (c) {
120 case 4:
jjako504ee452003-08-20 15:25:54 +0000121 mask->s_addr = 0xffffffff;
jjakoa7cd2492003-04-11 09:40:12 +0000122 break;
123 case 5:
jjakoada9ffa2004-12-30 16:39:11 +0000124 if (m1 > 32) {
jjakoc3213962004-09-09 20:23:50 +0000125 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
jjakoa7cd2492003-04-11 09:40:12 +0000126 return -1; /* Invalid mask */
127 }
128 mask->s_addr = htonl(0xffffffff << (32 - m1));
129 break;
130 case 8:
jjakoc3213962004-09-09 20:23:50 +0000131 if (m1 >= 256 || m2 >= 256 || m3 >= 256 || m4 >= 256) {
132 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
jjakoa7cd2492003-04-11 09:40:12 +0000133 return -1; /* Wrong mask format */
jjakoc3213962004-09-09 20:23:50 +0000134 }
jjakoa7cd2492003-04-11 09:40:12 +0000135 m = m1 * 0x1000000 + m2 * 0x10000 + m3 * 0x100 + m4;
136 for (masklog = 0; ((1 << masklog) < ((~m)+1)); masklog++);
jjakoc3213962004-09-09 20:23:50 +0000137 if (((~m)+1) != (1 << masklog)) {
138 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
jjakoa7cd2492003-04-11 09:40:12 +0000139 return -1; /* Wrong mask format (not all ones followed by all zeros)*/
jjakoc3213962004-09-09 20:23:50 +0000140 }
jjakoa7cd2492003-04-11 09:40:12 +0000141 mask->s_addr = htonl(m);
142 break;
143 default:
jjakoc3213962004-09-09 20:23:50 +0000144 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask");
jjakoa7cd2492003-04-11 09:40:12 +0000145 return -1; /* Invalid mask */
146 }
147
jjakoc3213962004-09-09 20:23:50 +0000148 if (a1 >= 256 || a2 >= 256 || a3 >= 256 || a4 >= 256) {
149 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Wrong IP address format");
150 return -1;
151 }
jjakoa7cd2492003-04-11 09:40:12 +0000152 else
153 addr->s_addr = htonl(a1 * 0x1000000 + a2 * 0x10000 + a3 * 0x100 + a4);
154
155 return 0;
156}
157
158/* Create new address pool */
jjako88c22162003-07-06 19:33:18 +0000159int ippool_new(struct ippool_t **this, char *dyn, char *stat,
160 int allowdyn, int allowstat, int flags) {
jjakoa7cd2492003-04-11 09:40:12 +0000161
jjako88c22162003-07-06 19:33:18 +0000162 /* Parse only first instance of pool for now */
jjakoa7cd2492003-04-11 09:40:12 +0000163
164 int i;
jjakoa7cd2492003-04-11 09:40:12 +0000165 struct in_addr addr;
166 struct in_addr mask;
jjako88c22162003-07-06 19:33:18 +0000167 struct in_addr stataddr;
168 struct in_addr statmask;
jjakoa7cd2492003-04-11 09:40:12 +0000169 unsigned int m;
170 unsigned int listsize;
jjako88c22162003-07-06 19:33:18 +0000171 unsigned int dynsize;
172 unsigned int statsize;
jjakoa7cd2492003-04-11 09:40:12 +0000173
jjako88c22162003-07-06 19:33:18 +0000174 if (!allowdyn) {
175 dynsize = 0;
176 }
177 else {
jjakoc3213962004-09-09 20:23:50 +0000178 if (ippool_aton(&addr, &mask, dyn, 0)) {
179 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
180 "Failed to parse dynamic pool");
181 return -1;
jjakoc6762cf2004-04-28 14:52:58 +0000182 }
183
jjako504ee452003-08-20 15:25:54 +0000184 /* Set IPPOOL_NONETWORK if IPPOOL_NOGATEWAY is set */
185 if (flags & IPPOOL_NOGATEWAY) {
186 flags |= IPPOOL_NONETWORK;
187 }
jjako88c22162003-07-06 19:33:18 +0000188
189 m = ntohl(mask.s_addr);
190 dynsize = ((~m)+1);
191 if (flags & IPPOOL_NONETWORK) /* Exclude network address from pool */
192 dynsize--;
jjako504ee452003-08-20 15:25:54 +0000193 if (flags & IPPOOL_NOGATEWAY) /* Exclude gateway address from pool */
194 dynsize--;
jjako88c22162003-07-06 19:33:18 +0000195 if (flags & IPPOOL_NOBROADCAST) /* Exclude broadcast address from pool */
196 dynsize--;
197 }
jjakoa7cd2492003-04-11 09:40:12 +0000198
jjako88c22162003-07-06 19:33:18 +0000199 if (!allowstat) {
200 statsize = 0;
201 stataddr.s_addr = 0;
202 statmask.s_addr = 0;
203 }
204 else {
jjakoc3213962004-09-09 20:23:50 +0000205 if (ippool_aton(&stataddr, &statmask, stat, 0)) {
206 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
207 "Failed to parse static range");
208 return -1;
209 }
210
jjako88c22162003-07-06 19:33:18 +0000211 m = ntohl(statmask.s_addr);
212 statsize = ((~m)+1);
213 if (statsize > IPPOOL_STATSIZE) statsize = IPPOOL_STATSIZE;
214 }
215
216 listsize = dynsize + statsize; /* Allocate space for static IP addresses */
jjakoa7cd2492003-04-11 09:40:12 +0000217
218 if (!(*this = calloc(sizeof(struct ippool_t), 1))) {
jjakoc3213962004-09-09 20:23:50 +0000219 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
220 "Failed to allocate memory for ippool");
jjakoa7cd2492003-04-11 09:40:12 +0000221 return -1;
222 }
223
jjako88c22162003-07-06 19:33:18 +0000224 (*this)->allowdyn = allowdyn;
225 (*this)->allowstat = allowstat;
226 (*this)->stataddr = stataddr;
227 (*this)->statmask = statmask;
228
jjakoa7cd2492003-04-11 09:40:12 +0000229 (*this)->listsize += listsize;
jjako88c22162003-07-06 19:33:18 +0000230 if (!((*this)->member = calloc(sizeof(struct ippoolm_t), listsize))){
jjakoc3213962004-09-09 20:23:50 +0000231 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
232 "Failed to allocate memory for members in ippool");
jjakoa7cd2492003-04-11 09:40:12 +0000233 return -1;
234 }
235
236 for ((*this)->hashlog = 0;
237 ((1 << (*this)->hashlog) < listsize);
238 (*this)->hashlog++);
239
240 /* printf ("Hashlog %d %d %d\n", (*this)->hashlog, listsize, (1 << (*this)->hashlog)); */
241
242 /* Determine hashsize */
243 (*this)->hashsize = 1 << (*this)->hashlog; /* Fails if mask=0: All Internet*/
244 (*this)->hashmask = (*this)->hashsize -1;
245
246 /* Allocate hash table */
247 if (!((*this)->hash = calloc(sizeof(struct ippoolm_t), (*this)->hashsize))){
jjakoc3213962004-09-09 20:23:50 +0000248 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
249 "Failed to allocate memory for hash members in ippool");
jjakoa7cd2492003-04-11 09:40:12 +0000250 return -1;
251 }
252
jjako88c22162003-07-06 19:33:18 +0000253 (*this)->firstdyn = NULL;
254 (*this)->lastdyn = NULL;
255 for (i = 0; i<dynsize; i++) {
jjakoa7cd2492003-04-11 09:40:12 +0000256
jjakoc3213962004-09-09 20:23:50 +0000257 if (flags & IPPOOL_NOGATEWAY)
jjako504ee452003-08-20 15:25:54 +0000258 (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 2);
259 else if (flags & IPPOOL_NONETWORK)
jjakoa7cd2492003-04-11 09:40:12 +0000260 (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 1);
261 else
262 (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i);
jjako504ee452003-08-20 15:25:54 +0000263
jjakoa7cd2492003-04-11 09:40:12 +0000264 (*this)->member[i].inuse = 0;
jjakoa7cd2492003-04-11 09:40:12 +0000265
266 /* Insert into list of unused */
jjako88c22162003-07-06 19:33:18 +0000267 (*this)->member[i].prev = (*this)->lastdyn;
268 if ((*this)->lastdyn) {
269 (*this)->lastdyn->next = &((*this)->member[i]);
jjakoa7cd2492003-04-11 09:40:12 +0000270 }
271 else {
jjako88c22162003-07-06 19:33:18 +0000272 (*this)->firstdyn = &((*this)->member[i]);
jjakoa7cd2492003-04-11 09:40:12 +0000273 }
jjako88c22162003-07-06 19:33:18 +0000274 (*this)->lastdyn = &((*this)->member[i]);
jjakoa7cd2492003-04-11 09:40:12 +0000275 (*this)->member[i].next = NULL; /* Redundant */
276
jjakoada9ffa2004-12-30 16:39:11 +0000277 ( void)ippool_hashadd(*this, &(*this)->member[i]);
jjakoa7cd2492003-04-11 09:40:12 +0000278 }
jjako88c22162003-07-06 19:33:18 +0000279
280 (*this)->firststat = NULL;
281 (*this)->laststat = NULL;
282 for (i = dynsize; i<listsize; i++) {
283
284 (*this)->member[i].addr.s_addr = 0;
285 (*this)->member[i].inuse = 0;
286
287 /* Insert into list of unused */
288 (*this)->member[i].prev = (*this)->laststat;
289 if ((*this)->laststat) {
290 (*this)->laststat->next = &((*this)->member[i]);
291 }
292 else {
293 (*this)->firststat = &((*this)->member[i]);
294 }
295 (*this)->laststat = &((*this)->member[i]);
296 (*this)->member[i].next = NULL; /* Redundant */
297 }
298
jjakoada9ffa2004-12-30 16:39:11 +0000299 if (0) (void)ippool_printaddr(*this);
jjakoa7cd2492003-04-11 09:40:12 +0000300 return 0;
301}
302
jjakoada9ffa2004-12-30 16:39:11 +0000303
304
jjakoa7cd2492003-04-11 09:40:12 +0000305/* Delete existing address pool */
306int ippool_free(struct ippool_t *this) {
307 free(this->hash);
308 free(this->member);
309 free(this);
310 return 0; /* Always OK */
311}
312
313/* Find an IP address in the pool */
314int ippool_getip(struct ippool_t *this, struct ippoolm_t **member,
315 struct in_addr *addr) {
316 struct ippoolm_t *p;
317 uint32_t hash;
318
319 /* Find in hash table */
320 hash = ippool_hash4(addr) & this->hashmask;
321 for (p = this->hash[hash]; p; p = p->nexthash) {
322 if ((p->addr.s_addr == addr->s_addr) && (p->inuse)) {
jjakoada9ffa2004-12-30 16:39:11 +0000323 if (member) *member = p;
jjakoa7cd2492003-04-11 09:40:12 +0000324 return 0;
325 }
326 }
jjakoada9ffa2004-12-30 16:39:11 +0000327 if (member) *member = NULL;
328 /*sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address could not be found");*/
jjakoc3213962004-09-09 20:23:50 +0000329 return -1;
jjakoa7cd2492003-04-11 09:40:12 +0000330}
331
jjako88c22162003-07-06 19:33:18 +0000332/**
333 * ippool_newip
334 * Get an IP address. If addr = 0.0.0.0 get a dynamic IP address. Otherwise
335 * check to see if the given address is available. If available within
336 * dynamic address space allocate it there, otherwise allocate within static
337 * address space.
338**/
jjakoa7cd2492003-04-11 09:40:12 +0000339int ippool_newip(struct ippool_t *this, struct ippoolm_t **member,
jjakoada9ffa2004-12-30 16:39:11 +0000340 struct in_addr *addr, int statip) {
jjakoa7cd2492003-04-11 09:40:12 +0000341 struct ippoolm_t *p;
342 struct ippoolm_t *p2 = NULL;
343 uint32_t hash;
344
jjako88c22162003-07-06 19:33:18 +0000345 /* If static:
346 * Look in dynaddr.
347 * If found remove from firstdyn/lastdyn linked list.
348 * Else allocate from stataddr.
349 * Remove from firststat/laststat linked list.
350 * Insert into hash table.
351 *
352 * If dynamic
353 * Remove from firstdyn/lastdyn linked list.
354 *
355 */
356
jjakoada9ffa2004-12-30 16:39:11 +0000357 if (0) (void)ippool_printaddr(this);
jjako88c22162003-07-06 19:33:18 +0000358
359 /* First check to see if this type of address is allowed */
jjakoada9ffa2004-12-30 16:39:11 +0000360 if ((addr) && (addr->s_addr) && statip) { /* IP address given */
jjako88c22162003-07-06 19:33:18 +0000361 if (!this->allowstat) {
jjakoc3213962004-09-09 20:23:50 +0000362 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Static IP address not allowed");
363 return -1;
jjako88c22162003-07-06 19:33:18 +0000364 }
365 if ((addr->s_addr & this->statmask.s_addr) != this->stataddr.s_addr) {
jjakoc3213962004-09-09 20:23:50 +0000366 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Static out of range");
367 return -1;
jjako88c22162003-07-06 19:33:18 +0000368 }
369 }
370 else {
371 if (!this->allowdyn) {
jjakoc3213962004-09-09 20:23:50 +0000372 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
373 "Dynamic IP address not allowed");
374 return -1;
jjako88c22162003-07-06 19:33:18 +0000375 }
376 }
jjakoa7cd2492003-04-11 09:40:12 +0000377
jjakoada9ffa2004-12-30 16:39:11 +0000378 /* If IP address given try to find it in dynamic address pool */
jjakoa7cd2492003-04-11 09:40:12 +0000379 if ((addr) && (addr->s_addr)) { /* IP address given */
380 /* Find in hash table */
381 hash = ippool_hash4(addr) & this->hashmask;
382 for (p = this->hash[hash]; p; p = p->nexthash) {
383 if ((p->addr.s_addr == addr->s_addr)) {
384 p2 = p;
385 break;
386 }
387 }
388 }
jjakoada9ffa2004-12-30 16:39:11 +0000389
390 /* If IP was already allocated we can not use it */
391 if ((!statip) && (p2) && (p2->inuse)) {
392 p2 = NULL;
393 }
394
395 /* If not found yet and dynamic IP then allocate dynamic IP */
396 if ((!p2) && (!statip)) {
jjakoc3213962004-09-09 20:23:50 +0000397 if (!this ->firstdyn) {
398 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
399 "No more IP addresses available");
400 return -1;
401 }
jjako88c22162003-07-06 19:33:18 +0000402 else
403 p2 = this ->firstdyn;
jjakoa7cd2492003-04-11 09:40:12 +0000404 }
jjakoada9ffa2004-12-30 16:39:11 +0000405
jjako88c22162003-07-06 19:33:18 +0000406 if (p2) { /* Was allocated from dynamic address pool */
jjakoc3213962004-09-09 20:23:50 +0000407 if (p2->inuse) {
408 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
409 "IP address allready in use");
410 return -1; /* Allready in use / Should not happen */
411 }
412
jjako88c22162003-07-06 19:33:18 +0000413 /* Remove from linked list of free dynamic addresses */
414 if (p2->prev)
415 p2->prev->next = p2->next;
416 else
417 this->firstdyn = p2->next;
418 if (p2->next)
419 p2->next->prev = p2->prev;
420 else
421 this->lastdyn = p2->prev;
422 p2->next = NULL;
423 p2->prev = NULL;
424 p2->inuse = 1; /* Dynamic address in use */
425
426 *member = p2;
jjakoada9ffa2004-12-30 16:39:11 +0000427 if (0) (void)ippool_printaddr(this);
jjako88c22162003-07-06 19:33:18 +0000428 return 0; /* Success */
429 }
430
431 /* It was not possible to allocate from dynamic address pool */
432 /* Try to allocate from static address space */
433
jjakoada9ffa2004-12-30 16:39:11 +0000434 if ((addr) && (addr->s_addr) && (statip)) { /* IP address given */
435 if (!this->firststat) {
jjakoc3213962004-09-09 20:23:50 +0000436 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
437 "No more IP addresses available");
jjako88c22162003-07-06 19:33:18 +0000438 return -1; /* No more available */
jjakoc3213962004-09-09 20:23:50 +0000439 }
jjako88c22162003-07-06 19:33:18 +0000440 else
441 p2 = this ->firststat;
442
443 /* Remove from linked list of free static addresses */
444 if (p2->prev)
445 p2->prev->next = p2->next;
446 else
447 this->firststat = p2->next;
448 if (p2->next)
449 p2->next->prev = p2->prev;
450 else
451 this->laststat = p2->prev;
452 p2->next = NULL;
453 p2->prev = NULL;
jjakoada9ffa2004-12-30 16:39:11 +0000454 p2->inuse = 2; /* Static address in use */
jjakoc3213962004-09-09 20:23:50 +0000455 memcpy(&p2->addr, addr, sizeof(addr));
jjako88c22162003-07-06 19:33:18 +0000456 *member = p2;
jjakoada9ffa2004-12-30 16:39:11 +0000457 (void)ippool_hashadd(this, *member);
458 if (0) (void)ippool_printaddr(this);
jjako88c22162003-07-06 19:33:18 +0000459 return 0; /* Success */
460 }
461
jjakoc3213962004-09-09 20:23:50 +0000462 sys_err(LOG_ERR, __FILE__, __LINE__, 0,
463 "Could not allocate IP address");
jjako88c22162003-07-06 19:33:18 +0000464 return -1; /* Should never get here. TODO: Bad code */
jjakoa7cd2492003-04-11 09:40:12 +0000465}
466
467
jjako88c22162003-07-06 19:33:18 +0000468int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member) {
jjakoa7cd2492003-04-11 09:40:12 +0000469
jjakoada9ffa2004-12-30 16:39:11 +0000470 if (0) (void)ippool_printaddr(this);
jjakoa7cd2492003-04-11 09:40:12 +0000471
jjakoc3213962004-09-09 20:23:50 +0000472 if (!member->inuse) {
473 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address not in use");
474 return -1; /* Not in use: Should not happen */
475 }
jjakoa7cd2492003-04-11 09:40:12 +0000476
jjako88c22162003-07-06 19:33:18 +0000477 switch (member->inuse) {
478 case 0: /* Not in use: Should not happen */
jjakoc3213962004-09-09 20:23:50 +0000479 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address not in use");
jjako88c22162003-07-06 19:33:18 +0000480 return -1;
481 case 1: /* Allocated from dynamic address space */
482 /* Insert into list of unused */
483 member->prev = this->lastdyn;
484 if (this->lastdyn) {
485 this->lastdyn->next = member;
486 }
487 else {
488 this->firstdyn = member;
489 }
490 this->lastdyn = member;
491
492 member->inuse = 0;
493 member->peer = NULL;
jjakoada9ffa2004-12-30 16:39:11 +0000494 if (0) (void)ippool_printaddr(this);
jjako88c22162003-07-06 19:33:18 +0000495 return 0;
496 case 2: /* Allocated from static address space */
497 if (ippool_hashdel(this, member))
498 return -1;
499 /* Insert into list of unused */
500 member->prev = this->laststat;
501 if (this->laststat) {
502 this->laststat->next = member;
503 }
504 else {
505 this->firststat = member;
506 }
507 this->laststat = member;
508
509 member->inuse = 0;
510 member->addr.s_addr = 0;
511 member->peer = NULL;
512 member->nexthash = NULL;
jjakoada9ffa2004-12-30 16:39:11 +0000513 if (0) (void)ippool_printaddr(this);
jjako88c22162003-07-06 19:33:18 +0000514 return 0;
515 default: /* Should not happen */
jjakoc3213962004-09-09 20:23:50 +0000516 sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Could not free IP address");
jjako88c22162003-07-06 19:33:18 +0000517 return -1;
jjakoa7cd2492003-04-11 09:40:12 +0000518 }
jjakoa7cd2492003-04-11 09:40:12 +0000519}
520
521
522#ifndef IPPOOL_NOIP6
523extern unsigned long int ippool_hash6(struct in6_addr *addr);
524extern int ippool_getip6(struct ippool_t *this, struct in6_addr *addr);
525extern int ippool_returnip6(struct ippool_t *this, struct in6_addr *addr);
526#endif