suricata
util-radix4-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 tree for IPv4
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-unittest.h"
32 #include "util-memcmp.h"
33 #include "util-print.h"
34 #include "util-byte.h"
35 #include "util-radix4-tree.h"
36 
37 #define ADDRESS_BYTES (uint8_t)4
38 #define NETMASK_MAX (uint8_t)32
39 
40 #define RADIX_TREE_TYPE SCRadix4Tree
41 #define RADIX_NODE_TYPE SCRadix4Node
42 #define RADIX_CONFIG_TYPE SCRadix4Config
43 #define RADIX_TREE_COMPARE_CALLBACK SCRadix4TreeCompareFunc
44 
45 static void PrintUserdata(SCRadix4Node *node, int level, void (*PrintData)(void *));
46 
47 static inline void AddNetmaskToMasks(SCRadix4Node *node, int netmask)
48 {
49  SCLogDebug("masks %" PRIX64 ", adding %d/%" PRIX64, (uint64_t)node->masks, netmask,
50  (uint64_t)BIT_U64(netmask));
51  node->masks |= BIT_U64(netmask);
52  SCLogDebug("masks %" PRIX64, (uint64_t)node->masks);
53 }
54 
55 static inline void RemoveNetmaskFromMasks(SCRadix4Node *node, int netmask)
56 {
57  SCLogDebug("masks %" PRIX64 ", removing %d/%" PRIX64, (uint64_t)node->masks, netmask,
58  (uint64_t)BIT_U64(netmask));
59  node->masks &= ~BIT_U64(netmask);
60  SCLogDebug("masks %" PRIX64, (uint64_t)node->masks);
61 }
62 
63 static inline void AddNetmasksFromNode(SCRadix4Node *dst, SCRadix4Node *src)
64 {
65  dst->masks |= src->masks;
66 }
67 
68 static inline bool NetmasksEmpty(const SCRadix4Node *node)
69 {
70  return (node->masks == 0);
71 }
72 
73 static inline bool NetmaskEqualsMask(const SCRadix4Node *node, int netmask)
74 {
75  return (node->masks == BIT_U64(netmask));
76 }
77 
78 static inline bool NetmaskIssetInMasks(const SCRadix4Node *node, int netmask)
79 {
80  return ((node->masks & BIT_U64(netmask)) != 0);
81 }
82 
83 static inline void ProcessInternode(SCRadix4Node *node, SCRadix4Node *inter_node)
84 {
85  const int differ_bit = inter_node->bit;
86  uint64_t rem = 0;
87  for (int x = 0; x <= NETMASK_MAX; x++) {
88  int m = NETMASK_MAX - x;
89  if (m == differ_bit)
90  break;
91  else {
92  rem |= (node->masks & BIT_U64(m));
93  }
94  }
95 
96  inter_node->masks |= node->masks;
97  inter_node->masks &= ~rem;
98  node->masks = rem;
99 }
100 
101 /**
102  * \brief Prints the node information from a Radix4 tree
103  *
104  * \param node Pointer to the Radix4 node whose information has to be printed
105  * \param level Used for indentation purposes
106  */
107 static void PrintNodeInfo(SCRadix4Node *node, int level, void (*PrintData)(void *))
108 {
109  if (node == NULL)
110  return;
111 
112  for (int i = 0; i < level; i++)
113  printf(" ");
114 
115  printf("%d [", node->bit);
116 
117  if (node->masks == 0) {
118  printf(" - ");
119  } else {
120  for (int i = 0, x = 0; i <= 32; i++) {
121  if (node->masks & BIT_U64(i)) {
122  printf("%s%d", (x && x < 32) ? ", " : "", i);
123  x++;
124  }
125  }
126  }
127  printf("] (");
128 
129  if (node->has_prefix) {
130  char addr[16] = "";
131  PrintInet(AF_INET, &node->prefix_stream, addr, sizeof(addr));
132  printf("%s - user_data %p)\n", addr, node->user_data);
133  PrintUserdata(node, level + 1, PrintData);
134  } else {
135  printf("no prefix)\n");
136  }
137  return;
138 }
139 
140 #include "util-radix-tree-common.h"
141 
143  const SCRadix4Tree *tree, const uint8_t *key, void **user_data)
144 {
145  return FindExactMatch(tree, key, user_data);
146 }
147 
149  const SCRadix4Tree *tree, const uint8_t *key, const uint8_t netmask, void **user_data)
150 {
151  return FindNetblock(tree, key, netmask, user_data);
152 }
153 
155  const SCRadix4Tree *tree, const uint8_t *key, void **user_data)
156 {
157  return FindBestMatch(tree, key, user_data);
158 }
159 
161  const SCRadix4Tree *tree, const uint8_t *key, void **user_data, uint8_t *out_netmask)
162 {
163  return FindBestMatch2(tree, key, user_data, out_netmask);
164 }
165 
167 {
169  return t;
170 }
171 
173 {
174  TreeRelease(tree, config);
175 }
176 
177 /**
178  * \brief Adds a new IPV4 address to the Radix4 tree
179  *
180  * \param key_stream Data that has to be added to the Radix4 tree. In this case
181  * a pointer to an IPV4 address
182  * \param tree Pointer to the Radix4 tree
183  * \param user Pointer to the user data that has to be associated with the
184  * key
185  *
186  * \retval node Pointer to the newly created node
187  */
189  SCRadix4Tree *tree, const SCRadix4Config *config, const uint8_t *key_stream, void *user)
190 {
191  return AddKey(tree, config, key_stream, 32, user, false);
192 }
193 
194 /**
195  * \brief Adds a new IPV4 netblock to the Radix4 tree
196  *
197  * \param key_stream Data that has to be added to the Radix4 tree. In this case
198  * a pointer to an IPV4 netblock
199  * \param tree Pointer to the Radix4 tree
200  * \param user Pointer to the user data that has to be associated with the
201  * key
202  * \param netmask The netmask (cidr) if we are adding a netblock
203  *
204  * \retval node Pointer to the newly created node
205  */
207  const uint8_t *key_stream, uint8_t netmask, void *user)
208 {
209  return AddKey(tree, config, key_stream, netmask, user, false);
210 }
211 
212 /**
213  * \brief Adds a new IPV4/netblock to the Radix4 tree from a string
214  *
215  * \param str IPV4 string with optional /cidr netmask
216  * \param tree Pointer to the Radix4 tree
217  * \param user Pointer to the user data that has to be associated with
218  * the key
219  *
220  * \retval bool true if node was added, false otherwise
221  *
222  * If the function returns false, `sc_errno` is set:
223  * - SC_EEXIST: Node already exists
224  * - SC_EINVAL: Parameter value error
225  * - SC_ENOMEM: Memory allocation failed
226  */
228  SCRadix4Tree *tree, const SCRadix4Config *config, const char *str, void *user)
229 {
230  uint32_t ip;
231  uint8_t netmask = 32;
232  char ip_str[32]; /* Max length for full ipv4/mask string with NUL */
233  char *mask_str = NULL;
234  struct in_addr addr;
235 
236  /* Make a copy of the string so it can be modified */
237  strlcpy(ip_str, str, sizeof(ip_str) - 2);
238  *(ip_str + (sizeof(ip_str) - 1)) = '\0';
239 
240  /* Does it have a mask? */
241  if (NULL != (mask_str = strchr(ip_str, '/'))) {
242  *(mask_str++) = '\0';
243 
244  /* Dotted type netmask not supported */
245  if (strchr(mask_str, '.') != NULL) {
247  return false;
248  }
249 
250  uint8_t cidr;
251  if (StringParseU8RangeCheck(&cidr, 10, 0, (const char *)mask_str, 0, 32) <= 0) {
253  return false;
254  }
255  netmask = (uint8_t)cidr;
256  }
257 
258  /* Validate the IP */
259  if (inet_pton(AF_INET, ip_str, &addr) <= 0) {
261  return false;
262  }
263  ip = addr.s_addr;
264 
265  if (AddKey(tree, config, (uint8_t *)&ip, netmask, user, true) == NULL) {
267  return false;
268  }
269  return true;
270 }
271 
272 /**
273  * \brief Removes an IPV4 address key(not a netblock) from the Radix4 tree.
274  * Instead of using this function, we can also used
275  * SCRadix4RemoveKeyIPV4Netblock(), by supplying a netmask value of 32.
276  *
277  * \param key_stream Data that has to be removed from the Radix4 tree. In this
278  * case an IPV4 address
279  * \param tree Pointer to the Radix4 tree from which the key has to be
280  * removed
281  */
283  SCRadix4Tree *tree, const SCRadix4Config *config, const uint8_t *key_stream)
284 {
285  RemoveKey(tree, config, key_stream, 32);
286 }
287 
288 /**
289  * \brief Removes an IPV4 address netblock key from the Radix4 tree.
290  *
291  * \param key_stream Data that has to be removed from the Radix4 tree. In this
292  * case an IPV4 address
293  * \param tree Pointer to the Radix4 tree from which the key has to be
294  * removed
295  */
297  const uint8_t *key_stream, uint8_t netmask)
298 {
299  SCLogNotice("removing with netmask %u", netmask);
300  RemoveKey(tree, config, key_stream, netmask);
301 }
302 
304 {
305  PrintTree(tree, config);
306 }
307 
308 static void PrintUserdata(SCRadix4Node *node, int level, void (*PrintData)(void *))
309 {
310  if (PrintData != NULL) {
311  RadixUserData *ud = node->user_data;
312  while (ud != NULL) {
313  for (int i = 0; i < level; i++)
314  printf(" ");
315  printf("[%d], ", ud->netmask);
316  PrintData(ud->user);
317  ud = ud->next;
318  }
319  } else {
320  RadixUserData *ud = node->user_data;
321  while (ud != NULL) {
322  for (int i = 0; i < level; i++)
323  printf(" ");
324  printf(" [%d], ", ud->netmask);
325  ud = ud->next;
326  }
327  }
328 }
329 
330 static int SCRadix4ForEachNodeSub(
331  const SCRadix4Node *node, SCRadix4ForEachNodeFunc Callback, void *data)
332 {
333  BUG_ON(!node);
334 
335  /* invoke callback for each stored user data */
336  for (RadixUserData *ud = node->user_data; ud != NULL; ud = ud->next) {
337  if (Callback(node, ud->user, ud->netmask, data) < 0)
338  return -1;
339  }
340 
341  if (node->left) {
342  if (SCRadix4ForEachNodeSub(node->left, Callback, data) < 0)
343  return -1;
344  }
345  if (node->right) {
346  if (SCRadix4ForEachNodeSub(node->right, Callback, data) < 0)
347  return -1;
348  }
349  return 0;
350 }
351 
352 int SCRadix4ForEachNode(const SCRadix4Tree *tree, SCRadix4ForEachNodeFunc Callback, void *data)
353 {
354  if (tree->head == NULL)
355  return 0;
356  return SCRadix4ForEachNodeSub(tree->head, Callback, data);
357 }
358 
360  const SCRadix4Tree *t1, const SCRadix4Tree *t2, SCRadix4TreeCompareFunc Callback)
361 {
362  return CompareTrees(t1, t2, Callback);
363 }
364 
365 /*------------------------------------Unit_Tests------------------------------*/
366 
367 #ifdef UNITTESTS
368 static void SCRadix4UtFree(void *ptr)
369 {
370  SCFree(ptr);
371 }
372 
373 static const SCRadix4Config ut_ip_radix4_config = { SCRadix4UtFree, NULL };
374 
375 #define GET_IPV4(str) \
376  SCLogDebug("setting up %s", (str)); \
377  memset(&(sa), 0, sizeof((sa))); \
378  FAIL_IF(inet_pton(AF_INET, (str), &(sa).sin_addr) <= 0);
379 
380 #define ADD_IPV4(str) \
381  GET_IPV4((str)); \
382  SCRadix4AddKeyIPV4(&tree, &ut_ip_radix4_config, (uint8_t *)&(sa).sin_addr, NULL);
383 
384 #define REM_IPV4(str) \
385  GET_IPV4((str)); \
386  SCRadix4RemoveKeyIPV4(&tree, &ut_ip_radix4_config, (uint8_t *)&(sa).sin_addr);
387 
388 #define ADD_IPV4_MASK(str, cidr) \
389  GET_IPV4((str)); \
390  SCRadix4AddKeyIPV4Netblock( \
391  &tree, &ut_ip_radix4_config, (uint8_t *)&(sa).sin_addr, (cidr), NULL);
392 
393 #define REM_IPV4_MASK(str, cidr) \
394  GET_IPV4((str)); \
395  SCRadix4RemoveKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&(sa).sin_addr, (cidr));
396 
397 static int SCRadix4TestIPV4Insertion03(void)
398 {
399  struct sockaddr_in sa;
401 
402  ADD_IPV4("192.168.1.1");
403  ADD_IPV4("192.168.1.2");
404  ADD_IPV4("192.167.1.3");
405  ADD_IPV4("192.167.1.4");
406  ADD_IPV4("192.167.1.4");
407 
408  /* test for the existance of a key */
409  GET_IPV4("192.168.1.6");
410  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
411 
412  /* test for the existance of a key */
413  GET_IPV4("192.167.1.4");
414  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
415 
416  /* continue adding keys */
417  ADD_IPV4("220.168.1.2");
418  ADD_IPV4("192.168.1.5");
419  ADD_IPV4("192.168.1.18");
420 
421  /* test the existence of keys */
422  GET_IPV4("192.168.1.3");
423  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
424  GET_IPV4("127.234.2.62");
425  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
426 
427  GET_IPV4("192.168.1.1");
428  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
429  GET_IPV4("192.168.1.5");
430  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
431  GET_IPV4("192.168.1.2");
432  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
433 
434  GET_IPV4("192.167.1.3");
435  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
436  GET_IPV4("192.167.1.4");
437  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
438  GET_IPV4("220.168.1.2");
439  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
440  GET_IPV4("192.168.1.18");
441  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
442 
443  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
444 
445  PASS;
446 }
447 
448 static int SCRadix4TestIPV4Removal04(void)
449 {
450  struct sockaddr_in sa;
451 
453 
454  /* add the keys */
455  ADD_IPV4("192.168.1.1");
456  ADD_IPV4("192.168.1.2");
457  ADD_IPV4("192.167.1.3");
458  ADD_IPV4("192.167.1.4");
459  ADD_IPV4("220.168.1.2");
460  ADD_IPV4("192.168.1.5");
461  ADD_IPV4("192.168.1.18");
462 
463  /* remove the keys from the tree */
464  REM_IPV4("192.168.1.1");
465  REM_IPV4("192.167.1.3");
466  REM_IPV4("192.167.1.4");
467  REM_IPV4("192.168.1.18");
468 
469  GET_IPV4("192.167.1.1");
470  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
471  GET_IPV4("192.168.1.2");
472  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
473 
474  REM_IPV4("192.167.1.3");
475  REM_IPV4("220.168.1.2");
476 
477  GET_IPV4("192.168.1.5");
478  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
479  GET_IPV4("192.168.1.2");
480  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
481 
482  REM_IPV4("192.168.1.2");
483  REM_IPV4("192.168.1.5");
484 
485  FAIL_IF_NOT_NULL(tree.head);
486 
487  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
488  PASS;
489 }
490 
491 static int SCRadix4TestIPV4NetblockInsertion09(void)
492 {
493  struct sockaddr_in sa;
495 
496  /* add the keys */
497  ADD_IPV4("192.168.1.1");
498  ADD_IPV4("192.168.1.2");
499  ADD_IPV4("192.167.1.3");
500  ADD_IPV4("192.167.1.4");
501  ADD_IPV4("220.168.1.2");
502  ADD_IPV4("192.168.1.5");
503  ADD_IPV4("192.168.1.18");
504 
505  ADD_IPV4_MASK("192.168.0.0", 16);
506  ADD_IPV4_MASK("192.171.128.0", 24);
507  ADD_IPV4_MASK("192.171.192.0", 18);
508  ADD_IPV4_MASK("192.175.0.0", 16);
509 
510  /* test for the existance of a key */
511  GET_IPV4("192.168.1.6");
512  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
513  GET_IPV4("192.170.1.6");
514  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
515  GET_IPV4("192.171.128.145");
516  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
517  GET_IPV4("192.171.64.6");
518  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
519  GET_IPV4("192.171.191.6");
520  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
521  GET_IPV4("192.171.224.6");
522  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
523  GET_IPV4("192.171.224.6");
524  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
525  GET_IPV4("192.175.224.6");
526  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
527 
528  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
529  PASS;
530 }
531 
532 static int SCRadix4TestIPV4NetblockInsertion10(void)
533 {
534  SCRadix4Node *node[2];
535  struct sockaddr_in sa;
537 
538  /* add the keys */
539  ADD_IPV4_MASK("253.192.0.0", 16);
540  ADD_IPV4_MASK("253.192.235.0", 24);
541  ADD_IPV4_MASK("192.167.0.0", 16);
542  ADD_IPV4("192.167.1.4");
543  ADD_IPV4_MASK("220.168.0.0", 16);
544  ADD_IPV4("253.224.1.5");
545  ADD_IPV4_MASK("192.168.0.0", 16);
546 
547  GET_IPV4("192.171.128.0");
548  node[0] = SCRadix4AddKeyIPV4Netblock(
549  &tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 24, NULL);
550 
551  GET_IPV4("192.171.128.45");
552  node[1] = SCRadix4AddKeyIPV4(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, NULL);
553 
554  ADD_IPV4_MASK("192.171.0.0", 18);
555  ADD_IPV4_MASK("192.175.0.0", 16);
556 
557  /* test for the existance of a key */
558  GET_IPV4("192.171.128.53");
559  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[0]);
560 
561  GET_IPV4("192.171.128.45");
562  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[1]);
563 
564  GET_IPV4("192.171.128.45");
565  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[1]);
566 
567  GET_IPV4("192.171.128.78");
568  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[0]);
569 
570  REM_IPV4_MASK("192.171.128.0", 24);
571 
572  GET_IPV4("192.171.128.78");
573  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
574  GET_IPV4("192.171.127.78");
575  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
576 
577  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
578 
579  PASS;
580 }
581 
582 static int SCRadix4TestIPV4NetblockInsertion11(void)
583 {
584  struct sockaddr_in sa;
586 
587  /* add the keys */
588  ADD_IPV4_MASK("253.192.0.0", 16);
589  ADD_IPV4_MASK("253.192.235.0", 24);
590  ADD_IPV4_MASK("192.167.0.0", 16);
591  ADD_IPV4("192.167.1.4");
592  ADD_IPV4_MASK("220.168.0.0", 16);
593  ADD_IPV4("253.224.1.5");
594  ADD_IPV4_MASK("192.168.0.0", 16);
595  ADD_IPV4_MASK("192.171.128.0", 24);
596  ADD_IPV4("192.171.128.45");
597  ADD_IPV4_MASK("192.171.0.0", 18);
598  ADD_IPV4_MASK("192.175.0.0", 16);
599 
600  GET_IPV4("0.0.0.0");
602  &tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 0, NULL);
603  FAIL_IF_NULL(node);
604 
605  /* test for the existance of a key */
606  GET_IPV4("192.171.128.53");
607  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
608 
609  GET_IPV4("192.171.128.45");
610  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
611 
612  GET_IPV4("192.171.128.78");
613  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
614 
615  GET_IPV4("192.171.127.78");
616  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
617 
618  GET_IPV4("1.1.1.1");
619  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
620 
621  GET_IPV4("192.255.254.25");
622  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
623 
624  GET_IPV4("169.255.254.25");
625  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
626 
627  GET_IPV4("0.0.0.0");
628  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
629 
630  GET_IPV4("253.224.1.5");
631  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
632  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != node);
633 
634  GET_IPV4("245.63.62.121");
635  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
636  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
637 
638  GET_IPV4("253.224.1.6");
639  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
640  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
641 
642  /* remove node 0.0.0.0 */
643  REM_IPV4_MASK("0.0.0.0", 0);
644 
645  GET_IPV4("253.224.1.6");
646  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
647  GET_IPV4("192.171.127.78");
648  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
649  GET_IPV4("1.1.1.1");
650  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
651 
652  GET_IPV4("192.255.254.25");
653  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
654  GET_IPV4("169.255.254.25");
655  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
656 
657  GET_IPV4("0.0.0.0");
658  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
659 
660  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
661  PASS;
662 }
663 
664 static int SCRadix4TestIPV4NetblockInsertion12(void)
665 {
666  struct sockaddr_in sa;
668  SCRadix4Node *node[2];
669 
670  /* add the keys */
671  ADD_IPV4_MASK("253.192.0.0", 16);
672  ADD_IPV4_MASK("253.192.235.0", 24);
673  ADD_IPV4_MASK("192.167.0.0", 16);
674  ADD_IPV4("192.167.1.4");
675  ADD_IPV4_MASK("220.168.0.0", 16);
676  ADD_IPV4("253.224.1.5");
677  ADD_IPV4_MASK("192.168.0.0", 16);
678 
679  GET_IPV4("192.171.128.0");
680  node[0] = SCRadix4AddKeyIPV4Netblock(
681  &tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 24, NULL);
682  FAIL_IF_NULL(node[0]);
683 
684  GET_IPV4("192.171.128.45");
685  node[1] = SCRadix4AddKeyIPV4(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, NULL);
686  FAIL_IF_NULL(node[1]);
687 
688  ADD_IPV4_MASK("192.171.0.0", 18);
689  ADD_IPV4_MASK("225.175.21.228", 32);
690 
691  /* test for the existance of a key */
692  GET_IPV4("192.171.128.53");
693  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[0]);
694  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
695 
696  GET_IPV4("192.171.128.45");
697  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[1]);
698  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[1]);
699 
700  GET_IPV4("192.171.128.78");
701  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[0]);
702  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
703 
704  GET_IPV4("225.175.21.228");
705  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
706 
707  GET_IPV4("225.175.21.224");
708  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
709 
710  GET_IPV4("225.175.21.229");
711  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
712 
713  GET_IPV4("225.175.21.230");
714  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
715 
716  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
717 
718  PASS;
719 }
720 
721 /**
722  * \test Check that the best match search works for all the
723  * possible netblocks of a fixed address
724  */
725 static int SCRadix4TestIPV4NetBlocksAndBestSearch16(void)
726 {
727  struct sockaddr_in sa;
729 
730  GET_IPV4("192.168.1.1");
731 
732  for (uint32_t i = 0; i <= 32; i++) {
733  uint32_t *user = SCMalloc(sizeof(uint32_t));
734  FAIL_IF_NULL(user);
735  *user = i;
736  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, i, user);
737  void *user_data = NULL;
738  SCRadix4Node *node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
739  FAIL_IF_NULL(node);
740  FAIL_IF_NULL(user_data);
741  FAIL_IF(*((uint32_t *)user_data) != i);
742  }
743 
744  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
745  PASS;
746 }
747 
748 /**
749  * \test Check special combinations of netblocks and addresses
750  * on best search checking the returned userdata
751  */
752 static int SCRadix4TestIPV4NetBlocksAndBestSearch19(void)
753 {
754  struct sockaddr_in sa;
755  void *user_data = NULL;
757 
758  GET_IPV4("0.0.0.0");
759  uint32_t *user = SCMalloc(sizeof(uint32_t));
760  FAIL_IF_NULL(user);
761  *user = 100;
762  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 0, user);
763 
764  GET_IPV4("192.168.1.15");
765  SCRadix4Node *node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
766  FAIL_IF_NULL(node);
767  FAIL_IF_NULL(user_data);
768  FAIL_IF(*((uint32_t *)user_data) != 100);
769  user_data = NULL;
770 
771  GET_IPV4("177.0.0.0");
772  user = SCMalloc(sizeof(uint32_t));
773  FAIL_IF_NULL(user);
774  *user = 200;
775  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 8, user);
776 
777  GET_IPV4("177.168.1.15");
778  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
779  FAIL_IF_NULL(node);
780  FAIL_IF_NULL(user_data);
781  FAIL_IF(*((uint32_t *)user_data) != 200);
782  user_data = NULL;
783 
784  GET_IPV4("178.168.1.15");
785  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
786  FAIL_IF_NULL(node);
787  FAIL_IF_NULL(user_data);
788  FAIL_IF(*((uint32_t *)user_data) != 100);
789  user_data = NULL;
790 
791  GET_IPV4("177.168.0.0");
792  user = SCMalloc(sizeof(uint32_t));
793  FAIL_IF_NULL(user);
794  *user = 300;
795  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 12, user);
796 
797  GET_IPV4("177.168.1.15");
798  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
799  FAIL_IF_NULL(node);
800  FAIL_IF_NULL(user_data);
801  FAIL_IF(*((uint32_t *)user_data) != 300);
802  user_data = NULL;
803 
804  GET_IPV4("177.167.1.15");
805  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
806  FAIL_IF_NULL(node);
807  FAIL_IF_NULL(user_data);
808  FAIL_IF(*((uint32_t *)user_data) != 300);
809  user_data = NULL;
810 
811  GET_IPV4("177.178.1.15");
812  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
813  FAIL_IF_NULL(node);
814  FAIL_IF_NULL(user_data);
815  FAIL_IF(*((uint32_t *)user_data) != 200);
816  user_data = NULL;
817 
818  GET_IPV4("197.178.1.15");
819  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
820  FAIL_IF_NULL(node);
821  FAIL_IF_NULL(user_data);
822  FAIL_IF(*((uint32_t *)user_data) != 100);
823  user_data = NULL;
824 
825  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
826  PASS;
827 }
828 
829 /**
830  * \test SCRadix4TestIPV4NetblockInsertion15 insert a node searching on it.
831  * Should always return true but the purposse of the test is to monitor
832  * the memory usage to detect memleaks (there was one on searching)
833  */
834 static int SCRadix4TestIPV4NetblockInsertion25(void)
835 {
836  struct sockaddr_in sa;
838  ADD_IPV4_MASK("192.168.0.0", 16);
839  GET_IPV4("192.168.128.53");
840  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
841  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
842  PASS;
843 }
844 
845 /**
846  * \test SCRadix4TestIPV4NetblockInsertion26 insert a node searching on it.
847  * Should always return true but the purposse of the test is to monitor
848  * the memory usage to detect memleaks (there was one on searching)
849  */
850 static int SCRadix4TestIPV4NetblockInsertion26(void)
851 {
852  SCRadix4Node *tmp = NULL;
853  struct sockaddr_in sa;
854  char *str = SCStrdup("Hello1");
855  FAIL_IF_NULL(str);
857  GET_IPV4("0.0.0.0");
858  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 0, str);
859  str = SCStrdup("Hello2");
860  FAIL_IF_NULL(str);
861  GET_IPV4("176.0.0.1");
862  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 5, str);
863  str = SCStrdup("Hello3");
864  FAIL_IF_NULL(str);
865  GET_IPV4("0.0.0.0");
866  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 7, str);
867  /* test for the existance of a key */
868  void *retptr = NULL;
869  tmp = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &retptr);
870  FAIL_IF_NULL(tmp);
871  FAIL_IF_NULL(retptr);
872  FAIL_IF_NOT(strcmp((char *)retptr, "Hello3") == 0);
873  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
874  PASS;
875 }
876 
877 static int SCRadix4TestIPV4InsertRemove01(void)
878 {
879  struct sockaddr_in sa;
880 
882  ADD_IPV4_MASK("1.0.0.0", 8);
883  ADD_IPV4_MASK("1.1.1.0", 24);
884  ADD_IPV4("1.1.1.1");
885  FAIL_IF(tree.head == NULL);
886  FAIL_IF_NOT(tree.head->bit == 15);
887  FAIL_IF_NULL(tree.head->left);
888  FAIL_IF_NOT(tree.head->left->masks == 0);
889  FAIL_IF_NOT(tree.head->left->bit == 32);
890  FAIL_IF_NULL(tree.head->right);
891  FAIL_IF_NOT(tree.head->right->masks == BIT_U64(24));
892  FAIL_IF_NOT(tree.head->right->bit == 31);
893  SCRadix4PrintTree(&tree, &ut_ip_radix4_config);
894  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
895 
896  /* tree after adds/removals */
897  tree = SCRadix4TreeInitialize();
898  ADD_IPV4_MASK("1.0.0.0", 8);
899  ADD_IPV4_MASK("1.0.0.0", 10);
900  ADD_IPV4_MASK("1.0.0.0", 12);
901  ADD_IPV4_MASK("1.1.0.0", 16);
902  ADD_IPV4_MASK("1.1.0.0", 18);
903  ADD_IPV4_MASK("1.1.0.0", 20);
904  ADD_IPV4_MASK("1.1.1.0", 24);
905  ADD_IPV4("1.1.1.1");
906  REM_IPV4_MASK("1.1.0.0", 20);
907  REM_IPV4_MASK("1.1.0.0", 18);
908  REM_IPV4_MASK("1.1.0.0", 16);
909  REM_IPV4_MASK("1.0.0.0", 12);
910  REM_IPV4_MASK("1.0.0.0", 10);
911  FAIL_IF(tree.head == NULL);
912  FAIL_IF_NOT(tree.head->bit == 15);
913  FAIL_IF_NULL(tree.head->left);
914  FAIL_IF_NOT(tree.head->left->masks == 0);
915  FAIL_IF_NOT(tree.head->left->bit == 32);
916  FAIL_IF_NULL(tree.head->right);
917  FAIL_IF_NOT(tree.head->right->masks == BIT_U64(24));
918  FAIL_IF_NOT(tree.head->right->bit == 31);
919  SCRadix4PrintTree(&tree, &ut_ip_radix4_config);
920  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
921 
922  PASS;
923 }
924 #endif
925 
927 {
928 #ifdef UNITTESTS
929  UtRegisterTest("SCRadix4TestIPV4Insertion03", SCRadix4TestIPV4Insertion03);
930  UtRegisterTest("SCRadix4TestIPV4Removal04", SCRadix4TestIPV4Removal04);
931  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion09", SCRadix4TestIPV4NetblockInsertion09);
932  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion10", SCRadix4TestIPV4NetblockInsertion10);
933  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion11", SCRadix4TestIPV4NetblockInsertion11);
934  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion12", SCRadix4TestIPV4NetblockInsertion12);
936  "SCRadix4TestIPV4NetBlocksAndBestSearch16", SCRadix4TestIPV4NetBlocksAndBestSearch16);
938  "SCRadix4TestIPV4NetBlocksAndBestSearch19", SCRadix4TestIPV4NetBlocksAndBestSearch19);
939  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion25", SCRadix4TestIPV4NetblockInsertion25);
940  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion26", SCRadix4TestIPV4NetblockInsertion26);
941  UtRegisterTest("SCRadix4TestIPV4InsertRemove01", SCRadix4TestIPV4InsertRemove01);
942 #endif
943  return;
944 }
SCRadix4ForEachNode
int SCRadix4ForEachNode(const SCRadix4Tree *tree, SCRadix4ForEachNodeFunc Callback, void *data)
Definition: util-radix4-tree.c:352
util-byte.h
SCRadix4Node_
Structure for the node in the radix tree.
Definition: util-radix4-tree.h:36
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
REM_IPV4
#define REM_IPV4(str)
Definition: util-radix4-tree.c:384
SCRadix4Node_::masks
uint64_t masks
Definition: util-radix4-tree.h:38
SCRadix4PrintTree
void SCRadix4PrintTree(SCRadix4Tree *tree, const SCRadix4Config *config)
Definition: util-radix4-tree.c:303
SCRadix4AddKeyIPV4String
bool SCRadix4AddKeyIPV4String(SCRadix4Tree *tree, const SCRadix4Config *config, const char *str, void *user)
Adds a new IPV4/netblock to the Radix4 tree from a string.
Definition: util-radix4-tree.c:227
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
util-radix-tree-common.h
SCRadix4TreeInitialize
SCRadix4Tree SCRadix4TreeInitialize(void)
Definition: util-radix4-tree.c:166
SC_EINVAL
@ SC_EINVAL
Definition: util-error.h:30
SCRadix4Node_::has_prefix
bool has_prefix
Definition: util-radix4-tree.h:46
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
SCRadix4RemoveKeyIPV4Netblock
void SCRadix4RemoveKeyIPV4Netblock(SCRadix4Tree *tree, const SCRadix4Config *config, const uint8_t *key_stream, uint8_t netmask)
Removes an IPV4 address netblock key from the Radix4 tree.
Definition: util-radix4-tree.c:296
m
SCMutex m
Definition: flow-hash.h:6
util-unittest.h
SCRadix4Node_::user_data
struct RadixUserData * user_data
Definition: util-radix4-tree.h:54
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
SCRadix4TreeRelease
void SCRadix4TreeRelease(SCRadix4Tree *tree, const SCRadix4Config *config)
Definition: util-radix4-tree.c:172
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
util-memcmp.h
SCRadix4Tree_
Structure for the radix tree.
Definition: util-radix4-tree.h:66
SCRadix4Node_::prefix_stream
uint8_t prefix_stream[4]
Definition: util-radix4-tree.h:49
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
SCRadix4TreeFindExactMatch
SCRadix4Node * SCRadix4TreeFindExactMatch(const SCRadix4Tree *tree, const uint8_t *key, void **user_data)
Definition: util-radix4-tree.c:142
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
SCRadix4CompareTrees
bool SCRadix4CompareTrees(const SCRadix4Tree *t1, const SCRadix4Tree *t2, SCRadix4TreeCompareFunc Callback)
Definition: util-radix4-tree.c:359
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
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
SCRadix4TreeCompareFunc
bool(* SCRadix4TreeCompareFunc)(const void *ud1, const void *ud2)
compare content of 2 user data entries
Definition: util-radix4-tree.h:115
NETMASK_MAX
#define NETMASK_MAX
Definition: util-radix4-tree.c:38
SC_RADIX4_TREE_INITIALIZER
#define SC_RADIX4_TREE_INITIALIZER
Definition: util-radix4-tree.h:78
SC_OK
@ SC_OK
Definition: util-error.h:27
SCRadix4AddKeyIPV4Netblock
SCRadix4Node * SCRadix4AddKeyIPV4Netblock(SCRadix4Tree *tree, const SCRadix4Config *config, const uint8_t *key_stream, uint8_t netmask, void *user)
Adds a new IPV4 netblock to the Radix4 tree.
Definition: util-radix4-tree.c:206
BIT_U64
#define BIT_U64(n)
Definition: suricata-common.h:418
SCRadix4RegisterTests
void SCRadix4RegisterTests(void)
Definition: util-radix4-tree.c:926
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
SCRadix4Tree_::head
SCRadix4Node * head
Definition: util-radix4-tree.h:68
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
SCRadix4Config_
Definition: util-radix4-tree.h:71
suricata-common.h
RadixUserData::user
void * user
Definition: util-radix-tree-common.h:43
SCRadix4TreeFindBestMatch2
SCRadix4Node * SCRadix4TreeFindBestMatch2(const SCRadix4Tree *tree, const uint8_t *key, void **user_data, uint8_t *out_netmask)
Definition: util-radix4-tree.c:160
util-radix4-tree.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
SCRadix4TreeFindBestMatch
SCRadix4Node * SCRadix4TreeFindBestMatch(const SCRadix4Tree *tree, const uint8_t *key, void **user_data)
Definition: util-radix4-tree.c:154
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:308
ADD_IPV4_MASK
#define ADD_IPV4_MASK(str, cidr)
Definition: util-radix4-tree.c:388
SCRadix4Node_::bit
uint8_t bit
Definition: util-radix4-tree.h:43
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SCRadix4AddKeyIPV4
SCRadix4Node * SCRadix4AddKeyIPV4(SCRadix4Tree *tree, const SCRadix4Config *config, const uint8_t *key_stream, void *user)
Adds a new IPV4 address to the Radix4 tree.
Definition: util-radix4-tree.c:188
SCRadix4ForEachNodeFunc
int(* SCRadix4ForEachNodeFunc)(const SCRadix4Node *node, void *user_data, const uint8_t netmask, void *data)
Definition: util-radix4-tree.h:106
src
uint16_t src
Definition: app-layer-dnp3.h:5
SCRadix4Node_::right
struct SCRadix4Node_ * right
Definition: util-radix4-tree.h:57
sc_errno
thread_local SCError sc_errno
Definition: util-error.c:31
GET_IPV4
#define GET_IPV4(str)
Definition: util-radix4-tree.c:375
SCRadix4RemoveKeyIPV4
void SCRadix4RemoveKeyIPV4(SCRadix4Tree *tree, const SCRadix4Config *config, const uint8_t *key_stream)
Removes an IPV4 address key(not a netblock) from the Radix4 tree. Instead of using this function,...
Definition: util-radix4-tree.c:282
ADD_IPV4
#define ADD_IPV4(str)
Definition: util-radix4-tree.c:380
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
SCRadix4Node_::left
struct SCRadix4Node_ * left
Definition: util-radix4-tree.h:57
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
REM_IPV4_MASK
#define REM_IPV4_MASK(str, cidr)
Definition: util-radix4-tree.c:393
SCRadix4TreeFindNetblock
SCRadix4Node * SCRadix4TreeFindNetblock(const SCRadix4Tree *tree, const uint8_t *key, const uint8_t netmask, void **user_data)
Definition: util-radix4-tree.c:148