mirror of
https://github.com/zeek/zeek.git
synced 2025-10-13 03:58:20 +00:00
Add bif that allows searching for all matching subnets in table.
Example: global test: set[subnet] = { 10.0.0.0/8, 10.1.0.0/16, 10.2.0.0/16, 10.2.0.2/31 } print matching_subnets(10.2.0.2/32, test); -> [10.2.0.2/31, 10.2.0.0/16, 10.0.0.0/8]
This commit is contained in:
parent
42e4072673
commit
562e5a9f63
10 changed files with 274 additions and 11 deletions
105
src/patricia.c
105
src/patricia.c
|
@ -1,3 +1,8 @@
|
|||
/*
|
||||
* Johanna Amann <johanna@icir.org>
|
||||
*
|
||||
* Added patricia_search_all function.
|
||||
*/
|
||||
/*
|
||||
* Dave Plonka <plonka@doit.wisc.edu>
|
||||
*
|
||||
|
@ -61,6 +66,7 @@ static char copyright[] =
|
|||
#include <string.h> /* memcpy, strchr, strlen */
|
||||
#include <arpa/inet.h> /* for inet_addr */
|
||||
#include <sys/types.h> /* for u_short, etc. */
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "patricia.h"
|
||||
|
||||
|
@ -561,6 +567,105 @@ patricia_search_exact (patricia_tree_t *patricia, prefix_t *prefix)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
patricia_search_all (patricia_tree_t *patricia, prefix_t *prefix, patricia_node_t ***list, int *n)
|
||||
{
|
||||
patricia_node_t *node;
|
||||
patricia_node_t *stack[PATRICIA_MAXBITS + 1];
|
||||
u_char *addr;
|
||||
u_int bitlen;
|
||||
int cnt = 0;
|
||||
|
||||
assert (patricia);
|
||||
assert (prefix);
|
||||
assert (prefix->bitlen <= patricia->maxbits);
|
||||
assert (n);
|
||||
assert (list);
|
||||
assert (*list == NULL);
|
||||
|
||||
*n = 0;
|
||||
|
||||
if (patricia->head == NULL)
|
||||
return (NULL);
|
||||
|
||||
node = patricia->head;
|
||||
addr = prefix_touchar (prefix);
|
||||
bitlen = prefix->bitlen;
|
||||
|
||||
while (node->bit < bitlen) {
|
||||
|
||||
if (node->prefix) {
|
||||
#ifdef PATRICIA_DEBUG
|
||||
fprintf (stderr, "patricia_search_all: push %s/%d\n",
|
||||
prefix_toa (node->prefix), node->prefix->bitlen);
|
||||
#endif /* PATRICIA_DEBUG */
|
||||
stack[cnt++] = node;
|
||||
}
|
||||
|
||||
if (BIT_TEST (addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) {
|
||||
#ifdef PATRICIA_DEBUG
|
||||
if (node->prefix)
|
||||
fprintf (stderr, "patricia_search_all: take right %s/%d\n",
|
||||
prefix_toa (node->prefix), node->prefix->bitlen);
|
||||
else
|
||||
fprintf (stderr, "patricia_search_all: take right at %d\n",
|
||||
node->bit);
|
||||
#endif /* PATRICIA_DEBUG */
|
||||
node = node->r;
|
||||
} else {
|
||||
#ifdef PATRICIA_DEBUG
|
||||
if (node->prefix)
|
||||
fprintf (stderr, "patricia_search_all: take left %s/%d\n",
|
||||
prefix_toa (node->prefix), node->prefix->bitlen);
|
||||
else
|
||||
fprintf (stderr, "patricia_search_all: take left at %d\n",
|
||||
node->bit);
|
||||
#endif /* PATRICIA_DEBUG */
|
||||
node = node->l;
|
||||
}
|
||||
|
||||
if (node == NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (node && node->prefix)
|
||||
stack[cnt++] = node;
|
||||
|
||||
#ifdef PATRICIA_DEBUG
|
||||
if (node == NULL)
|
||||
fprintf (stderr, "patricia_search_all: stop at null\n");
|
||||
else if (node->prefix)
|
||||
fprintf (stderr, "patricia_search_all: stop at %s/%d\n",
|
||||
prefix_toa (node->prefix), node->prefix->bitlen);
|
||||
else
|
||||
fprintf (stderr, "patricia_search_all: stop at %d\n", node->bit);
|
||||
#endif /* PATRICIA_DEBUG */
|
||||
|
||||
if (cnt <= 0)
|
||||
return false;
|
||||
|
||||
// ok, now we have an upper bound of how much we can return. Let's just alloc that...
|
||||
patricia_node_t **outlist = calloc(cnt, sizeof(patricia_node_t*));
|
||||
|
||||
while (--cnt >= 0) {
|
||||
node = stack[cnt];
|
||||
#ifdef PATRICIA_DEBUG
|
||||
fprintf (stderr, "patricia_search_all: pop %s/%d\n",
|
||||
prefix_toa (node->prefix), node->prefix->bitlen);
|
||||
#endif /* PATRICIA_DEBUG */
|
||||
if (comp_with_mask (prefix_tochar (node->prefix), prefix_tochar (prefix), node->prefix->bitlen)) {
|
||||
#ifdef PATRICIA_DEBUG
|
||||
fprintf (stderr, "patricia_search_all: found %s/%d\n",
|
||||
prefix_toa (node->prefix), node->prefix->bitlen);
|
||||
#endif /* PATRICIA_DEBUG */
|
||||
outlist[*n] = node;
|
||||
(*n)++;
|
||||
}
|
||||
}
|
||||
*list = outlist;
|
||||
return (*n == 0);
|
||||
}
|
||||
|
||||
|
||||
/* if inclusive != 0, "best" may be the given prefix itself */
|
||||
patricia_node_t *
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue