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);
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 static void SCRadix6UtFree(void *ptr)
428 {
429  SCFree(ptr);
430 }
431 
432 static const SCRadix6Config ut_ip_radix6_config = { SCRadix6UtFree, NULL };
433 
434 #define GET_IPV6(str) \
435  SCLogDebug("setting up %s", (str)); \
436  memset(&(sa), 0, sizeof((sa))); \
437  FAIL_IF(inet_pton(AF_INET6, (str), &(sa).sin6_addr) <= 0);
438 
439 #define ADD_IPV6(str) \
440  GET_IPV6((str)); \
441  SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, NULL);
442 
443 #define REM_IPV6(str) \
444  GET_IPV6((str)); \
445  SCRadix6RemoveKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr);
446 
447 #define ADD_IPV6_MASK(str, cidr) \
448  GET_IPV6((str)); \
449  SCRadix6AddKeyIPV6Netblock( \
450  &tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, (cidr), NULL);
451 
452 #define REM_IPV6_MASK(str, cidr) \
453  GET_IPV6((str)); \
454  SCRadix6RemoveKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&(sa).sin6_addr, (cidr));
455 
456 static int SCRadix6TestIPV6Insertion03(void)
457 {
458  struct sockaddr_in6 sa;
460 
461  ADD_IPV6("2000:1::1");
462  ADD_IPV6("2000:1::2");
463  ADD_IPV6("2000:0::3");
464  ADD_IPV6("2000:0::4");
465  ADD_IPV6("2000:0::4");
466 
467  /* test for the existance of a key */
468  GET_IPV6("2000:1::6");
469  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
470 
471  /* test for the existance of a key */
472  GET_IPV6("2000:0::4");
473  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
474 
475  /* continue adding keys */
476  ADD_IPV6("2000:0::2");
477  ADD_IPV6("2000:1::5");
478  ADD_IPV6("2000:1::18");
479 
480  /* test the existence of keys */
481  GET_IPV6("2000:1::3");
482  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
483  GET_IPV6("2001:1:2:3::62");
484  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
485 
486  GET_IPV6("2000:1::1");
487  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
488  GET_IPV6("2000:1::5");
489  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
490  GET_IPV6("2000:1::2");
491  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
492 
493  GET_IPV6("2000:0::3");
494  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
495  GET_IPV6("2000:0::4");
496  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
497  GET_IPV6("2000:0::2");
498  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
499  GET_IPV6("2000:1::18");
500  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
501 
502  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
503 
504  PASS;
505 }
506 
507 static int SCRadix6TestIPV6Removal04(void)
508 {
509  struct sockaddr_in6 sa;
511 
512  /* add the keys */
513  ADD_IPV6("2000:1::1");
514  ADD_IPV6("2000:1::2");
515  ADD_IPV6("2000:0::3");
516  ADD_IPV6("2000:0::4");
517  ADD_IPV6("1000:1::2");
518  ADD_IPV6("2000:1::5");
519  ADD_IPV6("2000:1::18");
520 
521  /* remove the keys from the tree */
522  REM_IPV6("2000:1::1");
523  REM_IPV6("2000:0::3");
524  REM_IPV6("2000:0::4");
525  REM_IPV6("2000:1::18");
526 
527  GET_IPV6("2000:0::1");
528  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
529  GET_IPV6("2000:1::2");
530  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
531 
532  REM_IPV6("2000:0::3");
533  REM_IPV6("1000:1::2");
534 
535  GET_IPV6("2000:1::5");
536  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
537  GET_IPV6("2000:1::2");
538  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
539 
540  REM_IPV6("2000:1::2");
541  REM_IPV6("2000:1::5");
542 
543  FAIL_IF_NOT_NULL(tree.head);
544 
545  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
546 
547  PASS;
548 }
549 
550 static int SCRadix6TestIPV6NetblockInsertion09(void)
551 {
552  struct sockaddr_in6 sa;
554 
555  /* add the keys */
556  ADD_IPV6("2000::1:1");
557  ADD_IPV6("2000::1:2");
558  ADD_IPV6("2000::0:3");
559  ADD_IPV6("2000::0:4");
560  ADD_IPV6("1000::1:2");
561  ADD_IPV6("2000::1:5");
562  ADD_IPV6("2000::1:18");
563 
564  ADD_IPV6_MASK("2000::", 16);
565  ADD_IPV6_MASK("2000::192:171:128:0", 128 - 8);
566  ADD_IPV6_MASK("2000::192:171:192:0", 128 - 14);
567  ADD_IPV6_MASK("2000::192:175:0:0", 128 - 16);
568 
569  /* test for the existance of a key */
570  GET_IPV6("2000:1::6");
571  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
572  GET_IPV6("2000::192:170:1:6");
573  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
574  GET_IPV6("2000::192:171:128:145");
575  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
576  GET_IPV6("2000::192:171:64:6");
577  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
578  GET_IPV6("2000::192:171:191:6");
579  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
580  GET_IPV6("2000::192:171:224:6");
581  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
582  GET_IPV6("2000::192:171:224:6");
583  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
584  GET_IPV6("2000::192:175:224:6");
585  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
586 
587  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
588 
589  PASS;
590 }
591 
592 static int SCRadix6TestIPV6NetblockInsertion10(void)
593 {
594  SCRadix6Node *node[2];
595  struct sockaddr_in6 sa;
597 
598  /* add the keys */
599  ADD_IPV6_MASK("2000::253:192:0:0", 112);
600  ADD_IPV6_MASK("2000::253:192:235:0", 112);
601  ADD_IPV6_MASK("2000::192:167:0:0", 112);
602  ADD_IPV6("2000:0::4");
603  ADD_IPV6_MASK("2000::220:168:0:0", 112);
604  ADD_IPV6("2000::253:224:1:5");
605  ADD_IPV6_MASK("2000::192:168:0:0", 112);
606 
607  GET_IPV6("2000::192:171:128:0");
608  node[0] = SCRadix6AddKeyIPV6Netblock(
609  &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 112, NULL);
610 
611  GET_IPV6("2000::192:171:128:45");
612  node[1] = SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, NULL);
613 
614  ADD_IPV6_MASK("2000::192:171:0:0", 110);
615  ADD_IPV6_MASK("2000::192:175:0:0", 112);
616 
617  /* test for the existance of a key */
618  GET_IPV6("2000::192:171:128:53");
619  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[0]);
620 
621  GET_IPV6("2000::192:171:128:45");
622  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[1]);
623 
624  GET_IPV6("2000::192:171:128:45");
625  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[1]);
626 
627  GET_IPV6("2000::192:171:128:78");
628  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[0]);
629 
630  REM_IPV6_MASK("2000::192:171:128:0", 112);
631 
632  GET_IPV6("2000::192:171:128:78");
633  SCRadix6Node *n = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL);
634  SCLogNotice("n %p", n);
635  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
636  GET_IPV6("2000::192:171:127:78");
637  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
638 
639  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
640 
641  PASS;
642 }
643 
644 static int SCRadix6TestIPV6NetblockInsertion11(void)
645 {
646  struct sockaddr_in6 sa;
648 
649  /* add the keys */
650  ADD_IPV6_MASK("2000::253:192:0:0", 96);
651  ADD_IPV6_MASK("2000::253:192:235:0", 112);
652  ADD_IPV6_MASK("2000::192:167:0:0", 96);
653  ADD_IPV6("2000:0::4");
654  ADD_IPV6_MASK("2000::220:168:0:0", 96);
655  ADD_IPV6("2000::253:224:1:5");
656  ADD_IPV6_MASK("2000::192:168:0:0", 96);
657  ADD_IPV6_MASK("2000::192:171:128:0", 112);
658  ADD_IPV6("2000::192:171:128:45");
659  ADD_IPV6_MASK("2000::192:171:0:0", 112);
660  ADD_IPV6_MASK("2000::192:175:0:0", 96);
661 
662  GET_IPV6("::");
664  &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 0, NULL);
665  FAIL_IF_NULL(node);
666 
667  /* test for the existance of a key */
668  GET_IPV6("2000::192:171:128:53");
669  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
670 
671  GET_IPV6("2000::192:171:128:45");
672  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
673 
674  GET_IPV6("2000::192:171:128:78");
675  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
676 
677  GET_IPV6("2000::192:171:127:78");
678  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
679 
680  GET_IPV6("2000::1:1:1:1");
681  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
682 
683  GET_IPV6("2000::192:255:254:25");
684  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
685 
686  GET_IPV6("2000::169:255:254:25");
687  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
688 
689  GET_IPV6("::");
690  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
691 
692  GET_IPV6("2000::253:224:1:5");
693  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
694  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != node);
695 
696  GET_IPV6("2000::245:63:62:121");
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  GET_IPV6("2000::253:224:1:6");
701  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
702  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node);
703 
704  /* remove node 0.0.0.0 */
705  REM_IPV6_MASK("::", 0);
706 
707  GET_IPV6("2000::253:224:1:6");
708  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
709  GET_IPV6("2000::192:171:127:78");
710  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
711  GET_IPV6("2000::1:1:1:1");
712  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
713 
714  GET_IPV6("2000::192:255:254:25");
715  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
716  GET_IPV6("2000::169:255:254:25");
717  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
718 
719  GET_IPV6("::");
720  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
721 
722  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
723 
724  PASS;
725 }
726 
727 static int SCRadix6TestIPV6NetblockInsertion12(void)
728 {
729  struct sockaddr_in6 sa;
730  SCRadix6Node *node[2];
732 
733  /* add the keys */
734  ADD_IPV6_MASK("2000::253:192:0:0", 96);
735  ADD_IPV6_MASK("2000::253:192:235:0", 112);
736  ADD_IPV6_MASK("2000::192:167:0:0", 96);
737  ADD_IPV6("2000:0::4");
738  ADD_IPV6_MASK("2000::220:168:0:0", 96);
739  ADD_IPV6("2000::253:224:1:5");
740  ADD_IPV6_MASK("2000::192:168:0:0", 96);
741 
742  GET_IPV6("2000::192:171:128:0");
743  node[0] = SCRadix6AddKeyIPV6Netblock(
744  &tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 96, NULL);
745  FAIL_IF_NULL(node[0]);
746 
747  GET_IPV6("2000::192:171:128:45");
748  node[1] = SCRadix6AddKeyIPV6(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, NULL);
749  FAIL_IF_NULL(node[1]);
750 
751  ADD_IPV6_MASK("2000::192:171:0:0", 96);
752  ADD_IPV6_MASK("2000::225:175:21:228", 128);
753 
754  /* test for the existance of a key */
755  GET_IPV6("2000::192:171:128:53");
756  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[0]);
757  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
758 
759  GET_IPV6("2000::192:171:128:45");
760  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[1]);
761  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[1]);
762 
763  GET_IPV6("2000::192:171:128:78");
764  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == node[0]);
765  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
766 
767  GET_IPV6("2000::225:175:21:228");
768  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
769 
770  GET_IPV6("2000::225:175:21:224");
771  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
772 
773  GET_IPV6("2000::225:175:21:229");
774  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
775 
776  GET_IPV6("2000::225:175:21:230");
777  FAIL_IF_NOT(SCRadix6TreeFindExactMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) == NULL);
778 
779  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
780  PASS;
781 }
782 
783 /**
784  * \test Check that the best match search works for all the
785  * possible netblocks of a fixed address
786  */
787 static int SCRadix6TestIPV6NetBlocksAndBestSearch16(void)
788 {
789  struct sockaddr_in6 sa;
791 
792  GET_IPV6("2000:1::1");
793  for (uint32_t i = 0; i <= 128; i++) {
794  uint32_t *user = SCMalloc(sizeof(uint32_t));
795  FAIL_IF_NULL(user);
796  *user = i;
797  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, i, user);
798  void *user_data = NULL;
799  SCRadix6Node *node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
800  FAIL_IF_NULL(node);
801  FAIL_IF_NULL(user_data);
802  FAIL_IF(*((uint32_t *)user_data) != i);
803  }
804 
805  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
806  PASS;
807 }
808 
809 /**
810  * \test Check special combinations of netblocks and addresses
811  * on best search checking the returned userdata
812  */
813 static int SCRadix6TestIPV6NetBlocksAndBestSearch19(void)
814 {
815  struct sockaddr_in6 sa;
816  void *user_data = NULL;
818 
819  GET_IPV6("::");
820  uint32_t *user = SCMalloc(sizeof(uint32_t));
821  FAIL_IF_NULL(user);
822  *user = 100;
823  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 0, user);
824 
825  GET_IPV6("2000:1::15");
826  SCRadix6Node *node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
827  FAIL_IF_NULL(node);
828  FAIL_IF_NULL(user_data);
829  FAIL_IF(*((uint32_t *)user_data) != 100);
830  user_data = NULL;
831 
832  GET_IPV6("2000:177::0:0:0");
833  user = SCMalloc(sizeof(uint32_t));
834  FAIL_IF_NULL(user);
835  *user = 200;
836  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 64, user);
837 
838  GET_IPV6("2000:177::168:1:15");
839  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
840  FAIL_IF_NULL(node);
841  FAIL_IF_NULL(user_data);
842  FAIL_IF(*((uint32_t *)user_data) != 200);
843  user_data = NULL;
844 
845  GET_IPV6("2000:178::168:1:15");
846  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
847  FAIL_IF_NULL(node);
848  FAIL_IF_NULL(user_data);
849  FAIL_IF(*((uint32_t *)user_data) != 100);
850  user_data = NULL;
851 
852  GET_IPV6("2000:177::168:0:0");
853  user = SCMalloc(sizeof(uint32_t));
854  FAIL_IF_NULL(user);
855  *user = 300;
856  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config, (uint8_t *)&sa.sin6_addr, 92, user);
857 
858  GET_IPV6("2000:177::168:1:15");
859  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
860  FAIL_IF_NULL(node);
861  FAIL_IF_NULL(user_data);
862  FAIL_IF(*((uint32_t *)user_data) != 300);
863  user_data = NULL;
864 
865  GET_IPV6("2000:177::167:1:15");
866  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
867  FAIL_IF_NULL(node);
868  FAIL_IF_NULL(user_data);
869  FAIL_IF(*((uint32_t *)user_data) != 300);
870  user_data = NULL;
871 
872  GET_IPV6("2000:177::178:1:15");
873  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
874  FAIL_IF_NULL(node);
875  FAIL_IF_NULL(user_data);
876  FAIL_IF(*((uint32_t *)user_data) != 200);
877  user_data = NULL;
878 
879  GET_IPV6("2000:197::178:1:15");
880  node = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &user_data);
881  FAIL_IF_NULL(node);
882  FAIL_IF_NULL(user_data);
883  FAIL_IF(*((uint32_t *)user_data) != 100);
884  user_data = NULL;
885 
886  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
887  PASS;
888 }
889 
890 /**
891  * \test SCRadix6TestIPV6NetblockInsertion15 insert a node searching on it.
892  * Should always return true but the purposse of the test is to monitor
893  * the memory usage to detect memleaks (there was one on searching)
894  */
895 static int SCRadix6TestIPV6NetblockInsertion25(void)
896 {
897  struct sockaddr_in6 sa;
899  ADD_IPV6_MASK("2000::192:168:0:0", 16);
900  GET_IPV6("2000::192:168:128:53");
901  FAIL_IF_NOT(SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, NULL) != NULL);
902  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config);
903  PASS;
904 }
905 
906 /**
907  * \test SCRadix6TestIPV6NetblockInsertion26 insert a node searching on it.
908  * Should always return true but the purposse of the test is to monitor
909  * the memory usage to detect memleaks (there was one on searching)
910  */
911 static int SCRadix6TestIPV6NetblockInsertion26(void)
912 {
913  SCRadix6Node *tmp = NULL;
914  struct sockaddr_in6 sa;
915  const SCRadix6Config ut_ip_radix6_config_26 = { free, NULL };
916 
917  char *str = SCStrdup("Hello1");
918  FAIL_IF_NULL(str);
919 
921 
922  GET_IPV6("::");
923  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config_26, (uint8_t *)&sa.sin6_addr, 0, str);
924 
925  str = SCStrdup("Hello2");
926  FAIL_IF_NULL(str);
927 
928  GET_IPV6("2000::176:0:0:1");
929  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config_26, (uint8_t *)&sa.sin6_addr, 5, str);
930 
931  str = SCStrdup("Hello3");
932  FAIL_IF_NULL(str);
933 
934  GET_IPV6("::");
935  SCRadix6AddKeyIPV6Netblock(&tree, &ut_ip_radix6_config_26, (uint8_t *)&sa.sin6_addr, 7, str);
936 
937  /* test for the existance of a key */
938  void *retptr = NULL;
939  tmp = SCRadix6TreeFindBestMatch(&tree, (uint8_t *)&sa.sin6_addr, &retptr);
940  FAIL_IF_NULL(tmp);
941  FAIL_IF_NULL(retptr);
942  FAIL_IF_NOT(strcmp((char *)retptr, "Hello3") == 0);
943 
944  SCRadix6TreeRelease(&tree, &ut_ip_radix6_config_26);
945 
946  PASS;
947 }
948 #endif
949 
951 {
952 #ifdef UNITTESTS
953  UtRegisterTest("SCRadix6TestIPV6Insertion03", SCRadix6TestIPV6Insertion03);
954  UtRegisterTest("SCRadix6TestIPV6Removal04", SCRadix6TestIPV6Removal04);
955  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion09", SCRadix6TestIPV6NetblockInsertion09);
956  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion10", SCRadix6TestIPV6NetblockInsertion10);
957  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion11", SCRadix6TestIPV6NetblockInsertion11);
958  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion12", SCRadix6TestIPV6NetblockInsertion12);
960  "SCRadix6TestIPV6NetBlocksAndBestSearch16", SCRadix6TestIPV6NetBlocksAndBestSearch16);
962  "SCRadix6TestIPV6NetBlocksAndBestSearch19", SCRadix6TestIPV6NetBlocksAndBestSearch19);
963  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion25", SCRadix6TestIPV6NetblockInsertion25);
964  UtRegisterTest("SCRadix6TestIPV6NetblockInsertion26", SCRadix6TestIPV6NetblockInsertion26);
965 #endif
966  return;
967 }
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:439
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:452
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:231
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:259
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
REM_IPV6
#define REM_IPV6(str)
Definition: util-radix6-tree.c:443
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:447
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:474
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:950
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:308
SCRadix6Tree_
Structure for the radix tree.
Definition: util-radix6-tree.h:64
SCFree
#define SCFree(p)
Definition: util-mem.h:61
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:434
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:247
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