30 #error "define ADDRESS_BYTES"
33 #error "define NETMASK_MAX"
36 #define RADIX_BITTEST(x, y) ((x) & (y))
96 BUG_ON(add == NULL || list == NULL);
101 while (temp != NULL) {
129 AppendToUserDataList(AllocUserData(
netmask,
user), &node->user_data);
145 prev = temp = node->user_data;
146 while (temp != NULL) {
148 if (temp == node->user_data)
149 node->user_data = temp->
next;
175 while (user_data != NULL) {
178 user_data = user_data->
next;
195 while (user_data != NULL) {
197 user_data = user_data->
next;
215 static int ContainNetmaskAndSetUserData(
225 if (user_data_result)
226 *user_data_result = user_data->
user;
234 while (user_data != NULL) {
236 if (user_data_result)
237 *user_data_result = user_data->
user;
240 user_data = user_data->
next;
244 if (user_data_result != NULL)
245 *user_data_result = NULL;
272 static void ReleaseNode(
280 if (config->Free != NULL && ud->
user) {
281 config->Free(ud->
user);
296 static void ReleaseSubtree(
301 ReleaseSubtree(node->left, tree, config);
302 ReleaseSubtree(node->right, tree, config);
303 ReleaseNode(node, tree, config);
318 ReleaseSubtree(tree->head, tree, config);
336 const uint8_t *key_stream, uint8_t
netmask,
void *
user,
const bool exclusive)
344 memcpy(tmp_stream, key_stream,
sizeof(tmp_stream));
356 if (tree->head == NULL) {
357 node = RadixCreateNode();
360 memcpy(node->prefix_stream, tmp_stream,
sizeof(tmp_stream));
361 node->has_prefix =
true;
363 if (node->user_data == NULL) {
364 ReleaseNode(node, tree, config);
371 AddNetmaskToMasks(node,
netmask);
380 while (node->bit <
NETMASK_MAX || node->has_prefix ==
false) {
385 if (NETMASK_MAX <= node->bit) {
386 if (node->right == NULL)
390 if (
RADIX_BITTEST(tmp_stream[node->bit >> 3], (0x80 >> (node->bit % 8)))) {
391 if (node->right == NULL)
395 if (node->left == NULL)
408 uint8_t differ_bit = 0;
410 for (uint8_t i = 0; (i * 8) < check_bit; i++) {
412 if ((temp = (tmp_stream[i] ^ bottom_node->prefix_stream[i])) == 0) {
413 differ_bit = (i + 1) * 8;
423 else if (temp >= 128)
438 differ_bit = i * 8 + j;
441 if (check_bit < differ_bit)
442 differ_bit = check_bit;
445 parent = node->parent;
446 while (parent && differ_bit <= parent->bit) {
448 parent = node->parent;
454 if (node->has_prefix) {
456 if (ContainNetmask(node,
netmask)) {
460 SCLogDebug(
"not inserting since it already exists");
464 SCLogDebug(
"Duplicate entry for this ip address/netblock");
481 parent = node->parent;
482 while (parent != NULL &&
netmask < (parent->bit + 1)) {
484 parent = parent->parent;
487 AddNetmaskToMasks(node,
netmask);
488 if (NetmaskEqualsMask(node,
netmask)) {
498 if (new_node == NULL)
500 memcpy(new_node->prefix_stream, tmp_stream,
sizeof(tmp_stream));
501 new_node->has_prefix =
true;
502 new_node->user_data = AllocUserData(
netmask,
user);
503 if (new_node->user_data == NULL) {
504 ReleaseNode(new_node, tree, config);
513 if (inter_node == NULL) {
514 ReleaseNode(new_node, tree, config);
517 inter_node->has_prefix =
false;
518 inter_node->bit = differ_bit;
519 inter_node->parent = node->parent;
520 SCLogDebug(
"inter_node: differ_bit %u", differ_bit);
523 ProcessInternode(node, inter_node);
525 if (
RADIX_BITTEST(tmp_stream[differ_bit >> 3], (0x80 >> (differ_bit % 8)))) {
526 inter_node->left = node;
527 inter_node->right = new_node;
529 inter_node->left = new_node;
530 inter_node->right = node;
532 new_node->parent = inter_node;
534 if (node->parent == NULL)
535 tree->head = inter_node;
536 else if (node->parent->right == node)
537 node->parent->right = inter_node;
539 node->parent->left = inter_node;
541 node->parent = inter_node;
546 parent = new_node->parent;
547 while (parent != NULL &&
netmask < (parent->bit + 1)) {
549 parent = parent->parent;
551 AddNetmaskToMasks(node,
netmask);
569 RemoveNetmaskUserDataFromNode(node,
netmask);
576 RemoveNetmaskFromMasks(node,
netmask);
577 if (node->parent != NULL)
578 RemoveNetmaskFromMasks(node->parent,
netmask);
590 const uint8_t *key_stream,
const uint8_t
netmask)
602 memcpy(tmp_stream, key_stream,
sizeof(tmp_stream));
605 if (
RADIX_BITTEST(tmp_stream[node->bit >> 3], (0x80 >> (node->bit % 8)))) {
617 if (node->bit !=
NETMASK_MAX || node->has_prefix ==
false) {
619 node->has_prefix ?
"true" :
"false");
623 if (
SCMemcmp(node->prefix_stream, tmp_stream,
sizeof(tmp_stream)) == 0) {
624 if (!ContainNetmask(node,
netmask)) {
625 SCLogDebug(
"key exists in the tree, but this (%d) "
626 "netblock entry doesn't exist",
631 SCLogDebug(
"You are trying to remove a key that doesn't exist in the "
640 if (NetmaskCount(node) > 1) {
641 RemoveNetblockEntry(node,
netmask);
649 if (tree->head == node) {
650 ReleaseNode(node, tree, config);
656 parent = node->parent;
658 if (parent->parent != NULL) {
659 if (parent->parent->left == parent) {
660 if (node->parent->left == node) {
661 temp_dest = parent->right;
662 parent->parent->left = parent->right;
663 parent->right->parent = parent->parent;
665 temp_dest = parent->left;
666 parent->parent->left = parent->left;
667 parent->left->parent = parent->parent;
670 if (node->parent->left == node) {
671 temp_dest = parent->right;
672 parent->parent->right = parent->right;
673 parent->right->parent = parent->parent;
675 temp_dest = parent->left;
676 parent->parent->right = parent->left;
677 parent->left->parent = parent->parent;
682 if (parent->left == node) {
683 temp_dest = tree->head->right;
684 tree->head->right->parent = NULL;
685 tree->head = tree->head->right;
687 temp_dest = tree->head->left;
688 tree->head->left->parent = NULL;
689 tree->head = tree->head->left;
694 AddNetmasksFromNode(temp_dest, parent);
695 RemoveNetmaskFromMasks(temp_dest,
netmask);
697 ReleaseNode(parent, tree, config);
698 ReleaseNode(node, tree, config);
712 void **user_data_result, uint8_t *out_netmask)
714 while (node != NULL && NetmasksEmpty(node))
720 memcpy(tmp_stream, key_stream,
sizeof(tmp_stream));
729 if (!(NetmaskIssetInMasks(netmask_node,
m)))
733 uint32_t mask = UINT_MAX;
734 if (((i + 1) * 8) >
m) {
735 if (((i + 1) * 8 -
m) < 8)
736 mask = UINT_MAX << ((i + 1) * 8 -
m);
740 tmp_stream[i] &= mask;
744 if (
RADIX_BITTEST(tmp_stream[node->bit >> 3], (0x80 >> (node->bit % 8)))) {
754 if (node->bit !=
NETMASK_MAX || node->has_prefix ==
false)
757 if (
SCMemcmp(node->prefix_stream, tmp_stream,
sizeof(tmp_stream)) == 0) {
758 if (ContainNetmaskAndSetUserData(node,
m,
false, user_data_result)) {
765 return FindKeyIPNetblock(tmp_stream, netmask_node->parent, user_data_result, out_netmask);
777 const uint8_t
netmask,
bool exact_match,
void **user_data_result, uint8_t *out_netmask)
779 if (tree == NULL || tree->head == NULL)
784 memcpy(tmp_stream, key_stream,
sizeof(tmp_stream));
787 if (
RADIX_BITTEST(tmp_stream[node->bit >> 3], (0x80 >> (node->bit % 8)))) {
798 if (node->bit !=
NETMASK_MAX || node->has_prefix ==
false) {
802 if (
SCMemcmp(node->prefix_stream, tmp_stream,
sizeof(tmp_stream)) == 0) {
804 if (ContainNetmaskAndSetUserData(node,
netmask,
true, user_data_result)) {
813 SCLogDebug(
"no node found and need exact match, so failed");
817 RADIX_NODE_TYPE *ret = FindKeyIPNetblock(tmp_stream, node, user_data_result, out_netmask);
829 const RADIX_TREE_TYPE *tree,
const uint8_t *key_stream,
void **user_data_result)
832 return FindKey(tree, key_stream,
NETMASK_MAX,
true, user_data_result, &unused);
843 const RADIX_TREE_TYPE *tree,
const uint8_t *key_stream,
void **user_data_result)
846 return FindKey(tree, key_stream,
NETMASK_MAX,
false, user_data_result, &unused);
850 void **user_data_result, uint8_t *out_netmask)
852 return FindKey(tree, key_stream,
NETMASK_MAX,
false, user_data_result, out_netmask);
863 const uint8_t
netmask,
void **user_data_result)
877 static void PrintSubtree(
RADIX_NODE_TYPE *node,
int level,
void (*PrintData)(
void *))
880 PrintNodeInfo(node, level, PrintData);
881 PrintSubtree(node->left, level + 1, PrintData);
882 PrintSubtree(node->right, level + 1, PrintData);
908 printf(
"Printing the Radix Tree: \n");
909 PrintSubtree(tree->head, 0, config->PrintData);
912 static bool CompareTreesSub(
916 bool n1_has_left = n1->left != NULL;
917 bool n2_has_left = n2->left != NULL;
918 if (n1_has_left != n2_has_left)
921 bool n1_has_right = n1->right != NULL;
922 bool n2_has_right = n2->right != NULL;
923 if (n1_has_right != n2_has_right)
932 if (u1 == NULL && u2 == NULL)
934 if ((u1 != NULL && u2 == NULL) || (u1 == NULL && u2 != NULL))
939 if (Callback != NULL) {
940 if (Callback(u1->
user, u2->
user) ==
false)
948 if (n1->left && n2->left)
949 if (CompareTreesSub(n1->left, n2->left, Callback) ==
false)
951 if (n1->right && n2->right)
952 if (CompareTreesSub(n1->right, n2->right, Callback) ==
false)
958 static bool CompareTrees(
961 if (t1->head == NULL && t2->head == NULL)
963 if ((t1->head == NULL && t2->head != NULL) || (t1->head != NULL && t2->head == NULL))
965 return CompareTreesSub(t1->head, t2->head, Callback);