suricata
util-radix6-tree.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2022 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23  *
24  * Implementation of radix trees
25  */
26 
27 #include "suricata-common.h"
28 #include "util-debug.h"
29 #include "util-error.h"
30 #include "util-ip.h"
31 #include "util-cidr.h"
32 #include "util-unittest.h"
33 #include "util-memcmp.h"
34 #include "util-print.h"
35 #include "util-byte.h"
36 #include "util-radix6-tree.h"
37 
38 #define ADDRESS_BYTES (uint8_t)16
39 #define NETMASK_MAX (uint8_t)128
40 
41 #define RADIX_TREE_TYPE SCRadix6Tree
42 #define RADIX_NODE_TYPE SCRadix6Node
43 #define RADIX_TREE_COMPARE_CALLBACK SCRadix6TreeCompareFunc
44 #define RADIX_CONFIG_TYPE SCRadix6Config
45 
46 static void PrintUserdata(SCRadix6Node *node, void (*PrintData)(void *));
47 
48 static inline void AddNetmaskToMasks(SCRadix6Node *node, int netmask)
49 {
50  uint8_t *masks = node->masks;
51  masks[netmask / 8] |= 1 << (netmask % 8);
52 }
53 
54 static inline void RemoveNetmaskFromMasks(SCRadix6Node *node, int netmask)
55 {
56  uint8_t *masks = node->masks;
57  masks[netmask / 8] &= ~(1 << (netmask % 8));
58 }
59 
60 static inline void AddNetmasksFromNode(SCRadix6Node *dst, SCRadix6Node *src)
61 {
62  for (size_t i = 0; i < sizeof(src->masks); i++) {
63  dst->masks[i] |= src->masks[i];
64  }
65 }
66 
67 static inline bool NetmasksEmpty(const SCRadix6Node *node)
68 {
69  for (size_t i = 0; i < sizeof(node->masks); i++) {
70  if (node->masks[i] != 0) {
71  return false;
72  }
73  }
74  return true;
75 }
76 
77 static inline bool NetmaskEqualsMask(const SCRadix6Node *node, int netmask)
78 {
79  size_t b = netmask / 8;
80 
81  for (size_t i = 0; i < sizeof(node->masks); i++) {
82  if (i != b && node->masks[i] != 0)
83  return false;
84  else if (node->masks[i] != (1 << (netmask % 8)))
85  return false;
86  }
87  return true;
88 }
89 
90 static inline bool NetmaskIssetInMasks(const SCRadix6Node *node, int netmask)
91 {
92  return ((node->masks[netmask / 8] & 1 << (netmask % 8)) != 0);
93 }
94 
95 static inline void ProcessInternode(SCRadix6Node *node, SCRadix6Node *inter_node)
96 {
97  const int differ_bit = inter_node->bit;
98  uint8_t rem[sizeof(node->masks)];
99  memset(rem, 0, sizeof(rem));
100 
101  for (int x = 0; x <= NETMASK_MAX; x++) {
102  int m = NETMASK_MAX - x;
103  if (m == differ_bit)
104  break;
105  else {
106  if (NetmaskIssetInMasks(node, m))
107  rem[m / 8] |= 1 << (m % 8);
108  }
109  }
110 
111  AddNetmasksFromNode(inter_node, node);
112 
113  for (size_t i = 0; i < sizeof(inter_node->masks); i++) {
114  inter_node->masks[i] &= ~rem[i];
115  }
116 
117  memcpy(node->masks, rem, sizeof(node->masks));
118 }
119 
120 /**
121  * \brief Prints the node information from a Radix6 tree
122  *
123  * \param node Pointer to the Radix6 node whose information has to be printed
124  * \param level Used for indentation purposes
125  */
126 static void PrintNodeInfo(SCRadix6Node *node, int level, void (*PrintData)(void *))
127 {
128  if (node == NULL)
129  return;
130  for (int i = 0; i < level; i++)
131  printf(" ");
132 
133  printf("%d [", node->bit);
134 
135  if (NetmasksEmpty(node)) {
136  printf(" - ");
137  } else {
138  for (int i = 0, x = 0; i <= NETMASK_MAX; i++) {
139  if (NetmaskIssetInMasks(node, i)) {
140  printf("%s%d", x ? ", " : "", i);
141  x++;
142  }
143  }
144  }
145  printf("] (");
146 
147  if (node->has_prefix) {
148  char addr[46] = "";
149  PrintInet(AF_INET6, &node->prefix_stream, addr, sizeof(addr));
150  printf("%s)\t%p", addr, node);
151  PrintUserdata(node, PrintData);
152  printf("\n");
153  } else {
154  printf("no prefix) %p\n", node);
155  }
156  return;
157 }
158 
159 #include "util-radix-tree-common.h"
160 
162  const SCRadix6Tree *tree, const uint8_t *key, void **user_data)
163 {
164  return FindExactMatch(tree, key, user_data);
165 }
166 
168  const SCRadix6Tree *tree, const uint8_t *key, const uint8_t netmask, void **user_data)
169 {
170  return FindNetblock(tree, key, netmask, user_data);
171 }
172 
174  const SCRadix6Tree *tree, const uint8_t *key, void **user_data)
175 {
176  return FindBestMatch(tree, key, user_data);
177 }
178 
180  const SCRadix6Tree *tree, const uint8_t *key, void **user_data, uint8_t *out_netmask)
181 {
182  return FindBestMatch2(tree, key, user_data, out_netmask);
183 }
184 
185 /**
186  * \brief Adds a new IPV6 address to the Radix6 tree
187  *
188  * \param key_stream Data that has to be added to the Radix6 tree. In this case
189  * a pointer to an IPV6 address
190  * \param tree Pointer to the Radix6 tree
191  * \param user Pointer to the user data that has to be associated with the
192  * key
193  *
194  * \retval node Pointer to the newly created node
195  */
197  SCRadix6Tree *tree, const SCRadix6Config *config, const uint8_t *key_stream, void *user)
198 {
199  return AddKey(tree, config, key_stream, 128, user, false);
200 }
201 
202 /**
203  * \brief Adds a new IPV6 netblock to the Radix6 tree
204  *
205  * \param key_stream Data that has to be added to the Radix6 tree. In this case
206  * a pointer to an IPV6 netblock
207  * \param tree Pointer to the Radix6 tree
208  * \param user Pointer to the user data that has to be associated with the
209  * key
210  * \param netmask The netmask (cidr) if we are adding a netblock
211  *
212  * \retval node Pointer to the newly created node
213  */
215  const uint8_t *key_stream, uint8_t netmask, void *user)
216 {
217  return AddKey(tree, config, key_stream, netmask, user, false);
218 }
219 
220 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
221 static void SCRadix6ValidateIPv6Key(uint8_t *key, const uint8_t netmask)
222 {
223  uint32_t address[4];
224  memcpy(&address, key, sizeof(address));
225 
226  uint32_t mask[4];
227  memset(&mask, 0, sizeof(mask));
228  struct in6_addr mask6;
229  CIDRGetIPv6(netmask, &mask6);
230  memcpy(&mask, &mask6.s6_addr, sizeof(mask));
231 
232  uint32_t masked[4];
233  masked[0] = address[0] & mask[0];
234  masked[1] = address[1] & mask[1];
235  masked[2] = address[2] & mask[2];
236  masked[3] = address[3] & mask[3];
237 
238  if (memcmp(masked, address, sizeof(masked)) != 0) {
239  char ostr[64], nstr[64];
240  PrintInet(AF_INET6, (void *)&address, ostr, sizeof(ostr));
241  PrintInet(AF_INET6, (void *)&masked, nstr, sizeof(nstr));
242  SCLogNotice("input %s/%u != expected %s/%u", ostr, netmask, nstr, netmask);
243  abort();
244  }
245 }
246 #endif
247 /**
248  * \brief Adds a new IPV6/netblock to the Radix6 tree from a string
249  *
250  * \param str IPV6 string with optional /cidr netmask
251  * \param tree Pointer to the Radix6 tree
252  * \param user Pointer to the user data that has to be associated with
253  * the key
254  *
255  * \retval bool true if node was added, false otherwise
256  *
257  * If the function returns false, `sc_errno` is set:
258  * - SC_EEXIST: Node already exists
259  * - SC_EINVAL: Parameter value error
260  * - SC_ENOMEM: Memory allocation failed
261  */
263  SCRadix6Tree *tree, const SCRadix6Config *config, const char *str, void *user)
264 {
265  uint8_t netmask = 128;
266  char ip_str[80] = ""; /* Max length for full ipv6/cidr string with NUL */
267  char *mask_str = NULL;
268  struct in6_addr addr;
269 
270  /* Make a copy of the string so it can be modified */
271  strlcpy(ip_str, str, sizeof(ip_str));
272 
273  /* Does it have a mask? */
274  if (NULL != (mask_str = strchr(ip_str, '/'))) {
275  *(mask_str++) = '\0';
276 
277  /* Dotted type netmask not valid for ipv6 */
278  if (strchr(mask_str, '.') != NULL) {
280  return false;
281  }
282 
283  uint8_t cidr;
284  if (StringParseU8RangeCheck(&cidr, 10, 0, (const char *)mask_str, 0, 128) < 0) {
286  return false;
287  }
288  netmask = (uint8_t)cidr;
289  }
290 
291  /* Validate the IP */
292  if (inet_pton(AF_INET6, ip_str, &addr) <= 0) {
294  return false;
295  }
296 
297  if (netmask != 128) {
298  struct in6_addr maddr;
299  struct in6_addr mask6, check;
300  CIDRGetIPv6(netmask, &mask6);
301  memcpy(&check, &addr, sizeof(check));
302  bool diff = false;
303  for (int i = 0; i < 16; i++) {
304  maddr.s6_addr[i] = addr.s6_addr[i] & mask6.s6_addr[i];
305  diff |= (maddr.s6_addr[i] != check.s6_addr[i]);
306  }
307  if (diff) {
308  char nstr[64];
309  PrintInet(AF_INET6, (void *)&maddr.s6_addr, nstr, sizeof(nstr));
310  SCLogWarning("adding '%s' as '%s/%u'", str, nstr, netmask);
311  memcpy(addr.s6_addr, maddr.s6_addr, 16);
312 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
313  SCRadix6ValidateIPv6Key((uint8_t *)&addr.s6_addr, netmask);
314 #endif
315  }
316  }
317 
318  if (AddKey(tree, config, (uint8_t *)&addr.s6_addr, netmask, user, true) == NULL) {
320  return false;
321  }
322  return true;
323 }
324 
325 /**
326  * \brief Removes an IPV6 address key(not a netblock) from the Radix6 tree.
327  * Instead of using this function, we can also used
328  * SCRadix6RemoveKeyIPV6Netblock(), by supplying a netmask value of 32.
329  *
330  * \param key_stream Data that has to be removed from the Radix6 tree. In this
331  * case an IPV6 address
332  * \param tree Pointer to the Radix6 tree from which the key has to be
333  * removed
334  */
336  SCRadix6Tree *tree, const SCRadix6Config *config, const uint8_t *key_stream)
337 {
338  RemoveKey(tree, config, key_stream, 128);
339 }
340 
341 /**
342  * \brief Removes an IPV6 address netblock key from the tree.
343  *
344  * \param key_stream Data that has to be removed from the tree. In this
345  * case an IPV6 address with netmask.
346  * \param tree Pointer to the tree from which the key has to be
347  * removed
348  */
350  const uint8_t *key_stream, uint8_t netmask)
351 {
352  RemoveKey(tree, config, key_stream, netmask);
353 }
354 
356 {
357  PrintTree(tree, config);
358 }
359 
361 {
363  return t;
364 }
365 
367 {
368  TreeRelease(tree, config);
369 }
370 
371 static void PrintUserdata(SCRadix6Node *node, void (*PrintData)(void *))
372 {
373  if (PrintData != NULL) {
374  RadixUserData *ud = node->user_data;
375  while (ud != NULL) {
376  printf("[%d], ", ud->netmask);
377  PrintData(ud->user);
378  ud = ud->next;
379  }
380  } else {
381  RadixUserData *ud = node->user_data;
382  while (ud != NULL) {
383  printf(" [%d], ", ud->netmask);
384  ud = ud->next;
385  }
386  }
387 }
388 
389 static int SCRadix6ForEachNodeSub(
390  const SCRadix6Node *node, SCRadix6ForEachNodeFunc Callback, void *data)
391 {
392  BUG_ON(!node);
393 
394  /* invoke callback for each stored user data */
395  for (RadixUserData *ud = node->user_data; ud != NULL; ud = ud->next) {
396  if (Callback(node, ud->user, ud->netmask, data) < 0)
397  return -1;
398  }
399 
400  if (node->left) {
401  if (SCRadix6ForEachNodeSub(node->left, Callback, data) < 0)
402  return -1;
403  }
404  if (node->right) {
405  if (SCRadix6ForEachNodeSub(node->right, Callback, data) < 0)
406  return -1;
407  }
408  return 0;
409 }
410 
411 int SCRadix6ForEachNode(const SCRadix6Tree *tree, SCRadix6ForEachNodeFunc Callback, void *data)
412 {
413  if (tree->head == NULL)
414  return 0;
415  return SCRadix6ForEachNodeSub(tree->head, Callback, data);
416 }
417 
419  const SCRadix6Tree *t1, const SCRadix6Tree *t2, SCRadix6TreeCompareFunc Callback)
420 {
421  return CompareTrees(t1, t2, Callback);
422 }
423 
424 /*------------------------------------Unit_Tests------------------------------*/
425 
426 #ifdef UNITTESTS
427 
428 static const SCRadix6Config ut_ip_radix6_config = { NULL, NULL };
429 
430 #define GET_IPV6(str) \
431  SCLogDebug("setting up %s", (str)); \
432  memset(&(sa), 0, sizeof((sa))); \
433  FAIL_IF(inet_pton(AF_INET6, (str), &(sa).sin6_addr) <= 0);
434 
435 #define ADD_IPV6(str) \
436  GET_IPV6((str)); \
437  SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, NULL);
438 
439 #define REM_IPV6(str) \
440  GET_IPV6((str)); \
441  SCRadix6RemoveKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr);
442 
443 #define ADD_IPV6_MASK(str, cidr) \
444  GET_IPV6((str)); \
445  SCRadix6AddKeyIPV6Netblock( \
446  &tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, (cidr), NULL);
447 
448 #define REM_IPV6_MASK(str, cidr) \
449  GET_IPV6((str)); \
450  SCRadix6RemoveKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, (cidr));
451 
452 static int SCRadix6TestIPV6Insertion03(void)
453 {
454  struct sockaddr_in6 sa;
456 
457  ADD_IPV6("2000:1::1");
458  ADD_IPV6("2000:1::2");
459  ADD_IPV6("2000:0::3");
460  ADD_IPV6("2000:0::4");
461  ADD_IPV6("2000:0::4");
462 
463  /* test for the existance of a key */
464  GET_IPV6("2000:1::6");
465  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
466 
467  /* test for the existance of a key */
468  GET_IPV6("2000:0::4");
469  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
470 
471  /* continue adding keys */
472  ADD_IPV6("2000:0::2");
473  ADD_IPV6("2000:1::5");
474  ADD_IPV6("2000:1::18");
475 
476  /* test the existence of keys */
477  GET_IPV6("2000:1::3");
478  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
479  GET_IPV6("2001:1:2:3::62");
480  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
481 
482  GET_IPV6("2000:1::1");
483  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
484  GET_IPV6("2000:1::5");
485  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
486  GET_IPV6("2000:1::2");
487  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
488 
489  GET_IPV6("2000:0::3");
490  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
491  GET_IPV6("2000:0::4");
492  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
493  GET_IPV6("2000:0::2");
494  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
495  GET_IPV6("2000:1::18");
496  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
497 
498  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
499 
500  PASS;
501 }
502 
503 static int SCRadix6TestIPV6Removal04(void)
504 {
505  struct sockaddr_in6 sa;
507 
508  /* add the keys */
509  ADD_IPV6("2000:1::1");
510  ADD_IPV6("2000:1::2");
511  ADD_IPV6("2000:0::3");
512  ADD_IPV6("2000:0::4");
513  ADD_IPV6("1000:1::2");
514  ADD_IPV6("2000:1::5");
515  ADD_IPV6("2000:1::18");
516 
517  /* remove the keys from the tree */
518  REM_IPV6("2000:1::1");
519  REM_IPV6("2000:0::3");
520  REM_IPV6("2000:0::4");
521  REM_IPV6("2000:1::18");
522 
523  GET_IPV6("2000:0::1");
524  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
525  GET_IPV6("2000:1::2");
526  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
527 
528  REM_IPV6("2000:0::3");
529  REM_IPV6("1000:1::2");
530 
531  GET_IPV6("2000:1::5");
532  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
533  GET_IPV6("2000:1::2");
534  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
535 
536  REM_IPV6("2000:1::2");
537  REM_IPV6("2000:1::5");
538 
539  FAIL_IF_NOT_NULL(tree.head);
540 
541  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
542 
543  PASS;
544 }
545 
546 static int SCRadix6TestIPV6NetblockInsertion09(void)
547 {
548  struct sockaddr_in6 sa;
550 
551  /* add the keys */
552  ADD_IPV6("2000::1:1");
553  ADD_IPV6("2000::1:2");
554  ADD_IPV6("2000::0:3");
555  ADD_IPV6("2000::0:4");
556  ADD_IPV6("1000::1:2");
557  ADD_IPV6("2000::1:5");
558  ADD_IPV6("2000::1:18");
559 
560  ADD_IPV6_MASK("2000::", 16);
561  ADD_IPV6_MASK("2000::192:171:128:0", 128 - 8);
562  ADD_IPV6_MASK("2000::192:171:192:0", 128 - 14);
563  ADD_IPV6_MASK("2000::192:175:0:0", 128 - 16);
564 
565  /* test for the existance of a key */
566  GET_IPV6("2000:1::6");
567  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
568  GET_IPV6("2000::192:170:1:6");
569  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
570  GET_IPV6("2000::192:171:128:145");
571  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
572  GET_IPV6("2000::192:171:64:6");
573  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
574  GET_IPV6("2000::192:171:191:6");
575  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
576  GET_IPV6("2000::192:171:224:6");
577  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
578  GET_IPV6("2000::192:171:224:6");
579  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
580  GET_IPV6("2000::192:175:224:6");
581  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
582 
583  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
584 
585  PASS;
586 }
587 
588 static int SCRadix6TestIPV6NetblockInsertion10(void)
589 {
590  SCRadix6Node *node[2];
591  struct sockaddr_in6 sa;
593 
594  /* add the keys */
595  ADD_IPV6_MASK("2000::253:192:0:0", 112);
596  ADD_IPV6_MASK("2000::253:192:235:0", 112);
597  ADD_IPV6_MASK("2000::192:167:0:0", 112);
598  ADD_IPV6("2000:0::4");
599  ADD_IPV6_MASK("2000::220:168:0:0", 112);
600  ADD_IPV6("2000::253:224:1:5");
601  ADD_IPV6_MASK("2000::192:168:0:0", 112);
602 
603  GET_IPV6("2000::192:171:128:0");
604  node[0] = SCRadix6AddKeyIPV6Netblock(
605  &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 112, NULL);
606 
607  GET_IPV6("2000::192:171:128:45");
608  node[1] = SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, NULL);
609 
610  ADD_IPV6_MASK("2000::192:171:0:0", 110);
611  ADD_IPV6_MASK("2000::192:175:0:0", 112);
612 
613  /* test for the existance of a key */
614  GET_IPV6("2000::192:171:128:53");
615  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[0]);
616 
617  GET_IPV6("2000::192:171:128:45");
618  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[1]);
619 
620  GET_IPV6("2000::192:171:128:45");
621  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[1]);
622 
623  GET_IPV6("2000::192:171:128:78");
624  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[0]);
625 
626  REM_IPV6_MASK("2000::192:171:128:0", 112);
627 
628  GET_IPV6("2000::192:171:128:78");
629  SCRadix6Node *n = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL);
630  SCLogNotice("n %p", n);
631  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
632  GET_IPV6("2000::192:171:127:78");
633  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
634 
635  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
636 
637  PASS;
638 }
639 
640 static int SCRadix6TestIPV6NetblockInsertion11(void)
641 {
642  struct sockaddr_in6 sa;
644 
645  /* add the keys */
646  ADD_IPV6_MASK("2000::253:192:0:0", 96);
647  ADD_IPV6_MASK("2000::253:192:235:0", 112);
648  ADD_IPV6_MASK("2000::192:167:0:0", 96);
649  ADD_IPV6("2000:0::4");
650  ADD_IPV6_MASK("2000::220:168:0:0", 96);
651  ADD_IPV6("2000::253:224:1:5");
652  ADD_IPV6_MASK("2000::192:168:0:0", 96);
653  ADD_IPV6_MASK("2000::192:171:128:0", 112);
654  ADD_IPV6("2000::192:171:128:45");
655  ADD_IPV6_MASK("2000::192:171:0:0", 112);
656  ADD_IPV6_MASK("2000::192:175:0:0", 96);
657 
658  GET_IPV6("::");
660  &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 0, NULL);
661  FAIL_IF_NULL(node);
662 
663  /* test for the existance of a key */
664  GET_IPV6("2000::192:171:128:53");
665  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
666 
667  GET_IPV6("2000::192:171:128:45");
668  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
669 
670  GET_IPV6("2000::192:171:128:78");
671  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
672 
673  GET_IPV6("2000::192:171:127:78");
674  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
675 
676  GET_IPV6("2000::1:1:1:1");
677  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
678 
679  GET_IPV6("2000::192:255:254:25");
680  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
681 
682  GET_IPV6("2000::169:255:254:25");
683  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
684 
685  GET_IPV6("::");
686  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
687 
688  GET_IPV6("2000::253:224:1:5");
689  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
690  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != node);
691 
692  GET_IPV6("2000::245:63:62:121");
693  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
694  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
695 
696  GET_IPV6("2000::253:224:1:6");
697  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
698  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
699 
700  /* remove node 0.0.0.0 */
701  REM_IPV6_MASK("::", 0);
702 
703  GET_IPV6("2000::253:224:1:6");
704  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
705  GET_IPV6("2000::192:171:127:78");
706  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
707  GET_IPV6("2000::1:1:1:1");
708  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
709 
710  GET_IPV6("2000::192:255:254:25");
711  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
712  GET_IPV6("2000::169:255:254:25");
713  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
714 
715  GET_IPV6("::");
716  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
717 
718  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
719 
720  PASS;
721 }
722 
723 static int SCRadix6TestIPV6NetblockInsertion12(void)
724 {
725  struct sockaddr_in6 sa;
726  SCRadix6Node *node[2];
728 
729  /* add the keys */
730  ADD_IPV6_MASK("2000::253:192:0:0", 96);
731  ADD_IPV6_MASK("2000::253:192:235:0", 112);
732  ADD_IPV6_MASK("2000::192:167:0:0", 96);
733  ADD_IPV6("2000:0::4");
734  ADD_IPV6_MASK("2000::220:168:0:0", 96);
735  ADD_IPV6("2000::253:224:1:5");
736  ADD_IPV6_MASK("2000::192:168:0:0", 96);
737 
738  GET_IPV6("2000::192:171:128:0");
739  node[0] = SCRadix6AddKeyIPV6Netblock(
740  &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 96, NULL);
741  FAIL_IF_NULL(node[0]);
742 
743  GET_IPV6("2000::192:171:128:45");
744  node[1] = SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, NULL);
745  FAIL_IF_NULL(node[1]);
746 
747  ADD_IPV6_MASK("2000::192:171:0:0", 96);
748  ADD_IPV6_MASK("2000::225:175:21:228", 128);
749 
750  /* test for the existance of a key */
751  GET_IPV6("2000::192:171:128:53");
752  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[0]);
753  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
754 
755  GET_IPV6("2000::192:171:128:45");
756  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[1]);
757  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[1]);
758 
759  GET_IPV6("2000::192:171:128:78");
760  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[0]);
761  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
762 
763  GET_IPV6("2000::225:175:21:228");
764  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
765 
766  GET_IPV6("2000::225:175:21:224");
767  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
768 
769  GET_IPV6("2000::225:175:21:229");
770  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
771 
772  GET_IPV6("2000::225:175:21:230");
773  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
774 
775  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
776  PASS;
777 }
778 
779 /**
780  * \test Check that the best match search works for all the
781  * possible netblocks of a fixed address
782  */
783 static int SCRadix6TestIPV6NetBlocksAndBestSearch16(void)
784 {
785  struct sockaddr_in6 sa;
787 
788  GET_IPV6("2000:1::1");
789  for (uint32_t i = 0; i <= 128; i++) {
790  uint32_t *user = SCMalloc(sizeof(uint32_t));
791  FAIL_IF_NULL(user);
792  *user = i;
793  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, i, user);
794  void *user_data = NULL;
795  SCRadix6Node *node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
796  FAIL_IF_NULL(node);
797  FAIL_IF_NULL(user_data);
798  FAIL_IF(*((uint32_t *)user_data) != i);
799  }
800 
801  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
802  PASS;
803 }
804 
805 /**
806  * \test Check special combinations of netblocks and addresses
807  * on best search checking the returned userdata
808  */
809 static int SCRadix6TestIPV6NetBlocksAndBestSearch19(void)
810 {
811  struct sockaddr_in6 sa;
812  void *user_data = NULL;
814 
815  GET_IPV6("::");
816  uint32_t *user = SCMalloc(sizeof(uint32_t));
817  FAIL_IF_NULL(user);
818  *user = 100;
819  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 0, user);
820 
821  GET_IPV6("2000:1::15");
822  SCRadix6Node *node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
823  FAIL_IF_NULL(node);
824  FAIL_IF_NULL(user_data);
825  FAIL_IF(*((uint32_t *)user_data) != 100);
826  user_data = NULL;
827 
828  GET_IPV6("2000:177::0:0:0");
829  user = SCMalloc(sizeof(uint32_t));
830  FAIL_IF_NULL(user);
831  *user = 200;
832  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 64, user);
833 
834  GET_IPV6("2000:177::168:1:15");
835  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
836  FAIL_IF_NULL(node);
837  FAIL_IF_NULL(user_data);
838  FAIL_IF(*((uint32_t *)user_data) != 200);
839  user_data = NULL;
840 
841  GET_IPV6("2000:178::168:1:15");
842  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
843  FAIL_IF_NULL(node);
844  FAIL_IF_NULL(user_data);
845  FAIL_IF(*((uint32_t *)user_data) != 100);
846  user_data = NULL;
847 
848  GET_IPV6("2000:177::168:0:0");
849  user = SCMalloc(sizeof(uint32_t));
850  FAIL_IF_NULL(user);
851  *user = 300;
852  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 92, user);
853 
854  GET_IPV6("2000:177::168:1:15");
855  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
856  FAIL_IF_NULL(node);
857  FAIL_IF_NULL(user_data);
858  FAIL_IF(*((uint32_t *)user_data) != 300);
859  user_data = NULL;
860 
861  GET_IPV6("2000:177::167:1:15");
862  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
863  FAIL_IF_NULL(node);
864  FAIL_IF_NULL(user_data);
865  FAIL_IF(*((uint32_t *)user_data) != 300);
866  user_data = NULL;
867 
868  GET_IPV6("2000:177::178:1:15");
869  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
870  FAIL_IF_NULL(node);
871  FAIL_IF_NULL(user_data);
872  FAIL_IF(*((uint32_t *)user_data) != 200);
873  user_data = NULL;
874 
875  GET_IPV6("2000:197::178:1:15");
876  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
877  FAIL_IF_NULL(node);
878  FAIL_IF_NULL(user_data);
879  FAIL_IF(*((uint32_t *)user_data) != 100);
880  user_data = NULL;
881 
882  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
883  PASS;
884 }
885 
886 /**
887  * \test SCRadix6TestIPV6NetblockInsertion15 insert a node searching on it.
888  * Should always return true but the purposse of the test is to monitor
889  * the memory usage to detect memleaks (there was one on searching)
890  */
891 static int SCRadix6TestIPV6NetblockInsertion25(void)
892 {
893  struct sockaddr_in6 sa;
895  ADD_IPV6_MASK("2000::192:168:0:0", 16);
896  GET_IPV6("2000::192:168:128:53");
897  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
898  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
899  PASS;
900 }
901 
902 /**
903  * \test SCRadix6TestIPV6NetblockInsertion26 insert a node searching on it.
904  * Should always return true but the purposse of the test is to monitor
905  * the memory usage to detect memleaks (there was one on searching)
906  */
907 static int SCRadix6TestIPV6NetblockInsertion26(void)
908 {
909  SCRadix6Node *tmp = NULL;
910  struct sockaddr_in6 sa;
911  const SCRadix6Config ut_ip_radix6_config_26 = { free, NULL };
912 
913  char *str = SCStrdup("Hello1");
914  FAIL_IF_NULL(str);
915 
917 
918  GET_IPV6("::");
919  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config_26, (uint8_t *)&sa.sin6_addr, 0, str);
920 
921  str = SCStrdup("Hello2");
922  FAIL_IF_NULL(str);
923 
924  GET_IPV6("2000::176:0:0:1");
925  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config_26, (uint8_t *)&sa.sin6_addr, 5, str);
926 
927  str = SCStrdup("Hello3");
928  FAIL_IF_NULL(str);
929 
930  GET_IPV6("::");
931  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config_26, (uint8_t *)&sa.sin6_addr, 7, str);
932 
933  /* test for the existance of a key */
934  void *retptr = NULL;
935  tmp = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &retptr);
936  FAIL_IF_NULL(tmp);
937  FAIL_IF_NULL(retptr);
938  FAIL_IF_NOT(strcmp((char *)retptr, "Hello3") == 0);
939 
940  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config_26);
941 
942  PASS;
943 }
944 #endif
945 
947 {
948 #ifdef UNITTESTS
949  UtRegisterTest("SCRadix6TestIPV6Insertion03", SCRadix6TestIPV6Insertion03);
950  UtRegisterTest("SCRadix6TestIPV6Removal04", SCRadix6TestIPV6Removal04);
951  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion09", SCRadix6TestIPV6NetblockInsertion09);
952  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion10", SCRadix6TestIPV6NetblockInsertion10);
953  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion11", SCRadix6TestIPV6NetblockInsertion11);
954  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion12", SCRadix6TestIPV6NetblockInsertion12);
956  "SCRadix6TestIPV6NetBlocksAndBestSearch16", SCRadix6TestIPV6NetBlocksAndBestSearch16);
958  "SCRadix6TestIPV6NetBlocksAndBestSearch19", SCRadix6TestIPV6NetBlocksAndBestSearch19);
959  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion25", SCRadix6TestIPV6NetblockInsertion25);
960  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion26", SCRadix6TestIPV6NetblockInsertion26);
961 #endif
962  return;
963 }
util-byte.h
SCRadix6AddKeyIPV6Netblock
SCRadix6Node * SCRadix6AddKeyIPV6Netblock(SCRadix6Tree *tree, const SCRadix6Config *config, const uint8_t *key_stream, uint8_t netmask, void *user)
Adds a new IPV6 netblock to the Radix6 tree.
Definition: util-radix6-tree.c:214
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SCRadix6TreeFindExactMatch
SCRadix6Node * SCRadix6TreeFindExactMatch(const SCRadix6Tree *tree, const uint8_t *key, void **user_data)
Definition: util-radix6-tree.c:161
SCRadix6Node_::masks
uint8_t masks[17]
Definition: util-radix6-tree.h:41
ADD_IPV6
#define ADD_IPV6(str)
Definition: util-radix6-tree.c:435
NETMASK_MAX
#define NETMASK_MAX
Definition: util-radix6-tree.c:39
SCRadix6TreeFindBestMatch
SCRadix6Node * SCRadix6TreeFindBestMatch(const SCRadix6Tree *tree, const uint8_t *key, void **user_data)
Definition: util-radix6-tree.c:173
SCRadix6ForEachNodeFunc
int(* SCRadix6ForEachNodeFunc)(const SCRadix6Node *node, void *user_data, const uint8_t netmask, void *data)
Definition: util-radix6-tree.h:104
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
util-radix-tree-common.h
SC_EINVAL
@ SC_EINVAL
Definition: util-error.h:30
REM_IPV6_MASK
#define REM_IPV6_MASK(str, cidr)
Definition: util-radix6-tree.c:448
RadixUserData
Structure that hold the user data and the netmask associated with it.
Definition: util-radix-tree-common.h:41
RadixUserData::next
struct RadixUserData * next
Definition: util-radix-tree-common.h:45
SCRadix6TreeFindNetblock
SCRadix6Node * SCRadix6TreeFindNetblock(const SCRadix6Tree *tree, const uint8_t *key, const uint8_t netmask, void **user_data)
Definition: util-radix6-tree.c:167
m
SCMutex m
Definition: flow-hash.h:6
util-unittest.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
util-memcmp.h
SCRadix6RemoveKeyIPV6
void SCRadix6RemoveKeyIPV6(SCRadix6Tree *tree, const SCRadix6Config *config, const uint8_t *key_stream)
Removes an IPV6 address key(not a netblock) from the Radix6 tree. Instead of using this function,...
Definition: util-radix6-tree.c:335
SCRadix6Tree_::head
SCRadix6Node * head
Definition: util-radix6-tree.h:66
util-cidr.h
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
SCRadix6Node_::left
struct SCRadix6Node_ * left
Definition: util-radix6-tree.h:55
util-print.h
util-ip.h
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:230
SCRadix6PrintTree
void SCRadix6PrintTree(SCRadix6Tree *tree, const SCRadix6Config *config)
Definition: util-radix6-tree.c:355
SCRadix6Node_::prefix_stream
uint8_t prefix_stream[16]
Definition: util-radix6-tree.h:38
SCRadix6Node_::user_data
struct RadixUserData * user_data
Definition: util-radix6-tree.h:52
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
REM_IPV6
#define REM_IPV6(str)
Definition: util-radix6-tree.c:439
SCRadix6CompareTrees
bool SCRadix6CompareTrees(const SCRadix6Tree *t1, const SCRadix6Tree *t2, SCRadix6TreeCompareFunc Callback)
Definition: util-radix6-tree.c:418
SCRadix6TreeFindBestMatch2
SCRadix6Node * SCRadix6TreeFindBestMatch2(const SCRadix6Tree *tree, const uint8_t *key, void **user_data, uint8_t *out_netmask)
Definition: util-radix6-tree.c:179
ADD_IPV6_MASK
#define ADD_IPV6_MASK(str, cidr)
Definition: util-radix6-tree.c:443
SC_OK
@ SC_OK
Definition: util-error.h:27
SCRadix6Node_::right
struct SCRadix6Node_ * right
Definition: util-radix6-tree.h:55
SCRadix6ForEachNode
int SCRadix6ForEachNode(const SCRadix6Tree *tree, SCRadix6ForEachNodeFunc Callback, void *data)
Definition: util-radix6-tree.c:411
StringParseU8RangeCheck
int StringParseU8RangeCheck(uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
Definition: util-byte.c:462
CIDRGetIPv6
void CIDRGetIPv6(int cidr, struct in6_addr *in6)
Creates a cidr ipv6 netblock, based on the cidr netblock value.
Definition: util-cidr.c:82
SCRadix6Config_
Definition: util-radix6-tree.h:69
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
RadixUserData::user
void * user
Definition: util-radix-tree-common.h:43
SCRadix6AddKeyIPV6
SCRadix6Node * SCRadix6AddKeyIPV6(SCRadix6Tree *tree, const SCRadix6Config *config, const uint8_t *key_stream, void *user)
Adds a new IPV6 address to the Radix6 tree.
Definition: util-radix6-tree.c:196
SCRadix6RegisterTests
void SCRadix6RegisterTests(void)
Definition: util-radix6-tree.c:946
util-radix6-tree.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
SCRadix6Node_
Structure for the node in the radix tree.
Definition: util-radix6-tree.h:36
SCRadix6RemoveKeyIPV6Netblock
void SCRadix6RemoveKeyIPV6Netblock(SCRadix6Tree *tree, const SCRadix6Config *config, const uint8_t *key_stream, uint8_t netmask)
Removes an IPV6 address netblock key from the tree.
Definition: util-radix6-tree.c:349
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCRadix6TreeCompareFunc
bool(* SCRadix6TreeCompareFunc)(const void *ud1, const void *ud2)
compare content of 2 user data entries
Definition: util-radix6-tree.h:113
str
#define str(s)
Definition: suricata-common.h:291
SCRadix6Tree_
Structure for the radix tree.
Definition: util-radix6-tree.h:64
src
uint16_t src
Definition: app-layer-dnp3.h:5
sc_errno
thread_local SCError sc_errno
Definition: util-error.c:31
address
uint8_t address
Definition: decode-ppp.h:0
SCRadix6AddKeyIPV6String
bool SCRadix6AddKeyIPV6String(SCRadix6Tree *tree, const SCRadix6Config *config, const char *str, void *user)
Adds a new IPV6/netblock to the Radix6 tree from a string.
Definition: util-radix6-tree.c:262
SCRadix6TreeInitialize
SCRadix6Tree SCRadix6TreeInitialize(void)
Definition: util-radix6-tree.c:360
SCRadix6Node_::bit
uint8_t bit
Definition: util-radix6-tree.h:45
GET_IPV6
#define GET_IPV6(str)
Definition: util-radix6-tree.c:430
SCRadix6TreeRelease
void SCRadix6TreeRelease(SCRadix6Tree *tree, const SCRadix6Config *config)
Definition: util-radix6-tree.c:366
SC_RADIX6_TREE_INITIALIZER
#define SC_RADIX6_TREE_INITIALIZER
Definition: util-radix6-tree.h:76
RadixUserData::netmask
uint8_t netmask
Definition: util-radix-tree-common.h:47
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:237
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
SCRadix6Node_::has_prefix
bool has_prefix
Definition: util-radix6-tree.h:47