aboutsummaryrefslogtreecommitdiffstats
path: root/src/patricia.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/patricia.c')
-rw-r--r--src/patricia.c65
1 files changed, 50 insertions, 15 deletions
diff --git a/src/patricia.c b/src/patricia.c
index c2c972a..90ce7d4 100644
--- a/src/patricia.c
+++ b/src/patricia.c
@@ -1,5 +1,5 @@
/*
- * $Id: patricia.c 7851 2016-11-06 18:19:57Z michael $
+ * $Id: patricia.c 8630 2018-11-03 19:27:05Z michael $
* Dave Plonka <plonka@doit.wisc.edu>
*
* This file had been called "radix.c" in the MRT sources.
@@ -65,7 +65,7 @@ comp_with_mask(void *addr, void *dest, unsigned int mask)
if ( /* mask/8 == 0 || */ memcmp(addr, dest, mask / 8) == 0)
{
int n = mask / 8;
- int m = ((-1) << (8 - (mask % 8)));
+ int m = ~((1 << (8 - (mask % 8))) - 1);
if (mask % 8 == 0 || (((unsigned char *)addr)[n] & m) == (((unsigned char *)dest)[n] & m))
return 1;
@@ -113,7 +113,7 @@ New_Prefix2(int family, void *dest, int bitlen, prefix_t *prefix)
if (prefix == NULL)
{
- prefix = xcalloc(sizeof(prefix_t));
+ prefix = xcalloc(sizeof(*prefix));
dynamic_allocated = 1;
}
@@ -137,6 +137,7 @@ New_Prefix(int family, void *dest, int bitlen)
static prefix_t *
ascii2prefix(int family, const char *string)
{
+ char save[INET6_ADDRSTRLEN];
int bitlen, maxbitlen = 0;
union
{
@@ -151,7 +152,7 @@ ascii2prefix(int family, const char *string)
{
family = AF_INET;
- if (strchr (string, ':'))
+ if (strchr(string, ':'))
family = AF_INET6;
}
@@ -163,16 +164,17 @@ ascii2prefix(int family, const char *string)
const char *const cp = strchr(string, '/');
if (cp)
{
- char save[MAXLINE];
+ size_t length = cp - string;
+
+ if (length >= sizeof(save))
+ return NULL;
bitlen = atoi(cp + 1);
- /* *cp = '\0'; */
/* Copy the string to save. Avoid destroying the string */
- assert(cp - string < MAXLINE);
- memcpy(save, string, cp - string);
+ memcpy(save, string, length);
+ save[length] = '\0';
- save[cp - string] = '\0';
string = save;
if (bitlen < 0 || bitlen > maxbitlen)
@@ -222,7 +224,7 @@ Deref_Prefix(prefix_t *prefix)
patricia_tree_t *
patricia_new(unsigned int maxbits)
{
- patricia_tree_t *patricia = xcalloc(sizeof *patricia);
+ patricia_tree_t *patricia = xcalloc(sizeof(*patricia));
patricia->maxbits = maxbits;
assert(maxbits <= PATRICIA_MAXBITS); /* XXX */
@@ -288,8 +290,9 @@ patricia_clear(patricia_tree_t *patricia, void (*func)(void *))
}
}
+ patricia->head = NULL;
+
assert(patricia->num_active_node == 0);
- /* xfree (patricia); */
}
void
@@ -504,9 +507,9 @@ patricia_lookup(patricia_tree_t *patricia, prefix_t *prefix)
if (patricia->head == NULL)
{
- node = xcalloc(sizeof *node);
+ node = xcalloc(sizeof(*node));
node->bit = prefix->bitlen;
- node->prefix = Ref_Prefix (prefix);
+ node->prefix = Ref_Prefix(prefix);
patricia->head = node;
#ifdef PATRICIA_DEBUG
fprintf(stderr, "patricia_lookup: new_node #0 %s/%d (head)\n",
@@ -629,7 +632,7 @@ patricia_lookup(patricia_tree_t *patricia, prefix_t *prefix)
return node;
}
- new_node = xcalloc(sizeof *new_node);
+ new_node = xcalloc(sizeof(*new_node));
new_node->bit = prefix->bitlen;
new_node->prefix = Ref_Prefix(prefix);
patricia->num_active_node++;
@@ -690,7 +693,7 @@ patricia_lookup(patricia_tree_t *patricia, prefix_t *prefix)
}
else
{
- glue = xcalloc(sizeof *glue);
+ glue = xcalloc(sizeof(*glue));
glue->bit = differ_bit;
glue->parent = node->parent;
patricia->num_active_node++;
@@ -873,6 +876,38 @@ patricia_make_and_lookup(patricia_tree_t *tree, const char *string)
return NULL;
}
+patricia_node_t *
+patricia_make_and_lookup_addr(patricia_tree_t *tree, struct sockaddr *addr, int bitlen)
+{
+ int family;
+ void *dest;
+
+ if (addr->sa_family == AF_INET6)
+ {
+ if (bitlen == 0 || bitlen > 128)
+ bitlen = 128;
+ family = AF_INET6;
+ dest = &((struct sockaddr_in6 *)addr)->sin6_addr;
+ }
+ else
+ {
+ if (bitlen == 0 || bitlen > 32)
+ bitlen = 32;
+ family = AF_INET;
+ dest = &((struct sockaddr_in *)addr)->sin_addr;
+ }
+
+ prefix_t *prefix = New_Prefix(family, dest, bitlen);
+ if (prefix)
+ {
+ patricia_node_t *node = patricia_lookup(tree, prefix);
+ Deref_Prefix(prefix);
+ return node;
+ }
+
+ return NULL;
+}
+
void
patricia_lookup_then_remove(patricia_tree_t *tree, const char *string)
{