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