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 
369 static const SCRadix4Config ut_ip_radix4_config = { NULL, NULL };
370 
371 #define GET_IPV4(str) \
372  SCLogDebug("setting up %s", (str)); \
373  memset(&(sa), 0, sizeof((sa))); \
374  FAIL_IF(inet_pton(AF_INET, (str), &(sa).sin_addr) <= 0);
375 
376 #define ADD_IPV4(str) \
377  GET_IPV4((str)); \
378  SCRadix4AddKeyIPV4(&tree, &ut_ip_radix4_config, (uint8_t *)&(sa).sin_addr, NULL);
379 
380 #define REM_IPV4(str) \
381  GET_IPV4((str)); \
382  SCRadix4RemoveKeyIPV4(&tree, &ut_ip_radix4_config, (uint8_t *)&(sa).sin_addr);
383 
384 #define ADD_IPV4_MASK(str, cidr) \
385  GET_IPV4((str)); \
386  SCRadix4AddKeyIPV4Netblock( \
387  &tree, &ut_ip_radix4_config, (uint8_t *)&(sa).sin_addr, (cidr), NULL);
388 
389 #define REM_IPV4_MASK(str, cidr) \
390  GET_IPV4((str)); \
391  SCRadix4RemoveKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&(sa).sin_addr, (cidr));
392 
393 static int SCRadix4TestIPV4Insertion03(void)
394 {
395  struct sockaddr_in sa;
397 
398  ADD_IPV4("192.168.1.1");
399  ADD_IPV4("192.168.1.2");
400  ADD_IPV4("192.167.1.3");
401  ADD_IPV4("192.167.1.4");
402  ADD_IPV4("192.167.1.4");
403 
404  /* test for the existance of a key */
405  GET_IPV4("192.168.1.6");
406  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
407 
408  /* test for the existance of a key */
409  GET_IPV4("192.167.1.4");
410  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
411 
412  /* continue adding keys */
413  ADD_IPV4("220.168.1.2");
414  ADD_IPV4("192.168.1.5");
415  ADD_IPV4("192.168.1.18");
416 
417  /* test the existence of keys */
418  GET_IPV4("192.168.1.3");
419  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
420  GET_IPV4("127.234.2.62");
421  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
422 
423  GET_IPV4("192.168.1.1");
424  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
425  GET_IPV4("192.168.1.5");
426  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
427  GET_IPV4("192.168.1.2");
428  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
429 
430  GET_IPV4("192.167.1.3");
431  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
432  GET_IPV4("192.167.1.4");
433  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
434  GET_IPV4("220.168.1.2");
435  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
436  GET_IPV4("192.168.1.18");
437  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
438 
439  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
440 
441  PASS;
442 }
443 
444 static int SCRadix4TestIPV4Removal04(void)
445 {
446  struct sockaddr_in sa;
447 
449 
450  /* add the keys */
451  ADD_IPV4("192.168.1.1");
452  ADD_IPV4("192.168.1.2");
453  ADD_IPV4("192.167.1.3");
454  ADD_IPV4("192.167.1.4");
455  ADD_IPV4("220.168.1.2");
456  ADD_IPV4("192.168.1.5");
457  ADD_IPV4("192.168.1.18");
458 
459  /* remove the keys from the tree */
460  REM_IPV4("192.168.1.1");
461  REM_IPV4("192.167.1.3");
462  REM_IPV4("192.167.1.4");
463  REM_IPV4("192.168.1.18");
464 
465  GET_IPV4("192.167.1.1");
466  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
467  GET_IPV4("192.168.1.2");
468  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
469 
470  REM_IPV4("192.167.1.3");
471  REM_IPV4("220.168.1.2");
472 
473  GET_IPV4("192.168.1.5");
474  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
475  GET_IPV4("192.168.1.2");
476  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
477 
478  REM_IPV4("192.168.1.2");
479  REM_IPV4("192.168.1.5");
480 
481  FAIL_IF_NOT_NULL(tree.head);
482 
483  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
484  PASS;
485 }
486 
487 static int SCRadix4TestIPV4NetblockInsertion09(void)
488 {
489  struct sockaddr_in sa;
491 
492  /* add the keys */
493  ADD_IPV4("192.168.1.1");
494  ADD_IPV4("192.168.1.2");
495  ADD_IPV4("192.167.1.3");
496  ADD_IPV4("192.167.1.4");
497  ADD_IPV4("220.168.1.2");
498  ADD_IPV4("192.168.1.5");
499  ADD_IPV4("192.168.1.18");
500 
501  ADD_IPV4_MASK("192.168.0.0", 16);
502  ADD_IPV4_MASK("192.171.128.0", 24);
503  ADD_IPV4_MASK("192.171.192.0", 18);
504  ADD_IPV4_MASK("192.175.0.0", 16);
505 
506  /* test for the existance of a key */
507  GET_IPV4("192.168.1.6");
508  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
509  GET_IPV4("192.170.1.6");
510  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
511  GET_IPV4("192.171.128.145");
512  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
513  GET_IPV4("192.171.64.6");
514  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
515  GET_IPV4("192.171.191.6");
516  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
517  GET_IPV4("192.171.224.6");
518  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
519  GET_IPV4("192.171.224.6");
520  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
521  GET_IPV4("192.175.224.6");
522  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
523 
524  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
525  PASS;
526 }
527 
528 static int SCRadix4TestIPV4NetblockInsertion10(void)
529 {
530  SCRadix4Node *node[2];
531  struct sockaddr_in sa;
533 
534  /* add the keys */
535  ADD_IPV4_MASK("253.192.0.0", 16);
536  ADD_IPV4_MASK("253.192.235.0", 24);
537  ADD_IPV4_MASK("192.167.0.0", 16);
538  ADD_IPV4("192.167.1.4");
539  ADD_IPV4_MASK("220.168.0.0", 16);
540  ADD_IPV4("253.224.1.5");
541  ADD_IPV4_MASK("192.168.0.0", 16);
542 
543  GET_IPV4("192.171.128.0");
544  node[0] = SCRadix4AddKeyIPV4Netblock(
545  &tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 24, NULL);
546 
547  GET_IPV4("192.171.128.45");
548  node[1] = SCRadix4AddKeyIPV4(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, NULL);
549 
550  ADD_IPV4_MASK("192.171.0.0", 18);
551  ADD_IPV4_MASK("192.175.0.0", 16);
552 
553  /* test for the existance of a key */
554  GET_IPV4("192.171.128.53");
555  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[0]);
556 
557  GET_IPV4("192.171.128.45");
558  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[1]);
559 
560  GET_IPV4("192.171.128.45");
561  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[1]);
562 
563  GET_IPV4("192.171.128.78");
564  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[0]);
565 
566  REM_IPV4_MASK("192.171.128.0", 24);
567 
568  GET_IPV4("192.171.128.78");
569  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
570  GET_IPV4("192.171.127.78");
571  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
572 
573  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
574 
575  PASS;
576 }
577 
578 static int SCRadix4TestIPV4NetblockInsertion11(void)
579 {
580  struct sockaddr_in sa;
582 
583  /* add the keys */
584  ADD_IPV4_MASK("253.192.0.0", 16);
585  ADD_IPV4_MASK("253.192.235.0", 24);
586  ADD_IPV4_MASK("192.167.0.0", 16);
587  ADD_IPV4("192.167.1.4");
588  ADD_IPV4_MASK("220.168.0.0", 16);
589  ADD_IPV4("253.224.1.5");
590  ADD_IPV4_MASK("192.168.0.0", 16);
591  ADD_IPV4_MASK("192.171.128.0", 24);
592  ADD_IPV4("192.171.128.45");
593  ADD_IPV4_MASK("192.171.0.0", 18);
594  ADD_IPV4_MASK("192.175.0.0", 16);
595 
596  GET_IPV4("0.0.0.0");
598  &tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 0, NULL);
599  FAIL_IF_NULL(node);
600 
601  /* test for the existance of a key */
602  GET_IPV4("192.171.128.53");
603  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
604 
605  GET_IPV4("192.171.128.45");
606  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
607 
608  GET_IPV4("192.171.128.78");
609  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
610 
611  GET_IPV4("192.171.127.78");
612  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
613 
614  GET_IPV4("1.1.1.1");
615  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
616 
617  GET_IPV4("192.255.254.25");
618  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
619 
620  GET_IPV4("169.255.254.25");
621  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
622 
623  GET_IPV4("0.0.0.0");
624  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
625 
626  GET_IPV4("253.224.1.5");
627  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
628  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != node);
629 
630  GET_IPV4("245.63.62.121");
631  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
632  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node);
633 
634  GET_IPV4("253.224.1.6");
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  /* remove node 0.0.0.0 */
639  REM_IPV4_MASK("0.0.0.0", 0);
640 
641  GET_IPV4("253.224.1.6");
642  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
643  GET_IPV4("192.171.127.78");
644  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
645  GET_IPV4("1.1.1.1");
646  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
647 
648  GET_IPV4("192.255.254.25");
649  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
650  GET_IPV4("169.255.254.25");
651  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
652 
653  GET_IPV4("0.0.0.0");
654  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
655 
656  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
657  PASS;
658 }
659 
660 static int SCRadix4TestIPV4NetblockInsertion12(void)
661 {
662  struct sockaddr_in sa;
664  SCRadix4Node *node[2];
665 
666  /* add the keys */
667  ADD_IPV4_MASK("253.192.0.0", 16);
668  ADD_IPV4_MASK("253.192.235.0", 24);
669  ADD_IPV4_MASK("192.167.0.0", 16);
670  ADD_IPV4("192.167.1.4");
671  ADD_IPV4_MASK("220.168.0.0", 16);
672  ADD_IPV4("253.224.1.5");
673  ADD_IPV4_MASK("192.168.0.0", 16);
674 
675  GET_IPV4("192.171.128.0");
676  node[0] = SCRadix4AddKeyIPV4Netblock(
677  &tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 24, NULL);
678  FAIL_IF_NULL(node[0]);
679 
680  GET_IPV4("192.171.128.45");
681  node[1] = SCRadix4AddKeyIPV4(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, NULL);
682  FAIL_IF_NULL(node[1]);
683 
684  ADD_IPV4_MASK("192.171.0.0", 18);
685  ADD_IPV4_MASK("225.175.21.228", 32);
686 
687  /* test for the existance of a key */
688  GET_IPV4("192.171.128.53");
689  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[0]);
690  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
691 
692  GET_IPV4("192.171.128.45");
693  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[1]);
694  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[1]);
695 
696  GET_IPV4("192.171.128.78");
697  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == node[0]);
698  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
699 
700  GET_IPV4("225.175.21.228");
701  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
702 
703  GET_IPV4("225.175.21.224");
704  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
705 
706  GET_IPV4("225.175.21.229");
707  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
708 
709  GET_IPV4("225.175.21.230");
710  FAIL_IF_NOT(SCRadix4TreeFindExactMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) == NULL);
711 
712  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
713 
714  PASS;
715 }
716 
717 /**
718  * \test Check that the best match search works for all the
719  * possible netblocks of a fixed address
720  */
721 static int SCRadix4TestIPV4NetBlocksAndBestSearch16(void)
722 {
723  struct sockaddr_in sa;
725 
726  GET_IPV4("192.168.1.1");
727 
728  for (uint32_t i = 0; i <= 32; i++) {
729  uint32_t *user = SCMalloc(sizeof(uint32_t));
730  FAIL_IF_NULL(user);
731  *user = i;
732  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, i, user);
733  void *user_data = NULL;
734  SCRadix4Node *node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
735  FAIL_IF_NULL(node);
736  FAIL_IF_NULL(user_data);
737  FAIL_IF(*((uint32_t *)user_data) != i);
738  }
739 
740  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
741  PASS;
742 }
743 
744 /**
745  * \test Check special combinations of netblocks and addresses
746  * on best search checking the returned userdata
747  */
748 static int SCRadix4TestIPV4NetBlocksAndBestSearch19(void)
749 {
750  struct sockaddr_in sa;
751  void *user_data = NULL;
753 
754  GET_IPV4("0.0.0.0");
755  uint32_t *user = SCMalloc(sizeof(uint32_t));
756  FAIL_IF_NULL(user);
757  *user = 100;
758  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 0, user);
759 
760  GET_IPV4("192.168.1.15");
761  SCRadix4Node *node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
762  FAIL_IF_NULL(node);
763  FAIL_IF_NULL(user_data);
764  FAIL_IF(*((uint32_t *)user_data) != 100);
765  user_data = NULL;
766 
767  GET_IPV4("177.0.0.0");
768  user = SCMalloc(sizeof(uint32_t));
769  FAIL_IF_NULL(user);
770  *user = 200;
771  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 8, user);
772 
773  GET_IPV4("177.168.1.15");
774  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
775  FAIL_IF_NULL(node);
776  FAIL_IF_NULL(user_data);
777  FAIL_IF(*((uint32_t *)user_data) != 200);
778  user_data = NULL;
779 
780  GET_IPV4("178.168.1.15");
781  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
782  FAIL_IF_NULL(node);
783  FAIL_IF_NULL(user_data);
784  FAIL_IF(*((uint32_t *)user_data) != 100);
785  user_data = NULL;
786 
787  GET_IPV4("177.168.0.0");
788  user = SCMalloc(sizeof(uint32_t));
789  FAIL_IF_NULL(user);
790  *user = 300;
791  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 12, user);
792 
793  GET_IPV4("177.168.1.15");
794  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
795  FAIL_IF_NULL(node);
796  FAIL_IF_NULL(user_data);
797  FAIL_IF(*((uint32_t *)user_data) != 300);
798  user_data = NULL;
799 
800  GET_IPV4("177.167.1.15");
801  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
802  FAIL_IF_NULL(node);
803  FAIL_IF_NULL(user_data);
804  FAIL_IF(*((uint32_t *)user_data) != 300);
805  user_data = NULL;
806 
807  GET_IPV4("177.178.1.15");
808  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
809  FAIL_IF_NULL(node);
810  FAIL_IF_NULL(user_data);
811  FAIL_IF(*((uint32_t *)user_data) != 200);
812  user_data = NULL;
813 
814  GET_IPV4("197.178.1.15");
815  node = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &user_data);
816  FAIL_IF_NULL(node);
817  FAIL_IF_NULL(user_data);
818  FAIL_IF(*((uint32_t *)user_data) != 100);
819  user_data = NULL;
820 
821  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
822  PASS;
823 }
824 
825 /**
826  * \test SCRadix4TestIPV4NetblockInsertion15 insert a node searching on it.
827  * Should always return true but the purposse of the test is to monitor
828  * the memory usage to detect memleaks (there was one on searching)
829  */
830 static int SCRadix4TestIPV4NetblockInsertion25(void)
831 {
832  struct sockaddr_in sa;
834  ADD_IPV4_MASK("192.168.0.0", 16);
835  GET_IPV4("192.168.128.53");
836  FAIL_IF_NOT(SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, NULL) != NULL);
837  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
838  PASS;
839 }
840 
841 /**
842  * \test SCRadix4TestIPV4NetblockInsertion26 insert a node searching on it.
843  * Should always return true but the purposse of the test is to monitor
844  * the memory usage to detect memleaks (there was one on searching)
845  */
846 static int SCRadix4TestIPV4NetblockInsertion26(void)
847 {
848  SCRadix4Node *tmp = NULL;
849  struct sockaddr_in sa;
850  char *str = SCStrdup("Hello1");
851  FAIL_IF_NULL(str);
853  GET_IPV4("0.0.0.0");
854  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 0, str);
855  str = SCStrdup("Hello2");
856  FAIL_IF_NULL(str);
857  GET_IPV4("176.0.0.1");
858  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 5, str);
859  str = SCStrdup("Hello3");
860  FAIL_IF_NULL(str);
861  GET_IPV4("0.0.0.0");
862  SCRadix4AddKeyIPV4Netblock(&tree, &ut_ip_radix4_config, (uint8_t *)&sa.sin_addr, 7, str);
863  /* test for the existance of a key */
864  void *retptr = NULL;
865  tmp = SCRadix4TreeFindBestMatch(&tree, (uint8_t *)&sa.sin_addr, &retptr);
866  FAIL_IF_NULL(tmp);
867  FAIL_IF_NULL(retptr);
868  FAIL_IF_NOT(strcmp((char *)retptr, "Hello3") == 0);
869  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
870  PASS;
871 }
872 
873 static int SCRadix4TestIPV4InsertRemove01(void)
874 {
875  struct sockaddr_in sa;
876 
878  ADD_IPV4_MASK("1.0.0.0", 8);
879  ADD_IPV4_MASK("1.1.1.0", 24);
880  ADD_IPV4("1.1.1.1");
881  FAIL_IF(tree.head == NULL);
882  FAIL_IF_NOT(tree.head->bit == 15);
883  FAIL_IF_NULL(tree.head->left);
884  FAIL_IF_NOT(tree.head->left->masks == 0);
885  FAIL_IF_NOT(tree.head->left->bit == 32);
886  FAIL_IF_NULL(tree.head->right);
887  FAIL_IF_NOT(tree.head->right->masks == BIT_U64(24));
888  FAIL_IF_NOT(tree.head->right->bit == 31);
889  SCRadix4PrintTree(&tree, &ut_ip_radix4_config);
890  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
891 
892  /* tree after adds/removals */
893  tree = SCRadix4TreeInitialize();
894  ADD_IPV4_MASK("1.0.0.0", 8);
895  ADD_IPV4_MASK("1.0.0.0", 10);
896  ADD_IPV4_MASK("1.0.0.0", 12);
897  ADD_IPV4_MASK("1.1.0.0", 16);
898  ADD_IPV4_MASK("1.1.0.0", 18);
899  ADD_IPV4_MASK("1.1.0.0", 20);
900  ADD_IPV4_MASK("1.1.1.0", 24);
901  ADD_IPV4("1.1.1.1");
902  REM_IPV4_MASK("1.1.0.0", 20);
903  REM_IPV4_MASK("1.1.0.0", 18);
904  REM_IPV4_MASK("1.1.0.0", 16);
905  REM_IPV4_MASK("1.0.0.0", 12);
906  REM_IPV4_MASK("1.0.0.0", 10);
907  FAIL_IF(tree.head == NULL);
908  FAIL_IF_NOT(tree.head->bit == 15);
909  FAIL_IF_NULL(tree.head->left);
910  FAIL_IF_NOT(tree.head->left->masks == 0);
911  FAIL_IF_NOT(tree.head->left->bit == 32);
912  FAIL_IF_NULL(tree.head->right);
913  FAIL_IF_NOT(tree.head->right->masks == BIT_U64(24));
914  FAIL_IF_NOT(tree.head->right->bit == 31);
915  SCRadix4PrintTree(&tree, &ut_ip_radix4_config);
916  SCRadix4TreeRelease(&tree, &ut_ip_radix4_config);
917 
918  PASS;
919 }
920 #endif
921 
923 {
924 #ifdef UNITTESTS
925  UtRegisterTest("SCRadix4TestIPV4Insertion03", SCRadix4TestIPV4Insertion03);
926  UtRegisterTest("SCRadix4TestIPV4Removal04", SCRadix4TestIPV4Removal04);
927  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion09", SCRadix4TestIPV4NetblockInsertion09);
928  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion10", SCRadix4TestIPV4NetblockInsertion10);
929  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion11", SCRadix4TestIPV4NetblockInsertion11);
930  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion12", SCRadix4TestIPV4NetblockInsertion12);
932  "SCRadix4TestIPV4NetBlocksAndBestSearch16", SCRadix4TestIPV4NetBlocksAndBestSearch16);
934  "SCRadix4TestIPV4NetBlocksAndBestSearch19", SCRadix4TestIPV4NetBlocksAndBestSearch19);
935  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion25", SCRadix4TestIPV4NetblockInsertion25);
936  UtRegisterTest("SCRadix4TestIPV4NetblockInsertion26", SCRadix4TestIPV4NetblockInsertion26);
937  UtRegisterTest("SCRadix4TestIPV4InsertRemove01", SCRadix4TestIPV4InsertRemove01);
938 #endif
939  return;
940 }
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:380
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:269
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:230
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
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:401
SCRadix4RegisterTests
void SCRadix4RegisterTests(void)
Definition: util-radix4-tree.c:922
StringParseU8RangeCheck
int StringParseU8RangeCheck(uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
Definition: util-byte.c:462
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:291
ADD_IPV4_MASK
#define ADD_IPV4_MASK(str, cidr)
Definition: util-radix4-tree.c:384
SCRadix4Node_::bit
uint8_t bit
Definition: util-radix4-tree.h:43
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:371
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:376
RadixUserData::netmask
uint8_t netmask
Definition: util-radix-tree-common.h:47
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:237
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:389
SCRadix4TreeFindNetblock
SCRadix4Node * SCRadix4TreeFindNetblock(const SCRadix4Tree *tree, const uint8_t *key, const uint8_t netmask, void **user_data)
Definition: util-radix4-tree.c:148