suricata
util-radix-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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Implementation of radix trees
24  */
25 
26 #include "suricata-common.h"
27 #include "util-radix-tree.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-byte.h"
34 #include "util-cidr.h"
35 #include "util-print.h"
36 #include "util-validate.h"
37 
38 /**
39  * \brief Allocates and returns a new instance of SCRadixUserData.
40  *
41  * \param netmask The netmask entry (cidr) that has to be made in the new
42  * SCRadixUserData instance
43  * \param user The user data that has to be set for the above
44  * netmask in the newly created SCRadixUserData instance.
45  *
46  * \retval user_data Pointer to a new instance of SCRadixUserData.
47  */
48 static SCRadixUserData *SCRadixAllocSCRadixUserData(uint8_t netmask, void *user)
49 {
50  SCRadixUserData *user_data = SCCalloc(1, sizeof(SCRadixUserData));
51  if (unlikely(user_data == NULL)) {
52  SCLogError("Error allocating memory");
53  return NULL;
54  }
55 
56  user_data->netmask = netmask;
57  user_data->user = user;
58 
59  return user_data;
60 }
61 
62 /**
63  * \brief Deallocates an instance of SCRadixUserData.
64  *
65  * \param user_data Pointer to the instance of SCRadixUserData that has to be
66  * freed.
67  */
68 static void SCRadixDeAllocSCRadixUserData(SCRadixUserData *user_data)
69 {
70  SCFree(user_data);
71 
72  return;
73 }
74 
75 /**
76  * \brief Appends a user_data instance(SCRadixUserData) to a
77  * user_data(SCRadixUserData) list. We add the new entry in descending
78  * order with respect to the netmask contained in the SCRadixUserData.
79  *
80  * \param new Pointer to the SCRadixUserData to be added to the list.
81  * \param list Pointer to the SCRadixUserData list head, to which "new" has to
82  * be appended.
83  */
84 static void SCRadixAppendToSCRadixUserDataList(SCRadixUserData *new,
85  SCRadixUserData **list)
86 {
87  SCRadixUserData *temp = NULL;
88  SCRadixUserData *prev = NULL;
89 
90  if (new == NULL || list == NULL) {
91  FatalError("new or list supplied as NULL");
92  }
93 
94  /* add to the list in descending order. The reason we do this is for
95  * optimizing key retrieval for a ip key under a netblock */
96  prev = temp = *list;
97  while (temp != NULL) {
98  if (new->netmask > temp->netmask)
99  break;
100  prev = temp;
101  temp = temp->next;
102  }
103 
104  if (temp == *list) {
105  new->next = *list;
106  *list = new;
107  } else {
108  new->next = prev->next;
109  prev->next = new;
110  }
111 
112  return;
113 }
114 
115 /**
116  * \brief Creates a new Prefix for a key. Used internally by the API.
117  *
118  * \param key_stream Data that has to be wrapped in a SCRadixPrefix instance to
119  * be processed for insertion/lookup/removal of a node by the
120  * radix tree
121  * \param key_bitlen The bitlen of the above stream. For example if the
122  * stream holds the ipv4 address(4 bytes), bitlen would be 32
123  * \param user Pointer to the user data that has to be associated with
124  * this key
125  *
126  * \retval prefix The newly created prefix instance on success; NULL on failure
127  */
128 static SCRadixPrefix *SCRadixCreatePrefix(uint8_t *key_stream,
129  uint16_t key_bitlen, void *user,
130  uint8_t netmask)
131 {
132  SCRadixPrefix *prefix = NULL;
133 
134  if (key_bitlen == 0 || (key_bitlen % 8 != 0)) {
135  SCLogError("Invalid argument bitlen - %d", key_bitlen);
136  return NULL;
137  }
138 
139  if (key_stream == NULL) {
140  SCLogError("Argument \"stream\" NULL");
141  return NULL;
142  }
143 
144  if ((prefix = SCCalloc(1, sizeof(SCRadixPrefix))) == NULL)
145  goto error;
146 
147  if ((prefix->stream = SCCalloc(1, key_bitlen / 8)) == NULL)
148  goto error;
149 
150  memcpy(prefix->stream, key_stream, key_bitlen / 8);
151  prefix->bitlen = key_bitlen;
152 
153  prefix->user_data = SCRadixAllocSCRadixUserData(netmask, user);
154  if (prefix->user_data == NULL) {
155  goto error;
156  }
157 
158  return prefix;
159 
160 error:
161  if (prefix != NULL) {
162  if (prefix->stream != NULL) {
163  SCFree(prefix->stream);
164  }
165  SCFree(prefix);
166  }
167 
168  return NULL;
169 }
170 
171 /**
172  * \brief Adds a netmask and its user_data for a particular prefix stream.
173  *
174  * \param prefix The prefix stream to which the netmask and its corresponding
175  * user data has to be added.
176  * \param netmask The netmask value (cidr) that has to be added to the prefix.
177  * \param user The pointer to the user data corresponding to the above
178  * netmask.
179  */
180 static void SCRadixAddNetmaskUserDataToPrefix(SCRadixPrefix *prefix,
181  uint8_t netmask,
182  void *user)
183 {
184  if (prefix == NULL || user == NULL) {
185  FatalError("prefix or user NULL");
186  }
187 
188  SCRadixAppendToSCRadixUserDataList(SCRadixAllocSCRadixUserData(netmask, user),
189  &prefix->user_data);
190 
191  return;
192 }
193 
194 /**
195  * \brief Removes a particular user_data corresponding to a particular netmask
196  * entry, from a prefix.
197  *
198  * \param prefix Pointer to the prefix from which the user_data/netmask entry
199  * has to be removed.
200  * \param netmask The netmask value (cidr) whose user_data has to be deleted.
201  */
202 static void SCRadixRemoveNetmaskUserDataFromPrefix(SCRadixPrefix *prefix,
203  uint8_t netmask)
204 {
205  SCRadixUserData *temp = NULL, *prev = NULL;
206 
207  if (prefix == NULL) {
208  FatalError("prefix NULL");
209  }
210 
211  prev = temp = prefix->user_data;
212  while (temp != NULL) {
213  if (temp->netmask == netmask) {
214  if (temp == prefix->user_data)
215  prefix->user_data = temp->next;
216  else
217  prev->next = temp->next;
218 
219  SCRadixDeAllocSCRadixUserData(temp);
220  break;
221  }
222  prev = temp;
223  temp = temp->next;
224  }
225 
226  return;
227 }
228 
229 /**
230  * \brief Indicates if prefix contains an entry for an ip with a specific netmask.
231  *
232  * \param prefix Pointer to the ip prefix that is being checked.
233  * \param netmask The netmask value (cidr) that has to be checked for
234  * presence in the prefix.
235  *
236  * \retval 1 On match.
237  * \retval 0 On no match.
238  */
239 static int SCRadixPrefixContainNetmask(SCRadixPrefix *prefix, uint8_t netmask)
240 {
241  SCRadixUserData *user_data = NULL;
242 
243  if (prefix == NULL) {
244  SCLogError("prefix is NULL");
245  goto no_match;
246  }
247 
248  user_data = prefix->user_data;
249  while (user_data != NULL) {
250  if (user_data->netmask == netmask)
251  return 1;
252  user_data = user_data->next;
253  }
254 
255  no_match:
256  return 0;
257 }
258 
259 /**
260  * \brief Returns the total netmask count for this prefix.
261  *
262  * \param prefix Pointer to the prefix
263  *
264  * \retval count The total netmask count for this prefix.
265  */
266 static int SCRadixPrefixNetmaskCount(SCRadixPrefix *prefix)
267 {
268  SCRadixUserData *user_data = NULL;
269  uint32_t count = 0;
270 
271  if (prefix == NULL) {
272  SCLogError("prefix is NULL");
273  return 0;
274  }
275 
276  user_data = prefix->user_data;
277  while (user_data != NULL) {
278  count++;
279  user_data = user_data->next;
280  }
281 
282  return count;
283 }
284 
285 /**
286  * \brief Indicates if prefix contains an entry for an ip with a specific netmask
287  * and if it does, it sets the user data field
288  * SCRadixPrefix->user_data_result to the netmask user_data entry.
289  *
290  * \param prefix Pointer to the ip prefix that is being checked.
291  * \param netmask The netmask value for which we will have to return the user_data
292  * \param exact_match flag which indicates if we should check if the prefix
293  * holds proper netblock(< 32 for ipv4 and < 128 for ipv6) or not.
294  *
295  * \retval 1 On match.
296  * \retval 0 On no match.
297  */
298 static int SCRadixPrefixContainNetmaskAndSetUserData(
299  SCRadixPrefix *prefix, uint16_t netmask, bool exact_match, void **user_data_result)
300 {
301  SCRadixUserData *user_data = NULL;
302 
303  if (prefix == NULL) {
304  SCLogError("prefix is NULL");
305  goto no_match;
306  }
307 
308  user_data = prefix->user_data;
309  /* Check if we have a match for an exact ip. An exact ip as in not a proper
310  * netblock, i.e. an ip with a netmask of 32(ipv4) or 128(ipv6) */
311  if (exact_match) {
312  if (user_data->netmask == netmask) {
313  if (user_data_result)
314  *user_data_result = user_data->user;
315  return 1;
316  } else {
317  goto no_match;
318  }
319  }
320 
321  /* Check for the user_data entry for this netmask_value */
322  while (user_data != NULL) {
323  if (user_data->netmask == netmask) {
324  if (user_data_result)
325  *user_data_result = user_data->user;
326  return 1;
327  }
328  user_data = user_data->next;
329  }
330 
331 no_match:
332  if (user_data_result != NULL)
333  *user_data_result = NULL;
334  return 0;
335 }
336 
337 /**
338  * \brief Frees a SCRadixPrefix instance
339  *
340  * \param prefix Pointer to a prefix instance
341  * \param tree Pointer to the Radix tree to which this prefix belongs
342  */
343 static void SCRadixReleasePrefix(SCRadixPrefix *prefix, SCRadixTree *tree)
344 {
345  SCRadixUserData *user_data_temp1 = NULL;
346  SCRadixUserData *user_data_temp2 = NULL;
347 
348  if (prefix != NULL) {
349  if (prefix->stream != NULL)
350  SCFree(prefix->stream);
351 
352  user_data_temp1 = prefix->user_data;
353  if (tree->Free != NULL) {
354  while (user_data_temp1 != NULL) {
355  user_data_temp2 = user_data_temp1;
356  user_data_temp1 = user_data_temp1->next;
357  tree->Free(user_data_temp2->user);
358  SCRadixDeAllocSCRadixUserData(user_data_temp2);
359  }
360  } else if (user_data_temp1 != NULL) {
361  SCFree(user_data_temp1);
362  }
363 
364  SCFree(prefix);
365  }
366 
367  return;
368 }
369 
370 /**
371  * \brief Creates a new node for the Radix tree
372  *
373  * \retval node The newly created node for the radix tree
374  */
375 static inline SCRadixNode *SCRadixCreateNode(void)
376 {
377  SCRadixNode *node = NULL;
378 
379  if ((node = SCCalloc(1, sizeof(SCRadixNode))) == NULL) {
380  SCLogError("Fatal error encountered in SCRadixCreateNode. Mem not allocated...");
381  return NULL;
382  }
383 
384  return node;
385 }
386 
387 /**
388  * \brief Frees a Radix tree node
389  *
390  * \param node Pointer to a Radix tree node
391  * \param tree Pointer to the Radix tree to which this node belongs
392  */
393 static void SCRadixReleaseNode(SCRadixNode *node, SCRadixTree *tree)
394 {
395  if (node != NULL) {
396  SCRadixReleasePrefix(node->prefix, tree);
397 
398  if (node->netmasks != NULL)
399  SCFree(node->netmasks);
400 
401  SCFree(node);
402  }
403 
404  return;
405 }
406 
407 /**
408  * \brief Creates a new Radix tree
409  *
410  * \param Free Function pointer supplied by the user to be used by the Radix
411  * cleanup API to free the user supplied data
412  *
413  * \retval tree The newly created radix tree on success
414  *
415  * \initonly (all radix trees should be created at init)
416  */
417 SCRadixTree *SCRadixCreateRadixTree(void (*Free)(void*), void (*PrintData)(void*))
418 {
419  SCRadixTree *tree = NULL;
420 
421  if ((tree = SCCalloc(1, sizeof(SCRadixTree))) == NULL) {
422  FatalError("Fatal error encountered in SCRadixCreateRadixTree. Exiting...");
423  }
424 
425  tree->Free = Free;
426  tree->PrintData = PrintData;
427 
428  return tree;
429 }
430 
431 /**
432  * \brief Internal helper function used by SCRadixReleaseRadixTree to free a
433  * subtree
434  *
435  * \param node Pointer to the root of the subtree that has to be freed
436  * \param tree Pointer to the Radix tree to which this subtree belongs
437  */
438 static void SCRadixReleaseRadixSubtree(SCRadixNode *node, SCRadixTree *tree)
439 {
440  if (node != NULL) {
441  SCRadixReleaseRadixSubtree(node->left, tree);
442  SCRadixReleaseRadixSubtree(node->right, tree);
443  SCRadixReleaseNode(node, tree);
444  }
445 
446  return;
447 }
448 
449 /**
450  * \brief Frees a Radix tree and all its nodes
451  *
452  * \param tree Pointer to the Radix tree that has to be freed
453  */
455 {
456  if (tree == NULL)
457  return;
458 
459  SCRadixReleaseRadixSubtree(tree->head, tree);
460  tree->head = NULL;
461  SCFree(tree);
462  return;
463 }
464 
465 /**
466  * \brief Adds a key to the Radix tree. Used internally by the API.
467  *
468  * \param key_stream Data that has to added to the Radix tree
469  * \param key_bitlen The bitlen of the above stream. For example if the
470  * stream is the string "abcd", the bitlen would be 32. If
471  * the stream is an IPV6 address bitlen would be 128
472  * \param tree Pointer to the Radix tree
473  * \param user Pointer to the user data that has to be associated with
474  * this key
475  * \param netmask The netmask (cidr) if we are adding an IP netblock; 255
476  * if we are not adding an IP netblock
477  * \param exclusive True if the node should be added iff it doesn't exist.
478  *
479  * \retval node Pointer to the newly created node
480  */
481 static SCRadixNode *SCRadixAddKeyInternal(uint8_t *key_stream, uint8_t key_bitlen,
482  SCRadixTree *tree, void *user, uint8_t netmask, bool exclusive)
483 {
484  SCRadixNode *node = NULL;
485  SCRadixNode *new_node = NULL;
486  SCRadixNode *parent = NULL;
487  SCRadixNode *inter_node = NULL;
488  SCRadixNode *bottom_node = NULL;
489  void *ptmp;
490 
491  uint8_t *stream = NULL;
492  uint8_t bitlen = 0;
493 
494  uint16_t check_bit = 0;
495  uint16_t differ_bit = 0;
496 
497  uint16_t i = 0;
498  uint16_t j = 0;
499 
500  if (tree == NULL) {
501  SCLogError("Argument \"tree\" NULL");
503  return NULL;
504  }
505 
506  /* chop the ip address against a netmask */
507  MaskIPNetblock(key_stream, netmask, key_bitlen);
508 
509  /* the very first element in the radix tree */
510  if (tree->head == NULL) {
511  SCRadixPrefix *prefix = NULL;
512  if ( (prefix = SCRadixCreatePrefix(key_stream, key_bitlen, user,
513  netmask)) == NULL) {
514  SCLogError("Error creating prefix");
516  return NULL;
517  }
518  node = SCRadixCreateNode();
519  if (node == NULL) {
520  SCRadixReleasePrefix(prefix, tree);
522  return NULL;
523  }
524  node->prefix = prefix;
525  node->bit = prefix->bitlen;
526  tree->head = node;
527  if (netmask == 255 || (netmask == 32 && key_bitlen == 32) ||
528  (netmask == 128 && key_bitlen == 128)) {
530  return node;
531  }
532 
533  /* if we have reached here, we are actually having a proper netblock in
534  * our hand(i.e. < 32 for ipv4 and < 128 for ipv6). Add the netmask for
535  * this node. The reason we add netmasks other than 32 and 128, is
536  * because we need those netmasks in case of searches for ips contained
537  * in netblocks. If the netmask is 32 or 128, either ways we will be
538  * having an exact match for that ip value. If it is not, we start
539  * chopping the incoming search ip key using the netmask values added
540  * into the tree and then verify for a match */
541  node->netmask_cnt++;
542  if ( (ptmp = SCRealloc(node->netmasks, (node->netmask_cnt *
543  sizeof(uint8_t)))) == NULL) {
544  SCFree(node->netmasks);
545  node->netmasks = NULL;
546  SCLogError("Fatal error encountered in SCRadixAddKey. Mem not allocated");
548  return NULL;
549  }
550  node->netmasks = ptmp;
551  node->netmasks[0] = netmask;
552  return node;
553  }
554 
555  node = tree->head;
556  stream = key_stream;
557  bitlen = key_bitlen;
558 
559  /* we walk down the tree only when we satisfy 2 conditions. The first one
560  * being the incoming prefix is shorter than the differ bit of the current
561  * node. In case we fail in this aspect, we walk down to the tree, till we
562  * arrive at a node that ends in a prefix */
563  while (node->bit < bitlen || node->prefix == NULL) {
564  /* if the bitlen isn't long enough to handle the bit test, we just walk
565  * down along one of the paths, since either paths should end up with a
566  * node that has a common prefix whose differ bit is greater than the
567  * bitlen of the incoming prefix */
568  if (bitlen <= node->bit) {
569  if (node->right == NULL)
570  break;
571  node = node->right;
572  } else {
573  if (SC_RADIX_BITTEST(stream[node->bit >> 3],
574  (0x80 >> (node->bit % 8))) ) {
575  if (node->right == NULL)
576  break;
577  node = node->right;
578  } else {
579  if (node->left == NULL)
580  break;
581  node = node->left;
582  }
583  }
584  }
585 
586  /* we need to keep a reference to the bottom-most node, that actually holds
587  * the prefix */
588  bottom_node = node;
589 
590  DEBUG_VALIDATE_BUG_ON(bottom_node == NULL);
591  DEBUG_VALIDATE_BUG_ON(bottom_node->prefix == NULL);
592 
593  /* get the first bit position where the ips differ */
594  check_bit = (node->bit < bitlen)? node->bit: bitlen;
595  for (i = 0; (i * 8) < check_bit; i++) {
596  int temp;
597  if ((temp = (stream[i] ^ bottom_node->prefix->stream[i])) == 0) {
598  differ_bit = (i + 1) * 8;
599  continue;
600  }
601 
602  /* find out the position where the first bit differs. This method is
603  * faster, but at the cost of being larger. But with larger caches
604  * these days we don't have to worry about cache misses */
605  temp = temp * 2;
606  if (temp >= 256)
607  j = 0;
608  else if (temp >= 128)
609  j = 1;
610  else if (temp >= 64)
611  j = 2;
612  else if (temp >= 32)
613  j = 3;
614  else if (temp >= 16)
615  j = 4;
616  else if (temp >= 8)
617  j = 5;
618  else if (temp >= 4)
619  j = 6;
620  else if (temp >= 2)
621  j = 7;
622 
623  differ_bit = i * 8 + j;
624  break;
625  }
626  if (check_bit < differ_bit)
627  differ_bit = check_bit;
628 
629  /* walk up the tree till we find the position, to fit our new node in */
630  parent = node->parent;
631  while (parent && differ_bit <= parent->bit) {
632  node = parent;
633  parent = node->parent;
634  }
635 
636  /* We already have the node in the tree with the same differing bit pstn */
637  if (differ_bit == bitlen && node->bit == bitlen) {
638  if (node->prefix != NULL) {
639  /* Check if we already have this netmask entry covered by this prefix */
640  if (SCRadixPrefixContainNetmask(node->prefix, netmask)) {
641  /* Basically we already have this stream prefix, as well as the
642  * netblock entry for this. A perfect duplicate. */
643  if (exclusive) {
644  SCLogDebug("not inserting since it already exists");
646  return NULL;
647  }
648  SCLogDebug("Duplicate entry for this ip address/netblock");
649  } else {
650  /* Basically we already have this stream prefix, but we don't
651  * have an entry for this particular netmask value for this
652  * prefix. For example, we have an entry for 192.168.0.0 and
653  * 192.168.0.0/16 and now we are trying to enter 192.168.0.0/20 */
654  SCRadixAddNetmaskUserDataToPrefix(node->prefix, netmask, user);
655 
656  /* if we are adding a netmask of 32(for ipv4) or 128(for ipv6)
657  * it indicates we are adding an exact host ip into the radix
658  * tree, in which case we don't need to add the netmask value
659  * into the tree */
660  if (netmask == 255 || (netmask == 32 && bitlen == 32) || (netmask == 128 && bitlen == 128))
661  return node;
662 
663  /* looks like we have a netmask which is != 32 or 128, in which
664  * case we walk up the tree to insert this netmask value in the
665  * correct node */
666  parent = node->parent;
667  while (parent != NULL && netmask < (parent->bit + 1)) {
668  node = parent;
669  parent = parent->parent;
670  }
671 
672  node->netmask_cnt++;
673  new_node = node;
674 
675  if ( (ptmp = SCRealloc(node->netmasks, (node->netmask_cnt *
676  sizeof(uint8_t)))) == NULL) {
677  SCFree(node->netmasks);
678  node->netmasks = NULL;
679  SCLogError("Fatal error encountered in SCRadixAddKey. Mem not allocated...");
681  return NULL;
682  }
683  node->netmasks = ptmp;
684 
685  if (node->netmask_cnt == 1) {
686  node->netmasks[0] = netmask;
687  return new_node;
688  }
689 
690  node->netmasks[node->netmask_cnt - 1] = netmask;
691 
692  for (i = node->netmask_cnt - 1; i > 0; i--) {
693  if (netmask < node->netmasks[i - 1]) {
694  node->netmasks[i] = netmask;
695  break;
696  }
697 
698  node->netmasks[i] = node->netmasks[i - 1];
699  node->netmasks[i - 1] = netmask;
700  }
701  }
702  } else {
703  node->prefix = SCRadixCreatePrefix(key_stream, key_bitlen,
704  user, 255);
705  }
706  return node;
707  }
708 
709  /* create the leaf node for the new key */
710  SCRadixPrefix *prefix = NULL;
711  if ( (prefix = SCRadixCreatePrefix(key_stream, key_bitlen, user,
712  netmask)) == NULL) {
713  SCLogError("Error creating prefix");
715  return NULL;
716  }
717  new_node = SCRadixCreateNode();
718  new_node->prefix = prefix;
719  new_node->bit = prefix->bitlen;
720 
721  /* indicates that we have got a key that has length that is already covered
722  * by a prefix of some other key in the tree. We create a new intermediate
723  * node with a single child and stick it in. We need the if only in the
724  * case of variable length keys */
725  if (differ_bit == bitlen) {
726  if (SC_RADIX_BITTEST(bottom_node->prefix->stream[differ_bit >> 3],
727  (0x80 >> (differ_bit % 8))) ) {
728  new_node->right = node;
729  } else {
730  new_node->left = node;
731  }
732  new_node->parent = node->parent;
733 
734  if (node->parent == NULL)
735  tree->head = new_node;
736  else if (node->parent->right == node)
737  node->parent->right = new_node;
738  else
739  node->parent->left = new_node;
740 
741  node->parent = new_node;
742  /* stick our new_node into the tree. Create a node that holds the
743  * differing bit position and break the branch. Also handle the
744  * transfer of netmasks between node and inter_node(explained in more
745  * detail below) */
746  } else {
747  inter_node = SCRadixCreateNode();
748  inter_node->prefix = NULL;
749  inter_node->bit = differ_bit;
750  inter_node->parent = node->parent;
751 
752  if (node->netmasks != NULL) {
753  for (i = 0; i < node->netmask_cnt; i++) {
754  if (node->netmasks[i] < differ_bit + 1)
755  break;
756  }
757 
758  if (i < node->netmask_cnt) {
759  if ( (inter_node->netmasks = SCMalloc((node->netmask_cnt - i) *
760  sizeof(uint8_t))) == NULL) {
761  SCLogError("Fatal error encountered in SCRadixAddKey. Mem not allocated...");
762  SCRadixReleaseNode(inter_node, tree);
763  SCRadixReleaseNode(new_node, tree);
765  return NULL;
766  }
767 
768  for (j = 0; j < (node->netmask_cnt - i); j++)
769  inter_node->netmasks[j] = node->netmasks[i + j];
770 
771  inter_node->netmask_cnt = (node->netmask_cnt - i);
772  node->netmask_cnt = i;
773  }
774  }
775 
776  if (SC_RADIX_BITTEST(stream[differ_bit >> 3],
777  (0x80 >> (differ_bit % 8))) ) {
778  inter_node->left = node;
779  inter_node->right = new_node;
780  } else {
781  inter_node->left = new_node;
782  inter_node->right = node;
783  }
784  new_node->parent = inter_node;
785 
786  if (node->parent == NULL)
787  tree->head = inter_node;
788  else if (node->parent->right == node)
789  node->parent->right = inter_node;
790  else
791  node->parent->left = inter_node;
792 
793  node->parent = inter_node;
794  }
795 
796  /* insert the netmask into the tree */
797  if (netmask != 255 && (netmask != 32 || (netmask == 32 && bitlen != 32)) && netmask != 128) {
798  node = new_node;
799  parent = new_node->parent;
800  while (parent != NULL && netmask < (parent->bit + 1)) {
801  node = parent;
802  parent = parent->parent;
803  }
804 
805  node->netmask_cnt++;
806  if ( (ptmp = SCRealloc(node->netmasks, (node->netmask_cnt *
807  sizeof(uint8_t)))) == NULL) {
808  SCFree(node->netmasks);
809  node->netmasks = NULL;
810  FatalError("Fatal error encountered in SCRadixAddKey. Exiting...");
811  }
812  node->netmasks = ptmp;
813 
814  if (node->netmask_cnt == 1) {
815  node->netmasks[0] = netmask;
816  return new_node;
817  }
818 
819  node->netmasks[node->netmask_cnt - 1] = netmask;
820 
821  for (i = node->netmask_cnt - 1; i > 0; i--) {
822  if (netmask < node->netmasks[i - 1]) {
823  node->netmasks[i] = netmask;
824  break;
825  }
826 
827  node->netmasks[i] = node->netmasks[i - 1];
828  node->netmasks[i - 1] = netmask;
829  }
830  }
831 
832  return new_node;
833 }
834 
835 static SCRadixNode *SCRadixAddKeyExclusive(
836  uint8_t *key_stream, uint8_t key_bitlen, SCRadixTree *tree, void *user, uint8_t netmask)
837 {
838  return SCRadixAddKeyInternal(key_stream, key_bitlen, tree, user, netmask, true);
839 }
840 
841 static SCRadixNode *SCRadixAddKey(
842  uint8_t *key_stream, uint8_t key_bitlen, SCRadixTree *tree, void *user, uint8_t netmask)
843 {
844  return SCRadixAddKeyInternal(key_stream, key_bitlen, tree, user, netmask, false);
845 }
846 
847 /**
848  * \brief Adds a new IPV4 address to the Radix tree
849  *
850  * \param key_stream Data that has to be added to the Radix tree. In this case
851  * a pointer to an IPV4 address
852  * \param tree Pointer to the Radix tree
853  * \param user Pointer to the user data that has to be associated with the
854  * key
855  *
856  * \retval node Pointer to the newly created node
857  */
858 SCRadixNode *SCRadixAddKeyIPV4(uint8_t *key_stream, SCRadixTree *tree,
859  void *user)
860 {
861  SCRadixNode *node = SCRadixAddKey(key_stream, 32, tree, user, 32);
862 
863  return node;
864 }
865 
866 /**
867  * \brief Adds a new IPV6 address to the Radix tree
868  *
869  * \param key_stream Data that has to be added to the Radix tree. In this case
870  * the pointer to an IPV6 address
871  * \param tree Pointer to the Radix tree
872  * \param user Pointer to the user data that has to be associated with the
873  * key
874  *
875  * \retval node Pointer to the newly created node
876  */
877 SCRadixNode *SCRadixAddKeyIPV6(uint8_t *key_stream, SCRadixTree *tree,
878  void *user)
879 {
880  SCRadixNode *node = SCRadixAddKey(key_stream, 128, tree, user, 128);
881 
882  return node;
883 }
884 
885 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
886 static void SCRadixValidateIPv4Key(uint8_t *key, const uint8_t netmask)
887 {
888  uint32_t address;
889  memcpy(&address, key, sizeof(address));
890  uint32_t mask = CIDRGet(netmask);
891  if (address != (address & mask)) {
892  uint32_t masked = address & mask;
893  char ostr[16], nstr[16];
894  PrintInet(AF_INET, (void *)&address, ostr, sizeof(ostr));
895  PrintInet(AF_INET, (void *)&masked, nstr, sizeof(nstr));
896  SCLogNotice("input %s/%u != expected %s/%u", ostr, netmask, nstr, netmask);
897  abort();
898  }
899 }
900 
901 static void SCRadixValidateIPv6Key(uint8_t *key, const uint8_t netmask)
902 {
903  uint32_t address[4];
904  memcpy(&address, key, sizeof(address));
905 
906  uint32_t mask[4];
907  memset(&mask, 0, sizeof(mask));
908  struct in6_addr mask6;
909  CIDRGetIPv6(netmask, &mask6);
910  memcpy(&mask, &mask6.s6_addr, sizeof(mask));
911 
912  uint32_t masked[4];
913  masked[0] = address[0] & mask[0];
914  masked[1] = address[1] & mask[1];
915  masked[2] = address[2] & mask[2];
916  masked[3] = address[3] & mask[3];
917 
918  if (memcmp(masked, address, sizeof(masked)) != 0) {
919  char ostr[64], nstr[64];
920  PrintInet(AF_INET6, (void *)&address, ostr, sizeof(ostr));
921  PrintInet(AF_INET6, (void *)&masked, nstr, sizeof(nstr));
922  SCLogNotice("input %s/%u != expected %s/%u", ostr, netmask, nstr, netmask);
923  abort();
924  }
925 }
926 #endif
927 
928 /**
929  * \brief Adds a new IPV4 netblock to the Radix tree
930  *
931  * \param key_stream Data that has to be added to the Radix tree. In this case
932  * a pointer to an IPV4 netblock
933  * \param tree Pointer to the Radix tree
934  * \param user Pointer to the user data that has to be associated with the
935  * key
936  * \param netmask The netmask (cidr) if we are adding a netblock
937  *
938  * \retval node Pointer to the newly created node
939  */
941  void *user, uint8_t netmask)
942 {
943 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
944  SCRadixValidateIPv4Key(key_stream, netmask);
945 #endif
946  SCRadixNode *node = SCRadixAddKey(key_stream, 32, tree, user, netmask);
947 
948  return node;
949 }
950 
951 /**
952  * \brief Adds a new IPV6 netblock to the Radix tree
953  *
954  * \param key_stream Data that has to be added to the Radix tree. In this case
955  * a pointer to an IPV6 netblock
956  * \param tree Pointer to the Radix tree
957  * \param user Pointer to the user data that has to be associated with the
958  * key
959  * \param netmask The netmask (cidr) if we are adding a netblock
960  *
961  * \retval node Pointer to the newly created node
962  */
964  void *user, uint8_t netmask)
965 {
966 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
967  SCRadixValidateIPv6Key(key_stream, netmask);
968 #endif
969  SCRadixNode *node = SCRadixAddKey(key_stream, 128, tree, user, netmask);
970 
971  return node;
972 }
973 
974 /**
975  * \brief Adds a new IPV4/netblock to the Radix tree from a string
976  *
977  * \param str IPV4 string with optional /cidr netmask
978  * \param tree Pointer to the Radix tree
979  * \param user Pointer to the user data that has to be associated with
980  * the key
981  *
982  * \retval bool true (false) if the node was (wasn't) added.
983  *
984  * sc_errno is set:
985  * - SC_OK: Node added
986  * - SC_EEXIST: Node already exists
987  * - SC_EINVAL: Parameter value error
988  */
989 bool SCRadixAddKeyIPV4String(const char *str, SCRadixTree *tree, void *user)
990 {
991  uint32_t ip;
992  uint8_t netmask = 32;
993  char ip_str[32]; /* Max length for full ipv4/mask string with NUL */
994  char *mask_str = NULL;
995  struct in_addr addr;
996 
997  /* Make a copy of the string so it can be modified */
998  strlcpy(ip_str, str, sizeof(ip_str) - 2);
999  *(ip_str + (sizeof(ip_str) - 1)) = '\0';
1000 
1001  /* Does it have a mask? */
1002  if (NULL != (mask_str = strchr(ip_str, '/'))) {
1003  uint8_t cidr;
1004  *(mask_str++) = '\0';
1005 
1006  /* Dotted type netmask not supported (yet) */
1007  if (strchr(mask_str, '.') != NULL) {
1008  sc_errno = SC_EINVAL;
1009  return false;
1010  }
1011 
1012  /* Get binary values for cidr mask */
1013  if (StringParseU8RangeCheck(&cidr, 10, 0, (const char *)mask_str, 0, 32) < 0) {
1014  sc_errno = SC_EINVAL;
1015  return false;
1016  }
1017 
1018  netmask = (uint8_t)cidr;
1019  }
1020 
1021  /* Validate the IP */
1022  if (inet_pton(AF_INET, ip_str, &addr) <= 0) {
1023  sc_errno = SC_EINVAL;
1024  return false;
1025  }
1026  ip = addr.s_addr;
1027  if (netmask != 32) {
1028  uint32_t mask = CIDRGet(netmask);
1029  uint32_t masked = ip & mask;
1030  if (masked != ip) {
1031  char nstr[16];
1032  PrintInet(AF_INET, (void *)&masked, nstr, sizeof(nstr));
1033  SCLogWarning("adding '%s' as '%s/%u'", str, nstr, netmask);
1034  ip = masked;
1035  }
1036 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
1037  SCRadixValidateIPv4Key((uint8_t *)&ip, netmask);
1038 #endif
1039  }
1040 
1041  SCLogDebug("trying to add %s, but only if it doesn't exist", ip_str);
1042  /* Add, but only if not there */
1043  if (SCRadixAddKeyExclusive((uint8_t *)&ip, 32, tree, user, netmask) == NULL) {
1044  return false;
1045  }
1046 
1047  return true;
1048 }
1049 
1050 /**
1051  * \brief Adds a new IPV6/netblock to the Radix tree from a string
1052  *
1053  * \param str IPV6 string with optional /cidr netmask
1054  * \param tree Pointer to the Radix tree
1055  * \param user Pointer to the user data that has to be associated with
1056  * the key
1057  *
1058  * \retval bool true (false) if the node was (wasn't) added.
1059  * sc_errno is set:
1060  * - SC_OK: Node added
1061  * - SC_EEXIST: Node already exists
1062  * - SC_EINVAL: Parameter value error
1063  */
1064 bool SCRadixAddKeyIPV6String(const char *str, SCRadixTree *tree, void *user)
1065 {
1066  uint8_t netmask = 128;
1067  char ip_str[80]; /* Max length for full ipv6/mask string with NUL */
1068  char *mask_str = NULL;
1069  struct in6_addr addr;
1070 
1071  /* Make a copy of the string so it can be modified */
1072  strlcpy(ip_str, str, sizeof(ip_str) - 2);
1073  *(ip_str + sizeof(ip_str) - 1) = '\0';
1074 
1075  /* Does it have a mask? */
1076  if (NULL != (mask_str = strchr(ip_str, '/'))) {
1077  uint8_t cidr;
1078  *(mask_str++) = '\0';
1079 
1080  /* Dotted type netmask not supported (yet) */
1081  if (strchr(mask_str, '.') != NULL) {
1082  sc_errno = SC_EINVAL;
1083  return false;
1084  }
1085 
1086  /* Get binary values for cidr mask */
1087  if (StringParseU8RangeCheck(&cidr, 10, 0, (const char *)mask_str, 0, 128) < 0) {
1088  sc_errno = SC_EINVAL;
1089  return false;
1090  }
1091 
1092  netmask = (uint8_t)cidr;
1093  }
1094 
1095  /* Validate the IP */
1096  if (inet_pton(AF_INET6, ip_str, &addr) <= 0) {
1097  sc_errno = SC_EINVAL;
1098  return false;
1099  }
1100 
1101  if (netmask != 128) {
1102  struct in6_addr mask6, check;
1103  CIDRGetIPv6(netmask, &mask6);
1104  memcpy(&check, &addr, sizeof(check));
1105  bool diff = false;
1106  for (int i = 0; i < 16; i++) {
1107  addr.s6_addr[i] &= mask6.s6_addr[i];
1108  diff |= (addr.s6_addr[i] != check.s6_addr[i]);
1109  }
1110  if (diff) {
1111  char nstr[64];
1112  PrintInet(AF_INET6, (void *)&addr.s6_addr, nstr, sizeof(nstr));
1113  SCLogWarning("adding '%s' as '%s/%u'", str, nstr, netmask);
1114  }
1115 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
1116  SCRadixValidateIPv6Key((uint8_t *)&addr.s6_addr, netmask);
1117 #endif
1118  }
1119 
1120  SCLogDebug("trying to add %s, but only if it doesn't exist", str);
1121  /* Add, but only if not there */
1122  if (SCRadixAddKeyExclusive(addr.s6_addr, 128, tree, user, netmask) == NULL) {
1123  return false;
1124  }
1125 
1126  sc_errno = SC_OK;
1127  return true;
1128 }
1129 
1130 static void SCRadixTransferNetmasksBWNodes(SCRadixNode *dest, SCRadixNode *src)
1131 {
1132  int i = 0, j = 0;
1133  void *ptmp = NULL;
1134 
1135  if (src == NULL || dest == NULL) {
1136  SCLogError("src or dest NULL");
1137  return;
1138  }
1139 
1140  /* no netmasks in the source node, to transfer to the destination node */
1141  if (src->netmasks == NULL)
1142  return;
1143 
1144  if ( (ptmp = SCRealloc(dest->netmasks,
1145  (src->netmask_cnt + dest->netmask_cnt) *
1146  sizeof(uint8_t))) == NULL) {
1147  SCFree(dest->netmasks);
1148  dest->netmasks = NULL;
1149  return;
1150  }
1151  dest->netmasks = ptmp;
1152 
1153  for (i = dest->netmask_cnt, j = 0; j < src->netmask_cnt; i++, j++)
1154  dest->netmasks[i] = src->netmasks[j];
1155 
1156  return;
1157 }
1158 
1159 /**
1160  * \brief Removes a netblock entry from an ip node. The function first
1161  * deletes the netblock/user_data entry for the prefix and then
1162  * removes the netmask entry that has been made in the tree, by
1163  * walking up the tree and deleting the entry from the specific node.
1164  *
1165  * \param node The node from which the netblock entry has to be removed.
1166  * \param netmask The netmask entry (cidr) that has to be removed.
1167  */
1168 static void SCRadixRemoveNetblockEntry(SCRadixNode *node, uint8_t netmask)
1169 {
1170  void *ptmp;
1171  SCRadixNode *parent = NULL;
1172  int i = 0;
1173 
1174  if (node == NULL) {
1175  SCLogError("Invalid argument. Node is NULL");
1176  return;
1177  }
1178 
1179  SCRadixRemoveNetmaskUserDataFromPrefix(node->prefix, netmask);
1180 
1181  if (netmask == 32 || netmask == 128)
1182  return;
1183 
1184  parent = node->parent;
1185  while (parent != NULL && netmask < (parent->bit + 1)) {
1186  parent = parent->parent;
1187  }
1188 
1189  for (i = 0; i < node->netmask_cnt; i++) {
1190  if (node->netmasks[i] == netmask)
1191  break;
1192  }
1193 
1194  if (i == node->netmask_cnt) {
1195  SCLogDebug("Something's wrong with the tree. We are unable to find the "
1196  "netmask entry");
1197  return;
1198  }
1199 
1200  for ( ; i < node->netmask_cnt - 1; i++)
1201  node->netmasks[i] = node->netmasks[i + 1];
1202 
1203  node->netmask_cnt--;
1204  if (node->netmask_cnt == 0) {
1205  SCFree(node->netmasks);
1206  node->netmasks = NULL;
1207  return;
1208  }
1209 
1210  ptmp = SCRealloc(node->netmasks, node->netmask_cnt * sizeof(uint8_t));
1211  if (ptmp == NULL) {
1212  SCFree(node->netmasks);
1213  node->netmasks = NULL;
1214  return;
1215  }
1216  node->netmasks = ptmp;
1217 
1218  return;
1219 }
1220 
1221 /**
1222  * \brief Removes a key from the Radix tree
1223  *
1224  * \param key_stream Data that has to be removed from the Radix tree
1225  * \param key_bitlen The bitlen of the above stream. For example if the
1226  * stream holds an IPV4 address(4 bytes), bitlen would be 32
1227  * \param tree Pointer to the Radix tree from which the key has to be
1228  * removed
1229  */
1230 static void SCRadixRemoveKey(uint8_t *key_stream, uint16_t key_bitlen,
1231  SCRadixTree *tree, uint8_t netmask)
1232 {
1233  SCRadixNode *node = tree->head;
1234  SCRadixNode *parent = NULL;
1235  SCRadixNode *temp_dest = NULL;
1236 
1237  SCRadixPrefix *prefix = NULL;
1238 
1239  uint32_t mask = 0;
1240  int i = 0;
1241 
1242  if (node == NULL)
1243  return;
1244 
1245  if ( (prefix = SCRadixCreatePrefix(key_stream, key_bitlen, NULL, 255)) == NULL)
1246  return;
1247 
1248  while (node->bit < prefix->bitlen) {
1249  if (SC_RADIX_BITTEST(prefix->stream[node->bit >> 3],
1250  (0x80 >> (node->bit % 8))) ) {
1251  node = node->right;
1252  } else {
1253  node = node->left;
1254  }
1255 
1256  if (node == NULL) {
1257  SCRadixReleasePrefix(prefix, tree);
1258  return;
1259  }
1260  }
1261 
1262  if (node->bit != prefix->bitlen || node->prefix == NULL) {
1263  SCRadixReleasePrefix(prefix, tree);
1264  return;
1265  }
1266 
1267  i = prefix->bitlen / 8;
1268  if (SCMemcmp(node->prefix->stream, prefix->stream, i) == 0) {
1269  mask = UINT_MAX << (8 - prefix->bitlen % 8);
1270 
1271  if (prefix->bitlen % 8 == 0 ||
1272  (node->prefix->stream[i] & mask) == (prefix->stream[i] & mask)) {
1273  if (!SCRadixPrefixContainNetmask(node->prefix, netmask)) {
1274  SCLogDebug("The ip key exists in the Radix Tree, but this(%d) "
1275  "netblock entry doesn't exist", netmask);
1276  SCRadixReleasePrefix(prefix, tree);
1277  return;
1278  }
1279  } else {
1280  SCLogDebug("You are trying to remove a key that doesn't exist in "
1281  "the Radix Tree");
1282  SCRadixReleasePrefix(prefix, tree);
1283  return;
1284  }
1285  } else {
1286  SCLogDebug("You are trying to remove a key that doesn't exist in the "
1287  "Radix Tree");
1288  SCRadixReleasePrefix(prefix, tree);
1289  return;
1290  }
1291 
1292  /* The ip node does exist, and the netblock entry does exist in this node, if
1293  * we have reached this point. If we have more than one netblock entry, it
1294  * indicates we have multiple entries for this key. So we delete that
1295  * particular netblock entry, and make our way out of this function */
1296  if (SCRadixPrefixNetmaskCount(node->prefix) > 1) {
1297  SCRadixRemoveNetblockEntry(node, netmask);
1298  SCRadixReleasePrefix(prefix, tree);
1299  return;
1300  }
1301 
1302  /* we are deleting the root of the tree. This would be the only node left
1303  * in the tree */
1304  if (tree->head == node) {
1305  SCRadixReleaseNode(node, tree);
1306  tree->head = NULL;
1307  SCRadixReleasePrefix(prefix, tree);
1308  return;
1309  }
1310 
1311  parent = node->parent;
1312  /* parent->parent is not the root of the tree */
1313  if (parent->parent != NULL) {
1314  if (parent->parent->left == parent) {
1315  if (node->parent->left == node) {
1316  temp_dest = parent->right;
1317  parent->parent->left = parent->right;
1318  parent->right->parent = parent->parent;
1319  } else {
1320  temp_dest = parent->left;
1321  parent->parent->left = parent->left;
1322  parent->left->parent = parent->parent;
1323  }
1324  } else {
1325  if (node->parent->left == node) {
1326  temp_dest = parent->right;
1327  parent->parent->right = parent->right;
1328  parent->right->parent = parent->parent;
1329  } else {
1330  temp_dest = parent->left;
1331  parent->parent->right = parent->left;
1332  parent->left->parent = parent->parent;
1333  }
1334  }
1335  /* parent is the root of the tree */
1336  } else {
1337  if (parent->left == node) {
1338  temp_dest = tree->head->right;
1339  tree->head->right->parent = NULL;
1340  tree->head = tree->head->right;
1341  } else {
1342  temp_dest = tree->head->left;
1343  tree->head->left->parent = NULL;
1344  tree->head = tree->head->left;
1345  }
1346  }
1347  /* We need to shift the netmask entries from the node that would be
1348  * deleted to its immediate descendant */
1349  SCRadixTransferNetmasksBWNodes(temp_dest, parent);
1350  /* release the nodes */
1351  SCRadixReleaseNode(parent, tree);
1352  SCRadixReleaseNode(node, tree);
1353  SCRadixReleasePrefix(prefix, tree);
1354 
1355  return;
1356 }
1357 
1358 /**
1359  * \brief Removes an IPV4 address netblock key from the Radix tree.
1360  *
1361  * \param key_stream Data that has to be removed from the Radix tree. In this
1362  * case an IPV4 address
1363  * \param tree Pointer to the Radix tree from which the key has to be
1364  * removed
1365  */
1366 void SCRadixRemoveKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree,
1367  uint8_t netmask)
1368 {
1369 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
1370  SCRadixValidateIPv4Key(key_stream, netmask);
1371 #endif
1372  SCRadixRemoveKey(key_stream, 32, tree, netmask);
1373  return;
1374 }
1375 
1376 /**
1377  * \brief Removes an IPV4 address key(not a netblock) from the Radix tree.
1378  * Instead of using this function, we can also used
1379  * SCRadixRemoveKeyIPV4Netblock(), by supplying a netmask value of 32.
1380  *
1381  * \param key_stream Data that has to be removed from the Radix tree. In this
1382  * case an IPV4 address
1383  * \param tree Pointer to the Radix tree from which the key has to be
1384  * removed
1385  */
1386 void SCRadixRemoveKeyIPV4(uint8_t *key_stream, SCRadixTree *tree)
1387 {
1388  SCRadixRemoveKey(key_stream, 32, tree, 32);
1389  return;
1390 }
1391 
1392 /**
1393  * \brief Removes an IPV6 netblock address key from the Radix tree.
1394  *
1395  * \param key_stream Data that has to be removed from the Radix tree. In this
1396  * case an IPV6 address
1397  * \param tree Pointer to the Radix tree from which the key has to be
1398  * removed
1399  */
1400 void SCRadixRemoveKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree,
1401  uint8_t netmask)
1402 {
1403 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
1404  SCRadixValidateIPv6Key(key_stream, netmask);
1405 #endif
1406  SCRadixRemoveKey(key_stream, 128, tree, netmask);
1407  return;
1408 }
1409 
1410 /**
1411  * \brief Removes an IPV6 address key(not a netblock) from the Radix tree.
1412  * Instead of using this function, we can also used
1413  * SCRadixRemoveKeyIPV6Netblock(), by supplying a netmask value of 128.
1414  *
1415  * \param key_stream Data that has to be removed from the Radix tree. In this
1416  * case an IPV6 address
1417  * \param tree Pointer to the Radix tree from which the key has to be
1418  * removed
1419  */
1420 void SCRadixRemoveKeyIPV6(uint8_t *key_stream, SCRadixTree *tree)
1421 {
1422  SCRadixRemoveKey(key_stream, 128, tree, 128);
1423  return;
1424 }
1425 
1426 /**
1427  * \brief Checks if an IP prefix falls under a netblock, in the path to the root
1428  * of the tree, from the node. Used internally by SCRadixFindKey()
1429  *
1430  * \param prefix Pointer to the prefix that contains the ip address
1431  * \param node Pointer to the node from where we have to climb the tree
1432  */
1433 static inline SCRadixNode *SCRadixFindKeyIPNetblock(
1434  uint8_t *key_stream, uint8_t key_bitlen, SCRadixNode *node, void **user_data_result)
1435 {
1436  SCRadixNode *netmask_node = NULL;
1437  uint32_t mask = 0;
1438  int bytes = 0;
1439  int i = 0;
1440  int j = 0;
1441 
1442  while (node != NULL && node->netmasks == NULL)
1443  node = node->parent;
1444 
1445  if (node == NULL)
1446  return NULL;
1447  /* hold the node found containing a netmask. We will need it when we call
1448  * this function recursively */
1449  netmask_node = node;
1450 
1451  for (j = 0; j < netmask_node->netmask_cnt; j++) {
1452  bytes = key_bitlen / 8;
1453  for (i = 0; i < bytes; i++) {
1454  mask = UINT_MAX;
1455  if ( ((i + 1) * 8) > netmask_node->netmasks[j]) {
1456  if ( ((i + 1) * 8 - netmask_node->netmasks[j]) < 8)
1457  mask = UINT_MAX << ((i + 1) * 8 - netmask_node->netmasks[j]);
1458  else
1459  mask = 0;
1460  }
1461  key_stream[i] &= mask;
1462  }
1463 
1464  while (node->bit < key_bitlen) {
1465  if (SC_RADIX_BITTEST(key_stream[node->bit >> 3],
1466  (0x80 >> (node->bit % 8))) ) {
1467  node = node->right;
1468  } else {
1469  node = node->left;
1470  }
1471 
1472  if (node == NULL)
1473  return NULL;
1474  }
1475 
1476  if (node->bit != key_bitlen || node->prefix == NULL)
1477  return NULL;
1478 
1479  if (SCMemcmp(node->prefix->stream, key_stream, bytes) == 0) {
1480  mask = UINT_MAX << (8 - key_bitlen % 8);
1481 
1482  if (key_bitlen % 8 == 0 ||
1483  (node->prefix->stream[bytes] & mask) == (key_stream[bytes] & mask)) {
1484  if (SCRadixPrefixContainNetmaskAndSetUserData(
1485  node->prefix, netmask_node->netmasks[j], false, user_data_result))
1486  return node;
1487  }
1488  }
1489  }
1490 
1491  return SCRadixFindKeyIPNetblock(key_stream, key_bitlen, netmask_node->parent, user_data_result);
1492 }
1493 
1494 /**
1495  * \brief Checks if an IP address key is present in the tree. The function
1496  * apart from handling any normal data, also handles ipv4/ipv6 netblocks
1497  *
1498  * \param key_stream Data that has to be found in the Radix tree
1499  * \param key_bitlen The bitlen of the above stream.
1500  * \param tree Pointer to the Radix tree
1501  * \param exact_match The key to be searched is an ip address
1502  * \param netmask Netmask used during exact match
1503  */
1504 static SCRadixNode *SCRadixFindKey(uint8_t *key_stream, uint8_t key_bitlen, uint8_t netmask,
1505  SCRadixTree *tree, bool exact_match, void **user_data_result)
1506 {
1507  if (tree == NULL || tree->head == NULL)
1508  return NULL;
1509 
1510  SCRadixNode *node = tree->head;
1511  uint32_t mask = 0;
1512  int bytes = 0;
1513  uint8_t tmp_stream[255];
1514 
1515  memset(tmp_stream, 0, 255);
1516  memcpy(tmp_stream, key_stream, key_bitlen / 8);
1517 
1518  while (node->bit < key_bitlen) {
1519  if (SC_RADIX_BITTEST(tmp_stream[node->bit >> 3],
1520  (0x80 >> (node->bit % 8))) ) {
1521  node = node->right;
1522  } else {
1523  node = node->left;
1524  }
1525 
1526  if (node == NULL) {
1527  return NULL;
1528  }
1529  }
1530 
1531  if (node->bit != key_bitlen || node->prefix == NULL) {
1532  return NULL;
1533  }
1534 
1535  bytes = key_bitlen / 8;
1536  if (SCMemcmp(node->prefix->stream, tmp_stream, bytes) == 0) {
1537  mask = UINT_MAX << (8 - key_bitlen % 8);
1538 
1539  if (key_bitlen % 8 == 0 ||
1540  (node->prefix->stream[bytes] & mask) == (tmp_stream[bytes] & mask)) {
1541  if (SCRadixPrefixContainNetmaskAndSetUserData(
1542  node->prefix, netmask, true, user_data_result)) {
1543  return node;
1544  }
1545  }
1546  }
1547 
1548  /* if you are not an ip key, get out of here */
1549  if (exact_match) {
1550  return NULL;
1551  }
1552 
1553  SCRadixNode *ret = SCRadixFindKeyIPNetblock(tmp_stream, key_bitlen, node, user_data_result);
1554  return ret;
1555 }
1556 
1557 /**
1558  * \brief Checks if an IPV4 address is present in the tree
1559  *
1560  * \param key_stream Data that has to be found in the Radix tree. In this case
1561  * an IPV4 address
1562  * \param tree Pointer to the Radix tree instance
1563  */
1564 SCRadixNode *SCRadixFindKeyIPV4ExactMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
1565 {
1566  return SCRadixFindKey(key_stream, 32, 32, tree, true, user_data_result);
1567 }
1568 
1569 /**
1570  * \brief Checks if an IPV4 address is present in the tree under a netblock
1571  *
1572  * \param key_stream Data that has to be found in the Radix tree. In this case
1573  * an IPV4 address
1574  * \param tree Pointer to the Radix tree instance
1575  */
1576 SCRadixNode *SCRadixFindKeyIPV4BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
1577 {
1578  return SCRadixFindKey(key_stream, 32, 32, tree, false, user_data_result);
1579 }
1580 
1581 /**
1582  * \brief Checks if an IPV4 Netblock address is present in the tree
1583  *
1584  * \param key_stream Data that has to be found in the Radix tree. In this case
1585  * an IPV4 netblock address
1586  * \param tree Pointer to the Radix tree instance
1587  */
1589  uint8_t netmask, void **user_data_result)
1590 {
1591 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
1592  SCRadixValidateIPv4Key(key_stream, netmask);
1593 #endif
1594  SCRadixNode *node = SCRadixFindKey(key_stream, 32, netmask, tree, true, user_data_result);
1595  return node;
1596 }
1597 
1598 /**
1599  * \brief Checks if an IPV6 Netblock address is present in the tree
1600  *
1601  * \param key_stream Data that has to be found in the Radix tree. In this case
1602  * an IPV6 netblock address
1603  * \param tree Pointer to the Radix tree instance
1604  */
1606  uint8_t netmask, void **user_data_result)
1607 {
1608 #if defined(DEBUG_VALIDATION) || defined(UNITTESTS)
1609  SCRadixValidateIPv6Key(key_stream, netmask);
1610 #endif
1611  SCRadixNode *node = SCRadixFindKey(key_stream, 128, netmask, tree, true, user_data_result);
1612  return node;
1613 }
1614 
1615 /**
1616  * \brief Checks if an IPV6 address is present in the tree
1617  *
1618  * \param key_stream Data that has to be found in the Radix tree. In this case
1619  * an IPV6 address
1620  * \param tree Pointer to the Radix tree instance
1621  */
1622 SCRadixNode *SCRadixFindKeyIPV6ExactMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
1623 {
1624  return SCRadixFindKey(key_stream, 128, 128, tree, true, user_data_result);
1625 }
1626 
1627 /**
1628  * \brief Checks if an IPV6 address is present in the tree under a netblock
1629  *
1630  * \param key_stream Data that has to be found in the Radix tree. In this case
1631  * an IPV6 address
1632  * \param tree Pointer to the Radix tree instance
1633  */
1634 SCRadixNode *SCRadixFindKeyIPV6BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
1635 {
1636  return SCRadixFindKey(key_stream, 128, 128, tree, false, user_data_result);
1637 }
1638 
1639 /**
1640  * \brief Prints the node information from a Radix tree
1641  *
1642  * \param node Pointer to the Radix node whose information has to be printed
1643  * \param level Used for indentation purposes
1644  */
1645 void SCRadixPrintNodeInfo(SCRadixNode *node, int level, void (*PrintData)(void*))
1646 {
1647  int i = 0;
1648 
1649  if (node == NULL)
1650  return;
1651 
1652  for (i = 0; i < level; i++)
1653  printf(" ");
1654 
1655  printf("%d [", node->bit);
1656 
1657  if (node->netmasks == NULL) {
1658  printf("%d, ", -1);
1659  } else {
1660  for (i = 0; i < node->netmask_cnt; i++)
1661  printf("%s%d", (0 == i ? "" : ", "), node->netmasks[i]);
1662  }
1663 
1664  printf("] (");
1665  if (node->prefix != NULL) {
1666  for (i = 0; i * 8 < node->prefix->bitlen; i++)
1667  printf("%s%d", (0 == i ? "" : "."), node->prefix->stream[i]);
1668  printf(") user_data %p\n", node->prefix->user_data);
1669 
1670  SCRadixUserData *ud = node->prefix->user_data;
1671  do {
1672  for (int x = 0; x <= level; x++)
1673  printf(" ");
1674  printf("[%d] (%p): ", ud->netmask, ud->user);
1675  if (PrintData != NULL) {
1676  PrintData(ud->user);
1677  } else {
1678  printf("NULL");
1679  }
1680  printf("\n");
1681  ud = ud->next;
1682  } while (ud != NULL);
1683  } else {
1684  printf("inter_node)\n");
1685  }
1686 
1687  return;
1688 }
1689 
1690 /**
1691  * \brief Helper function used by SCRadixPrintTree. Prints the subtree with
1692  * node as the root of the subtree
1693  *
1694  * \param node Pointer to the node that is the root of the subtree to be printed
1695  * \param level Used for indentation purposes
1696  */
1697 static void SCRadixPrintRadixSubtree(SCRadixNode *node, int level, void (*PrintData)(void*))
1698 {
1699  if (node != NULL) {
1700  SCRadixPrintNodeInfo(node, level, PrintData);
1701  SCRadixPrintRadixSubtree(node->left, level + 1, PrintData);
1702  SCRadixPrintRadixSubtree(node->right, level + 1, PrintData);
1703  }
1704 
1705  return;
1706 }
1707 
1708 /**
1709  * \brief Prints the Radix Tree. While printing the radix tree we use the
1710  * following format
1711  *
1712  * Parent_0
1713  * Left_Child_1
1714  * Left_Child_2
1715  * Right_Child_2
1716  * Right_Child_1
1717  * Left_Child_2
1718  * Right_Child_2 and so on
1719  *
1720  * Each node printed out holds details on the next bit that differs
1721  * amongst its children, and if the node holds a prefix, the perfix is
1722  * printed as well.
1723  *
1724  * \param tree Pointer to the Radix tree that has to be printed
1725  */
1727 {
1728  printf("Printing the Radix Tree: \n");
1729 
1730  SCRadixPrintRadixSubtree(tree->head, 0, tree->PrintData);
1731 
1732  return;
1733 }
1734 
1735 /*------------------------------------Unit_Tests------------------------------*/
1736 
1737 #ifdef UNITTESTS
1738 
1739 static int SCRadixTestIPV4Insertion03(void)
1740 {
1741  SCRadixTree *tree = NULL;
1742  struct sockaddr_in servaddr;
1743  int result = 1;
1744 
1745  tree = SCRadixCreateRadixTree(free, NULL);
1746 
1747  /* add the keys */
1748  memset(&servaddr, 0, sizeof(servaddr));
1749  if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0)
1750  return 0;
1751  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1752 
1753  memset(&servaddr, 0, sizeof(servaddr));
1754  if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
1755  return 0;
1756  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1757 
1758  memset(&servaddr, 0, sizeof(servaddr));
1759  if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0)
1760  return 0;
1761  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1762 
1763  memset(&servaddr, 0, sizeof(servaddr));
1764  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
1765  return 0;
1766  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1767 
1768  /* add a key that already exists in the tree */
1769  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1770 
1771  /* test for the existence of a key */
1772  memset(&servaddr, 0, sizeof(servaddr));
1773  if (inet_pton(AF_INET, "192.168.1.6", &servaddr.sin_addr) <= 0)
1774  return 0;
1775  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
1776 
1777  /* test for the existence of a key */
1778  memset(&servaddr, 0, sizeof(servaddr));
1779  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
1780  return 0;
1781  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1782 
1783  /* continue adding keys */
1784  memset(&servaddr, 0, sizeof(servaddr));
1785  if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0)
1786  return 0;
1787  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1788 
1789  memset(&servaddr, 0, sizeof(servaddr));
1790  if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0)
1791  return 0;
1792  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1793 
1794  memset(&servaddr, 0, sizeof(servaddr));
1795  if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0)
1796  return 0;
1797  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1798 
1799  /* test the existence of keys */
1800  memset(&servaddr, 0, sizeof(servaddr));
1801  if (inet_pton(AF_INET, "192.168.1.3", &servaddr.sin_addr) <= 0)
1802  return 0;
1803  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
1804 
1805  memset(&servaddr, 0, sizeof(servaddr));
1806  if (inet_pton(AF_INET, "127.234.2.62", &servaddr.sin_addr) <= 0)
1807  return 0;
1808  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
1809 
1810  memset(&servaddr, 0, sizeof(servaddr));
1811  if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0)
1812  return 0;
1813  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1814 
1815  memset(&servaddr, 0, sizeof(servaddr));
1816  if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0)
1817  return 0;
1818  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1819 
1820  memset(&servaddr, 0, sizeof(servaddr));
1821  if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
1822  return 0;
1823  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1824 
1825  memset(&servaddr, 0, sizeof(servaddr));
1826  if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0)
1827  return 0;
1828  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1829 
1830  memset(&servaddr, 0, sizeof(servaddr));
1831  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
1832  return 0;
1833  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1834 
1835  memset(&servaddr, 0, sizeof(servaddr));
1836  if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0)
1837  return 0;
1838  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1839 
1840  memset(&servaddr, 0, sizeof(servaddr));
1841  if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0)
1842  return 0;
1843  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1844 
1846 
1847  return result;
1848 }
1849 
1850 static int SCRadixTestIPV4Removal04(void)
1851 {
1852  SCRadixTree *tree = NULL;
1853  struct sockaddr_in servaddr;
1854  int result = 1;
1855 
1856  tree = SCRadixCreateRadixTree(free, NULL);
1857 
1858  /* add the keys */
1859  memset(&servaddr, 0, sizeof(servaddr));
1860  if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0)
1861  return 0;
1862  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1863 
1864  memset(&servaddr, 0, sizeof(servaddr));
1865  if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
1866  return 0;
1867  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1868 
1869  memset(&servaddr, 0, sizeof(servaddr));
1870  if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0)
1871  return 0;
1872  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1873 
1874  memset(&servaddr, 0, sizeof(servaddr));
1875  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
1876  return 0;
1877  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1878 
1879  memset(&servaddr, 0, sizeof(servaddr));
1880  if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0)
1881  return 0;
1882  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1883 
1884  memset(&servaddr, 0, sizeof(servaddr));
1885  if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0)
1886  return 0;
1887  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1888 
1889  memset(&servaddr, 0, sizeof(servaddr));
1890  if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0)
1891  return 0;
1892  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
1893 
1894  /* remove the keys from the tree */
1895  memset(&servaddr, 0, sizeof(servaddr));
1896  if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0)
1897  return 0;
1898  SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree);
1899 
1900  memset(&servaddr, 0, sizeof(servaddr));
1901  if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0)
1902  return 0;
1903  SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree);
1904 
1905  memset(&servaddr, 0, sizeof(servaddr));
1906  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
1907  return 0;
1908  SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree);
1909 
1910  memset(&servaddr, 0, sizeof(servaddr));
1911  if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0)
1912  return 0;
1913  SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree);
1914 
1915  memset(&servaddr, 0, sizeof(servaddr));
1916  if (inet_pton(AF_INET, "192.167.1.1", &servaddr.sin_addr) <= 0)
1917  return 0;
1918  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
1919 
1920  memset(&servaddr, 0, sizeof(servaddr));
1921  if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
1922  return 0;
1923  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1924 
1925  memset(&servaddr, 0, sizeof(servaddr));
1926  if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0)
1927  return 0;
1928  SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree);
1929 
1930  memset(&servaddr, 0, sizeof(servaddr));
1931  if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0)
1932  return 0;
1933  SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree);
1934 
1935  memset(&servaddr, 0, sizeof(servaddr));
1936  if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0)
1937  return 0;
1938  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1939 
1940  memset(&servaddr, 0, sizeof(servaddr));
1941  if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
1942  return 0;
1943  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
1944 
1945  memset(&servaddr, 0, sizeof(servaddr));
1946  if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
1947  return 0;
1948  SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree);
1949 
1950  memset(&servaddr, 0, sizeof(servaddr));
1951  if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0)
1952  return 0;
1953  SCRadixRemoveKeyIPV4((uint8_t *)&servaddr.sin_addr, tree);
1954 
1955  result &= (tree->head == NULL);
1956 
1958 
1959  return result;
1960 }
1961 
1962 static int SCRadixTestIPV6Insertion07(void)
1963 {
1964  SCRadixTree *tree = NULL;
1965  struct sockaddr_in6 servaddr;
1966  int result = 1;
1967 
1968  tree = SCRadixCreateRadixTree(free, NULL);
1969 
1970  /* add the keys */
1971  memset(&servaddr, 0, sizeof(servaddr));
1972  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
1973  &servaddr.sin6_addr) <= 0)
1974  return 0;
1975  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
1976 
1977  memset(&servaddr, 0, sizeof(servaddr));
1978  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
1979  &servaddr.sin6_addr) <= 0)
1980  return 0;
1981  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
1982 
1983  memset(&servaddr, 0, sizeof(servaddr));
1984  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
1985  &servaddr.sin6_addr) <= 0)
1986  return 0;
1987  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
1988 
1989  memset(&servaddr, 0, sizeof(servaddr));
1990  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
1991  &servaddr.sin6_addr) <= 0)
1992  return 0;
1993  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
1994 
1995  /* Try to add the prefix that already exists in the tree */
1996  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
1997 
1998  memset(&servaddr, 0, sizeof(servaddr));
1999  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
2000  &servaddr.sin6_addr) <= 0)
2001  return 0;
2002  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2003 
2004  memset(&servaddr, 0, sizeof(servaddr));
2005  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
2006  &servaddr.sin6_addr) <= 0)
2007  return 0;
2008  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2009 
2010  memset(&servaddr, 0, sizeof(servaddr));
2011  if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315",
2012  &servaddr.sin6_addr) <= 0)
2013  return 0;
2014  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2015 
2016  /* test the existence of keys */
2017  memset(&servaddr, 0, sizeof(servaddr));
2018  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
2019  &servaddr.sin6_addr) <= 0)
2020  return 0;
2021  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2022 
2023  memset(&servaddr, 0, sizeof(servaddr));
2024  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
2025  &servaddr.sin6_addr) <= 0)
2026  return 0;
2027  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2028 
2029  memset(&servaddr, 0, sizeof(servaddr));
2030  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
2031  &servaddr.sin6_addr) <= 0)
2032  return 0;
2033  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2034 
2035  memset(&servaddr, 0, sizeof(servaddr));
2036  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
2037  &servaddr.sin6_addr) <= 0)
2038  return 0;
2039  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2040 
2041  memset(&servaddr, 0, sizeof(servaddr));
2042  if (inet_pton(AF_INET6, "DBCA:ABC2:ABCD:DBCA:1245:2342:1111:2212",
2043  &servaddr.sin6_addr) <= 0)
2044  return 0;
2045  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2046 
2047  memset(&servaddr, 0, sizeof(servaddr));
2048  if (inet_pton(AF_INET6, "2003:0BF5:5346:1251:7422:1112:9124:2315",
2049  &servaddr.sin6_addr) <= 0)
2050  return 0;
2051  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2052 
2053  memset(&servaddr, 0, sizeof(servaddr));
2054  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
2055  &servaddr.sin6_addr) <= 0)
2056  return 0;
2057  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2058 
2059  memset(&servaddr, 0, sizeof(servaddr));
2060  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
2061  &servaddr.sin6_addr) <= 0)
2062  return 0;
2063  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2064 
2065  memset(&servaddr, 0, sizeof(servaddr));
2066  if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315",
2067  &servaddr.sin6_addr) <= 0)
2068  return 0;
2069  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2070 
2072 
2073  return result;
2074 }
2075 
2076 static int SCRadixTestIPV6Removal08(void)
2077 {
2078  SCRadixTree *tree = NULL;
2079  struct sockaddr_in6 servaddr;
2080  int result = 1;
2081 
2082  tree = SCRadixCreateRadixTree(free, NULL);
2083 
2084  /* add the keys */
2085  memset(&servaddr, 0, sizeof(servaddr));
2086  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
2087  &servaddr.sin6_addr) <= 0)
2088  return 0;
2089  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2090 
2091  memset(&servaddr, 0, sizeof(servaddr));
2092  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
2093  &servaddr.sin6_addr) <= 0)
2094  return 0;
2095  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2096 
2097  memset(&servaddr, 0, sizeof(servaddr));
2098  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
2099  &servaddr.sin6_addr) <= 0)
2100  return 0;
2101  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2102 
2103  memset(&servaddr, 0, sizeof(servaddr));
2104  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
2105  &servaddr.sin6_addr) <= 0)
2106  return 0;
2107  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2108 
2109  /* Try to add the prefix that already exists in the tree */
2110  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2111 
2112  memset(&servaddr, 0, sizeof(servaddr));
2113  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
2114  &servaddr.sin6_addr) <= 0)
2115  return 0;
2116  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2117 
2118  memset(&servaddr, 0, sizeof(servaddr));
2119  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
2120  &servaddr.sin6_addr) <= 0)
2121  return 0;
2122  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2123 
2124  memset(&servaddr, 0, sizeof(servaddr));
2125  if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315",
2126  &servaddr.sin6_addr) <= 0)
2127  return 0;
2128  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2129 
2130  /* test the existence of keys */
2131  memset(&servaddr, 0, sizeof(servaddr));
2132  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
2133  &servaddr.sin6_addr) <= 0)
2134  return 0;
2135  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2136 
2137  memset(&servaddr, 0, sizeof(servaddr));
2138  if (inet_pton(AF_INET6, "8888:0BF1:5346:BDEA:6422:8713:9124:2315",
2139  &servaddr.sin6_addr) <= 0)
2140  return 0;
2141  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2142 
2143  memset(&servaddr, 0, sizeof(servaddr));
2144  if (inet_pton(AF_INET6, "2006:0BF1:5346:BDEA:7422:8713:9124:2315",
2145  &servaddr.sin6_addr) <= 0)
2146  return 0;
2147  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2148 
2149  memset(&servaddr, 0, sizeof(servaddr));
2150  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
2151  &servaddr.sin6_addr) <= 0)
2152  return 0;
2153  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2154 
2155  memset(&servaddr, 0, sizeof(servaddr));
2156  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
2157  &servaddr.sin6_addr) <= 0)
2158  return 0;
2159  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
2160 
2161  /* test for existence */
2162  memset(&servaddr, 0, sizeof(servaddr));
2163  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
2164  &servaddr.sin6_addr) <= 0)
2165  return 0;
2166  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2167 
2168  memset(&servaddr, 0, sizeof(servaddr));
2169  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
2170  &servaddr.sin6_addr) <= 0)
2171  return 0;
2172  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2173 
2174  memset(&servaddr, 0, sizeof(servaddr));
2175  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
2176  &servaddr.sin6_addr) <= 0)
2177  return 0;
2178  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2179 
2180  memset(&servaddr, 0, sizeof(servaddr));
2181  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
2182  &servaddr.sin6_addr) <= 0)
2183  return 0;
2184  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2185 
2186  memset(&servaddr, 0, sizeof(servaddr));
2187  if (inet_pton(AF_INET6, "2003:0BF1:5346:1251:7422:1112:9124:2315",
2188  &servaddr.sin6_addr) <= 0)
2189  return 0;
2190  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2191 
2192  memset(&servaddr, 0, sizeof(servaddr));
2193  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:DDDD:2315",
2194  &servaddr.sin6_addr) <= 0)
2195  return 0;
2196  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2197 
2198  /* remove keys */
2199  memset(&servaddr, 0, sizeof(servaddr));
2200  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
2201  &servaddr.sin6_addr) <= 0)
2202  return 0;
2203  SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree);
2204 
2205  memset(&servaddr, 0, sizeof(servaddr));
2206  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
2207  &servaddr.sin6_addr) <= 0)
2208  return 0;
2209  SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree);
2210 
2211  /* test for existence */
2212  memset(&servaddr, 0, sizeof(servaddr));
2213  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
2214  &servaddr.sin6_addr) <= 0)
2215  return 0;
2216  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2217 
2218  memset(&servaddr, 0, sizeof(servaddr));
2219  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
2220  &servaddr.sin6_addr) <= 0)
2221  return 0;
2222  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2223 
2224  memset(&servaddr, 0, sizeof(servaddr));
2225  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
2226  &servaddr.sin6_addr) <= 0)
2227  return 0;
2228  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2229 
2230  memset(&servaddr, 0, sizeof(servaddr));
2231  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
2232  &servaddr.sin6_addr) <= 0)
2233  return 0;
2234  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2235 
2236  memset(&servaddr, 0, sizeof(servaddr));
2237  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
2238  &servaddr.sin6_addr) <= 0)
2239  return 0;
2240  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2241 
2242  memset(&servaddr, 0, sizeof(servaddr));
2243  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
2244  &servaddr.sin6_addr) <= 0)
2245  return 0;
2246  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
2247 
2248  /* remove keys */
2249  memset(&servaddr, 0, sizeof(servaddr));
2250  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
2251  &servaddr.sin6_addr) <= 0)
2252  return 0;
2253  SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree);
2254 
2255  memset(&servaddr, 0, sizeof(servaddr));
2256  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
2257  &servaddr.sin6_addr) <= 0)
2258  return 0;
2259  SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree);
2260 
2261  memset(&servaddr, 0, sizeof(servaddr));
2262  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
2263  &servaddr.sin6_addr) <= 0)
2264  return 0;
2265  SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree);
2266 
2267  memset(&servaddr, 0, sizeof(servaddr));
2268  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
2269  &servaddr.sin6_addr) <= 0)
2270  return 0;
2271  SCRadixRemoveKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree);
2272 
2273  /* test for existence */
2274  memset(&servaddr, 0, sizeof(servaddr));
2275  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
2276  &servaddr.sin6_addr) <= 0)
2277  return 0;
2278  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2279 
2280  memset(&servaddr, 0, sizeof(servaddr));
2281  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
2282  &servaddr.sin6_addr) <= 0)
2283  return 0;
2284  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2285 
2286  memset(&servaddr, 0, sizeof(servaddr));
2287  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
2288  &servaddr.sin6_addr) <= 0)
2289  return 0;
2290  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2291 
2292  memset(&servaddr, 0, sizeof(servaddr));
2293  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
2294  &servaddr.sin6_addr) <= 0)
2295  return 0;
2296  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2297 
2298  memset(&servaddr, 0, sizeof(servaddr));
2299  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
2300  &servaddr.sin6_addr) <= 0)
2301  return 0;
2302  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2303 
2304  memset(&servaddr, 0, sizeof(servaddr));
2305  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
2306  &servaddr.sin6_addr) <= 0)
2307  return 0;
2308  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
2309 
2311 
2312  return result;
2313 }
2314 
2315 /** Bug #5066
2316  *
2317  * insert:
2318  * - 100.117.241.0/25: 100.117.241.0 - 100.117.241.127
2319  * - 100.117.241.0/26: 100.117.241.0 - 100.117.241.63
2320  *
2321  * check:
2322  * - 100.117.241.64/26: 100.117.241.64 - 100.117.241.127
2323  */
2324 
2325 static int SCRadixTestIPV4Bug5066(void)
2326 {
2327  struct sockaddr_in servaddr;
2328  SCRadixNode *node = NULL;
2329 
2330  SCLogDebug("setup tree");
2331  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
2332 
2333  memset(&servaddr, 0, sizeof(servaddr));
2334  FAIL_IF(inet_pton(AF_INET, "100.117.241.0", &servaddr.sin_addr) <= 0);
2335  SCLogDebug("add 100.117.241.0/25");
2336  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("1"), 25);
2337  SCRadixPrintTree(tree);
2338  SCLogDebug("find 100.117.241.0/25");
2339  char *r = NULL;
2340  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 25, (void **)&r);
2341  FAIL_IF_NULL(node);
2342  SCRadixPrintNodeInfo(node, 0, NULL);
2343 
2344  SCLogDebug("add 100.117.241.0/26");
2345  FAIL_IF(inet_pton(AF_INET, "100.117.241.0", &servaddr.sin_addr) <= 0);
2346  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("2"), 26);
2347  SCRadixPrintTree(tree);
2348  SCLogDebug("find 100.117.241.0/26");
2349  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 26, NULL);
2350  FAIL_IF_NULL(node);
2351  SCRadixPrintNodeInfo(node, 0, NULL);
2352 
2353  SCLogDebug("find 100.117.241.64/26 (should fail)");
2354  FAIL_IF(inet_pton(AF_INET, "100.117.241.64", &servaddr.sin_addr) <= 0);
2355  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 26, NULL);
2356  FAIL_IF_NOT_NULL(node);
2357  SCRadixPrintNodeInfo(node, 0, NULL);
2358 
2359  SCLogDebug("add 100.117.241.64/26");
2360  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("3"), 26);
2361  SCLogDebug("find 100.117.241.64/26 (should succeed)");
2362  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 26, NULL);
2363  FAIL_IF_NULL(node);
2364  SCRadixPrintNodeInfo(node, 0, NULL);
2365 
2366  SCRadixPrintTree(tree);
2367 
2369  PASS;
2370 }
2371 
2372 static void SCRadixTestIPV4Bug5066v2PrintData(void *d)
2373 {
2374  const char *s = d;
2375  printf("%s", s);
2376 }
2377 
2378 static int SCRadixTestIPV4Bug5066v2(void)
2379 {
2380  struct sockaddr_in servaddr;
2381  SCRadixNode *node = NULL;
2382 
2383  SCLogDebug("setup tree");
2384  SCRadixTree *tree = SCRadixCreateRadixTree(free, SCRadixTestIPV4Bug5066v2PrintData);
2385 
2386  memset(&servaddr, 0, sizeof(servaddr));
2387  FAIL_IF(inet_pton(AF_INET, "1.2.3.0", &servaddr.sin_addr) <= 0);
2388  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("1.2.3.0/24"), 24);
2389  SCRadixPrintTree(tree);
2390  char *r = NULL;
2391  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 24, (void **)&r);
2392  SCRadixPrintTree(tree);
2393  FAIL_IF_NULL(node);
2394  SCRadixPrintNodeInfo(node, 0, NULL);
2395  FAIL_IF_NOT(strcmp(r, "1.2.3.0/24") == 0);
2396 
2397  memset(&servaddr, 0, sizeof(servaddr));
2398  FAIL_IF(inet_pton(AF_INET, "1.2.3.0", &servaddr.sin_addr) <= 0);
2399  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("1.2.3.0/25"), 25);
2400  SCRadixPrintTree(tree);
2401  r = NULL;
2402  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 25, (void **)&r);
2403  SCRadixPrintTree(tree);
2404  FAIL_IF_NULL(node);
2405  SCRadixPrintNodeInfo(node, 0, NULL);
2406  FAIL_IF_NOT(strcmp(r, "1.2.3.0/25") == 0);
2407 
2408  memset(&servaddr, 0, sizeof(servaddr));
2409  FAIL_IF(inet_pton(AF_INET, "1.2.3.0", &servaddr.sin_addr) <= 0);
2410  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("1.2.3.0/26"), 26);
2411  SCRadixPrintTree(tree);
2412  r = NULL;
2413  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 26, (void **)&r);
2414  SCRadixPrintTree(tree);
2415  FAIL_IF_NULL(node);
2416  SCRadixPrintNodeInfo(node, 0, NULL);
2417  FAIL_IF_NOT(strcmp(r, "1.2.3.0/26") == 0);
2418 
2419  memset(&servaddr, 0, sizeof(servaddr));
2420  FAIL_IF(inet_pton(AF_INET, "1.2.3.64", &servaddr.sin_addr) <= 0);
2421  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("1.2.3.64/26"), 26);
2422  SCRadixPrintTree(tree);
2423  r = NULL;
2424  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 26, (void **)&r);
2425  SCRadixPrintTree(tree);
2426  FAIL_IF_NULL(node);
2427  SCRadixPrintNodeInfo(node, 0, NULL);
2428  FAIL_IF_NOT(strcmp(r, "1.2.3.64/26") == 0);
2429 
2430  memset(&servaddr, 0, sizeof(servaddr));
2431  FAIL_IF(inet_pton(AF_INET, "1.2.3.64", &servaddr.sin_addr) <= 0);
2432  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("1.2.3.64/27"), 27);
2433  SCRadixPrintTree(tree);
2434  r = NULL;
2435  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 27, (void **)&r);
2436  SCRadixPrintTree(tree);
2437  FAIL_IF_NULL(node);
2438  SCRadixPrintNodeInfo(node, 0, NULL);
2439  FAIL_IF_NOT(strcmp(r, "1.2.3.64/27") == 0);
2440 
2441  memset(&servaddr, 0, sizeof(servaddr));
2442  FAIL_IF(inet_pton(AF_INET, "1.2.3.96", &servaddr.sin_addr) <= 0);
2443  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, strdup("1.2.3.96/27"), 27);
2444  SCRadixPrintTree(tree);
2445  r = NULL;
2446  node = SCRadixFindKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 27, (void **)&r);
2447  SCRadixPrintTree(tree);
2448  FAIL_IF_NULL(node);
2449  SCLogNotice("node:");
2450  SCRadixPrintNodeInfo(node, 0, NULL);
2451  FAIL_IF_NOT(strcmp(r, "1.2.3.96/27") == 0);
2452 
2454  PASS;
2455 }
2456 
2457 /** Bug #5066
2458  */
2459 static int SCRadixTestIPV6Bug5066(void)
2460 {
2461  struct sockaddr_in6 servaddr;
2462  SCRadixNode *node = NULL;
2463 
2464  SCLogDebug("setup tree");
2465  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
2466 
2467  memset(&servaddr, 0, sizeof(servaddr));
2468  FAIL_IF(inet_pton(AF_INET6, "2000::1:0", &servaddr.sin6_addr) <= 0);
2469  SCLogDebug("add 2000::1:0/121");
2470  SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, strdup("1"), 121);
2471  SCRadixPrintTree(tree);
2472  SCLogDebug("find 2000::1:0/121");
2473  char *r = NULL;
2474  node = SCRadixFindKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, 121, (void **)&r);
2475  FAIL_IF_NULL(node);
2476  SCRadixPrintNodeInfo(node, 0, NULL);
2477 
2478  SCLogDebug("add 2000::1:0/122");
2479  FAIL_IF(inet_pton(AF_INET6, "2000::1:0", &servaddr.sin6_addr) <= 0);
2480  SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, strdup("2"), 122);
2481  SCRadixPrintTree(tree);
2482  SCLogDebug("find 2000::1:0/122");
2483  node = SCRadixFindKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, 122, NULL);
2484  FAIL_IF_NULL(node);
2485  SCRadixPrintNodeInfo(node, 0, NULL);
2486 
2487  SCLogDebug("find 2000::1:40/122 (should fail)");
2488  FAIL_IF(inet_pton(AF_INET6, "2000::1:40", &servaddr.sin6_addr) <= 0);
2489  node = SCRadixFindKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, 122, NULL);
2490  FAIL_IF_NOT_NULL(node);
2491  SCRadixPrintNodeInfo(node, 0, NULL);
2492 
2493  SCLogDebug("add 2000::1:40/122");
2494  SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, strdup("3"), 122);
2495  SCLogDebug("find 2000::1:40/122 (should succeed)");
2496  node = SCRadixFindKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, 122, NULL);
2497  FAIL_IF_NULL(node);
2498  SCRadixPrintNodeInfo(node, 0, NULL);
2499 
2500  SCRadixPrintTree(tree);
2501 
2503  PASS;
2504 }
2505 
2506 static int SCRadixTestIPV4NetblockInsertion09(void)
2507 {
2508  SCRadixTree *tree = NULL;
2509  struct sockaddr_in servaddr;
2510  int result = 1;
2511 
2512  tree = SCRadixCreateRadixTree(free, NULL);
2513 
2514  /* add the keys */
2515  memset(&servaddr, 0, sizeof(servaddr));
2516  if (inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0)
2517  return 0;
2518  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2519 
2520  memset(&servaddr, 0, sizeof(servaddr));
2521  if (inet_pton(AF_INET, "192.168.1.2", &servaddr.sin_addr) <= 0)
2522  return 0;
2523  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2524 
2525  memset(&servaddr, 0, sizeof(servaddr));
2526  if (inet_pton(AF_INET, "192.167.1.3", &servaddr.sin_addr) <= 0)
2527  return 0;
2528  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2529 
2530  memset(&servaddr, 0, sizeof(servaddr));
2531  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
2532  return 0;
2533  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2534 
2535  memset(&servaddr, 0, sizeof(servaddr));
2536  if (inet_pton(AF_INET, "220.168.1.2", &servaddr.sin_addr) <= 0)
2537  return 0;
2538  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2539 
2540  memset(&servaddr, 0, sizeof(servaddr));
2541  if (inet_pton(AF_INET, "192.168.1.5", &servaddr.sin_addr) <= 0)
2542  return 0;
2543  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2544 
2545  memset(&servaddr, 0, sizeof(servaddr));
2546  if (inet_pton(AF_INET, "192.168.1.18", &servaddr.sin_addr) <= 0)
2547  return 0;
2548  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2549 
2550  memset(&servaddr, 0, sizeof(servaddr));
2551  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
2552  return 0;
2553  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2554 
2555  memset(&servaddr, 0, sizeof(servaddr));
2556  if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0)
2557  return 0;
2558  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24);
2559 
2560  memset(&servaddr, 0, sizeof(servaddr));
2561  if (inet_pton(AF_INET, "192.171.192.0", &servaddr.sin_addr) <= 0)
2562  return 0;
2563  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 18);
2564 
2565  if (inet_pton(AF_INET, "192.175.0.0", &servaddr.sin_addr) <= 0)
2566  return 0;
2567  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2568 
2569  /* test for the existence of a key */
2570  memset(&servaddr, 0, sizeof(servaddr));
2571  if (inet_pton(AF_INET, "192.168.1.6", &servaddr.sin_addr) <= 0)
2572  return 0;
2573  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
2574 
2575  memset(&servaddr, 0, sizeof(servaddr));
2576  if (inet_pton(AF_INET, "192.170.1.6", &servaddr.sin_addr) <= 0)
2577  return 0;
2578  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2579 
2580  memset(&servaddr, 0, sizeof(servaddr));
2581  if (inet_pton(AF_INET, "192.171.128.145", &servaddr.sin_addr) <= 0)
2582  return 0;
2583  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
2584 
2585  memset(&servaddr, 0, sizeof(servaddr));
2586  if (inet_pton(AF_INET, "192.171.64.6", &servaddr.sin_addr) <= 0)
2587  return 0;
2588  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2589 
2590  memset(&servaddr, 0, sizeof(servaddr));
2591  if (inet_pton(AF_INET, "192.171.191.6", &servaddr.sin_addr) <= 0)
2592  return 0;
2593  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2594 
2595  memset(&servaddr, 0, sizeof(servaddr));
2596  if (inet_pton(AF_INET, "192.171.224.6", &servaddr.sin_addr) <= 0)
2597  return 0;
2598  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
2599 
2600  memset(&servaddr, 0, sizeof(servaddr));
2601  if (inet_pton(AF_INET, "192.174.224.6", &servaddr.sin_addr) <= 0)
2602  return 0;
2603  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2604 
2605  memset(&servaddr, 0, sizeof(servaddr));
2606  if (inet_pton(AF_INET, "192.175.224.6", &servaddr.sin_addr) <= 0)
2607  return 0;
2608  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
2609 
2611 
2612  return result;
2613 }
2614 
2615 static int SCRadixTestIPV4NetblockInsertion10(void)
2616 {
2617  SCRadixTree *tree = NULL;
2618  SCRadixNode *node[2];
2619  struct sockaddr_in servaddr;
2620 
2621  tree = SCRadixCreateRadixTree(free, NULL);
2622 
2623  /* add the keys */
2624  memset(&servaddr, 0, sizeof(servaddr));
2625  if (inet_pton(AF_INET, "253.192.0.0", &servaddr.sin_addr) <= 0)
2626  return 0;
2627  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2628 
2629  memset(&servaddr, 0, sizeof(servaddr));
2630  if (inet_pton(AF_INET, "253.192.235.0", &servaddr.sin_addr) <= 0)
2631  return 0;
2632  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24);
2633 
2634  memset(&servaddr, 0, sizeof(servaddr));
2635  if (inet_pton(AF_INET, "192.167.0.0", &servaddr.sin_addr) <= 0)
2636  return 0;
2637  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2638 
2639  memset(&servaddr, 0, sizeof(servaddr));
2640  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
2641  return 0;
2642  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2643 
2644  memset(&servaddr, 0, sizeof(servaddr));
2645  if (inet_pton(AF_INET, "220.168.0.0", &servaddr.sin_addr) <= 0)
2646  return 0;
2647  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2648 
2649  memset(&servaddr, 0, sizeof(servaddr));
2650  if (inet_pton(AF_INET, "253.224.1.5", &servaddr.sin_addr) <= 0)
2651  return 0;
2652  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2653 
2654  memset(&servaddr, 0, sizeof(servaddr));
2655  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
2656  return 0;
2657  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2658 
2659  memset(&servaddr, 0, sizeof(servaddr));
2660  if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0)
2661  return 0;
2662  node[0] = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24);
2663 
2664  memset(&servaddr, 0, sizeof(servaddr));
2665  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2666  return 0;
2667  node[1] = SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2668 
2669  memset(&servaddr, 0, sizeof(servaddr));
2670  if (inet_pton(AF_INET, "192.171.0.0", &servaddr.sin_addr) <= 0)
2671  return 0;
2672  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 18);
2673 
2674  if (inet_pton(AF_INET, "192.175.0.0", &servaddr.sin_addr) <= 0)
2675  return 0;
2676  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2677 
2678  SCRadixPrintTree(tree);
2679 
2680  /* test for the existence of a key */
2681  memset(&servaddr, 0, sizeof(servaddr));
2682  if (inet_pton(AF_INET, "192.171.128.53", &servaddr.sin_addr) <= 0)
2683  return 0;
2684  SCRadixNode *found = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL);
2685  FAIL_IF_NOT(found == node[0]);
2686 
2687  SCLogDebug("search \"exact\" match for 192.171.128.45");
2688  memset(&servaddr, 0, sizeof(servaddr));
2689  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2690  return 0;
2691  found = SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL);
2692  FAIL_IF_NOT(found == node[1]);
2693 
2694  SCLogDebug("search \"best\" match for 192.171.128.45");
2695  memset(&servaddr, 0, sizeof(servaddr));
2696  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2697  return 0;
2698  found = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL);
2699  FAIL_IF_NOT(found == node[1]);
2700 
2701  memset(&servaddr, 0, sizeof(servaddr));
2702  if (inet_pton(AF_INET, "192.171.128.78", &servaddr.sin_addr) <= 0)
2703  return 0;
2704  found = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL);
2705  FAIL_IF_NOT(found == node[0]);
2706 
2707  /* let us remove a netblock */
2708  memset(&servaddr, 0, sizeof(servaddr));
2709  if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0)
2710  return 0;
2711  SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 24);
2712 
2713  memset(&servaddr, 0, sizeof(servaddr));
2714  if (inet_pton(AF_INET, "192.171.128.78", &servaddr.sin_addr) <= 0)
2715  return 0;
2716  found = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL);
2717  FAIL_IF_NOT_NULL(found);
2718 
2719  memset(&servaddr, 0, sizeof(servaddr));
2720  if (inet_pton(AF_INET, "192.171.127.78", &servaddr.sin_addr) <= 0)
2721  return 0;
2722  found = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL);
2723  FAIL_IF_NOT_NULL(found);
2724 
2726  PASS;
2727 }
2728 
2729 static int SCRadixTestIPV4NetblockInsertion11(void)
2730 {
2731  SCRadixTree *tree = NULL;
2732  SCRadixNode *node = NULL;
2733  struct sockaddr_in servaddr;
2734  int result = 1;
2735 
2736  tree = SCRadixCreateRadixTree(free, NULL);
2737 
2738  /* add the keys */
2739  memset(&servaddr, 0, sizeof(servaddr));
2740  if (inet_pton(AF_INET, "253.192.0.0", &servaddr.sin_addr) <= 0)
2741  return 0;
2742  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2743 
2744  memset(&servaddr, 0, sizeof(servaddr));
2745  if (inet_pton(AF_INET, "253.192.235.0", &servaddr.sin_addr) <= 0)
2746  return 0;
2747  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24);
2748 
2749  memset(&servaddr, 0, sizeof(servaddr));
2750  if (inet_pton(AF_INET, "192.167.0.0", &servaddr.sin_addr) <= 0)
2751  return 0;
2752  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2753 
2754  memset(&servaddr, 0, sizeof(servaddr));
2755  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
2756  return 0;
2757  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2758 
2759  memset(&servaddr, 0, sizeof(servaddr));
2760  if (inet_pton(AF_INET, "220.168.0.0", &servaddr.sin_addr) <= 0)
2761  return 0;
2762  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2763 
2764  memset(&servaddr, 0, sizeof(servaddr));
2765  if (inet_pton(AF_INET, "253.224.1.5", &servaddr.sin_addr) <= 0)
2766  return 0;
2767  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2768 
2769  memset(&servaddr, 0, sizeof(servaddr));
2770  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
2771  return 0;
2772  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2773 
2774  memset(&servaddr, 0, sizeof(servaddr));
2775  if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0)
2776  return 0;
2777  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24);
2778 
2779  memset(&servaddr, 0, sizeof(servaddr));
2780  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2781  return 0;
2782  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2783 
2784  memset(&servaddr, 0, sizeof(servaddr));
2785  if (inet_pton(AF_INET, "192.171.0.0", &servaddr.sin_addr) <= 0)
2786  return 0;
2787  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 18);
2788 
2789  if (inet_pton(AF_INET, "192.175.0.0", &servaddr.sin_addr) <= 0)
2790  return 0;
2791  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2792 
2793  if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0)
2794  return 0;
2795  node = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 0);
2796 
2797  /* test for the existence of a key */
2798  memset(&servaddr, 0, sizeof(servaddr));
2799  if (inet_pton(AF_INET, "192.171.128.53", &servaddr.sin_addr) <= 0)
2800  return 0;
2801  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
2802 
2803  memset(&servaddr, 0, sizeof(servaddr));
2804  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2805  return 0;
2806  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
2807 
2808  memset(&servaddr, 0, sizeof(servaddr));
2809  if (inet_pton(AF_INET, "192.171.128.78", &servaddr.sin_addr) <= 0)
2810  return 0;
2811  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
2812 
2813  memset(&servaddr, 0, sizeof(servaddr));
2814  if (inet_pton(AF_INET, "192.171.127.78", &servaddr.sin_addr) <= 0)
2815  return 0;
2816  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node);
2817 
2818  memset(&servaddr, 0, sizeof(servaddr));
2819  if (inet_pton(AF_INET, "1.1.1.1", &servaddr.sin_addr) <= 0)
2820  return 0;
2821  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node);
2822 
2823  memset(&servaddr, 0, sizeof(servaddr));
2824  if (inet_pton(AF_INET, "192.255.254.25", &servaddr.sin_addr) <= 0)
2825  return 0;
2826  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node);
2827 
2828  memset(&servaddr, 0, sizeof(servaddr));
2829  if (inet_pton(AF_INET, "169.255.254.25", &servaddr.sin_addr) <= 0)
2830  return 0;
2831  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node);
2832 
2833  memset(&servaddr, 0, sizeof(servaddr));
2834  if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0)
2835  return 0;
2836  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node);
2837 
2838  memset(&servaddr, 0, sizeof(servaddr));
2839  if (inet_pton(AF_INET, "253.224.1.5", &servaddr.sin_addr) <= 0)
2840  return 0;
2841  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL &&
2842  SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != node);
2843 
2844  memset(&servaddr, 0, sizeof(servaddr));
2845  if (inet_pton(AF_INET, "245.63.62.121", &servaddr.sin_addr) <= 0)
2846  return 0;
2847  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL &&
2848  SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node);
2849 
2850  memset(&servaddr, 0, sizeof(servaddr));
2851  if (inet_pton(AF_INET, "253.224.1.6", &servaddr.sin_addr) <= 0)
2852  return 0;
2853  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL &&
2854  SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node);
2855 
2856  /* remove node 0.0.0.0 */
2857  memset(&servaddr, 0, sizeof(servaddr));
2858  if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0)
2859  return 0;
2860  SCRadixRemoveKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, 0);
2861 
2862  memset(&servaddr, 0, sizeof(servaddr));
2863  if (inet_pton(AF_INET, "253.224.1.6", &servaddr.sin_addr) <= 0)
2864  return 0;
2865  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2866 
2867  memset(&servaddr, 0, sizeof(servaddr));
2868  if (inet_pton(AF_INET, "192.171.127.78", &servaddr.sin_addr) <= 0)
2869  return 0;
2870  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2871 
2872  memset(&servaddr, 0, sizeof(servaddr));
2873  if (inet_pton(AF_INET, "1.1.1.1", &servaddr.sin_addr) <= 0)
2874  return 0;
2875  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2876 
2877  memset(&servaddr, 0, sizeof(servaddr));
2878  if (inet_pton(AF_INET, "192.255.254.25", &servaddr.sin_addr) <= 0)
2879  return 0;
2880  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2881 
2882  memset(&servaddr, 0, sizeof(servaddr));
2883  if (inet_pton(AF_INET, "169.255.254.25", &servaddr.sin_addr) <= 0)
2884  return 0;
2885  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2886 
2887  memset(&servaddr, 0, sizeof(servaddr));
2888  if (inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0)
2889  return 0;
2890  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2891 
2893 
2894  return result;
2895 }
2896 
2897 static int SCRadixTestIPV4NetblockInsertion12(void)
2898 {
2899  SCRadixTree *tree = NULL;
2900  SCRadixNode *node[2];
2901  struct sockaddr_in servaddr;
2902  int result = 1;
2903 
2904  tree = SCRadixCreateRadixTree(free, NULL);
2905 
2906  /* add the keys */
2907  memset(&servaddr, 0, sizeof(servaddr));
2908  if (inet_pton(AF_INET, "253.192.0.0", &servaddr.sin_addr) <= 0)
2909  return 0;
2910  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2911 
2912  memset(&servaddr, 0, sizeof(servaddr));
2913  if (inet_pton(AF_INET, "253.192.235.0", &servaddr.sin_addr) <= 0)
2914  return 0;
2915  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24);
2916 
2917  memset(&servaddr, 0, sizeof(servaddr));
2918  if (inet_pton(AF_INET, "192.167.0.0", &servaddr.sin_addr) <= 0)
2919  return 0;
2920  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2921 
2922  memset(&servaddr, 0, sizeof(servaddr));
2923  if (inet_pton(AF_INET, "192.167.1.4", &servaddr.sin_addr) <= 0)
2924  return 0;
2925  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2926 
2927  memset(&servaddr, 0, sizeof(servaddr));
2928  if (inet_pton(AF_INET, "220.168.0.0", &servaddr.sin_addr) <= 0)
2929  return 0;
2930  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2931 
2932  memset(&servaddr, 0, sizeof(servaddr));
2933  if (inet_pton(AF_INET, "253.224.1.5", &servaddr.sin_addr) <= 0)
2934  return 0;
2935  SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2936 
2937  memset(&servaddr, 0, sizeof(servaddr));
2938  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
2939  return 0;
2940  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
2941 
2942  memset(&servaddr, 0, sizeof(servaddr));
2943  if (inet_pton(AF_INET, "192.171.128.0", &servaddr.sin_addr) <= 0)
2944  return 0;
2945  node[0] = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 24);
2946 
2947  memset(&servaddr, 0, sizeof(servaddr));
2948  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2949  return 0;
2950  node[1] = SCRadixAddKeyIPV4((uint8_t *)&servaddr.sin_addr, tree, NULL);
2951 
2952  memset(&servaddr, 0, sizeof(servaddr));
2953  if (inet_pton(AF_INET, "192.171.0.0", &servaddr.sin_addr) <= 0)
2954  return 0;
2955  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 18);
2956 
2957  if (inet_pton(AF_INET, "225.175.21.228", &servaddr.sin_addr) <= 0)
2958  return 0;
2959  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 32);
2960 
2961  /* test for the existence of a key */
2962  memset(&servaddr, 0, sizeof(servaddr));
2963  if (inet_pton(AF_INET, "192.171.128.53", &servaddr.sin_addr) <= 0)
2964  return 0;
2965  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[0]);
2966 
2967  memset(&servaddr, 0, sizeof(servaddr));
2968  if (inet_pton(AF_INET, "192.171.128.53", &servaddr.sin_addr) <= 0)
2969  return 0;
2970  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2971 
2972  memset(&servaddr, 0, sizeof(servaddr));
2973  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2974  return 0;
2975  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[1]);
2976 
2977  memset(&servaddr, 0, sizeof(servaddr));
2978  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2979  return 0;
2980  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[1]);
2981 
2982  memset(&servaddr, 0, sizeof(servaddr));
2983  if (inet_pton(AF_INET, "192.171.128.45", &servaddr.sin_addr) <= 0)
2984  return 0;
2985  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[1]);
2986 
2987  memset(&servaddr, 0, sizeof(servaddr));
2988  if (inet_pton(AF_INET, "192.171.128.78", &servaddr.sin_addr) <= 0)
2989  return 0;
2990  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == node[0]);
2991 
2992  memset(&servaddr, 0, sizeof(servaddr));
2993  if (inet_pton(AF_INET, "192.171.127.78", &servaddr.sin_addr) <= 0)
2994  return 0;
2995  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
2996 
2997  memset(&servaddr, 0, sizeof(servaddr));
2998  if (inet_pton(AF_INET, "225.175.21.228", &servaddr.sin_addr) <= 0)
2999  return 0;
3000  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
3001 
3002  memset(&servaddr, 0, sizeof(servaddr));
3003  if (inet_pton(AF_INET, "225.175.21.224", &servaddr.sin_addr) <= 0)
3004  return 0;
3005  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
3006 
3007  memset(&servaddr, 0, sizeof(servaddr));
3008  if (inet_pton(AF_INET, "225.175.21.229", &servaddr.sin_addr) <= 0)
3009  return 0;
3010  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
3011 
3012  memset(&servaddr, 0, sizeof(servaddr));
3013  if (inet_pton(AF_INET, "225.175.21.230", &servaddr.sin_addr) <= 0)
3014  return 0;
3015  result &= (SCRadixFindKeyIPV4ExactMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) == NULL);
3016 
3018 
3019  return result;
3020 }
3021 
3022 static int SCRadixTestIPV6NetblockInsertion13(void)
3023 {
3024  SCRadixTree *tree = NULL;
3025  struct sockaddr_in6 servaddr;
3026  int result = 1;
3027 
3028  tree = SCRadixCreateRadixTree(free, NULL);
3029 
3030  /* add the keys */
3031  memset(&servaddr, 0, sizeof(servaddr));
3032  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
3033  &servaddr.sin6_addr) <= 0)
3034  return 0;
3035  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3036 
3037  memset(&servaddr, 0, sizeof(servaddr));
3038  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
3039  &servaddr.sin6_addr) <= 0)
3040  return 0;
3041  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3042 
3043  memset(&servaddr, 0, sizeof(servaddr));
3044  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
3045  &servaddr.sin6_addr) <= 0)
3046  return 0;
3047  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3048 
3049  memset(&servaddr, 0, sizeof(servaddr));
3050  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
3051  &servaddr.sin6_addr) <= 0)
3052  return 0;
3053  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3054 
3055  memset(&servaddr, 0, sizeof(servaddr));
3056  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
3057  &servaddr.sin6_addr) <= 0)
3058  return 0;
3059  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3060 
3061  memset(&servaddr, 0, sizeof(servaddr));
3062  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DB00:0000:0000:0000:0000",
3063  &servaddr.sin6_addr) <= 0)
3064  return 0;
3065  SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, NULL, 56);
3066 
3067  memset(&servaddr, 0, sizeof(servaddr));
3068  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1145:6241",
3069  &servaddr.sin6_addr) <= 0)
3070  return 0;
3071  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3072 
3073  /* test the existence of keys */
3074  memset(&servaddr, 0, sizeof(servaddr));
3075  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
3076  &servaddr.sin6_addr) <= 0)
3077  return 0;
3078  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3079 
3080  memset(&servaddr, 0, sizeof(servaddr));
3081  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
3082  &servaddr.sin6_addr) <= 0)
3083  return 0;
3084  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3085 
3086  memset(&servaddr, 0, sizeof(servaddr));
3087  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
3088  &servaddr.sin6_addr) <= 0)
3089  return 0;
3090  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3091 
3092  memset(&servaddr, 0, sizeof(servaddr));
3093  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
3094  &servaddr.sin6_addr) <= 0)
3095  return 0;
3096  result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3097 
3098  memset(&servaddr, 0, sizeof(servaddr));
3099  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
3100  &servaddr.sin6_addr) <= 0)
3101  return 0;
3102  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3103 
3104  memset(&servaddr, 0, sizeof(servaddr));
3105  if (inet_pton(AF_INET6, "DBCA:ABC2:ABCD:DBCA:1245:2342:1111:2212",
3106  &servaddr.sin6_addr) <= 0)
3107  return 0;
3108  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
3109 
3110  memset(&servaddr, 0, sizeof(servaddr));
3111  if (inet_pton(AF_INET6, "2003:0BF5:5346:1251:7422:1112:9124:2315",
3112  &servaddr.sin6_addr) <= 0)
3113  return 0;
3114  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
3115 
3116  memset(&servaddr, 0, sizeof(servaddr));
3117  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
3118  &servaddr.sin6_addr) <= 0)
3119  return 0;
3120  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3121 
3122  memset(&servaddr, 0, sizeof(servaddr));
3123  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBCA:1245:2342:1111:2212",
3124  &servaddr.sin6_addr) <= 0)
3125  return 0;
3126  result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3127 
3128  memset(&servaddr, 0, sizeof(servaddr));
3129  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1146:6241",
3130  &servaddr.sin6_addr) <= 0)
3131  return 0;
3132  result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3133 
3134  memset(&servaddr, 0, sizeof(servaddr));
3135  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1356:1241",
3136  &servaddr.sin6_addr) <= 0)
3137  return 0;
3138  result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL);
3139 
3140  memset(&servaddr, 0, sizeof(servaddr));
3141  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DAAA:1245:2342:1146:6241",
3142  &servaddr.sin6_addr) <= 0)
3143  return 0;
3144  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
3145 
3146 
3148 
3149  return result;
3150 }
3151 
3152 static int SCRadixTestIPV6NetblockInsertion14(void)
3153 {
3154  SCRadixTree *tree = NULL;
3155  SCRadixNode *node = NULL;
3156  struct sockaddr_in6 servaddr;
3157  int result = 1;
3158 
3159  tree = SCRadixCreateRadixTree(free, NULL);
3160 
3161  /* add the keys */
3162  memset(&servaddr, 0, sizeof(servaddr));
3163  if (inet_pton(AF_INET6, "2003:0BF1:5346:BDEA:7422:8713:9124:2315",
3164  &servaddr.sin6_addr) <= 0)
3165  return 0;
3166  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3167 
3168  memset(&servaddr, 0, sizeof(servaddr));
3169  if (inet_pton(AF_INET6, "BD15:9791:5346:6223:AADB:8713:9882:2432",
3170  &servaddr.sin6_addr) <= 0)
3171  return 0;
3172  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3173 
3174  memset(&servaddr, 0, sizeof(servaddr));
3175  if (inet_pton(AF_INET6, "1111:A21B:6221:BDEA:BBBA::DBAA:9861",
3176  &servaddr.sin6_addr) <= 0)
3177  return 0;
3178  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3179 
3180  memset(&servaddr, 0, sizeof(servaddr));
3181  if (inet_pton(AF_INET6, "4444:0BF7:5346:BDEA:7422:8713:9124:2315",
3182  &servaddr.sin6_addr) <= 0)
3183  return 0;
3184  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3185 
3186  memset(&servaddr, 0, sizeof(servaddr));
3187  if (inet_pton(AF_INET6, "5555:0BF1:ABCD:ADEA:7922:ABCD:9124:2375",
3188  &servaddr.sin6_addr) <= 0)
3189  return 0;
3190  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3191 
3192  memset(&servaddr, 0, sizeof(servaddr));
3193  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DB00:0000:0000:0000:0000",
3194  &servaddr.sin6_addr) <= 0)
3195  return 0;
3196  SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, NULL, 56);
3197 
3198  memset(&servaddr, 0, sizeof(servaddr));
3199  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1145:6241",
3200  &servaddr.sin6_addr) <= 0)
3201  return 0;
3202  SCRadixAddKeyIPV6((uint8_t *)&servaddr.sin6_addr, tree, NULL);
3203 
3204  memset(&servaddr, 0, sizeof(servaddr));
3205  if (inet_pton(AF_INET6, "::", &servaddr.sin6_addr) <= 0)
3206  return 0;
3207  node = SCRadixAddKeyIPV6Netblock((uint8_t *)&servaddr.sin6_addr, tree, NULL,
3208  0);
3209 
3210  /* test the existence of keys */
3211  memset(&servaddr, 0, sizeof(servaddr));
3212  if (inet_pton(AF_INET6, "2004:0BF1:5346:BDEA:7422:8713:9124:2315",
3213  &servaddr.sin6_addr) <= 0)
3214  return 0;
3215  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == NULL);
3216 
3217  memset(&servaddr, 0, sizeof(servaddr));
3218  if (inet_pton(AF_INET6, "2004:0BF1:5346:BDEA:7422:8713:9124:2315",
3219  &servaddr.sin6_addr) <= 0)
3220  return 0;
3221  result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == node);
3222 
3223  memset(&servaddr, 0, sizeof(servaddr));
3224  if (inet_pton(AF_INET6, "2004:0BF1:5346:B116:2362:8713:9124:2315",
3225  &servaddr.sin6_addr) <= 0)
3226  return 0;
3227  result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == node);
3228 
3229  memset(&servaddr, 0, sizeof(servaddr));
3230  if (inet_pton(AF_INET6, "2004:0B23:3252:BDEA:7422:8713:9124:2341",
3231  &servaddr.sin6_addr) <= 0)
3232  return 0;
3233  result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) == node);
3234 
3235  memset(&servaddr, 0, sizeof(servaddr));
3236  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1145:6241",
3237  &servaddr.sin6_addr) <= 0)
3238  return 0;
3239  result &= (SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL &&
3240  SCRadixFindKeyIPV6ExactMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != node);
3241 
3242  memset(&servaddr, 0, sizeof(servaddr));
3243  if (inet_pton(AF_INET6, "DBCA:ABCD:ABCD:DBAA:1245:2342:1145:6241",
3244  &servaddr.sin6_addr) <= 0)
3245  return 0;
3246  result &= (SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != NULL &&
3247  SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, NULL) != node);
3248 
3250 
3251  return result;
3252 }
3253 
3254 /**
3255  * \test Check that the best match search works for all the
3256  * possible netblocks of a fixed address
3257  */
3258 static int SCRadixTestIPV4NetBlocksAndBestSearch15(void)
3259 {
3260 
3261  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3262  FAIL_IF_NULL(tree);
3263 
3264  struct sockaddr_in servaddr;
3265  memset(&servaddr, 0, sizeof(servaddr));
3266  FAIL_IF(inet_pton(AF_INET, "192.168.0.1", &servaddr.sin_addr) <= 0);
3267 
3268  for (uint32_t i = 0; i <= 32; i++) {
3269  uint32_t *user = SCMalloc(sizeof(uint32_t));
3270  FAIL_IF_NULL(user);
3271  *user = i;
3272 
3273  char str[32];
3274  snprintf(str, sizeof(str), "192.168.0.1/%u", i);
3275  SCRadixAddKeyIPV4String(str, tree, user);
3276 
3277  void *user_data = NULL;
3278  SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3279  FAIL_IF_NULL(node);
3280  FAIL_IF_NULL(user_data);
3281  FAIL_IF(*((uint32_t *)user_data) != i);
3282  }
3283 
3285  PASS;
3286 }
3287 
3288 /**
3289  * \test Check that the best match search works for all the
3290  * possible netblocks of a fixed address
3291  */
3292 static int SCRadixTestIPV4NetBlocksAndBestSearch16(void)
3293 {
3294 
3295  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3296  FAIL_IF_NULL(tree);
3297 
3298  struct sockaddr_in servaddr;
3299  memset(&servaddr, 0, sizeof(servaddr));
3300  FAIL_IF(inet_pton(AF_INET, "192.168.1.1", &servaddr.sin_addr) <= 0);
3301 
3302  for (uint32_t i = 0; i <= 32; i++) {
3303  uint32_t *user = SCMalloc(sizeof(uint32_t));
3304  FAIL_IF_NULL(user);
3305  *user = i;
3306 
3307  char str[32];
3308  snprintf(str, sizeof(str), "192.168.1.1/%u", i);
3309  SCRadixAddKeyIPV4String(str, tree, user);
3310 
3311  void *user_data = NULL;
3312  SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3313  FAIL_IF_NULL(node);
3314  FAIL_IF_NULL(user_data);
3315  FAIL_IF(*((uint32_t *)user_data) != i);
3316  }
3317 
3319  PASS;
3320 }
3321 
3322 /**
3323  * \test Check that the best match search works for all the
3324  * possible netblocks of a fixed address
3325  */
3326 static int SCRadixTestIPV4NetBlocksAndBestSearch17(void)
3327 {
3328  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3329  FAIL_IF_NULL(tree);
3330 
3331  struct sockaddr_in servaddr;
3332  memset(&servaddr, 0, sizeof(servaddr));
3333  FAIL_IF(inet_pton(AF_INET, "10.0.0.1", &servaddr.sin_addr) <= 0);
3334 
3335  for (uint32_t i = 0; i <= 32; i++) {
3336  uint32_t *user = SCMalloc(sizeof(uint32_t));
3337  FAIL_IF_NULL(user);
3338  *user = i;
3339 
3340  char str[32];
3341  snprintf(str, sizeof(str), "10.0.0.1/%u", i);
3342  SCRadixAddKeyIPV4String(str, tree, user);
3343 
3344  void *user_data = NULL;
3345  SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3346  FAIL_IF_NULL(node);
3347  FAIL_IF_NULL(user_data);
3348  FAIL_IF(*((uint32_t *)user_data) != i);
3349  }
3350 
3352  PASS;
3353 }
3354 
3355 /**
3356  * \test Check that the best match search works for all the
3357  * possible netblocks of a fixed address
3358  */
3359 static int SCRadixTestIPV4NetBlocksAndBestSearch18(void)
3360 {
3361  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3362  FAIL_IF_NULL(tree);
3363 
3364  struct sockaddr_in servaddr;
3365  memset(&servaddr, 0, sizeof(servaddr));
3366  FAIL_IF(inet_pton(AF_INET, "172.26.0.1", &servaddr.sin_addr) <= 0);
3367 
3368  for (uint32_t i = 0; i <= 32; i++) {
3369  uint32_t *user = SCMalloc(sizeof(uint32_t));
3370  FAIL_IF_NULL(user);
3371  *user = i;
3372 
3373  char str[32];
3374  snprintf(str, sizeof(str), "172.26.0.1/%u", i);
3375  SCRadixAddKeyIPV4String(str, tree, user);
3376 
3377  void *user_data = NULL;
3378  SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3379  FAIL_IF_NULL(node);
3380  FAIL_IF_NULL(user_data);
3381  FAIL_IF(*((uint32_t *)user_data) != i);
3382  }
3383 
3385  PASS;
3386 }
3387 
3388 /**
3389  * \test Check special combinations of netblocks and addresses
3390  * on best search checking the returned userdata
3391  */
3392 static int SCRadixTestIPV4NetBlocksAndBestSearch19(void)
3393 {
3394  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3395  FAIL_IF_NULL(tree);
3396 
3397  struct sockaddr_in servaddr;
3398  memset(&servaddr, 0, sizeof(servaddr));
3399  FAIL_IF(inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0);
3400 
3401  uint32_t *user = SCMalloc(sizeof(uint32_t));
3402  FAIL_IF_NULL(user);
3403  *user = 100;
3404 
3405  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, 0);
3406 
3407  memset(&servaddr, 0, sizeof(servaddr));
3408  FAIL_IF(inet_pton(AF_INET, "192.168.1.15", &servaddr.sin_addr) <= 0);
3409  void *user_data = NULL;
3410  SCRadixNode *node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3411  FAIL_IF_NULL(node);
3412  FAIL_IF_NULL(user_data);
3413  FAIL_IF(*((uint32_t *)user_data) != 100);
3414 
3415  user_data = NULL;
3416  memset(&servaddr, 0, sizeof(servaddr));
3417  FAIL_IF(inet_pton(AF_INET, "177.0.0.0", &servaddr.sin_addr) <= 0);
3418  user = SCMalloc(sizeof(uint32_t));
3419  FAIL_IF_NULL(user);
3420  *user = 200;
3421 
3422  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, 8);
3423 
3424  memset(&servaddr, 0, sizeof(servaddr));
3425  FAIL_IF(inet_pton(AF_INET, "177.168.1.15", &servaddr.sin_addr) <= 0);
3426 
3427  node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3428  FAIL_IF_NULL(node);
3429  FAIL_IF_NULL(user_data);
3430  FAIL_IF(*((uint32_t *)user_data) != 200);
3431 
3432  user_data = NULL;
3433  memset(&servaddr, 0, sizeof(servaddr));
3434  FAIL_IF(inet_pton(AF_INET, "178.168.1.15", &servaddr.sin_addr) <= 0);
3435 
3436  node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3437  FAIL_IF_NULL(node);
3438  FAIL_IF_NULL(user_data);
3439  FAIL_IF(*((uint32_t *)user_data) != 100);
3440 
3441  user_data = NULL;
3442  memset(&servaddr, 0, sizeof(servaddr));
3443  FAIL_IF(inet_pton(AF_INET, "177.160.0.0", &servaddr.sin_addr) <= 0);
3444  user = SCMalloc(sizeof(uint32_t));
3445  FAIL_IF_NULL(user);
3446  *user = 300;
3447 
3448  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, user, 12);
3449 
3450  memset(&servaddr, 0, sizeof(servaddr));
3451  FAIL_IF(inet_pton(AF_INET, "177.168.1.15", &servaddr.sin_addr) <= 0);
3452 
3453  node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3454  FAIL_IF_NULL(node);
3455  FAIL_IF_NULL(user_data);
3456  FAIL_IF(*((uint32_t *)user_data) != 300);
3457 
3458  user_data = NULL;
3459  memset(&servaddr, 0, sizeof(servaddr));
3460  FAIL_IF(inet_pton(AF_INET, "177.167.1.15", &servaddr.sin_addr) <= 0);
3461 
3462  node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3463  FAIL_IF_NULL(node);
3464  FAIL_IF_NULL(user_data);
3465  FAIL_IF(*((uint32_t *)user_data) != 300);
3466 
3467  user_data = NULL;
3468  memset(&servaddr, 0, sizeof(servaddr));
3469  FAIL_IF(inet_pton(AF_INET, "177.178.1.15", &servaddr.sin_addr) <= 0);
3470 
3471  node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3472  FAIL_IF_NULL(node);
3473  FAIL_IF_NULL(user_data);
3474  FAIL_IF(*((uint32_t *)user_data) != 200);
3475 
3476  user_data = NULL;
3477  memset(&servaddr, 0, sizeof(servaddr));
3478  FAIL_IF(inet_pton(AF_INET, "197.178.1.15", &servaddr.sin_addr) <= 0);
3479 
3480  node = SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, &user_data);
3481  FAIL_IF_NULL(node);
3482  FAIL_IF_NULL(user_data);
3483  FAIL_IF(*((uint32_t *)user_data) != 100);
3484 
3486  PASS;
3487 }
3488 
3489 /**
3490  * \test Check that the best match search works for all the
3491  * possible netblocks of a fixed address
3492  */
3493 static int SCRadixTestIPV6NetBlocksAndBestSearch20(void)
3494 {
3495  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3496  FAIL_IF_NULL(tree);
3497 
3498  struct sockaddr_in6 servaddr;
3499  memset(&servaddr, 0, sizeof(servaddr));
3500  FAIL_IF(inet_pton(AF_INET6, "ABAB:CDCD:ABAB:CDCD:1234:4321:1234:4321", &servaddr.sin6_addr) <=
3501  0);
3502 
3503  for (uint32_t i = 0; i <= 128; i++) {
3504  uint32_t *user = SCMalloc(sizeof(uint32_t));
3505  FAIL_IF_NULL(user);
3506  *user = i;
3507 
3508  char str[64];
3509  snprintf(str, sizeof(str), "ABAB:CDCD:ABAB:CDCD:1234:4321:1234:4321/%u", i);
3510  SCRadixAddKeyIPV6String(str, tree, user);
3511 
3512  void *user_data = NULL;
3513  SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3514  FAIL_IF_NULL(node);
3515  FAIL_IF_NULL(user_data);
3516  FAIL_IF(*((uint32_t *)user_data) != i);
3517  }
3518 
3520  PASS;
3521 }
3522 
3523 /**
3524  * \test Check that the best match search works for all the
3525  * possible netblocks of a fixed address
3526  */
3527 static int SCRadixTestIPV6NetBlocksAndBestSearch21(void)
3528 {
3529  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3530  FAIL_IF_NULL(tree);
3531 
3532  struct sockaddr_in6 servaddr;
3533  memset(&servaddr, 0, sizeof(servaddr));
3534  FAIL_IF(inet_pton(AF_INET6, "ff00::1", &servaddr.sin6_addr) <= 0);
3535 
3536  for (uint32_t i = 0; i <= 128; i++) {
3537  uint32_t *user = SCMalloc(sizeof(uint32_t));
3538  FAIL_IF_NULL(user);
3539  *user = i;
3540 
3541  char str[64];
3542  snprintf(str, sizeof(str), "ff00::1/%u", i);
3543  SCRadixAddKeyIPV6String(str, tree, user);
3544 
3545  void *user_data = NULL;
3546  SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3547  FAIL_IF_NULL(node);
3548  FAIL_IF_NULL(user_data);
3549  FAIL_IF(*((uint32_t *)user_data) != i);
3550  }
3551 
3553  PASS;
3554 }
3555 
3556 /**
3557  * \test Check that the best match search works for all the
3558  * possible netblocks of a fixed address
3559  */
3560 static int SCRadixTestIPV6NetBlocksAndBestSearch22(void)
3561 {
3562  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3563  FAIL_IF_NULL(tree);
3564 
3565  struct sockaddr_in6 servaddr;
3566  memset(&servaddr, 0, sizeof(servaddr));
3567  FAIL_IF(inet_pton(AF_INET6, "ff00::192:168:1:1", &servaddr.sin6_addr) <= 0);
3568 
3569  for (uint32_t i = 0; i <= 128; i++) {
3570  uint32_t *user = SCMalloc(sizeof(uint32_t));
3571  FAIL_IF_NULL(user);
3572  *user = i;
3573 
3574  char str[64];
3575  snprintf(str, sizeof(str), "ff00::192:168:1:1/%u", i);
3576  SCRadixAddKeyIPV6String(str, tree, user);
3577 
3578  void *user_data = NULL;
3579  SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3580  FAIL_IF_NULL(node);
3581  FAIL_IF_NULL(user_data);
3582  FAIL_IF(*((uint32_t *)user_data) != i);
3583  }
3584 
3586  PASS;
3587 }
3588 
3589 /**
3590  * \test Check that the best match search works for all the
3591  * possible netblocks of a fixed address
3592  */
3593 static int SCRadixTestIPV6NetBlocksAndBestSearch23(void)
3594 {
3595  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3596  FAIL_IF_NULL(tree);
3597 
3598  struct sockaddr_in6 servaddr;
3599  memset(&servaddr, 0, sizeof(servaddr));
3600  FAIL_IF(inet_pton(AF_INET6, "FF00:ABCD:BCDA::ABCD", &servaddr.sin6_addr) <= 0);
3601 
3602  for (uint32_t i = 0; i <= 128; i++) {
3603  uint32_t *user = SCMalloc(sizeof(uint32_t));
3604  FAIL_IF_NULL(user);
3605  *user = i;
3606 
3607  char str[64];
3608  snprintf(str, sizeof(str), "FF00:ABCD:BCDA::ABCD/%u", i);
3609  SCRadixAddKeyIPV6String(str, tree, user);
3610 
3611  void *user_data = NULL;
3612  SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3613  FAIL_IF_NULL(node);
3614  FAIL_IF_NULL(user_data);
3615  FAIL_IF(*((uint32_t *)user_data) != i);
3616  }
3617 
3619  PASS;
3620 }
3621 
3622 /**
3623  * \test Check special combinations of netblocks and addresses
3624  * on best search checking the returned userdata
3625  */
3626 static int SCRadixTestIPV6NetBlocksAndBestSearch24(void)
3627 {
3628  struct sockaddr_in6 servaddr;
3629  void *user_data = NULL;
3630 
3631  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3632  FAIL_IF_NULL(tree);
3633 
3634  uint32_t *user = SCMalloc(sizeof(uint32_t));
3635  FAIL_IF_NULL(user);
3636  *user = 100;
3637  SCRadixAddKeyIPV6String("::/0", tree, user);
3638 
3639  memset(&servaddr, 0, sizeof(servaddr));
3640  FAIL_IF(inet_pton(AF_INET6, "ABCD::1", &servaddr.sin6_addr) <= 0);
3641  SCRadixNode *node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3642  FAIL_IF_NULL(node);
3643  FAIL_IF_NULL(user_data);
3644  FAIL_IF(*((uint32_t *)user_data) != 100);
3645 
3646  user_data = NULL;
3647  user = SCMalloc(sizeof(uint32_t));
3648  FAIL_IF_NULL(user);
3649  *user = 200;
3650  SCRadixAddKeyIPV6String("ABCD::0/8", tree, user);
3651 
3652  memset(&servaddr, 0, sizeof(servaddr));
3653  FAIL_IF(inet_pton(AF_INET6, "ABCD::1", &servaddr.sin6_addr) <= 0);
3654  node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3655  FAIL_IF_NULL(node);
3656  FAIL_IF_NULL(user_data);
3657  FAIL_IF(*((uint32_t *)user_data) != 200);
3658 
3659  user_data = NULL;
3660  memset(&servaddr, 0, sizeof(servaddr));
3661  FAIL_IF(inet_pton(AF_INET6, "DCBA::1", &servaddr.sin6_addr) <= 0);
3662 
3663  node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3664  FAIL_IF_NULL(node);
3665  FAIL_IF_NULL(user_data);
3666  FAIL_IF(*((uint32_t *)user_data) != 100);
3667 
3668  user_data = NULL;
3669  user = SCMalloc(sizeof(uint32_t));
3670  FAIL_IF_NULL(user);
3671  *user = 300;
3672  SCRadixAddKeyIPV6String("ABCD:ABCD::0/12", tree, user);
3673 
3674  memset(&servaddr, 0, sizeof(servaddr));
3675  FAIL_IF(inet_pton(AF_INET6, "ABCD:ABCD::1", &servaddr.sin6_addr) <= 0);
3676  node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3677  FAIL_IF_NULL(node);
3678  FAIL_IF_NULL(user_data);
3679  FAIL_IF(*((uint32_t *)user_data) != 300);
3680 
3681  user_data = NULL;
3682  memset(&servaddr, 0, sizeof(servaddr));
3683  FAIL_IF(inet_pton(AF_INET6, "ABCD:AAAA::1", &servaddr.sin6_addr) <= 0);
3684  node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3685  FAIL_IF_NULL(node);
3686  FAIL_IF_NULL(user_data);
3687  FAIL_IF(*((uint32_t *)user_data) != 300);
3688 
3689  user_data = NULL;
3690  memset(&servaddr, 0, sizeof(servaddr));
3691  FAIL_IF(inet_pton(AF_INET6, "ABAB::1", &servaddr.sin6_addr) <= 0);
3692  node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3693  FAIL_IF_NULL(node);
3694  FAIL_IF_NULL(user_data);
3695  FAIL_IF(*((uint32_t *)user_data) != 200);
3696 
3697  user_data = NULL;
3698  memset(&servaddr, 0, sizeof(servaddr));
3699  FAIL_IF(inet_pton(AF_INET6, "CABD::1", &servaddr.sin6_addr) <= 0);
3700  node = SCRadixFindKeyIPV6BestMatch((uint8_t *)&servaddr.sin6_addr, tree, &user_data);
3701  FAIL_IF_NULL(node);
3702  FAIL_IF_NULL(user_data);
3703  FAIL_IF(*((uint32_t *)user_data) != 100);
3704 
3706  PASS;
3707 }
3708 
3709 /**
3710  * \test SCRadixTestIPV4NetblockInsertion15 insert a node searching on it.
3711  * Should always return true but the purpose of the test is to monitor
3712  * the memory usage to detect memleaks (there was one on searching)
3713  */
3714 static int SCRadixTestIPV4NetblockInsertion25(void)
3715 {
3716  SCRadixTree *tree = NULL;
3717  struct sockaddr_in servaddr;
3718  int result = 1;
3719 
3720  tree = SCRadixCreateRadixTree(free, NULL);
3721 
3722  memset(&servaddr, 0, sizeof(servaddr));
3723  if (inet_pton(AF_INET, "192.168.0.0", &servaddr.sin_addr) <= 0)
3724  return 0;
3725  SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, NULL, 16);
3726 
3727  /* test for the existence of a key */
3728  memset(&servaddr, 0, sizeof(servaddr));
3729  if (inet_pton(AF_INET, "192.168.128.53", &servaddr.sin_addr) <= 0)
3730  return 0;
3731 
3732  result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree, NULL) != NULL);
3733 
3735 
3736  return result;
3737 }
3738 
3739 /**
3740  * \test SCRadixTestIPV4NetblockInsertion26 insert a node searching on it.
3741  * Should always return true but the purpose of the test is to monitor
3742  * the memory usage to detect memleaks (there was one on searching)
3743  */
3744 static int SCRadixTestIPV4NetblockInsertion26(void)
3745 {
3746  struct sockaddr_in servaddr;
3747 
3748  SCRadixTree *tree = SCRadixCreateRadixTree(free, NULL);
3749  FAIL_IF_NULL(tree);
3750 
3751  memset(&servaddr, 0, sizeof(servaddr));
3752  FAIL_IF(inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0);
3753 
3754  char *str = SCStrdup("Hello1");
3755  FAIL_IF_NULL(str);
3756  SCRadixNode *node = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 0);
3757  FAIL_IF_NULL(node);
3758 
3759  str = SCStrdup("Hello1");
3760  FAIL_IF_NULL(str);
3761 
3762  memset(&servaddr, 0, sizeof(servaddr));
3763  FAIL_IF(inet_pton(AF_INET, "176.0.0.0", &servaddr.sin_addr) <= 0);
3764 
3765  node = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 5);
3766  FAIL_IF_NULL(node);
3767 
3768  str = SCStrdup("Hello1");
3769  FAIL_IF_NULL(str);
3770 
3771  memset(&servaddr, 0, sizeof(servaddr));
3772  FAIL_IF(inet_pton(AF_INET, "0.0.0.0", &servaddr.sin_addr) <= 0);
3773 
3774  node = SCRadixAddKeyIPV4Netblock((uint8_t *)&servaddr.sin_addr, tree, str, 7);
3775  FAIL_IF_NULL(node);
3776 
3777  /* test for the existence of a key */
3778  // result &= (SCRadixFindKeyIPV4BestMatch((uint8_t *)&servaddr.sin_addr, tree) != NULL);
3779 
3781 
3782  PASS;
3783 }
3784 
3785 #endif
3786 
3788 {
3789 
3790 #ifdef UNITTESTS
3791  UtRegisterTest("SCRadixTestIPV4Insertion03", SCRadixTestIPV4Insertion03);
3792  UtRegisterTest("SCRadixTestIPV4Removal04", SCRadixTestIPV4Removal04);
3793  UtRegisterTest("SCRadixTestIPV6Insertion07", SCRadixTestIPV6Insertion07);
3794  UtRegisterTest("SCRadixTestIPV6Removal08", SCRadixTestIPV6Removal08);
3795  UtRegisterTest("SCRadixTestIPV4NetblockInsertion09",
3796  SCRadixTestIPV4NetblockInsertion09);
3797  UtRegisterTest("SCRadixTestIPV4Bug5066", SCRadixTestIPV4Bug5066);
3798  UtRegisterTest("SCRadixTestIPV4Bug5066v2", SCRadixTestIPV4Bug5066v2);
3799  UtRegisterTest("SCRadixTestIPV6Bug5066", SCRadixTestIPV6Bug5066);
3800  UtRegisterTest("SCRadixTestIPV4NetblockInsertion10",
3801  SCRadixTestIPV4NetblockInsertion10);
3802  UtRegisterTest("SCRadixTestIPV4NetblockInsertion11",
3803  SCRadixTestIPV4NetblockInsertion11);
3804  UtRegisterTest("SCRadixTestIPV4NetblockInsertion12",
3805  SCRadixTestIPV4NetblockInsertion12);
3806  UtRegisterTest("SCRadixTestIPV6NetblockInsertion13",
3807  SCRadixTestIPV6NetblockInsertion13);
3808  UtRegisterTest("SCRadixTestIPV6NetblockInsertion14",
3809  SCRadixTestIPV6NetblockInsertion14);
3810  UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch15",
3811  SCRadixTestIPV4NetBlocksAndBestSearch15);
3812  UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch16",
3813  SCRadixTestIPV4NetBlocksAndBestSearch16);
3814  UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch17",
3815  SCRadixTestIPV4NetBlocksAndBestSearch17);
3816  UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch18",
3817  SCRadixTestIPV4NetBlocksAndBestSearch18);
3818  UtRegisterTest("SCRadixTestIPV4NetBlocksAndBestSearch19",
3819  SCRadixTestIPV4NetBlocksAndBestSearch19);
3820  UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch20",
3821  SCRadixTestIPV6NetBlocksAndBestSearch20);
3822  UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch21",
3823  SCRadixTestIPV6NetBlocksAndBestSearch21);
3824  UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch22",
3825  SCRadixTestIPV6NetBlocksAndBestSearch22);
3826  UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch23",
3827  SCRadixTestIPV6NetBlocksAndBestSearch23);
3828  UtRegisterTest("SCRadixTestIPV6NetBlocksAndBestSearch24",
3829  SCRadixTestIPV6NetBlocksAndBestSearch24);
3830  UtRegisterTest("SCRadixTestIPV4NetblockInsertion25",
3831  SCRadixTestIPV4NetblockInsertion25);
3832  UtRegisterTest("SCRadixTestIPV4NetblockInsertion26",
3833  SCRadixTestIPV4NetblockInsertion26);
3834 #endif
3835 
3836  return;
3837 }
SCRadixPrefix_::user_data
SCRadixUserData * user_data
Definition: util-radix-tree.h:55
util-byte.h
SCRadixRemoveKeyIPV4Netblock
void SCRadixRemoveKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree, uint8_t netmask)
Removes an IPV4 address netblock key from the Radix tree.
Definition: util-radix-tree.c:1366
SCRadixRemoveKeyIPV6Netblock
void SCRadixRemoveKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree, uint8_t netmask)
Removes an IPV6 netblock address key from the Radix tree.
Definition: util-radix-tree.c:1400
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
MaskIPNetblock
void MaskIPNetblock(uint8_t *stream, int netmask, int key_bitlen)
Culls the non-netmask portion of the IP address. For example an IP address 192.168....
Definition: util-ip.c:187
SCRadixAddKeyIPV6String
bool SCRadixAddKeyIPV6String(const char *str, SCRadixTree *tree, void *user)
Adds a new IPV6/netblock to the Radix tree from a string.
Definition: util-radix-tree.c:1064
SCRadixFindKeyIPV6Netblock
SCRadixNode * SCRadixFindKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree, uint8_t netmask, void **user_data_result)
Checks if an IPV6 Netblock address is present in the tree.
Definition: util-radix-tree.c:1605
SCRadixNode_::prefix
SCRadixPrefix * prefix
Definition: util-radix-tree.h:74
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
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
SCRadixNode_::bit
uint16_t bit
Definition: util-radix-tree.h:64
SCRadixRemoveKeyIPV6
void SCRadixRemoveKeyIPV6(uint8_t *key_stream, SCRadixTree *tree)
Removes an IPV6 address key(not a netblock) from the Radix tree. Instead of using this function,...
Definition: util-radix-tree.c:1420
CIDRGet
uint32_t CIDRGet(int cidr)
Definition: util-cidr.c:57
SC_EINVAL
@ SC_EINVAL
Definition: util-error.h:30
SCRadixPrefix_
Structure for the prefix/key in the radix tree.
Definition: util-radix-tree.h:44
SCRadixTree_
Structure for the radix tree.
Definition: util-radix-tree.h:86
SCRadixAddKeyIPV6
SCRadixNode * SCRadixAddKeyIPV6(uint8_t *key_stream, SCRadixTree *tree, void *user)
Adds a new IPV6 address to the Radix tree.
Definition: util-radix-tree.c:877
SCRadixUserData_::next
struct SCRadixUserData_ * next
Definition: util-radix-tree.h:36
SCRadixFindKeyIPV4BestMatch
SCRadixNode * SCRadixFindKeyIPV4BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
Checks if an IPV4 address is present in the tree under a netblock.
Definition: util-radix-tree.c:1576
SCRadixPrefix_::stream
uint8_t * stream
Definition: util-radix-tree.h:49
SCRadixFindKeyIPV6BestMatch
SCRadixNode * SCRadixFindKeyIPV6BestMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
Checks if an IPV6 address is present in the tree under a netblock.
Definition: util-radix-tree.c:1634
SCRadixNode_::right
struct SCRadixNode_ * right
Definition: util-radix-tree.h:77
SCRadixAddKeyIPV4String
bool SCRadixAddKeyIPV4String(const char *str, SCRadixTree *tree, void *user)
Adds a new IPV4/netblock to the Radix tree from a string.
Definition: util-radix-tree.c:989
util-unittest.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
SC_ENOMEM
@ SC_ENOMEM
Definition: util-error.h:29
SCRadixAddKeyIPV4Netblock
SCRadixNode * SCRadixAddKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree, void *user, uint8_t netmask)
Adds a new IPV4 netblock to the Radix tree.
Definition: util-radix-tree.c:940
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
util-memcmp.h
util-cidr.h
SCRadixRegisterTests
void SCRadixRegisterTests(void)
Definition: util-radix-tree.c:3787
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
SCRadixReleaseRadixTree
void SCRadixReleaseRadixTree(SCRadixTree *tree)
Frees a Radix tree and all its nodes.
Definition: util-radix-tree.c:454
SCRadixTree_::Free
void(* Free)(void *)
Definition: util-radix-tree.h:93
SCRadixUserData_
Structure that hold the user data and the netmask associated with it.
Definition: util-radix-tree.h:32
util-print.h
util-ip.h
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:241
SC_RADIX_BITTEST
#define SC_RADIX_BITTEST(x, y)
Definition: util-radix-tree.h:27
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
SCRadixCreateRadixTree
SCRadixTree * SCRadixCreateRadixTree(void(*Free)(void *), void(*PrintData)(void *))
Creates a new Radix tree.
Definition: util-radix-tree.c:417
SCRadixRemoveKeyIPV4
void SCRadixRemoveKeyIPV4(uint8_t *key_stream, SCRadixTree *tree)
Removes an IPV4 address key(not a netblock) from the Radix tree. Instead of using this function,...
Definition: util-radix-tree.c:1386
util-radix-tree.h
SC_OK
@ SC_OK
Definition: util-error.h:27
SCRadixFindKeyIPV6ExactMatch
SCRadixNode * SCRadixFindKeyIPV6ExactMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
Checks if an IPV6 address is present in the tree.
Definition: util-radix-tree.c:1622
SCRadixUserData_::netmask
uint8_t netmask
Definition: util-radix-tree.h:38
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
SCRadixTree_::head
SCRadixNode * head
Definition: util-radix-tree.h:88
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
SCRadixTree_::PrintData
void(* PrintData)(void *)
Definition: util-radix-tree.h:92
CIDRGetIPv6
void CIDRGetIPv6(int cidr, struct in6_addr *in6)
Creates a cidr ipv6 netblock, based on the cidr netblock value.
Definition: util-cidr.c:82
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
SCRadixFindKeyIPV4Netblock
SCRadixNode * SCRadixFindKeyIPV4Netblock(uint8_t *key_stream, SCRadixTree *tree, uint8_t netmask, void **user_data_result)
Checks if an IPV4 Netblock address is present in the tree.
Definition: util-radix-tree.c:1588
SCRadixPrintTree
void SCRadixPrintTree(SCRadixTree *tree)
Prints the Radix Tree. While printing the radix tree we use the following format.
Definition: util-radix-tree.c:1726
SCRadixUserData_::user
void * user
Definition: util-radix-tree.h:34
SCRadixAddKeyIPV6Netblock
SCRadixNode * SCRadixAddKeyIPV6Netblock(uint8_t *key_stream, SCRadixTree *tree, void *user, uint8_t netmask)
Adds a new IPV6 netblock to the Radix tree.
Definition: util-radix-tree.c:963
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(...)
Definition: util-debug.h:502
util-validate.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SC_EEXIST
@ SC_EEXIST
Definition: util-error.h:32
str
#define str(s)
Definition: suricata-common.h:291
SCRadixNode_
Structure for the node in the radix tree.
Definition: util-radix-tree.h:61
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
src
uint16_t src
Definition: app-layer-dnp3.h:5
SCRadixNode_::netmask_cnt
uint16_t netmask_cnt
Definition: util-radix-tree.h:69
sc_errno
thread_local SCError sc_errno
Definition: util-error.c:31
address
uint8_t address
Definition: decode-ppp.h:0
SCRadixFindKeyIPV4ExactMatch
SCRadixNode * SCRadixFindKeyIPV4ExactMatch(uint8_t *key_stream, SCRadixTree *tree, void **user_data_result)
Checks if an IPV4 address is present in the tree.
Definition: util-radix-tree.c:1564
SCRadixAddKeyIPV4
SCRadixNode * SCRadixAddKeyIPV4(uint8_t *key_stream, SCRadixTree *tree, void *user)
Adds a new IPV4 address to the Radix tree.
Definition: util-radix-tree.c:858
SCRadixNode_::netmasks
uint8_t * netmasks
Definition: util-radix-tree.h:71
SCRadixNode_::parent
struct SCRadixNode_ * parent
Definition: util-radix-tree.h:80
SCRadixPrintNodeInfo
void SCRadixPrintNodeInfo(SCRadixNode *node, int level, void(*PrintData)(void *))
Prints the node information from a Radix tree.
Definition: util-radix-tree.c:1645
SCRadixNode_::left
struct SCRadixNode_ * left
Definition: util-radix-tree.h:77
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:237
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCMemcmp
#define SCMemcmp(a, b, c)
Definition: util-memcmp.h:290
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:103
SCRadixPrefix_::bitlen
uint16_t bitlen
Definition: util-radix-tree.h:46