37 #define ADDRESS_BYTES (uint8_t)16
38 #define NETMASK_MAX (uint8_t)128
40 #define RADIX_TREE_TYPE SCRadix6Tree
41 #define RADIX_NODE_TYPE SCRadix6Node
42 #define RADIX_TREE_COMPARE_CALLBACK SCRadix6TreeCompareFunc
43 #define RADIX_CONFIG_TYPE SCRadix6Config
45 static void PrintUserdata(
SCRadix6Node *node,
void (*PrintData)(
void *));
47 static inline void AddNetmaskToMasks(
SCRadix6Node *node,
int netmask)
49 uint8_t *masks = node->
masks;
50 masks[netmask / 8] |= 1 << (netmask % 8);
53 static inline void RemoveNetmaskFromMasks(
SCRadix6Node *node,
int netmask)
55 uint8_t *masks = node->
masks;
56 masks[netmask / 8] &= ~(1 << (netmask % 8));
61 for (
size_t i = 0; i <
sizeof(
src->masks); i++) {
62 dst->masks[i] |=
src->masks[i];
66 static inline bool NetmasksEmpty(
const SCRadix6Node *node)
68 for (
size_t i = 0; i <
sizeof(node->
masks); i++) {
69 if (node->
masks[i] != 0) {
76 static inline bool NetmaskEqualsMask(
const SCRadix6Node *node,
int netmask)
78 size_t b = netmask / 8;
80 for (
size_t i = 0; i <
sizeof(node->
masks); i++) {
81 if (i != b && node->
masks[i] != 0)
83 else if (node->
masks[i] != (1 << (netmask % 8)))
89 static inline bool NetmaskIssetInMasks(
const SCRadix6Node *node,
int netmask)
91 return ((node->
masks[netmask / 8] & 1 << (netmask % 8)) != 0);
96 const int differ_bit = inter_node->
bit;
97 uint8_t rem[
sizeof(node->
masks)];
98 memset(rem, 0,
sizeof(rem));
105 if (NetmaskIssetInMasks(node,
m))
106 rem[
m / 8] |= 1 << (
m % 8);
110 AddNetmasksFromNode(inter_node, node);
112 for (
size_t i = 0; i <
sizeof(inter_node->
masks); i++) {
113 inter_node->
masks[i] &= ~rem[i];
116 memcpy(node->
masks, rem,
sizeof(node->
masks));
125 static void PrintNodeInfo(
SCRadix6Node *node,
int level,
void (*PrintData)(
void *))
129 for (
int i = 0; i < level; i++)
132 printf(
"%d [", node->
bit);
134 if (NetmasksEmpty(node)) {
138 if (NetmaskIssetInMasks(node, i)) {
139 printf(
"%s%d", x ?
", " :
"", i);
149 printf(
"%s)\t%p", addr, node);
150 PrintUserdata(node, PrintData);
153 printf(
"no prefix) %p\n", node);
161 const SCRadix6Tree *tree,
const uint8_t *key,
void **user_data)
163 return FindExactMatch(tree, key, user_data);
167 const SCRadix6Tree *tree,
const uint8_t *key,
const uint8_t netmask,
void **user_data)
169 return FindNetblock(tree, key, netmask, user_data);
173 const SCRadix6Tree *tree,
const uint8_t *key,
void **user_data)
175 return FindBestMatch(tree, key, user_data);
179 const SCRadix6Tree *tree,
const uint8_t *key,
void **user_data, uint8_t *out_netmask)
181 return FindBestMatch2(tree, key, user_data, out_netmask);
198 return AddKey(tree, config, key_stream, 128, user,
false);
214 const uint8_t *key_stream, uint8_t netmask,
void *user)
216 return AddKey(tree, config, key_stream, netmask, user,
false);
219 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
220 static void SCRadix6ValidateIPv6Key(uint8_t *key,
const uint8_t netmask)
226 memset(&mask, 0,
sizeof(mask));
227 struct in6_addr mask6;
229 memcpy(&mask, &mask6.s6_addr,
sizeof(mask));
232 masked[0] =
address[0] & mask[0];
233 masked[1] =
address[1] & mask[1];
234 masked[2] =
address[2] & mask[2];
235 masked[3] =
address[3] & mask[3];
237 if (memcmp(masked,
address,
sizeof(masked)) != 0) {
238 char ostr[64], nstr[64];
240 PrintInet(AF_INET6, (
void *)&masked, nstr,
sizeof(nstr));
241 SCLogNotice(
"input %s/%u != expected %s/%u", ostr, netmask, nstr, netmask);
264 uint8_t netmask = 128;
265 char ip_str[80] =
"";
266 char *mask_str = NULL;
267 struct in6_addr addr;
273 if (NULL != (mask_str = strchr(ip_str,
'/'))) {
274 *(mask_str++) =
'\0';
277 if (strchr(mask_str,
'.') != NULL) {
287 netmask = (uint8_t)cidr;
291 if (inet_pton(AF_INET6, ip_str, &addr) <= 0) {
296 if (netmask != 128) {
297 struct in6_addr maddr;
298 struct in6_addr mask6, check;
300 memcpy(&check, &addr,
sizeof(check));
302 for (
int i = 0; i < 16; i++) {
303 maddr.s6_addr[i] = addr.s6_addr[i] & mask6.s6_addr[i];
304 diff |= (maddr.s6_addr[i] != check.s6_addr[i]);
308 PrintInet(AF_INET6, (
void *)&maddr.s6_addr, nstr,
sizeof(nstr));
310 memcpy(addr.s6_addr, maddr.s6_addr, 16);
311 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
312 SCRadix6ValidateIPv6Key((uint8_t *)&addr.s6_addr, netmask);
317 if (AddKey(tree, config, (uint8_t *)&addr.s6_addr, netmask, user,
true) == NULL) {
337 RemoveKey(tree, config, key_stream, 128);
349 const uint8_t *key_stream, uint8_t netmask)
351 RemoveKey(tree, config, key_stream, netmask);
356 PrintTree(tree, config);
367 TreeRelease(tree, config);
370 static void PrintUserdata(
SCRadix6Node *node,
void (*PrintData)(
void *))
372 if (PrintData != NULL) {
382 printf(
" [%d], ", ud->
netmask);
388 static int SCRadix6ForEachNodeSub(
395 if (Callback(node, ud->
user, ud->
netmask, data) < 0)
400 if (SCRadix6ForEachNodeSub(node->
left, Callback, data) < 0)
404 if (SCRadix6ForEachNodeSub(node->
right, Callback, data) < 0)
412 if (tree->
head == NULL)
414 return SCRadix6ForEachNodeSub(tree->
head, Callback, data);
420 return CompareTrees(t1, t2, Callback);
426 static void SCRadix6UtFree(
void *ptr)
431 static const SCRadix6Config ut_ip_radix6_config = { SCRadix6UtFree, NULL };
433 #define GET_IPV6(str) \
434 SCLogDebug("setting up %s", (str)); \
435 memset(&(sa), 0, sizeof((sa))); \
436 FAIL_IF(inet_pton(AF_INET6, (str), &(sa).sin6_addr) <= 0);
438 #define ADD_IPV6(str) \
440 SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, NULL);
442 #define REM_IPV6(str) \
444 SCRadix6RemoveKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr);
446 #define ADD_IPV6_MASK(str, cidr) \
448 SCRadix6AddKeyIPV6Netblock( \
449 &tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, (cidr), NULL);
451 #define REM_IPV6_MASK(str, cidr) \
453 SCRadix6RemoveKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, (cidr));
455 static int SCRadix6TestIPV6Insertion03(
void)
457 struct sockaddr_in6 sa;
506 static int SCRadix6TestIPV6Removal04(
void)
508 struct sockaddr_in6 sa;
549 static int SCRadix6TestIPV6NetblockInsertion09(
void)
551 struct sockaddr_in6 sa;
591 static int SCRadix6TestIPV6NetblockInsertion10(
void)
594 struct sockaddr_in6 sa;
608 &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 112, NULL);
611 node[1] =
SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, NULL);
643 static int SCRadix6TestIPV6NetblockInsertion11(
void)
645 struct sockaddr_in6 sa;
663 &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 0, NULL);
726 static int SCRadix6TestIPV6NetblockInsertion12(
void)
728 struct sockaddr_in6 sa;
743 &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 96, NULL);
747 node[1] =
SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, NULL);
786 static int SCRadix6TestIPV6NetBlocksAndBestSearch16(
void)
788 struct sockaddr_in6 sa;
792 for (uint32_t i = 0; i <= 128; i++) {
793 uint32_t *user =
SCMalloc(
sizeof(uint32_t));
797 void *user_data = NULL;
801 FAIL_IF(*((uint32_t *)user_data) != i);
812 static int SCRadix6TestIPV6NetBlocksAndBestSearch19(
void)
814 struct sockaddr_in6 sa;
815 void *user_data = NULL;
819 uint32_t *user =
SCMalloc(
sizeof(uint32_t));
828 FAIL_IF(*((uint32_t *)user_data) != 100);
841 FAIL_IF(*((uint32_t *)user_data) != 200);
848 FAIL_IF(*((uint32_t *)user_data) != 100);
861 FAIL_IF(*((uint32_t *)user_data) != 300);
868 FAIL_IF(*((uint32_t *)user_data) != 300);
875 FAIL_IF(*((uint32_t *)user_data) != 200);
882 FAIL_IF(*((uint32_t *)user_data) != 100);
894 static int SCRadix6TestIPV6NetblockInsertion25(
void)
896 struct sockaddr_in6 sa;
910 static int SCRadix6TestIPV6NetblockInsertion26(
void)
913 struct sockaddr_in6 sa;
941 FAIL_IF_NOT(strcmp((
char *)retptr,
"Hello3") == 0);
952 UtRegisterTest(
"SCRadix6TestIPV6Insertion03", SCRadix6TestIPV6Insertion03);
953 UtRegisterTest(
"SCRadix6TestIPV6Removal04", SCRadix6TestIPV6Removal04);
954 UtRegisterTest(
"SCRadix6TestIPV6NetblockInsertion09", SCRadix6TestIPV6NetblockInsertion09);
955 UtRegisterTest(
"SCRadix6TestIPV6NetblockInsertion10", SCRadix6TestIPV6NetblockInsertion10);
956 UtRegisterTest(
"SCRadix6TestIPV6NetblockInsertion11", SCRadix6TestIPV6NetblockInsertion11);
957 UtRegisterTest(
"SCRadix6TestIPV6NetblockInsertion12", SCRadix6TestIPV6NetblockInsertion12);
959 "SCRadix6TestIPV6NetBlocksAndBestSearch16", SCRadix6TestIPV6NetBlocksAndBestSearch16);
961 "SCRadix6TestIPV6NetBlocksAndBestSearch19", SCRadix6TestIPV6NetBlocksAndBestSearch19);
962 UtRegisterTest(
"SCRadix6TestIPV6NetblockInsertion25", SCRadix6TestIPV6NetblockInsertion25);
963 UtRegisterTest(
"SCRadix6TestIPV6NetblockInsertion26", SCRadix6TestIPV6NetblockInsertion26);