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