mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1157 lines
35 KiB
C
1157 lines
35 KiB
C
16 years ago
|
/** Copyright (c) 2009 Open Information Security Foundation.
|
||
|
* \author Anoop Saldanha <poonaatsoc@gmail.com>
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdint.h>
|
||
|
#include <string.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/socket.h>
|
||
|
#include <arpa/inet.h>
|
||
|
|
||
|
#include "util-radix-tree.h"
|
||
|
#include "util-unittest.h"
|
||
|
|
||
|
/**
|
||
|
* \brief Creates a new node for the Radix tree
|
||
|
*
|
||
|
* \retval node The newly created node for the radix tree
|
||
|
*/
|
||
|
static inline SCRadixNode *SCRadixCreateNode()
|
||
|
{
|
||
|
SCRadixNode *node = NULL;
|
||
|
|
||
|
if ( (node = malloc(sizeof(SCRadixNode))) == NULL) {
|
||
|
printf("Error allocating memory\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
memset(node, 0, sizeof(SCRadixNode));
|
||
|
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Frees a Radix tree node
|
||
|
*
|
||
|
* \param node Pointer to a Radix tree node
|
||
|
*/
|
||
|
static inline void SCRadixReleaseNode(SCRadixNode *node)
|
||
|
{
|
||
|
if (node != NULL) {
|
||
|
//SCRadixReleaseKeyPrefix(node->prefix);
|
||
|
free(node);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Creates a new Prefix
|
||
|
*
|
||
|
* \param stream Data that has to be wrapped in a SCRadixPrefix instance to be
|
||
|
* processed for insertion/lookup by the radix tree
|
||
|
* \param bitlen The bitlen of the the above stream. For example if the stream
|
||
|
* holds the ipv4 address(in 1 byte), bitlen would be 32
|
||
|
*
|
||
|
* \retval prefix The newly created prefix instance on success; NULL on failure
|
||
|
*/
|
||
|
SCRadixPrefix *SCRadixCreatePrefix(uint8_t *stream, uint16_t bitlen)
|
||
|
{
|
||
|
SCRadixPrefix *prefix = NULL;
|
||
|
|
||
|
if ((bitlen % 8 != 0) || bitlen == 0) {
|
||
|
printf("Error: SCRadixCreatePrefix: Invalid bitlen: %d", bitlen);
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if (stream == NULL) {
|
||
|
printf("Error: SCRadixCreatePrefix: Argument \"stream\" NULL");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if ( (prefix = malloc(sizeof(SCRadixPrefix))) == NULL) {
|
||
|
printf("Error allocating memory\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
memset(prefix, 0, sizeof(SCRadixPrefix));
|
||
|
|
||
|
if ( (prefix->stream = malloc(bitlen / 8)) == NULL) {
|
||
|
printf("Error allocating memory\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
memset(prefix->stream, 0, bitlen / 8);
|
||
|
|
||
|
memcpy(prefix->stream, stream, bitlen / 8);
|
||
|
prefix->bitlen = bitlen;
|
||
|
|
||
|
return prefix;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Creates a new Prefix for an IPV4 address
|
||
|
*
|
||
|
* \param stream IPV4 address that has to be wrapped in a SCRadixPrefix instance
|
||
|
* to be processed for insertion/lookup by the radix tree
|
||
|
*
|
||
|
* \retval prefix The newly created prefix instance on success; NULL on failure
|
||
|
*/
|
||
|
SCRadixPrefix *SCRadixCreateIPV4Prefix(uint8_t *stream)
|
||
|
{
|
||
|
return SCRadixCreatePrefix(stream, 32);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Creates a new Prefix for an IPV6 address
|
||
|
*
|
||
|
* \param stream IPV6 address that has to be wrapped in a SCRadixPrefix instance
|
||
|
* to be processed for insertion/lookup by the radix tree
|
||
|
*
|
||
|
* \retval prefix The newly created prefix instance on success; NULL on failure
|
||
|
*/
|
||
|
SCRadixPrefix *SCRadixCreateIPV6Prefix(uint8_t *stream)
|
||
|
{
|
||
|
return SCRadixCreatePrefix(stream, 128);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Frees a SCRadixPrefix instance
|
||
|
*
|
||
|
* \param prefix Pointer to a prefix instance
|
||
|
*/
|
||
|
void SCRadixReleasePrefix(SCRadixPrefix *prefix)
|
||
|
{
|
||
|
if (prefix != NULL) {
|
||
|
if (prefix->stream != NULL)
|
||
|
free(prefix->stream);
|
||
|
free(prefix);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Creates a new Radix tree
|
||
|
*
|
||
|
* \retval tree The newly created radix tree on success
|
||
|
*/
|
||
|
SCRadixTree *SCRadixCreateRadixTree()
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
|
||
|
if ( (tree = malloc(sizeof(SCRadixTree))) == NULL) {
|
||
|
printf("Error allocating memory\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
memset(tree, 0, sizeof(SCRadixTree));
|
||
|
|
||
|
return tree;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Internal helper function used by SCRadixReleaseRadixTree to free a subtree
|
||
|
*
|
||
|
* \param node Pointer to the root of the subtree that has to be freed
|
||
|
*/
|
||
|
static void SCRadixReleaseRadixSubtree(SCRadixNode *node)
|
||
|
{
|
||
|
if (node != NULL) {
|
||
|
SCRadixReleaseRadixSubtree(node->left);
|
||
|
SCRadixReleaseRadixSubtree(node->right);
|
||
|
SCRadixReleaseNode(node);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Frees a Radix tree and all its nodes
|
||
|
*
|
||
|
* \param tree Pointer to the Radix tree that has to be freed
|
||
|
*/
|
||
|
void SCRadixReleaseRadixTree(SCRadixTree *tree)
|
||
|
{
|
||
|
SCRadixReleaseRadixSubtree(tree->head);
|
||
|
|
||
|
tree->head = NULL;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Adds a prefix to the Radix tree
|
||
|
*
|
||
|
* \param tree Pointer to the Radix tree
|
||
|
* \param prefix The prefix that has to be added to the Radix tree
|
||
|
*
|
||
|
* \retval node Pointer to the newly created node
|
||
|
*/
|
||
|
SCRadixNode *SCRadixAddKey(SCRadixPrefix *prefix, SCRadixTree *tree)
|
||
|
{
|
||
|
SCRadixNode *node = NULL;
|
||
|
SCRadixNode *new_node = NULL;
|
||
|
SCRadixNode *parent = NULL;
|
||
|
SCRadixNode *inter_node = NULL;
|
||
|
SCRadixNode *bottom_node = NULL;
|
||
|
|
||
|
uint8_t *stream = NULL;
|
||
|
uint8_t bitlen = 0;
|
||
|
|
||
|
int check_bit = 0;
|
||
|
int differ_bit = 0;
|
||
|
|
||
|
int i = 0;
|
||
|
int j = 0;
|
||
|
int temp = 0;
|
||
|
|
||
|
if (tree->head == NULL) {
|
||
|
node = SCRadixCreateNode();
|
||
|
node->prefix = prefix;
|
||
|
node->bit = prefix->bitlen;
|
||
|
tree->head = node;
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
node = tree->head;
|
||
|
stream = prefix->stream;
|
||
|
bitlen = prefix->bitlen;
|
||
|
|
||
|
/* we walk down the tree only when we satisfy 2 conditions. The first one
|
||
|
* being the incoming prefix is shorter than the differ bit of the current
|
||
|
* node. In case we fail in this aspect, we walk down to the tree, till we
|
||
|
* arrive at a node that ends in a prefix */
|
||
|
while (node->bit < bitlen || node->prefix == NULL) {
|
||
|
/* if the bitlen isn't long enough to handle the bit test, we just walk
|
||
|
* down along one of the paths, since either paths should end up with a
|
||
|
* node that has a common prefix whose differ bit is greater than the
|
||
|
* bitlen of the incoming prefix */
|
||
|
if (bitlen < node->bit) {
|
||
|
if (node->right == NULL)
|
||
|
break;
|
||
|
|
||
|
node = node->right;
|
||
|
} else {
|
||
|
if (SC_RADIX_BITTEST(stream[node->bit >> 3],
|
||
|
(0x80 >> (node->bit % 8))) ) {
|
||
|
if (node->right == NULL)
|
||
|
break;
|
||
|
|
||
|
node = node->right;
|
||
|
} else {
|
||
|
if (node->left == NULL)
|
||
|
break;
|
||
|
|
||
|
node = node->left;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* we need to keep a reference to the bottom-most node, that actually holds
|
||
|
* the prefix */
|
||
|
bottom_node = node;
|
||
|
|
||
|
check_bit = (node->bit < bitlen)? node->bit: bitlen;
|
||
|
for (i = 0; (i * 8) < check_bit; i++) {
|
||
|
if ((temp = (stream[i] ^ bottom_node->prefix->stream[i])) == 0) {
|
||
|
differ_bit = (i + 1) * 8;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
/* find out the position where the first bit differs. This method is
|
||
|
* larger and faster, but with larger caches these days we don't have
|
||
|
* to worry about cache misses */
|
||
|
temp = temp * 2;
|
||
|
if (temp >= 256)
|
||
|
j = 0;
|
||
|
else if (temp >= 128)
|
||
|
j = 1;
|
||
|
else if (temp >= 64)
|
||
|
j = 2;
|
||
|
else if (temp >= 32)
|
||
|
j = 3;
|
||
|
else if (temp >= 16)
|
||
|
j = 4;
|
||
|
else if (temp >= 8)
|
||
|
j = 5;
|
||
|
else if (temp >= 4)
|
||
|
j = 6;
|
||
|
else if (temp >= 2)
|
||
|
j = 7;
|
||
|
|
||
|
differ_bit = i * 8 + j;
|
||
|
break;
|
||
|
}
|
||
|
if (check_bit < differ_bit)
|
||
|
differ_bit = check_bit;
|
||
|
|
||
|
/* walk up the tree till we find the position, to fit our new node in */
|
||
|
parent = node->parent;
|
||
|
while (parent && differ_bit <= parent->bit) {
|
||
|
node = parent;
|
||
|
parent = node->parent;
|
||
|
}
|
||
|
|
||
|
/* We already have the node in the tree with the same differing bit pstn */
|
||
|
if (differ_bit == bitlen && node->bit == bitlen) {
|
||
|
if (node->prefix)
|
||
|
return node;
|
||
|
|
||
|
node->prefix = SCRadixCreatePrefix(prefix->stream, prefix->bitlen);
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
new_node = SCRadixCreateNode();
|
||
|
new_node->prefix = prefix;
|
||
|
new_node->bit = prefix->bitlen;
|
||
|
|
||
|
/* indicates that we have got a key that has length that is already covered
|
||
|
* by a prefix of some other key in the tree. We create a new intermediate
|
||
|
* node with a single child and stick it in */
|
||
|
if (differ_bit == bitlen) {
|
||
|
if (SC_RADIX_BITTEST(bottom_node->prefix->stream[differ_bit >> 3],
|
||
|
(0x80 >> (differ_bit % 8))) ) {
|
||
|
new_node->right = node;
|
||
|
} else {
|
||
|
new_node->left = node;
|
||
|
}
|
||
|
new_node->parent = node->parent;
|
||
|
|
||
|
if (node->parent == NULL)
|
||
|
tree->head = new_node;
|
||
|
else if (node->parent->right == node)
|
||
|
node->parent->right = new_node;
|
||
|
else
|
||
|
node->parent->left = new_node;
|
||
|
|
||
|
node->parent = new_node;
|
||
|
} else {
|
||
|
inter_node = SCRadixCreateNode();
|
||
|
inter_node->prefix = NULL;
|
||
|
inter_node->bit = differ_bit;
|
||
|
inter_node->parent = node->parent;
|
||
|
|
||
|
if (SC_RADIX_BITTEST(stream[differ_bit >> 3],
|
||
|
(0x80 >> (differ_bit % 8))) ) {
|
||
|
inter_node->left = node;
|
||
|
inter_node->right = new_node;
|
||
|
} else {
|
||
|
inter_node->left = new_node;
|
||
|
inter_node->right = node;
|
||
|
}
|
||
|
new_node->parent = inter_node;
|
||
|
|
||
|
if (node->parent == NULL)
|
||
|
tree->head = inter_node;
|
||
|
else if (node->parent->right == node)
|
||
|
node->parent->right = inter_node;
|
||
|
else
|
||
|
node->parent->left = inter_node;
|
||
|
|
||
|
node->parent = inter_node;
|
||
|
}
|
||
|
|
||
|
return new_node;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Removes a key from the Radix tree
|
||
|
*
|
||
|
* \param prefix Pointer to the key instance that has to be removed
|
||
|
* \param tree Pointer to the Radix tree from which the key has to be removed
|
||
|
*/
|
||
|
void SCRadixRemoveKey(SCRadixPrefix *prefix, SCRadixTree *tree)
|
||
|
{
|
||
|
SCRadixNode *node = tree->head;
|
||
|
SCRadixNode *parent = NULL;
|
||
|
SCRadixNode *temp = NULL;
|
||
|
int mask = 0;
|
||
|
int i = 0;
|
||
|
|
||
|
if (node == NULL)
|
||
|
return;
|
||
|
|
||
|
while (node->bit < prefix->bitlen) {
|
||
|
if (SC_RADIX_BITTEST(prefix->stream[node->bit >> 3],
|
||
|
(0x80 >> (node->bit % 8))) ) {
|
||
|
node = node->right;
|
||
|
} else {
|
||
|
node = node->left;
|
||
|
}
|
||
|
|
||
|
if (node == NULL)
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (node->bit != prefix->bitlen || node->prefix == NULL)
|
||
|
return;
|
||
|
|
||
|
i = prefix->bitlen / 8;
|
||
|
if (memcmp(node->prefix->stream, prefix->stream, i) == 0) {
|
||
|
mask = -1 << (8 - prefix->bitlen % 8);
|
||
|
|
||
|
if (prefix->bitlen % 8 == 0 ||
|
||
|
(node->prefix->stream[i] & mask) == (prefix->stream[i] & mask))
|
||
|
;
|
||
|
else
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (tree->head == node) {
|
||
|
free(node);
|
||
|
tree->head = NULL;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
parent = node->parent;
|
||
|
if (parent->parent != NULL) {
|
||
|
if (parent->parent->left == parent) {
|
||
|
if (node->parent->left == node) {
|
||
|
parent->parent->left = parent->right;
|
||
|
parent->right->parent = parent->parent;
|
||
|
} else {
|
||
|
parent->parent->left = parent->left;
|
||
|
parent->left->parent = parent->parent;
|
||
|
}
|
||
|
} else {
|
||
|
if (node->parent->left == node) {
|
||
|
parent->parent->right = parent->right;
|
||
|
parent->right->parent = parent->parent;
|
||
|
} else {
|
||
|
parent->parent->right = parent->left;
|
||
|
parent->left->parent = parent->parent;
|
||
|
}
|
||
|
}
|
||
|
SCRadixReleaseNode(parent);
|
||
|
SCRadixReleaseNode(node);
|
||
|
} else {
|
||
|
temp = tree->head;
|
||
|
if (parent->left == node) {
|
||
|
tree->head->right->parent = NULL;
|
||
|
tree->head = tree->head->right;
|
||
|
} else {
|
||
|
tree->head->left->parent = NULL;
|
||
|
tree->head = tree->head->left;
|
||
|
}
|
||
|
SCRadixReleaseNode(temp);
|
||
|
SCRadixReleaseNode(node);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Checks if a key is present in the tree
|
||
|
*
|
||
|
* \param prefix Pointer to a SCRadixPrefix instance that holds the key to be
|
||
|
* checked
|
||
|
* \param tree Pointer to the Radix tree instance
|
||
|
*/
|
||
|
SCRadixNode *SCRadixFindKey(SCRadixPrefix *prefix, SCRadixTree *tree)
|
||
|
{
|
||
|
SCRadixNode *node = tree->head;
|
||
|
int mask = 0;
|
||
|
int i = 0;
|
||
|
|
||
|
if (tree->head == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
while (node->bit < prefix->bitlen) {
|
||
|
if (SC_RADIX_BITTEST(prefix->stream[node->bit >> 3],
|
||
|
(0x80 >> (node->bit % 8))) ) {
|
||
|
node = node->right;
|
||
|
} else {
|
||
|
node = node->left;
|
||
|
}
|
||
|
|
||
|
if (node == NULL)
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if (node->bit != prefix->bitlen || node->prefix == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
i = prefix->bitlen / 8;
|
||
|
if (memcmp(node->prefix->stream, prefix->stream, i) == 0) {
|
||
|
mask = -1 << (8 - prefix->bitlen % 8);
|
||
|
|
||
|
if (prefix->bitlen % 8 == 0 ||
|
||
|
(node->prefix->stream[i] & mask) == (prefix->stream[i] & mask))
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Prints the node information from a Radix tree
|
||
|
*
|
||
|
* \param node Pointer to the Radix node whose information has to be printed
|
||
|
* \param level Used for indentation purposes
|
||
|
*/
|
||
|
static void SCRadixPrintNodeInfo(SCRadixNode *node, int level)
|
||
|
{
|
||
|
int i = 0;
|
||
|
|
||
|
if (node == NULL)
|
||
|
return;
|
||
|
|
||
|
for (i = 0; i < level; i++)
|
||
|
printf(" ");
|
||
|
|
||
|
printf("%d (", node->bit);
|
||
|
if (node->prefix != NULL) {
|
||
|
for (i = 0; i * 8 < node->prefix->bitlen; i++) {
|
||
|
if (i != 0)
|
||
|
printf(".");
|
||
|
printf("%d", node->prefix->stream[i]);
|
||
|
}
|
||
|
printf(")\n");
|
||
|
} else {
|
||
|
printf("NULL)\n");
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Helper function used by SCRadixPrintTree. Prints the subtree with
|
||
|
* node as the root of the subtree
|
||
|
*
|
||
|
* \param node Pointer to the node that is the root of the subtree to be printed
|
||
|
* \param level Used for indentation purposes
|
||
|
*/
|
||
|
static void SCRadixPrintRadixSubtree(SCRadixNode *node, int level)
|
||
|
{
|
||
|
if (node != NULL) {
|
||
|
SCRadixPrintNodeInfo(node, level);
|
||
|
SCRadixPrintRadixSubtree(node->left, level + 1);
|
||
|
SCRadixPrintRadixSubtree(node->right, level + 1);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* \brief Prints the Radix Tree. While printing the radix tree we use the
|
||
|
* following format
|
||
|
*
|
||
|
* Parent_0
|
||
|
* Left_Child_1
|
||
|
* Left_Child_2
|
||
|
* Right_Child_2
|
||
|
* Right_Child_1
|
||
|
* Left_Child_2
|
||
|
* Right_Child_2 and so on
|
||
|
*
|
||
|
* Each node printed out holds details on the next bit that differs
|
||
|
* amongst its children, and if the node holds a prefix, the perfix is
|
||
|
* printed as well.
|
||
|
*
|
||
|
* \param tree Pointer to the Radix tree that has to be printed
|
||
|
*/
|
||
|
void SCRadixPrintTree(SCRadixTree *tree)
|
||
|
{
|
||
|
printf("Printing the Radix Tree: \n");
|
||
|
|
||
|
SCRadixPrintRadixSubtree(tree->head, 0);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/*------------------------------------Unit_Tests------------------------------*/
|
||
|
|
||
|
#ifdef UNITTESTS
|
||
|
|
||
|
int SCRadixTestInsertion01(void)
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
SCRadixPrefix *prefix = NULL;
|
||
|
SCRadixNode *node[2];
|
||
|
|
||
|
int result = 1;
|
||
|
|
||
|
tree = SCRadixCreateRadixTree();
|
||
|
prefix = SCRadixCreatePrefix((uint8_t *)"abaa", 32);
|
||
|
node[0] = SCRadixAddKey(prefix, tree);
|
||
|
prefix = SCRadixCreatePrefix((uint8_t *)"abab", 32);
|
||
|
node[1] = SCRadixAddKey(prefix, tree);
|
||
|
|
||
|
result &= (tree->head->bit == 30);
|
||
|
result &= (tree->head->right == node[0]);
|
||
|
result &= (tree->head->left == node[1]);
|
||
|
|
||
|
SCRadixReleaseRadixTree(tree);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int SCRadixTestInsertion02(void)
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
SCRadixPrefix *prefix = NULL;
|
||
|
|
||
|
int result = 1;
|
||
|
|
||
|
tree = SCRadixCreateRadixTree();
|
||
|
prefix = SCRadixCreatePrefix((uint8_t *)"aaaaaa", 48);
|
||
|
SCRadixAddKey(prefix, tree);
|
||
|
prefix = SCRadixCreatePrefix((uint8_t *)"aaaaab", 48);
|
||
|
SCRadixAddKey(prefix, tree);
|
||
|
prefix = SCRadixCreatePrefix((uint8_t *)"aaaaaba", 56);
|
||
|
SCRadixAddKey(prefix, tree);
|
||
|
prefix = SCRadixCreatePrefix((uint8_t *)"abab", 32);
|
||
|
SCRadixAddKey(prefix, tree);
|
||
|
|
||
|
SCRadixReleaseRadixTree(tree);
|
||
|
|
||
|
/* If we don't have a segfault till here we have succeeded */
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
int SCRadixTestIPV4Insertion03(void)
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
SCRadixPrefix *prefix[10];
|
||
|
SCRadixPrefix *temp_prefix = NULL;
|
||
|
|
||
|
struct sockaddr_in servaddr;
|
||
|
|
||
|
int result = 1;
|
||
|
|
||
|
/* add the keys */
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
tree = SCRadixCreateRadixTree();
|
||
|
prefix[0] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[0], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[1] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[1], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[2] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[3] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[3], tree);
|
||
|
|
||
|
/* Try to add the prefix that already exists in the tree */
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[4] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[4], tree);
|
||
|
|
||
|
if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[5] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[5], tree);
|
||
|
|
||
|
if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[6] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[6], tree);
|
||
|
|
||
|
/* test the existence of keys */
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) != NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.168.1.3", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "127.234.2.62", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[2], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[3], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[4], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[5], tree) != NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.168.1.6", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
SCRadixReleaseRadixTree(tree);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
int SCRadixTestIPV4Removal04(void)
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
SCRadixPrefix *prefix[10];
|
||
|
|
||
|
struct sockaddr_in servaddr;
|
||
|
|
||
|
int result = 1;
|
||
|
|
||
|
/* add the keys */
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
tree = SCRadixCreateRadixTree();
|
||
|
prefix[0] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[0], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[1] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[1], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[2] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[3] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[3], tree);
|
||
|
|
||
|
/* Try to add the prefix that already exists in the tree */
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[4] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[4], tree);
|
||
|
|
||
|
if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[5] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[5], tree);
|
||
|
|
||
|
if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[6] = SCRadixCreateIPV4Prefix((uint8_t *)&servaddr.sin_addr);
|
||
|
SCRadixAddKey(prefix[6], tree);
|
||
|
|
||
|
/* test the existence of keys */
|
||
|
SCRadixRemoveKey(prefix[0], tree);
|
||
|
SCRadixRemoveKey(prefix[2], tree);
|
||
|
SCRadixRemoveKey(prefix[5], tree);
|
||
|
SCRadixRemoveKey(prefix[3], tree);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[3], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[6], tree) != NULL);
|
||
|
|
||
|
SCRadixRemoveKey(prefix[1], tree);
|
||
|
SCRadixRemoveKey(prefix[4], tree);
|
||
|
SCRadixRemoveKey(prefix[6], tree);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[5], tree) == NULL);
|
||
|
result &= (tree->head == NULL);
|
||
|
|
||
|
SCRadixReleaseRadixTree(tree);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
int SCRadixTestCharacterInsertion05(void)
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
SCRadixPrefix *prefix[10];
|
||
|
SCRadixPrefix *temp_prefix = NULL;
|
||
|
|
||
|
int result = 1;
|
||
|
|
||
|
tree = SCRadixCreateRadixTree();
|
||
|
|
||
|
/* Let us have our team here ;-) */
|
||
|
prefix[0] = SCRadixCreatePrefix((uint8_t *)"Victor", 48);
|
||
|
SCRadixAddKey(prefix[0], tree);
|
||
|
|
||
|
prefix[1] = SCRadixCreatePrefix((uint8_t *)"Matt", 32);
|
||
|
SCRadixAddKey(prefix[1], tree);
|
||
|
|
||
|
prefix[2] = SCRadixCreatePrefix((uint8_t *)"Josh", 56);
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
prefix[3] = SCRadixCreatePrefix((uint8_t *)"Margaret", 64);
|
||
|
SCRadixAddKey(prefix[3], tree);
|
||
|
|
||
|
prefix[4] = SCRadixCreatePrefix((uint8_t *)"Pablo", 40);
|
||
|
SCRadixAddKey(prefix[4], tree);
|
||
|
|
||
|
prefix[5] = SCRadixCreatePrefix((uint8_t *)"Brian", 40);
|
||
|
SCRadixAddKey(prefix[5], tree);
|
||
|
|
||
|
prefix[6] = SCRadixCreatePrefix((uint8_t *)"Jasonish", 64);
|
||
|
SCRadixAddKey(prefix[6], tree);
|
||
|
|
||
|
prefix[7] = SCRadixCreatePrefix((uint8_t *)"Jasonmc", 56);
|
||
|
SCRadixAddKey(prefix[7], tree);
|
||
|
|
||
|
prefix[8] = SCRadixCreatePrefix((uint8_t *)"Nathan", 48);
|
||
|
SCRadixAddKey(prefix[8], tree);
|
||
|
|
||
|
prefix[9] = SCRadixCreatePrefix((uint8_t *)"Anoop", 40);
|
||
|
SCRadixAddKey(prefix[9], tree);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[1], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[2], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[3], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[4], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[5], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[6], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[7], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[8], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[9], tree) != NULL);
|
||
|
|
||
|
temp_prefix = SCRadixCreatePrefix((uint8_t *)"bamboo", 48);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
temp_prefix = SCRadixCreatePrefix((uint8_t *)"bool", 32);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
temp_prefix = SCRadixCreatePrefix((uint8_t *)"meerkat", 56);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
temp_prefix = SCRadixCreatePrefix((uint8_t *)"Victor", 48);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
|
||
|
SCRadixReleaseRadixTree(tree);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int SCRadixTestCharacterRemoval06(void)
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
SCRadixPrefix *prefix[10];
|
||
|
|
||
|
int result = 1;
|
||
|
|
||
|
tree = SCRadixCreateRadixTree();
|
||
|
|
||
|
/* Let us have our team here ;-) */
|
||
|
prefix[0] = SCRadixCreatePrefix((uint8_t *)"Victor", 48);
|
||
|
SCRadixAddKey(prefix[0], tree);
|
||
|
|
||
|
prefix[1] = SCRadixCreatePrefix((uint8_t *)"Matt", 32);
|
||
|
SCRadixAddKey(prefix[1], tree);
|
||
|
|
||
|
prefix[2] = SCRadixCreatePrefix((uint8_t *)"Josh", 56);
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
prefix[3] = SCRadixCreatePrefix((uint8_t *)"Margaret", 64);
|
||
|
SCRadixAddKey(prefix[3], tree);
|
||
|
|
||
|
prefix[4] = SCRadixCreatePrefix((uint8_t *)"Pablo", 40);
|
||
|
SCRadixAddKey(prefix[4], tree);
|
||
|
|
||
|
prefix[5] = SCRadixCreatePrefix((uint8_t *)"Brian", 40);
|
||
|
SCRadixAddKey(prefix[5], tree);
|
||
|
|
||
|
prefix[6] = SCRadixCreatePrefix((uint8_t *)"Jasonish", 64);
|
||
|
SCRadixAddKey(prefix[6], tree);
|
||
|
|
||
|
prefix[7] = SCRadixCreatePrefix((uint8_t *)"Jasonmc", 56);
|
||
|
SCRadixAddKey(prefix[7], tree);
|
||
|
|
||
|
prefix[8] = SCRadixCreatePrefix((uint8_t *)"Nathan", 48);
|
||
|
SCRadixAddKey(prefix[8], tree);
|
||
|
|
||
|
prefix[9] = SCRadixCreatePrefix((uint8_t *)"Anoop", 40);
|
||
|
SCRadixAddKey(prefix[9], tree);
|
||
|
|
||
|
SCRadixRemoveKey(prefix[8], tree);
|
||
|
SCRadixRemoveKey(prefix[5], tree);
|
||
|
SCRadixRemoveKey(prefix[3], tree);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[1], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[2], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[3], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[5], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[8], tree) == NULL);
|
||
|
|
||
|
SCRadixRemoveKey(prefix[0], tree);
|
||
|
SCRadixRemoveKey(prefix[2], tree);
|
||
|
SCRadixRemoveKey(prefix[7], tree);
|
||
|
SCRadixRemoveKey(prefix[1], tree);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[4], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[6], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[9], tree) != NULL);
|
||
|
|
||
|
SCRadixRemoveKey(prefix[4], tree);
|
||
|
SCRadixRemoveKey(prefix[6], tree);
|
||
|
SCRadixRemoveKey(prefix[9], tree);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[4], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[6], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[9], tree) == NULL);
|
||
|
|
||
|
result &= (tree->head == NULL);
|
||
|
|
||
|
SCRadixReleaseRadixTree(tree);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int SCRadixTestIPV6Insertion07(void)
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
SCRadixPrefix *prefix[10];
|
||
|
SCRadixPrefix *temp_prefix = NULL;
|
||
|
|
||
|
struct sockaddr_in6 servaddr;
|
||
|
|
||
|
int result = 1;
|
||
|
|
||
|
/* add the keys */
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
tree = SCRadixCreateRadixTree();
|
||
|
prefix[0] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[0], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[1] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[1], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[2] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[3] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[3], tree);
|
||
|
|
||
|
/* Try to add the prefix that already exists in the tree */
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[4] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[4], tree);
|
||
|
|
||
|
if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[5] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[5], tree);
|
||
|
|
||
|
if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[6] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[6], tree);
|
||
|
|
||
|
/* test the existence of keys */
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) != NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "8888:0BF1:5346:BDEA:6422:8713:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "2006:0BF1:5346:BDEA:7422:8713:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[1], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[2], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[3], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[4], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[5], tree) != NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:DDDD:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
SCRadixReleaseRadixTree(tree);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
int SCRadixTestIPV6Removal08(void)
|
||
|
{
|
||
|
SCRadixTree *tree = NULL;
|
||
|
SCRadixPrefix *prefix[10];
|
||
|
SCRadixPrefix *temp_prefix = NULL;
|
||
|
|
||
|
struct sockaddr_in6 servaddr;
|
||
|
|
||
|
int result = 1;
|
||
|
|
||
|
/* add the keys */
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
tree = SCRadixCreateRadixTree();
|
||
|
prefix[0] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[0], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[1] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[1], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[2] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[3] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[3], tree);
|
||
|
|
||
|
/* Try to add the prefix that already exists in the tree */
|
||
|
SCRadixAddKey(prefix[2], tree);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[4] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[4], tree);
|
||
|
|
||
|
if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[5] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[5], tree);
|
||
|
|
||
|
if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
prefix[6] = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
SCRadixAddKey(prefix[6], tree);
|
||
|
|
||
|
/* test the existence of keys */
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) != NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "8888:0BF1:5346:BDEA:6422:8713:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "2006:0BF1:5346:BDEA:7422:8713:9124:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[1], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[2], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[3], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[4], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[5], tree) != NULL);
|
||
|
|
||
|
bzero(&servaddr, sizeof(servaddr));
|
||
|
if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:DDDD:2315",
|
||
|
&servaddr.sin6_addr) <= 0)
|
||
|
return 0;
|
||
|
temp_prefix = SCRadixCreateIPV6Prefix((uint8_t *)&servaddr.sin6_addr);
|
||
|
result &= (SCRadixFindKey(temp_prefix, tree) == NULL);
|
||
|
|
||
|
SCRadixRemoveKey(prefix[0], tree);
|
||
|
SCRadixRemoveKey(prefix[1], tree);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[1], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[2], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[3], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[4], tree) != NULL);
|
||
|
result &= (SCRadixFindKey(prefix[5], tree) != NULL);
|
||
|
|
||
|
SCRadixRemoveKey(prefix[2], tree);
|
||
|
SCRadixRemoveKey(prefix[3], tree);
|
||
|
SCRadixRemoveKey(prefix[4], tree);
|
||
|
SCRadixRemoveKey(prefix[5], tree);
|
||
|
|
||
|
result &= (SCRadixFindKey(prefix[0], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[1], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[2], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[3], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[4], tree) == NULL);
|
||
|
result &= (SCRadixFindKey(prefix[5], tree) == NULL);
|
||
|
|
||
|
SCRadixReleaseRadixTree(tree);
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
void SCRadixRegisterTests(void)
|
||
|
{
|
||
|
|
||
|
#ifdef UNITTESTS
|
||
|
|
||
|
UtRegisterTest("SCRadixTestInsertion01", SCRadixTestInsertion01, 1);
|
||
|
UtRegisterTest("SCRadixTestInsertion02", SCRadixTestInsertion02, 1);
|
||
|
UtRegisterTest("SCRadixTestIPV4Insertion03", SCRadixTestIPV4Insertion03, 1);
|
||
|
UtRegisterTest("SCRadixTestIPV4Removal04", SCRadixTestIPV4Removal04, 1);
|
||
|
UtRegisterTest("SCRadixTestCharacterInsertion05",
|
||
|
SCRadixTestCharacterInsertion05, 1);
|
||
|
UtRegisterTest("SCRadixTestCharacterRemoval06",
|
||
|
SCRadixTestCharacterRemoval06, 1);
|
||
|
UtRegisterTest("SCRadixTestIPV6Insertion07", SCRadixTestIPV6Insertion07, 1);
|
||
|
UtRegisterTest("SCRadixTestIPV6Removal08", SCRadixTestIPV6Removal08, 1);
|
||
|
|
||
|
#endif
|
||
|
|
||
|
return;
|
||
|
}
|