cosmetics
[tomato.git] / release / src / router / dhcpv6 / lease.c
blobd46ddfd1e38ef2508b8d60fad167b19a9eab2b1d
1 #include <sys/types.h>
2 /*
3 * Copyright (C) 1998 and 1999 WIDE Project.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the project nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
30 #include <unistd.h>
31 #include <syslog.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/socket.h>
35 #include <sys/queue.h>
36 #if TIME_WITH_SYS_TIME
37 # include <sys/time.h>
38 # include <time.h>
39 #else
40 # if HAVE_SYS_TIME_H
41 # include <sys/time.h>
42 # else
43 # include <time.h>
44 # endif
45 #endif
46 #include <netinet/in.h>
47 #include "dhcp6.h"
48 #include "config.h"
49 #include "common.h"
51 #ifndef FALSE
52 #define FALSE 0
53 #define TRUE !FALSE
54 #endif
56 struct hash_entry {
57 LIST_ENTRY(hash_entry) list;
58 char *val;
59 char flag; /* 0x01: DHCP6_LEASE_DECLINED */
62 /* marked as declined (e.g. someone has been using the same address) */
63 #define DHCP6_LEASE_DECLINED 0x01
65 LIST_HEAD(hash_head, hash_entry);
67 typedef unsigned int (*pfn_hash_t)(void *val) ;
68 typedef int (*pfh_hash_match_t)(void *val1, void *val2);
70 struct hash_table {
71 struct hash_head *table;
72 unsigned int size;
73 pfn_hash_t hash;
74 pfh_hash_match_t match;
77 #ifndef DHCP6_LEASE_TABLE_SIZE
78 #define DHCP6_LEASE_TABLE_SIZE 256
79 #endif
81 static struct hash_table dhcp6_lease_table;
83 static unsigned int in6_addr_hash __P((void *));
84 static int in6_addr_match __P((void *, void *));
86 static int hash_table_init __P((struct hash_table *, unsigned int,
87 pfn_hash_t, pfh_hash_match_t));
88 static void hash_table_cleanup __P((struct hash_table *));
89 static int hash_table_add __P((struct hash_table *, void *, unsigned int));
90 static int hash_table_remove __P((struct hash_table *, void *));
91 static struct hash_entry * hash_table_find __P((struct hash_table *, void *));
93 int
94 lease_init(void)
96 dprintf(LOG_DEBUG, FNAME, "called");
98 if (hash_table_init(&dhcp6_lease_table, DHCP6_LEASE_TABLE_SIZE,
99 in6_addr_hash, in6_addr_match) != 0) {
100 return (-1);
103 return (0);
106 void
107 lease_cleanup(void)
109 hash_table_cleanup(&dhcp6_lease_table);
113 lease_address(addr)
114 struct in6_addr *addr;
116 if (!addr)
117 return (FALSE);
119 dprintf(LOG_DEBUG, FNAME, "addr=%s", in6addr2str(addr, 0));
121 if (hash_table_find(&dhcp6_lease_table, addr)) {
122 dprintf(LOG_WARNING, FNAME, "already leased: %s",
123 in6addr2str(addr, 0));
124 return (FALSE);
127 if (hash_table_add(&dhcp6_lease_table, addr, sizeof(*addr)) != 0) {
128 return (FALSE);
131 return (TRUE);
134 void
135 release_address(addr)
136 struct in6_addr *addr;
138 if (!addr)
139 return;
141 dprintf(LOG_DEBUG, FNAME, "addr=%s", in6addr2str(addr, 0));
143 if (hash_table_remove(&dhcp6_lease_table, addr) != 0) {
144 dprintf(LOG_WARNING, FNAME, "not found: %s", in6addr2str(addr, 0));
148 void
149 decline_address(addr)
150 struct in6_addr *addr;
152 struct hash_entry *entry;
154 if (!addr)
155 return;
157 dprintf(LOG_DEBUG, FNAME, "addr=%s", in6addr2str(addr, 0));
159 entry = hash_table_find(&dhcp6_lease_table, addr);
160 if (entry == NULL) {
161 dprintf(LOG_WARNING, FNAME, "not found: %s",
162 in6addr2str(addr, 0));
163 return;
166 entry->flag |= DHCP6_LEASE_DECLINED;
170 is_leased(addr)
171 struct in6_addr *addr;
173 return (hash_table_find(&dhcp6_lease_table, addr) != NULL);
176 static unsigned int
177 in6_addr_hash(val)
178 void *val;
180 u_int8_t *addr = ((struct in6_addr *)val)->s6_addr;
181 unsigned int hash = 0;
182 int i;
184 for (i = 0; i < 16; i++) {
185 hash += addr[i];
188 return (hash);
191 static int
192 in6_addr_match(val1, val2)
193 void *val1, *val2;
195 struct in6_addr * addr1 = val1;
196 struct in6_addr * addr2 = val2;
198 return (memcmp(addr1->s6_addr, addr2->s6_addr, 16) == 0);
202 * hash table
204 static int
205 hash_table_init(table, size, hash, match)
206 struct hash_table *table;
207 unsigned int size;
208 pfn_hash_t hash;
209 pfh_hash_match_t match;
211 int i;
213 if (!table || !hash || !match) {
214 return (-1);
217 if ((table->table = malloc(sizeof(*table->table) * size)) == NULL) {
218 return (-1);
221 for (i = 0; i < size; i++)
222 LIST_INIT(&table->table[i]);
224 table->size = size;
225 table->hash = hash;
226 table->match = match;
228 return (0);
231 static void
232 hash_table_cleanup(table)
233 struct hash_table *table;
235 int i;
237 if (!table) {
238 return;
241 for (i = 0; i < table->size; i++) {
242 while (!LIST_EMPTY(&table->table[i])) {
243 struct hash_entry *entry = LIST_FIRST(&table->table[i]);
244 LIST_REMOVE(entry, list);
245 if (entry->val)
246 free(entry->val);
247 free(entry);
250 free(table->table);
251 memset(table, 0, sizeof(*table));
254 static int
255 hash_table_add(table, val, size)
256 struct hash_table *table;
257 void *val;
258 unsigned int size;
260 struct hash_entry *entry = NULL;
261 int i = 0;
263 if (!table || !val) {
264 return (-1);
267 if ((entry = malloc(sizeof(*entry))) == NULL) {
268 return (-1);
270 memset(entry, 0, sizeof(*entry));
272 if ((entry->val = malloc(size)) == NULL) {
273 return (-1);
275 memcpy(entry->val, val, size);
277 i = table->hash(val) % table->size;
278 LIST_INSERT_HEAD(&table->table[i], entry, list);
280 return (0);
283 static int
284 hash_table_remove(table, val)
285 struct hash_table *table;
286 void *val;
288 struct hash_entry *entry;
290 if (!table || !val) {
291 return (-1);
294 if ((entry = hash_table_find(table, val)) == NULL) {
295 return (-1);
298 LIST_REMOVE(entry, list);
299 if (entry->val)
300 free(entry->val);
301 free(entry);
303 return (0);
306 static struct hash_entry *
307 hash_table_find(table, val)
308 struct hash_table *table;
309 void *val;
311 struct hash_entry *entry;
312 int i;
314 if (!table || !val) {
315 return (NULL);
318 i = table->hash(val) % table->size;
319 LIST_FOREACH(entry, &table->table[i], list)
321 if (table->match(val, entry->val)) {
322 return (entry);
326 return (NULL);