123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- /*
- * Copyright (c) 2017 Linus Lüssing <linus.luessing@c0d3.blue>
- *
- * SPDX-License-Identifier: GPL-2.0+
- * License-Filename: LICENSE
- */
- #include <errno.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "addr_store.h"
- #include "gluon-arp-limiter.h"
- #include "lookup3.h"
- static struct addr_list *addr_node_alloc(void *addr,
- struct addr_store *store)
- {
- struct addr_list *node;
- size_t addr_len = store->addr_len;
- node = malloc(sizeof(struct addr_list) + addr_len);
- if (!node)
- return NULL;
- memcpy(node->addr, addr, addr_len);
- node->next = NULL;
- node->tic = clock;
- return node;
- }
- static struct addr_list *addr_list_search(void *addr,
- size_t addr_len,
- struct addr_list *list)
- {
- struct addr_list *node = list;
- struct addr_list *ret = NULL;
- if (!node)
- goto out;
- do {
- // Found it!
- if (!memcmp(node->addr, addr, addr_len)) {
- ret = node;
- break;
- }
- node = node->next;
- } while (node);
- out:
- return ret;
- }
- static void addr_list_add(struct addr_list *node, struct addr_list **list)
- {
- node->next = *list;
- *list = node;
- }
- static struct addr_list **addr_store_get_bucket(void *addr,
- struct addr_store *store)
- {
- int len = store->addr_len / sizeof(uint32_t);
- int idx;
- uint32_t ret;
- ret = hashword(addr, len, 0);
- idx = ret % ADDR_STORE_NUM_BUCKETS;
- return &store->buckets[idx];
- }
- int addr_store_add(void *addr, struct addr_store *store)
- {
- struct addr_list **bucket = addr_store_get_bucket(addr, store);
- struct addr_list *node = addr_list_search(addr, store->addr_len,
- *bucket);
- if (node) {
- node->tic = clock;
- return -EEXIST;
- }
- node = addr_node_alloc(addr, store);
- if (!node) {
- printf("Error: Out of memory\n");
- return -ENOMEM;
- }
- addr_list_add(node, bucket);
- return 0;
- }
- int addr_store_init(size_t addr_len,
- void (*destructor)(struct addr_list *),
- char *(*ntoa)(void *),
- struct addr_store *store)
- {
- int i;
- store->addr_len = addr_len;
- store->destructor = destructor;
- store->ntoa = ntoa;
- for (i = 0; i < ADDR_STORE_NUM_BUCKETS; i++)
- store->buckets[i] = NULL;
- return 0;
- }
- static char *addr_ntoa(void *addr, struct addr_store *store)
- {
- return store->ntoa(addr);
- }
- static void addr_store_dump(struct addr_store *store)
- {
- int i;
- struct addr_list *node;
- for (i = 0; i < ADDR_STORE_NUM_BUCKETS; i++) {
- node = store->buckets[i];
- if (node)
- printf("Bucket #%i:\n", i);
- while (node) {
- printf("\t%s\n", addr_ntoa(node->addr, store));
- node = node->next;
- }
- }
- }
- void addr_store_cleanup(struct addr_store *store)
- {
- struct addr_list *node, *prev;
- int i;
- for (i = 0; i < ADDR_STORE_NUM_BUCKETS; i++) {
- node = store->buckets[i];
- prev = NULL;
- while (node) {
- if (node->tic != clock) {
- store->destructor(node);
- if (prev) {
- prev->next = node->next;
- free(node);
- node = prev->next;
- } else {
- store->buckets[i] = node->next;
- free(node);
- node = store->buckets[i];
- }
- } else {
- prev = node;
- node = node->next;
- }
- }
- }
- addr_store_dump(store);
- }
|