suricata
detect-engine-iponly.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2022 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
23  *
24  * Signatures that only inspect IP addresses are processed here
25  * We use radix trees for src dst ipv4 and ipv6 addresses
26  * This radix trees hold information for subnets and hosts in a
27  * hierarchical distribution
28  */
29 
30 #include "suricata-common.h"
31 #include "detect.h"
32 #include "decode.h"
33 #include "flow.h"
34 
35 #include "detect-parse.h"
36 #include "detect-engine.h"
37 
38 #include "detect-engine-siggroup.h"
39 #include "detect-engine-address.h"
40 #include "detect-engine-proto.h"
41 #include "detect-engine-port.h"
42 #include "detect-engine-mpm.h"
43 #include "detect-engine-build.h"
44 
46 #include "detect-engine-iponly.h"
47 #include "detect-threshold.h"
49 #include "util-rule-vars.h"
50 #include "detect-engine-alert.h"
51 
52 #include "flow-util.h"
53 #include "util-debug.h"
54 #include "util-unittest-helper.h"
55 #include "util-print.h"
56 #include "util-byte.h"
57 #include "util-profiling.h"
58 #include "util-validate.h"
59 #include "util-cidr.h"
60 
61 #ifdef OS_WIN32
62 #include <winsock.h>
63 #else
64 #include <netinet/in.h>
65 #endif /* OS_WIN32 */
66 
67 /**
68  * \brief This function creates a new IPOnlyCIDRItem
69  *
70  * \retval IPOnlyCIDRItem address of the new instance
71  */
72 static IPOnlyCIDRItem *IPOnlyCIDRItemNew(void)
73 {
74  SCEnter();
75  IPOnlyCIDRItem *item = NULL;
76 
77  item = SCCalloc(1, sizeof(IPOnlyCIDRItem));
78  if (unlikely(item == NULL))
79  SCReturnPtr(NULL, "IPOnlyCIDRItem");
80 
81  SCReturnPtr(item, "IPOnlyCIDRItem");
82 }
83 
84 /**
85  * \brief Compares two list items
86  *
87  * \retval An integer less than, equal to, or greater than zero if lhs is
88  * considered to be respectively less than, equal to, or greater than
89  * rhs.
90  */
91 static int IPOnlyCIDRItemCompareReal(const IPOnlyCIDRItem *lhs, const IPOnlyCIDRItem *rhs)
92 {
93  if (lhs->netmask == rhs->netmask) {
94  uint8_t i = 0;
95  for (; i < lhs->netmask / 32 || i < 1; i++) {
96  if (lhs->ip[i] < rhs->ip[i])
97  return -1;
98  if (lhs->ip[i] > rhs->ip[i])
99  return 1;
100  }
101  return 0;
102  }
103 
104  return lhs->netmask < rhs->netmask ? -1 : 1;
105 }
106 
107 static int IPOnlyCIDRItemCompare(const void *lhsv, const void *rhsv)
108 {
109  const IPOnlyCIDRItem *lhs = *(const IPOnlyCIDRItem **)lhsv;
110  const IPOnlyCIDRItem *rhs = *(const IPOnlyCIDRItem **)rhsv;
111 
112  return IPOnlyCIDRItemCompareReal(lhs, rhs);
113 }
114 
115 static void IPOnlyCIDRListQSort(IPOnlyCIDRItem **head)
116 {
117  if (unlikely(head == NULL || *head == NULL))
118  return;
119 
120  // First count the number of elements in the list
121  size_t len = 0;
122  IPOnlyCIDRItem *curr = *head;
123 
124  while (curr) {
125  curr = curr->next;
126  len++;
127  }
128 
129  // Place a pointer to the list item in an array for sorting
130  IPOnlyCIDRItem **tmp = SCMalloc(len * sizeof(IPOnlyCIDRItem *));
131 
132  if (unlikely(tmp == NULL)) {
133  SCLogError("Failed to allocate enough memory to sort IP-only CIDR items.");
134  return;
135  }
136 
137  curr = *head;
138  for (size_t i = 0; i < len; i++) {
139  tmp[i] = curr;
140  curr = curr->next;
141  }
142 
143  // Perform the sort using the qsort algorithm
144  qsort(tmp, len, sizeof(IPOnlyCIDRItem *), IPOnlyCIDRItemCompare);
145 
146  // Update the links to the next element
147  *head = tmp[0];
148 
149  for (size_t i = 0; i + 1 < len; i++) {
150  tmp[i]->next = tmp[i + 1];
151  }
152 
153  tmp[len - 1]->next = NULL;
154 
155  SCFree(tmp);
156 }
157 
158 //declaration for using it already
159 static IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head,
160  IPOnlyCIDRItem *item);
161 
162 static int InsertRange(
163  IPOnlyCIDRItem **pdd, IPOnlyCIDRItem *dd, const uint32_t first_in, const uint32_t last_in)
164 {
165  DEBUG_VALIDATE_BUG_ON(dd == NULL);
166  DEBUG_VALIDATE_BUG_ON(pdd == NULL);
167 
168  uint32_t first = first_in;
169  uint32_t last = last_in;
170 
171  dd->netmask = 32;
172  /* Find the maximum netmask starting from current address first
173  * and not crossing last.
174  * To extend the mask, we need to start from a power of 2.
175  * And we need to pay attention to unsigned overflow back to 0.0.0.0
176  */
177  while (dd->netmask > 0 && (first & (1UL << (32 - dd->netmask))) == 0 &&
178  first + (1UL << (32 - (dd->netmask - 1))) - 1 <= last) {
179  dd->netmask--;
180  }
181  dd->ip[0] = htonl(first);
182  first += 1UL << (32 - dd->netmask);
183  // case whatever-255.255.255.255 looping to 0.0.0.0/0
184  while (first <= last && first != 0) {
185  IPOnlyCIDRItem *new = IPOnlyCIDRItemNew();
186  if (new == NULL)
187  goto error;
188  new->negated = dd->negated;
189  new->family = dd->family;
190  new->netmask = 32;
191  while (new->netmask > 0 && (first & (1UL << (32 - new->netmask))) == 0 &&
192  first + (1UL << (32 - (new->netmask - 1))) - 1 <= last) {
193  new->netmask--;
194  }
195  new->ip[0] = htonl(first);
196  first += 1UL << (32 - new->netmask);
197  dd = IPOnlyCIDRItemInsert(dd, new);
198  }
199  // update head of list
200  *pdd = dd;
201  return 0;
202 error:
203  return -1;
204 }
205 
206 /**
207  * \internal
208  * \brief Parses an ipv4/ipv6 address string and updates the result into the
209  * IPOnlyCIDRItem instance sent as the argument.
210  *
211  * \param pdd Double pointer to the IPOnlyCIDRItem instance which should be updated
212  * with the address (in cidr) details from the parsed ip string.
213  * \param str Pointer to address string that has to be parsed.
214  *
215  * \retval 0 On successfully parsing the address string.
216  * \retval -1 On failure.
217  */
218 static int IPOnlyCIDRItemParseSingle(IPOnlyCIDRItem **pdd, const char *str)
219 {
220  char buf[256] = "";
221  char *ip = NULL, *ip2 = NULL;
222  char *mask = NULL;
223  int r = 0;
224  IPOnlyCIDRItem *dd = *pdd;
225 
226  while (*str != '\0' && *str == ' ')
227  str++;
228 
229  SCLogDebug("str %s", str);
230  strlcpy(buf, str, sizeof(buf));
231  ip = buf;
232 
233  /* first handle 'any' */
234  if (strcasecmp(str, "any") == 0) {
235  /* if any, insert 0.0.0.0/0 and ::/0 as well */
236  SCLogDebug("adding 0.0.0.0/0 and ::/0 as we\'re handling \'any\'");
237 
238  IPOnlyCIDRItemParseSingle(&dd, "0.0.0.0/0");
239  BUG_ON(dd->family == 0);
240 
241  dd->next = IPOnlyCIDRItemNew();
242  if (dd->next == NULL)
243  goto error;
244 
245  IPOnlyCIDRItemParseSingle(&dd->next, "::/0");
246  BUG_ON(dd->family == 0);
247 
248  SCLogDebug("address is \'any\'");
249  return 0;
250  }
251 
252  /* handle the negation case */
253  if (ip[0] == '!') {
254  dd->negated = (dd->negated)? 0 : 1;
255  ip++;
256  }
257 
258  /* see if the address is an ipv4 or ipv6 address */
259  if ((strchr(str, ':')) == NULL) {
260  /* IPv4 Address */
261  struct in_addr in;
262 
263  dd->family = AF_INET;
264 
265  if ((mask = strchr(ip, '/')) != NULL) {
266  /* 1.2.3.4/xxx format (either dotted or cidr notation */
267  ip[mask - ip] = '\0';
268  mask++;
269  uint32_t netmask = 0;
270  size_t u = 0;
271 
272  if ((strchr (mask, '.')) == NULL) {
273  /* 1.2.3.4/24 format */
274 
275  for (u = 0; u < strlen(mask); u++) {
276  if(!isdigit((unsigned char)mask[u]))
277  goto error;
278  }
279 
280  uint8_t cidr;
281  if (StringParseU8RangeCheck(&cidr, 10, 0, (const char *)mask, 0, 32) <= 0)
282  goto error;
283 
284  dd->netmask = cidr;
285  netmask = CIDRGet(cidr);
286  } else {
287  /* 1.2.3.4/255.255.255.0 format */
288  r = inet_pton(AF_INET, mask, &in);
289  if (r <= 0)
290  goto error;
291 
292  int cidr = CIDRFromMask(in.s_addr);
293  if (cidr < 0)
294  goto error;
295 
296  dd->netmask = (uint8_t)cidr;
297  }
298 
299  r = inet_pton(AF_INET, ip, &in);
300  if (r <= 0)
301  goto error;
302 
303  dd->ip[0] = in.s_addr & netmask;
304 
305  } else if ((ip2 = strchr(ip, '-')) != NULL) {
306  /* 1.2.3.4-1.2.3.6 range format */
307  ip[ip2 - ip] = '\0';
308  ip2++;
309 
310  uint32_t first, last;
311 
312  r = inet_pton(AF_INET, ip, &in);
313  if (r <= 0)
314  goto error;
315  first = SCNtohl(in.s_addr);
316 
317  r = inet_pton(AF_INET, ip2, &in);
318  if (r <= 0)
319  goto error;
320  last = SCNtohl(in.s_addr);
321 
322  /* a > b is illegal, a = b is ok */
323  if (first > last)
324  goto error;
325 
326  SCLogDebug("Creating CIDR range for [%s - %s]", ip, ip2);
327  return InsertRange(pdd, dd, first, last);
328  } else {
329  /* 1.2.3.4 format */
330  r = inet_pton(AF_INET, ip, &in);
331  if (r <= 0)
332  goto error;
333 
334  /* single host */
335  dd->ip[0] = in.s_addr;
336  dd->netmask = 32;
337  }
338  } else {
339  /* IPv6 Address */
340  struct in6_addr in6, mask6;
341  uint32_t ip6addr[4], netmask[4];
342 
343  dd->family = AF_INET6;
344 
345  if ((mask = strchr(ip, '/')) != NULL) {
346  mask[0] = '\0';
347  mask++;
348 
349  r = inet_pton(AF_INET6, ip, &in6);
350  if (r <= 0)
351  goto error;
352 
353  /* Format is cidr val */
354  if (StringParseU8RangeCheck(&dd->netmask, 10, 0,
355  (const char *)mask, 0, 128) < 0) {
356  goto error;
357  }
358 
359  memcpy(&ip6addr, &in6.s6_addr, sizeof(ip6addr));
360  CIDRGetIPv6(dd->netmask, &mask6);
361  memcpy(&netmask, &mask6.s6_addr, sizeof(netmask));
362 
363  dd->ip[0] = ip6addr[0] & netmask[0];
364  dd->ip[1] = ip6addr[1] & netmask[1];
365  dd->ip[2] = ip6addr[2] & netmask[2];
366  dd->ip[3] = ip6addr[3] & netmask[3];
367  } else {
368  r = inet_pton(AF_INET6, ip, &in6);
369  if (r <= 0)
370  goto error;
371 
372  memcpy(dd->ip, &in6.s6_addr, sizeof(dd->ip));
373  dd->netmask = 128;
374  }
375 
376  }
377 
378  BUG_ON(dd->family == 0);
379  return 0;
380 
381 error:
382  return -1;
383 }
384 
385 /**
386  * \brief Setup a single address string, parse it and add the resulting
387  * Address items in cidr format to the list of gh
388  *
389  * \param gh Pointer to the IPOnlyCIDRItem list Head to which the
390  * resulting Address-Range(s) from the parsed ip string has to
391  * be added.
392  * \param s Pointer to the ip address string to be parsed.
393  *
394  * \retval 0 On success.
395  * \retval -1 On failure.
396  */
397 static int IPOnlyCIDRItemSetup(IPOnlyCIDRItem **gh, char *s)
398 {
399  SCLogDebug("gh %p, s %s", *gh, s);
400 
401  /* parse the address */
402  if (IPOnlyCIDRItemParseSingle(gh, s) == -1) {
403  SCLogError("address parsing error \"%s\"", s);
404  goto error;
405  }
406 
407  return 0;
408 
409 error:
410  return -1;
411 }
412 
413 /**
414  * \brief This function insert a IPOnlyCIDRItem
415  * to a list of IPOnlyCIDRItems
416  * \param head Pointer to the head of IPOnlyCIDRItems list
417  * \param item Pointer to the item to insert in the list
418  *
419  * \retval IPOnlyCIDRItem address of the new head if apply
420  */
421 static IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head,
422  IPOnlyCIDRItem *item)
423 {
424  if (item == NULL)
425  return head;
426 
427  /* Always insert item as head */
428  item->next = head;
429  return item;
430 }
431 
432 /**
433  * \brief This function insert a IPOnlyCIDRItem list
434  * to a list of IPOnlyCIDRItems sorted by netmask
435  * ascending
436  * \param head Pointer to the head of IPOnlyCIDRItems list
437  * \param item Pointer to the list of items to insert in the list
438  *
439  * \retval IPOnlyCIDRItem address of the new head if apply
440  */
441 static IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head,
442  IPOnlyCIDRItem *item)
443 {
444  IPOnlyCIDRItem *it, *prev = NULL;
445 
446  /* The first element */
447  if (head == NULL) {
448  SCLogDebug("Head is NULL to insert item (%p)",item);
449  return item;
450  }
451 
452  if (item == NULL) {
453  SCLogDebug("Item is NULL");
454  return head;
455  }
456 
457  SCLogDebug("Inserting item(%p)->netmask %u head %p", item, item->netmask, head);
458 
459  prev = item;
460  while (prev != NULL) {
461  it = prev->next;
462 
463  /* Separate from the item list */
464  prev->next = NULL;
465 
466  //SCLogDebug("Before:");
467  //IPOnlyCIDRListPrint(head);
468  head = IPOnlyCIDRItemInsertReal(head, prev);
469  //SCLogDebug("After:");
470  //IPOnlyCIDRListPrint(head);
471  prev = it;
472  }
473 
474  return head;
475 }
476 
477 /**
478  * \brief This function free a IPOnlyCIDRItem list
479  * \param tmphead Pointer to the list
480  */
482 {
483  SCEnter();
484 #ifdef DEBUG
485  uint32_t i = 0;
486 #endif
487  IPOnlyCIDRItem *it, *next = NULL;
488 
489  if (tmphead == NULL) {
490  SCLogDebug("temphead is NULL");
491  return;
492  }
493 
494  it = tmphead;
495  next = it->next;
496 
497  while (it != NULL) {
498 #ifdef DEBUG
499  i++;
500  SCLogDebug("Item(%p) %"PRIu32" removed", it, i);
501 #endif
502  SCFree(it);
503  it = next;
504 
505  if (next != NULL)
506  next = next->next;
507  }
508  SCReturn;
509 }
510 
511 /**
512  * \brief This function update a list of IPOnlyCIDRItems
513  * setting the signature internal id (signum) to "i"
514  *
515  * \param tmphead Pointer to the list
516  * \param i number of signature internal id
517  */
518 static void IPOnlyCIDRListSetSigNum(IPOnlyCIDRItem *tmphead, SigIntId i)
519 {
520  while (tmphead != NULL) {
521  tmphead->signum = i;
522  tmphead = tmphead->next;
523  }
524 }
525 
526 #ifdef UNITTESTS
527 /**
528  * \brief This function print a IPOnlyCIDRItem list
529  * \param tmphead Pointer to the head of IPOnlyCIDRItems list
530  */
531 static void IPOnlyCIDRListPrint(IPOnlyCIDRItem *tmphead)
532 {
533 #ifdef DEBUG
534  uint32_t i = 0;
535 
536  while (tmphead != NULL) {
537  i++;
538  SCLogDebug("Item %"PRIu32" has netmask %"PRIu8" negated:"
539  " %s; IP: %s; signum: %"PRIu32, i, tmphead->netmask,
540  (tmphead->negated) ? "yes":"no",
541  inet_ntoa(*(struct in_addr*)&tmphead->ip[0]),
542  tmphead->signum);
543  tmphead = tmphead->next;
544  }
545 #endif
546 }
547 #endif
548 
549 /** \brief user data for storing signature id's in the radix tree
550  *
551  * Bit array representing signature internal id's (Signature::num).
552  */
553 typedef struct SigNumArray_ {
554  uint8_t *array; /* bit array of sig nums */
555  uint32_t size; /* size in bytes of the array */
557 
558 /**
559  * \brief This function print a SigNumArray, it's used with the
560  * radix tree print function to help debugging
561  * \param tmp Pointer to the head of SigNumArray
562  */
563 static void SigNumArrayPrint(void *tmp)
564 {
565  SigNumArray *sna = (SigNumArray *)tmp;
566  for (uint32_t u = 0; u < sna->size; u++) {
567  uint8_t bitarray = sna->array[u];
568  for (uint8_t i = 0; i < 8; i++) {
569  if (bitarray & 0x01)
570  printf("%" PRIu32 " ", u * 8 + i);
571  bitarray = bitarray >> 1;
572  }
573  }
574 }
575 
576 /**
577  * \brief This function creates a new SigNumArray with the
578  * size fixed to the io_ctx->max_idx
579  * \param de_ctx Pointer to the current detection context
580  * \param io_ctx Pointer to the current ip only context
581  *
582  * \retval SigNumArray address of the new instance
583  */
584 static SigNumArray *SigNumArrayNew(DetectEngineCtx *de_ctx,
585  DetectEngineIPOnlyCtx *io_ctx)
586 {
587  SigNumArray *new = SCCalloc(1, sizeof(SigNumArray));
588 
589  if (unlikely(new == NULL)) {
590  FatalError("Fatal error encountered in SigNumArrayNew. Exiting...");
591  }
592 
593  new->array = SCCalloc(1, io_ctx->max_idx / 8 + 1);
594  if (new->array == NULL) {
595  exit(EXIT_FAILURE);
596  }
597 
598  new->size = io_ctx->max_idx / 8 + 1;
599 
600  SCLogDebug("max idx= %u", io_ctx->max_idx);
601 
602  return new;
603 }
604 
605 /**
606  * \brief This function creates a new SigNumArray with the
607  * same data as the argument
608  *
609  * \param orig Pointer to the original SigNumArray to copy
610  *
611  * \retval SigNumArray address of the new instance
612  */
613 static SigNumArray *SigNumArrayCopy(SigNumArray *orig)
614 {
615  SigNumArray *new = SCCalloc(1, sizeof(SigNumArray));
616 
617  if (unlikely(new == NULL)) {
618  FatalError("Fatal error encountered in SigNumArrayCopy. Exiting...");
619  }
620 
621  new->size = orig->size;
622 
623  new->array = SCMalloc(orig->size);
624  if (new->array == NULL) {
625  exit(EXIT_FAILURE);
626  }
627 
628  memcpy(new->array, orig->array, orig->size);
629  return new;
630 }
631 
632 /**
633  * \brief This function free() a SigNumArray
634  * \param orig Pointer to the original SigNumArray to copy
635  */
636 static void SigNumArrayFree(void *tmp)
637 {
638  SigNumArray *sna = (SigNumArray *)tmp;
639 
640  if (sna == NULL)
641  return;
642 
643  if (sna->array != NULL)
644  SCFree(sna->array);
645 
646  SCFree(sna);
647 }
648 
649 /**
650  * \brief This function parses and return a list of IPOnlyCIDRItem
651  *
652  * \param s Pointer to the string of the addresses
653  * (in the format of signatures)
654  * \param negate flag to indicate if all this string is negated or not
655  *
656  * \retval 0 if success
657  * \retval -1 if fails
658  */
659 static IPOnlyCIDRItem *IPOnlyCIDRListParse2(
660  const DetectEngineCtx *de_ctx, const char *s, int negate)
661 {
662  size_t x = 0;
663  size_t u = 0;
664  int o_set = 0, n_set = 0, d_set = 0;
665  int depth = 0;
666  size_t size = strlen(s);
667  char address[8196] = "";
668  const char *rule_var_address = NULL;
669  char *temp_rule_var_address = NULL;
671  IPOnlyCIDRItem *subhead;
672  head = subhead = NULL;
673 
674  SCLogDebug("s %s negate %s", s, negate ? "true" : "false");
675 
676  for (u = 0, x = 0; u < size && x < sizeof(address); u++) {
677  address[x] = s[u];
678  x++;
679 
680  if (!o_set && s[u] == '!') {
681  n_set = 1;
682  x--;
683  } else if (s[u] == '[') {
684  if (!o_set) {
685  o_set = 1;
686  x = 0;
687  }
688  depth++;
689  } else if (s[u] == ']') {
690  if (depth == 1) {
691  address[x - 1] = '\0';
692  x = 0;
693 
694  if ( (subhead = IPOnlyCIDRListParse2(de_ctx, address,
695  (negate + n_set) % 2)) == NULL)
696  goto error;
697 
698  head = IPOnlyCIDRItemInsert(head, subhead);
699  n_set = 0;
700  }
701  depth--;
702  } else if (depth == 0 && s[u] == ',') {
703  if (o_set == 1) {
704  o_set = 0;
705  } else if (d_set == 1) {
706  address[x - 1] = '\0';
707 
708  rule_var_address = SCRuleVarsGetConfVar(de_ctx, address,
710  if (rule_var_address == NULL)
711  goto error;
712 
713  if ((negate + n_set) % 2) {
714  /* add +1 to safisfy gcc 15 + -Wformat-truncation=2 */
715  const size_t str_size = strlen(rule_var_address) + 3 + 1;
716  temp_rule_var_address = SCMalloc(str_size);
717  if (unlikely(temp_rule_var_address == NULL)) {
718  goto error;
719  }
720 
721  snprintf(temp_rule_var_address, str_size, "[%s]", rule_var_address);
722  } else {
723  temp_rule_var_address = SCStrdup(rule_var_address);
724  if (unlikely(temp_rule_var_address == NULL)) {
725  goto error;
726  }
727  }
728 
729  subhead = IPOnlyCIDRListParse2(de_ctx, temp_rule_var_address,
730  (negate + n_set) % 2);
731  head = IPOnlyCIDRItemInsert(head, subhead);
732 
733  d_set = 0;
734  n_set = 0;
735 
736  SCFree(temp_rule_var_address);
737 
738  } else {
739  address[x - 1] = '\0';
740 
741  subhead = IPOnlyCIDRItemNew();
742  if (subhead == NULL)
743  goto error;
744 
745  if (!((negate + n_set) % 2))
746  subhead->negated = 0;
747  else
748  subhead->negated = 1;
749 
750  if (IPOnlyCIDRItemSetup(&subhead, address) < 0) {
751  IPOnlyCIDRListFree(subhead);
752  subhead = NULL;
753  goto error;
754  }
755  head = IPOnlyCIDRItemInsert(head, subhead);
756 
757  n_set = 0;
758  }
759  x = 0;
760  } else if (depth == 0 && s[u] == '$') {
761  d_set = 1;
762  } else if (depth == 0 && u == size - 1) {
763  if (x == sizeof(address)) {
764  address[x - 1] = '\0';
765  } else {
766  address[x] = '\0';
767  }
768  x = 0;
769 
770  if (d_set == 1) {
771  rule_var_address = SCRuleVarsGetConfVar(de_ctx, address,
773  if (rule_var_address == NULL)
774  goto error;
775 
776  if ((negate + n_set) % 2) {
777  /* add +1 to safisfy gcc 15 + -Wformat-truncation=2 */
778  const size_t str_size = strlen(rule_var_address) + 3 + 1;
779  temp_rule_var_address = SCMalloc(str_size);
780  if (unlikely(temp_rule_var_address == NULL)) {
781  goto error;
782  }
783  snprintf(temp_rule_var_address, str_size, "[%s]", rule_var_address);
784  } else {
785  temp_rule_var_address = SCStrdup(rule_var_address);
786  if (unlikely(temp_rule_var_address == NULL)) {
787  goto error;
788  }
789  }
790  subhead = IPOnlyCIDRListParse2(de_ctx, temp_rule_var_address,
791  (negate + n_set) % 2);
792  head = IPOnlyCIDRItemInsert(head, subhead);
793 
794  d_set = 0;
795 
796  SCFree(temp_rule_var_address);
797  } else {
798  subhead = IPOnlyCIDRItemNew();
799  if (subhead == NULL)
800  goto error;
801 
802  if (!((negate + n_set) % 2))
803  subhead->negated = 0;
804  else
805  subhead->negated = 1;
806 
807  if (IPOnlyCIDRItemSetup(&subhead, address) < 0) {
808  IPOnlyCIDRListFree(subhead);
809  subhead = NULL;
810  goto error;
811  }
812  head = IPOnlyCIDRItemInsert(head, subhead);
813  }
814  n_set = 0;
815  }
816  }
817 
818  return head;
819 
820 error:
821  SCLogError("Error parsing addresses");
822  return head;
823 }
824 
825 
826 /**
827  * \brief Parses an address group sent as a character string and updates the
828  * IPOnlyCIDRItem list
829  *
830  * \param gh Pointer to the IPOnlyCIDRItem list
831  * \param str Pointer to the character string containing the address group
832  * that has to be parsed.
833  *
834  * \retval 0 On success.
835  * \retval -1 On failure.
836  */
837 static int IPOnlyCIDRListParse(const DetectEngineCtx *de_ctx, IPOnlyCIDRItem **gh, const char *str)
838 {
839  SCLogDebug("gh %p, str %s", gh, str);
840 
841  if (gh == NULL)
842  goto error;
843 
844  *gh = IPOnlyCIDRListParse2(de_ctx, str, 0);
845  if (*gh == NULL) {
846  SCLogDebug("IPOnlyCIDRListParse2 returned null");
847  goto error;
848  }
849 
850  return 0;
851 
852 error:
853  return -1;
854 }
855 
856 /**
857  * \brief Parses an address group sent as a character string and updates the
858  * IPOnlyCIDRItem lists src and dst of the Signature *s
859  *
860  * \param s Pointer to the signature structure
861  * \param addrstr Pointer to the character string containing the address group
862  * that has to be parsed.
863  * \param flag to indicate if we are parsing the src string or the dst string
864  *
865  * \retval 0 On success.
866  * \retval -1 On failure.
867  */
869  Signature *s, const char *addrstr, char flag)
870 {
871  SCLogDebug("Address Group \"%s\" to be parsed now", addrstr);
872 
873  /* pass on to the address(list) parser */
874  if (flag == 0) {
875  if (strcasecmp(addrstr, "any") == 0) {
876  s->flags |= SIG_FLAG_SRC_ANY;
877  if (IPOnlyCIDRListParse(de_ctx, &s->init_data->cidr_src, "[0.0.0.0/0,::/0]") < 0)
878  goto error;
879 
880  } else if (IPOnlyCIDRListParse(de_ctx, &s->init_data->cidr_src, (char *)addrstr) < 0) {
881  goto error;
882  }
883 
884  /* IPOnlyCIDRListPrint(s->CidrSrc); */
885  } else {
886  if (strcasecmp(addrstr, "any") == 0) {
887  s->flags |= SIG_FLAG_DST_ANY;
888  if (IPOnlyCIDRListParse(de_ctx, &s->init_data->cidr_dst, "[0.0.0.0/0,::/0]") < 0)
889  goto error;
890 
891  } else if (IPOnlyCIDRListParse(de_ctx, &s->init_data->cidr_dst, (char *)addrstr) < 0) {
892  goto error;
893  }
894 
895  /* IPOnlyCIDRListPrint(s->CidrDst); */
896  }
897 
898  return 0;
899 
900 error:
901  SCLogError("failed to parse addresses");
902  return -1;
903 }
904 
905 static const SCRadix4Config iponly_radix4_config = { SigNumArrayFree, SigNumArrayPrint };
906 static const SCRadix6Config iponly_radix6_config = { SigNumArrayFree, SigNumArrayPrint };
907 
908 /**
909  * \brief Setup the IP Only detection engine context
910  *
911  * \param de_ctx Pointer to the current detection engine
912  * \param io_ctx Pointer to the current ip only detection engine
913  */
915 {
920 
921  io_ctx->sig_mapping = SCCalloc(1, de_ctx->sig_array_len * sizeof(uint32_t));
922  if (io_ctx->sig_mapping == NULL) {
923  FatalError("Unable to allocate iponly signature tracking area");
924  }
925  io_ctx->sig_mapping_size = 0;
926 }
927 
929 {
930  SigIntId loc = io_ctx->sig_mapping_size;
931  io_ctx->sig_mapping[loc] = signum;
932  io_ctx->sig_mapping_size++;
933  return loc;
934 }
935 
936 /**
937  * \brief Print stats of the IP Only engine
938  *
939  * \param de_ctx Pointer to the current detection engine
940  * \param io_ctx Pointer to the current ip only detection engine
941  */
943 {
944  /* XXX: how are we going to print the stats now? */
945 }
946 
947 /**
948  * \brief Deinitialize the IP Only detection engine context
949  *
950  * \param de_ctx Pointer to the current detection engine
951  * \param io_ctx Pointer to the current ip only detection engine
952  */
954 {
955 
956  if (io_ctx == NULL)
957  return;
958 
959  SCRadix4TreeRelease(&io_ctx->tree_ipv4src, &iponly_radix4_config);
960  SCRadix4TreeRelease(&io_ctx->tree_ipv4dst, &iponly_radix4_config);
961 
962  SCRadix6TreeRelease(&io_ctx->tree_ipv6src, &iponly_radix6_config);
963  SCRadix6TreeRelease(&io_ctx->tree_ipv6dst, &iponly_radix6_config);
964 
965  if (io_ctx->sig_mapping != NULL)
966  SCFree(io_ctx->sig_mapping);
967  io_ctx->sig_mapping = NULL;
968 }
969 
970 static inline int IPOnlyMatchCompatSMs(
971  ThreadVars *tv, DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p)
972 {
975  while (smd) {
978  if (sigmatch_table[smd->type].Match(det_ctx, p, s, smd->ctx) > 0) {
979  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
980  if (smd->is_last)
981  break;
982  smd++;
983  continue;
984  }
985  KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
986  return 0;
987  }
988  return 1;
989 }
990 
991 /**
992  * \brief Match a packet against the IP Only detection engine contexts
993  *
994  * \param de_ctx Pointer to the current detection engine
995  * \param io_ctx Pointer to the current ip only detection engine
996  * \param io_ctx Pointer to the current ip only thread detection engine
997  * \param p Pointer to the Packet to match against
998  */
1000  DetectEngineThreadCtx *det_ctx, const DetectEngineIPOnlyCtx *io_ctx, Packet *p)
1001 {
1002  SigNumArray *src = NULL;
1003  SigNumArray *dst = NULL;
1004  void *user_data_src = NULL, *user_data_dst = NULL;
1005 
1006  SCEnter();
1007 
1008  if (p->src.family == AF_INET) {
1010  &io_ctx->tree_ipv4src, (uint8_t *)&GET_IPV4_SRC_ADDR_U32(p), &user_data_src);
1011  } else if (p->src.family == AF_INET6) {
1013  &io_ctx->tree_ipv6src, (uint8_t *)&GET_IPV6_SRC_ADDR(p), &user_data_src);
1014  }
1015 
1016  if (p->dst.family == AF_INET) {
1018  &io_ctx->tree_ipv4dst, (uint8_t *)&GET_IPV4_DST_ADDR_U32(p), &user_data_dst);
1019  } else if (p->dst.family == AF_INET6) {
1021  &io_ctx->tree_ipv6dst, (uint8_t *)&GET_IPV6_DST_ADDR(p), &user_data_dst);
1022  }
1023 
1024  src = user_data_src;
1025  dst = user_data_dst;
1026 
1027  if (src == NULL || dst == NULL)
1028  SCReturn;
1029 
1030  for (uint32_t u = 0; u < src->size; u++) {
1031  SCLogDebug("And %"PRIu8" & %"PRIu8, src->array[u], dst->array[u]);
1032 
1033  uint8_t bitarray = dst->array[u] & src->array[u];
1034 
1035  /* We have to move the logic of the signature checking
1036  * to the main detect loop, in order to apply the
1037  * priority of actions (pass, drop, reject, alert) */
1038  if (!bitarray)
1039  continue;
1040 
1041  /* We have a match :) Let's see from which signum's */
1042 
1043  for (uint8_t i = 0; i < 8; i++, bitarray = bitarray >> 1) {
1044  if (bitarray & 0x01) {
1045  const Signature *s = de_ctx->sig_array[io_ctx->sig_mapping[u * 8 + i]];
1046  if (s->proto) {
1047  if ((s->proto->flags & DETECT_PROTO_IPV4) && !PacketIsIPv4(p)) {
1048  SCLogDebug("ip version didn't match");
1049  continue;
1050  }
1051  if ((s->proto->flags & DETECT_PROTO_IPV6) && !PacketIsIPv6(p)) {
1052  SCLogDebug("ip version didn't match");
1053  continue;
1054  }
1055 
1056  if (DetectProtoContainsProto(s->proto, PacketGetIPProto(p)) == 0) {
1057  SCLogDebug("proto didn't match");
1058  continue;
1059  }
1060  }
1061 
1062  /* check the source & dst port in the sig */
1063  if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP ||
1064  p->proto == IPPROTO_SCTP) {
1065  if (!(s->flags & SIG_FLAG_DP_ANY)) {
1066  if (p->flags & PKT_IS_FRAGMENT)
1067  continue;
1068 
1069  const DetectPort *dport = DetectPortLookupGroup(s->dp, p->dp);
1070  if (dport == NULL) {
1071  SCLogDebug("dport didn't match.");
1072  continue;
1073  }
1074  }
1075  if (!(s->flags & SIG_FLAG_SP_ANY)) {
1076  if (p->flags & PKT_IS_FRAGMENT)
1077  continue;
1078 
1079  const DetectPort *sport = DetectPortLookupGroup(s->sp, p->sp);
1080  if (sport == NULL) {
1081  SCLogDebug("sport didn't match.");
1082  continue;
1083  }
1084  }
1085  } else if ((s->flags & (SIG_FLAG_DP_ANY | SIG_FLAG_SP_ANY)) !=
1087  SCLogDebug("port-less protocol and sig needs ports");
1088  continue;
1089  }
1090 
1091  if (!IPOnlyMatchCompatSMs(tv, det_ctx, s, p)) {
1092  continue;
1093  }
1094 
1095  SCLogDebug("Signum %" PRIu32 " match (sid: %" PRIu32 ", msg: %s)", u * 8 + i, s->id,
1096  s->msg);
1097 
1098  if (s->sm_arrays[DETECT_SM_LIST_POSTMATCH] != NULL) {
1101 
1102  SCLogDebug("running match functions, sm %p", smd);
1103 
1104  if (smd != NULL) {
1105  while (1) {
1107  (void)sigmatch_table[smd->type].Match(det_ctx, p, s, smd->ctx);
1108  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
1109  if (smd->is_last)
1110  break;
1111  smd++;
1112  }
1113  }
1114  }
1115  AlertQueueAppendPacket(det_ctx, s, p, 0);
1116  }
1117  }
1118  }
1119  SCReturn;
1120 }
1121 
1122 static void IPOnlyPrepareUpdateBitarray(const IPOnlyCIDRItem *src, SigNumArray *sna)
1123 {
1124  uint8_t tmp = (uint8_t)(1 << (src->signum % 8));
1125  if (src->negated > 0)
1126  /* Unset it */
1127  sna->array[src->signum / 8] &= ~tmp;
1128  else
1129  /* Set it */
1130  sna->array[src->signum / 8] |= tmp;
1131 }
1132 
1133 /**
1134  * \brief Build the radix trees from the lists of parsed addresses in CIDR format
1135  * the result should be 4 radix trees: src/dst ipv4 and src/dst ipv6
1136  * holding SigNumArrays, each of them with a hierarchical relation
1137  * of subnets and hosts
1138  *
1139  * \param de_ctx Pointer to the current detection engine
1140  */
1142 {
1143  SCLogDebug("Preparing Final Lists");
1144 
1145  /*
1146  IPOnlyCIDRListPrint((de_ctx->io_ctx).ip_src);
1147  IPOnlyCIDRListPrint((de_ctx->io_ctx).ip_dst);
1148  */
1149 
1150  IPOnlyCIDRListQSort(&de_ctx->io_ctx.ip_src);
1151  IPOnlyCIDRListQSort(&de_ctx->io_ctx.ip_dst);
1152 
1153  SCRadix4Node *node4 = NULL;
1154  SCRadix6Node *node6 = NULL;
1155 
1156  /* Prepare Src radix trees */
1157  for (IPOnlyCIDRItem *src = de_ctx->io_ctx.ip_src; src != NULL;) {
1158  if (src->family == AF_INET) {
1159  /*
1160  SCLogDebug("To IPv4");
1161  SCLogDebug("Item has netmask %"PRIu16" negated: %s; IP: %s; "
1162  "signum: %"PRIu16, src->netmask,
1163  (src->negated) ? "yes":"no",
1164  inet_ntoa( *(struct in_addr*)&src->ip[0]),
1165  src->signum);
1166  */
1167 
1168  void *user_data = NULL;
1169  if (src->netmask == 32)
1171  &de_ctx->io_ctx.tree_ipv4src, (uint8_t *)&src->ip[0], &user_data);
1172  else
1173  (void)SCRadix4TreeFindNetblock(&de_ctx->io_ctx.tree_ipv4src, (uint8_t *)&src->ip[0],
1174  src->netmask, &user_data);
1175  if (user_data == NULL) {
1176  SCLogDebug("Exact match not found");
1177 
1178  /** Not found, look if there's a subnet of this range with
1179  * bigger netmask */
1181  &de_ctx->io_ctx.tree_ipv4src, (uint8_t *)&src->ip[0], &user_data);
1182  if (user_data == NULL) {
1183  SCLogDebug("best match not found");
1184 
1185  /* Not found, insert a new one */
1186  SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
1187  IPOnlyPrepareUpdateBitarray(src, sna);
1188 
1189  if (src->netmask == 32)
1191  &iponly_radix4_config, (uint8_t *)&src->ip[0], sna);
1192  else
1194  &iponly_radix4_config, (uint8_t *)&src->ip[0], src->netmask, sna);
1195  if (node4 == NULL)
1196  SCLogError("Error inserting in the "
1197  "src ipv4 radix tree");
1198  } else {
1199  SCLogDebug("Best match found");
1200 
1201  /* Found, copy the sig num table, add this signum and insert */
1202  SigNumArray *sna = SigNumArrayCopy((SigNumArray *)user_data);
1203  IPOnlyPrepareUpdateBitarray(src, sna);
1204 
1205  if (src->netmask == 32)
1207  &iponly_radix4_config, (uint8_t *)&src->ip[0], sna);
1208  else
1210  &iponly_radix4_config, (uint8_t *)&src->ip[0], src->netmask, sna);
1211  if (node4 == NULL) {
1212  char tmpstr[64];
1213  PrintInet(src->family, &src->ip[0], tmpstr, sizeof(tmpstr));
1214  SCLogError("Error inserting in the"
1215  " src ipv4 radix tree ip %s netmask %" PRIu8,
1216  tmpstr, src->netmask);
1217  exit(-1);
1218  }
1219  }
1220  } else {
1221  SCLogDebug("Exact match found");
1222 
1223  /* it's already inserted. Update it */
1224  SigNumArray *sna = (SigNumArray *)user_data;
1225  IPOnlyPrepareUpdateBitarray(src, sna);
1226  }
1227  } else if (src->family == AF_INET6) {
1228  SCLogDebug("To IPv6");
1229 
1230  void *user_data = NULL;
1231  if (src->netmask == 128)
1233  &de_ctx->io_ctx.tree_ipv6src, (uint8_t *)&src->ip[0], &user_data);
1234  else
1235  (void)SCRadix6TreeFindNetblock(&de_ctx->io_ctx.tree_ipv6src, (uint8_t *)&src->ip[0],
1236  src->netmask, &user_data);
1237  if (user_data == NULL) {
1238  /* Not found, look if there's a subnet of this range with bigger netmask */
1240  &de_ctx->io_ctx.tree_ipv6src, (uint8_t *)&src->ip[0], &user_data);
1241  if (user_data == NULL) {
1242  /* Not found, insert a new one */
1243  SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
1244  IPOnlyPrepareUpdateBitarray(src, sna);
1245 
1246  if (src->netmask == 128)
1248  &iponly_radix6_config, (uint8_t *)&src->ip[0], sna);
1249  else
1251  &iponly_radix6_config, (uint8_t *)&src->ip[0], src->netmask, sna);
1252  if (node6 == NULL)
1253  SCLogError("Error inserting in the src "
1254  "ipv6 radix tree");
1255  } else {
1256  /* Found, copy the sig num table, add this signum and insert */
1257  SigNumArray *sna = SigNumArrayCopy((SigNumArray *)user_data);
1258  IPOnlyPrepareUpdateBitarray(src, sna);
1259 
1260  if (src->netmask == 128)
1262  &iponly_radix6_config, (uint8_t *)&src->ip[0], sna);
1263  else
1265  &iponly_radix6_config, (uint8_t *)&src->ip[0], src->netmask, sna);
1266  if (node6 == NULL)
1267  SCLogError("Error inserting in the src "
1268  "ipv6 radix tree");
1269  }
1270  } else {
1271  /* it's already inserted. Update it */
1272  SigNumArray *sna = (SigNumArray *)user_data;
1273  IPOnlyPrepareUpdateBitarray(src, sna);
1274  }
1275  }
1276  IPOnlyCIDRItem *tmpaux = src;
1277  src = src->next;
1278  SCFree(tmpaux);
1279  }
1280 
1281  SCLogDebug("dsts:");
1282 
1283  /* Prepare Dst radix trees */
1284  for (IPOnlyCIDRItem *dst = de_ctx->io_ctx.ip_dst; dst != NULL;) {
1285  if (dst->family == AF_INET) {
1286  SCLogDebug("To IPv4");
1287  SCLogDebug("Item has netmask %"PRIu8" negated: %s; IP: %s; signum:"
1288  " %"PRIu32"", dst->netmask, (dst->negated)?"yes":"no",
1289  inet_ntoa(*(struct in_addr*)&dst->ip[0]), dst->signum);
1290 
1291  void *user_data = NULL;
1292  if (dst->netmask == 32)
1294  &de_ctx->io_ctx.tree_ipv4dst, (uint8_t *)&dst->ip[0], &user_data);
1295  else
1296  (void)SCRadix4TreeFindNetblock(&de_ctx->io_ctx.tree_ipv4dst, (uint8_t *)&dst->ip[0],
1297  dst->netmask, &user_data);
1298  if (user_data == NULL) {
1299  SCLogDebug("Exact match not found");
1300 
1301  /**
1302  * Not found, look if there's a subnet of this range
1303  * with bigger netmask
1304  */
1306  &de_ctx->io_ctx.tree_ipv4dst, (uint8_t *)&dst->ip[0], &user_data);
1307  if (user_data == NULL) {
1308  SCLogDebug("Best match not found");
1309 
1310  /** Not found, insert a new one */
1311  SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
1312  IPOnlyPrepareUpdateBitarray(dst, sna);
1313 
1314  if (dst->netmask == 32)
1316  &iponly_radix4_config, (uint8_t *)&dst->ip[0], sna);
1317  else
1319  &iponly_radix4_config, (uint8_t *)&dst->ip[0], dst->netmask, sna);
1320  if (node4 == NULL)
1321  SCLogError("Error inserting in the dst "
1322  "ipv4 radix tree");
1323  } else {
1324  SCLogDebug("Best match found");
1325 
1326  /* Found, copy the sig num table, add this signum and insert */
1327  SigNumArray *sna = SigNumArrayCopy((SigNumArray *)user_data);
1328  IPOnlyPrepareUpdateBitarray(dst, sna);
1329 
1330  if (dst->netmask == 32)
1332  &iponly_radix4_config, (uint8_t *)&dst->ip[0], sna);
1333  else
1335  &iponly_radix4_config, (uint8_t *)&dst->ip[0], dst->netmask, sna);
1336 
1337  if (node4 == NULL)
1338  SCLogError("Error inserting in the dst "
1339  "ipv4 radix tree");
1340  }
1341  } else {
1342  SCLogDebug("Exact match found");
1343 
1344  /* it's already inserted. Update it */
1345  SigNumArray *sna = (SigNumArray *)user_data;
1346  IPOnlyPrepareUpdateBitarray(dst, sna);
1347  }
1348  } else if (dst->family == AF_INET6) {
1349  SCLogDebug("To IPv6");
1350 
1351  void *user_data = NULL;
1352  if (dst->netmask == 128)
1354  &de_ctx->io_ctx.tree_ipv6dst, (uint8_t *)&dst->ip[0], &user_data);
1355  else
1356  (void)SCRadix6TreeFindNetblock(&de_ctx->io_ctx.tree_ipv6dst, (uint8_t *)&dst->ip[0],
1357  dst->netmask, &user_data);
1358  if (user_data == NULL) {
1359  /** Not found, look if there's a subnet of this range with
1360  * bigger netmask
1361  */
1363  &de_ctx->io_ctx.tree_ipv6dst, (uint8_t *)&dst->ip[0], &user_data);
1364  if (user_data == NULL) {
1365  /* Not found, insert a new one */
1366  SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
1367  IPOnlyPrepareUpdateBitarray(dst, sna);
1368 
1369  if (dst->netmask == 128)
1371  &iponly_radix6_config, (uint8_t *)&dst->ip[0], sna);
1372  else
1374  &iponly_radix6_config, (uint8_t *)&dst->ip[0], dst->netmask, sna);
1375  if (node6 == NULL)
1376  SCLogError("Error inserting in the dst "
1377  "ipv6 radix tree");
1378  } else {
1379  /* Found, copy the sig num table, add this signum and insert */
1380  SigNumArray *sna = SigNumArrayCopy((SigNumArray *)user_data);
1381  IPOnlyPrepareUpdateBitarray(dst, sna);
1382 
1383  if (dst->netmask == 128)
1385  &iponly_radix6_config, (uint8_t *)&dst->ip[0], sna);
1386  else
1388  &iponly_radix6_config, (uint8_t *)&dst->ip[0], dst->netmask, sna);
1389  if (node6 == NULL)
1390  SCLogError("Error inserting in the dst "
1391  "ipv6 radix tree");
1392  }
1393  } else {
1394  /* it's already inserted. Update it */
1395  SigNumArray *sna = (SigNumArray *)user_data;
1396  IPOnlyPrepareUpdateBitarray(dst, sna);
1397  }
1398  }
1399  IPOnlyCIDRItem *tmpaux = dst;
1400  dst = dst->next;
1401  SCFree(tmpaux);
1402  }
1403 }
1404 
1405 /**
1406  * \brief Add a signature to the lists of Addresses in CIDR format (sorted)
1407  * this step is necessary to build the radix tree with a hierarchical
1408  * relation between nodes
1409  * \param de_ctx Pointer to the current detection engine context
1410  * \param de_ctx Pointer to the current ip only detection engine contest
1411  * \param s Pointer to the current signature
1412  */
1414  Signature *s)
1415 {
1416  if (!(s->type == SIG_TYPE_IPONLY))
1417  return;
1418 
1419  SigIntId mapped_signum = IPOnlyTrackSigNum(io_ctx, s->iid);
1420  SCLogDebug("Adding IPs from rule: %" PRIu32 " (%s) as %" PRIu32 " mapped to %" PRIu32 "\n",
1421  s->id, s->msg, s->iid, mapped_signum);
1422  /* Set the internal signum to the list before merging */
1423  IPOnlyCIDRListSetSigNum(s->init_data->cidr_src, mapped_signum);
1424 
1425  IPOnlyCIDRListSetSigNum(s->init_data->cidr_dst, mapped_signum);
1426 
1427  /**
1428  * ipv4 and ipv6 are mixed, but later we will separate them into
1429  * different trees
1430  */
1431  io_ctx->ip_src = IPOnlyCIDRItemInsert(io_ctx->ip_src, s->init_data->cidr_src);
1432  io_ctx->ip_dst = IPOnlyCIDRItemInsert(io_ctx->ip_dst, s->init_data->cidr_dst);
1433 
1434  if (mapped_signum > io_ctx->max_idx)
1435  io_ctx->max_idx = mapped_signum;
1436 
1437  /** no longer ref to this, it's in the table now */
1438  s->init_data->cidr_src = NULL;
1439  s->init_data->cidr_dst = NULL;
1440 }
1441 
1442 #ifdef UNITTESTS
1443 /**
1444  * \test check that we set a Signature as IPOnly because it has no rule
1445  * option appending a SigMatch and no port is fixed
1446  */
1447 
1448 static int IPOnlyTestSig01(void)
1449 {
1451  FAIL_IF(de_ctx == NULL);
1452  de_ctx->flags |= DE_QUIET;
1453 
1454  Signature *s = SigInit(de_ctx,"alert tcp any any -> any any (sid:400001; rev:1;)");
1455  FAIL_IF(s == NULL);
1456 
1457  FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
1458  SigFree(de_ctx, s);
1460  PASS;
1461 }
1462 
1463 /**
1464  * \test check that we don't set a Signature as IPOnly because it has no rule
1465  * option appending a SigMatch but a port is fixed
1466  */
1467 
1468 static int IPOnlyTestSig02 (void)
1469 {
1471  FAIL_IF(de_ctx == NULL);
1472  de_ctx->flags |= DE_QUIET;
1473 
1474  Signature *s = SigInit(de_ctx,"alert tcp any any -> any 80 (sid:400001; rev:1;)");
1475  FAIL_IF(s == NULL);
1476 
1477  FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
1478  SigFree(de_ctx, s);
1480  PASS;
1481 }
1482 
1483 /**
1484  * \test check that we set don't set a Signature as IPOnly
1485  * because it has rule options appending a SigMatch like content, and pcre
1486  */
1487 
1488 static int IPOnlyTestSig03 (void)
1489 {
1490  int result = 1;
1492  Signature *s=NULL;
1493 
1495  if (de_ctx == NULL)
1496  goto end;
1497  de_ctx->flags |= DE_QUIET;
1498 
1499  /* combination of pcre and content */
1500  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pcre and content) \"; content:\"php\"; pcre:\"/require(_once)?/i\"; classtype:misc-activity; sid:400001; rev:1;)");
1501  if (s == NULL) {
1502  goto end;
1503  }
1504  if(SignatureIsIPOnly(de_ctx, s))
1505  {
1506  printf("got a IPOnly signature (content): ");
1507  result=0;
1508  }
1509  SigFree(de_ctx, s);
1510 
1511  /* content */
1512  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (content) \"; content:\"match something\"; classtype:misc-activity; sid:400001; rev:1;)");
1513  if (s == NULL) {
1514  goto end;
1515  }
1516  if(SignatureIsIPOnly(de_ctx, s))
1517  {
1518  printf("got a IPOnly signature (content): ");
1519  result=0;
1520  }
1521  SigFree(de_ctx, s);
1522 
1523  /* uricontent */
1524  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (uricontent) \"; uricontent:\"match something\"; classtype:misc-activity; sid:400001; rev:1;)");
1525  if (s == NULL) {
1526  goto end;
1527  }
1528  if(SignatureIsIPOnly(de_ctx, s))
1529  {
1530  printf("got a IPOnly signature (uricontent): ");
1531  result=0;
1532  }
1533  SigFree(de_ctx, s);
1534 
1535  /* pcre */
1536  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pcre) \"; pcre:\"/e?idps rule[sz]/i\"; classtype:misc-activity; sid:400001; rev:1;)");
1537  if (s == NULL) {
1538  goto end;
1539  }
1540  if(SignatureIsIPOnly(de_ctx, s))
1541  {
1542  printf("got a IPOnly signature (pcre): ");
1543  result=0;
1544  }
1545  SigFree(de_ctx, s);
1546 
1547  /* flow */
1548  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flow) \"; flow:to_server; classtype:misc-activity; sid:400001; rev:1;)");
1549  if (s == NULL) {
1550  goto end;
1551  }
1552  if(SignatureIsIPOnly(de_ctx, s))
1553  {
1554  printf("got a IPOnly signature (flow): ");
1555  result=0;
1556  }
1557  SigFree(de_ctx, s);
1558 
1559  /* dsize */
1560  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (dsize) \"; dsize:100; classtype:misc-activity; sid:400001; rev:1;)");
1561  if (s == NULL) {
1562  goto end;
1563  }
1564  if(SignatureIsIPOnly(de_ctx, s))
1565  {
1566  printf("got a IPOnly signature (dsize): ");
1567  result=0;
1568  }
1569  SigFree(de_ctx, s);
1570 
1571  /* flowbits */
1572  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flowbits) \"; flowbits:unset; classtype:misc-activity; sid:400001; rev:1;)");
1573  if (s == NULL) {
1574  goto end;
1575  }
1576  if(SignatureIsIPOnly(de_ctx, s))
1577  {
1578  printf("got a IPOnly signature (flowbits): ");
1579  result=0;
1580  }
1581  SigFree(de_ctx, s);
1582 
1583  /* flowvar */
1584  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (flowvar) \"; pcre:\"/(?<flow_var>.*)/i\"; flowvar:var,\"str\"; classtype:misc-activity; sid:400001; rev:1;)");
1585  if (s == NULL) {
1586  goto end;
1587  }
1588  if(SignatureIsIPOnly(de_ctx, s))
1589  {
1590  printf("got a IPOnly signature (flowvar): ");
1591  result=0;
1592  }
1593  SigFree(de_ctx, s);
1594 
1595  /* pktvar */
1596  s = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest40-03 sig is not IPOnly (pktvar) \"; pcre:\"/(?<pkt_var>.*)/i\"; pktvar:var,\"str\"; classtype:misc-activity; sid:400001; rev:1;)");
1597  if (s == NULL) {
1598  goto end;
1599  }
1600  if(SignatureIsIPOnly(de_ctx, s))
1601  {
1602  printf("got a IPOnly signature (pktvar): ");
1603  result=0;
1604  }
1605  SigFree(de_ctx, s);
1606 
1607 end:
1608  if (de_ctx != NULL)
1610  return result;
1611 }
1612 
1613 /**
1614  * \test
1615  */
1616 static int IPOnlyTestSig04 (void)
1617 {
1618  int result = 1;
1619  IPOnlyCIDRItem *head = NULL;
1620 
1621  // Test a linked list of size 0, 1, 2, ..., 5
1622  for (int size = 0; size < 6; size++) {
1623  IPOnlyCIDRItem *new = NULL;
1624 
1625  if (size > 0) {
1626  new = IPOnlyCIDRItemNew();
1627  new->netmask = 10;
1628  new->ip[0] = 3;
1629 
1630  head = IPOnlyCIDRItemInsert(head, new);
1631  }
1632 
1633  if (size > 1) {
1634  new = IPOnlyCIDRItemNew();
1635  new->netmask = 11;
1636 
1637  head = IPOnlyCIDRItemInsert(head, new);
1638  }
1639 
1640  if (size > 2) {
1641  new = IPOnlyCIDRItemNew();
1642  new->netmask = 9;
1643 
1644  head = IPOnlyCIDRItemInsert(head, new);
1645  }
1646 
1647  if (size > 3) {
1648  new = IPOnlyCIDRItemNew();
1649  new->netmask = 10;
1650  new->ip[0] = 1;
1651 
1652  head = IPOnlyCIDRItemInsert(head, new);
1653  }
1654 
1655  if (size > 4) {
1656  new = IPOnlyCIDRItemNew();
1657  new->netmask = 10;
1658  new->ip[0] = 2;
1659 
1660  head = IPOnlyCIDRItemInsert(head, new);
1661  }
1662 
1663  IPOnlyCIDRListPrint(head);
1664 
1665  IPOnlyCIDRListQSort(&head);
1666 
1667  if (size == 0) {
1668  if (head != NULL) {
1669  result = 0;
1670  goto end;
1671  }
1672  }
1673 
1674  /**
1675  * Validate the following list entries for each size
1676  * 1 - 10
1677  * 2 - 10<3> 11
1678  * 3 - 9 10<3> 11
1679  * 4 - 9 10<1> 10<3> 11
1680  * 5 - 9 10<1> 10<2> 10<3> 11
1681  */
1682  new = head;
1683  if (size >= 3) {
1684  if (new->netmask != 9) {
1685  result = 0;
1686  goto end;
1687  }
1688  new = new->next;
1689  }
1690 
1691  if (size >= 4) {
1692  if (new->netmask != 10 || new->ip[0] != 1) {
1693  result = 0;
1694  goto end;
1695  }
1696  new = new->next;
1697  }
1698 
1699  if (size >= 5) {
1700  if (new->netmask != 10 || new->ip[0] != 2) {
1701  result = 0;
1702  goto end;
1703  }
1704  new = new->next;
1705  }
1706 
1707  if (size >= 1) {
1708  if (new->netmask != 10 || new->ip[0] != 3) {
1709  result = 0;
1710  goto end;
1711  }
1712  new = new->next;
1713  }
1714 
1715  if (size >= 2) {
1716  if (new->netmask != 11) {
1717  result = 0;
1718  goto end;
1719  }
1720  new = new->next;
1721  }
1722 
1723  if (new != NULL) {
1724  result = 0;
1725  goto end;
1726  }
1727 
1729  head = NULL;
1730  }
1731 
1732 end:
1733  if (head) {
1735  head = NULL;
1736  }
1737  return result;
1738 }
1739 
1740 /**
1741  * \test Test a set of ip only signatures making use a lot of
1742  * addresses for src and dst (all should match)
1743  */
1744 static int IPOnlyTestSig05(void)
1745 {
1746  int result = 0;
1747  uint8_t *buf = (uint8_t *)"Hi all!";
1748  uint16_t buflen = strlen((char *)buf);
1749 
1750  uint8_t numpkts = 1;
1751  uint8_t numsigs = 7;
1752 
1753  Packet *p[1];
1754 
1755  p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1756 
1757  const char *sigs[numsigs];
1758  sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1759  sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1760  sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1761  sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1762  sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1763  sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1764  sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)";
1765 
1766  /* Sid numbers (we could extract them from the sig) */
1767  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1768  uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1769 
1770  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1771 
1772  UTHFreePackets(p, numpkts);
1773 
1774  return result;
1775 }
1776 
1777 /**
1778  * \test Test a set of ip only signatures making use a lot of
1779  * addresses for src and dst (none should match)
1780  */
1781 static int IPOnlyTestSig06(void)
1782 {
1783  int result = 0;
1784  uint8_t *buf = (uint8_t *)"Hi all!";
1785  uint16_t buflen = strlen((char *)buf);
1786 
1787  uint8_t numpkts = 1;
1788  uint8_t numsigs = 7;
1789 
1790  Packet *p[1];
1791 
1792  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "80.58.0.33", "195.235.113.3");
1793 
1794  const char *sigs[numsigs];
1795  sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1796  sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1797  sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1798  sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1799  sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1800  sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1801  sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)";
1802 
1803  /* Sid numbers (we could extract them from the sig) */
1804  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1805  uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
1806 
1807  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1808 
1809  UTHFreePackets(p, numpkts);
1810 
1811  return result;
1812 }
1813 
1814 /* \todo fix it. We have disabled this unittest because 599 exposes 608,
1815  * which is why these unittests fail. When we fix 608, we need to renable
1816  * these sigs */
1817 #if 0
1818 /**
1819  * \test Test a set of ip only signatures making use a lot of
1820  * addresses for src and dst (all should match)
1821  */
1822 static int IPOnlyTestSig07(void)
1823 {
1824  int result = 0;
1825  uint8_t *buf = (uint8_t *)"Hi all!";
1826  uint16_t buflen = strlen((char *)buf);
1827 
1828  uint8_t numpkts = 1;
1829  uint8_t numsigs = 7;
1830 
1831  Packet *p[1];
1832 
1833  p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1834 
1835  char *sigs[numsigs];
1836  sigs[0]= "alert tcp 192.168.1.5 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
1837  sigs[1]= "alert tcp [192.168.1.2,192.168.1.5,192.168.1.4] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)";
1838  sigs[2]= "alert tcp [192.168.1.0/24,!192.168.1.1] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1839  sigs[3]= "alert tcp [192.0.0.0/8,!192.168.0.0/16,192.168.1.0/24,!192.168.1.1] any -> [192.168.1.0/24,!192.168.1.5] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1840  sigs[4]= "alert tcp any any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1841  sigs[5]= "alert tcp any any -> [192.168.0.0/16,!192.168.1.0/24,192.168.1.1] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1842  sigs[6]= "alert tcp [78.129.202.0/24,192.168.1.5,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> 192.168.1.1 any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */
1843 
1844  /* Sid numbers (we could extract them from the sig) */
1845  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1846  uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1847 
1848  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1849 
1850  UTHFreePackets(p, numpkts);
1851 
1852  return result;
1853 }
1854 #endif
1855 
1856 /**
1857  * \test Test a set of ip only signatures making use a lot of
1858  * addresses for src and dst (none should match)
1859  */
1860 static int IPOnlyTestSig08(void)
1861 {
1862  int result = 0;
1863  uint8_t *buf = (uint8_t *)"Hi all!";
1864  uint16_t buflen = strlen((char *)buf);
1865 
1866  uint8_t numpkts = 1;
1867  uint8_t numsigs = 7;
1868 
1869  Packet *p[1];
1870 
1871  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"192.168.1.1","192.168.1.5");
1872 
1873  const char *sigs[numsigs];
1874  sigs[0]= "alert tcp 192.168.1.5 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
1875  sigs[1]= "alert tcp [192.168.1.2,192.168.1.5,192.168.1.4] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)";
1876  sigs[2]= "alert tcp [192.168.1.0/24,!192.168.1.1] any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1877  sigs[3]= "alert tcp [192.0.0.0/8,!192.168.0.0/16,192.168.1.0/24,!192.168.1.1] any -> [192.168.1.0/24,!192.168.1.5] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1878  sigs[4]= "alert tcp any any -> !192.168.1.5 any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1879  sigs[5]= "alert tcp any any -> [192.168.0.0/16,!192.168.1.0/24,192.168.1.1] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1880  sigs[6]= "alert tcp [78.129.202.0/24,192.168.1.5,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> 192.168.1.1 any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */
1881 
1882  /* Sid numbers (we could extract them from the sig) */
1883  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1884  uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
1885 
1886  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1887 
1888  UTHFreePackets(p, numpkts);
1889 
1890  return result;
1891 }
1892 
1893 /**
1894  * \test Test a set of ip only signatures making use a lot of
1895  * addresses for src and dst (all should match)
1896  */
1897 static int IPOnlyTestSig09(void)
1898 {
1899  int result = 0;
1900  uint8_t *buf = (uint8_t *)"Hi all!";
1901  uint16_t buflen = strlen((char *)buf);
1902 
1903  uint8_t numpkts = 1;
1904  uint8_t numsigs = 7;
1905 
1906  Packet *p[1];
1907 
1908  p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562");
1909 
1910  const char *sigs[numsigs];
1911  sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1912  sigs[1]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1913  sigs[2]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1914  sigs[3]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:0/96 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1915  sigs[4]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1916  sigs[5]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1917  sigs[6]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)";
1918 
1919  /* Sid numbers (we could extract them from the sig) */
1920  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1921  uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1922 
1923  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1924 
1925  UTHFreePackets(p, numpkts);
1926 
1927  return result;
1928 }
1929 
1930 /**
1931  * \test Test a set of ip only signatures making use a lot of
1932  * addresses for src and dst (none should match)
1933  */
1934 static int IPOnlyTestSig10(void)
1935 {
1936  int result = 0;
1937  uint8_t *buf = (uint8_t *)"Hi all!";
1938  uint16_t buflen = strlen((char *)buf);
1939 
1940  uint8_t numpkts = 1;
1941  uint8_t numsigs = 7;
1942 
1943  Packet *p[1];
1944 
1945  p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565");
1946 
1947  const char *sigs[numsigs];
1948  sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1949  sigs[1]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1950  sigs[2]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1951  sigs[3]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> !3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562/96 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1952  sigs[4]= "alert tcp !3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1953  sigs[5]= "alert tcp any any -> !3FFE:FFFF:7654:FEDA:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1954  sigs[6]= "alert tcp 3FFE:FFFF:7654:FEDA:0:0:0:0/64 any -> 3FFE:FFFF:7654:FEDB:0:0:0:0/64 any (msg:\"Testing src/dst ip (sid 7)\"; content:\"Hi all\";sid:7;)";
1955 
1956  /* Sid numbers (we could extract them from the sig) */
1957  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1958  uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
1959 
1960  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1961 
1962  UTHFreePackets(p, numpkts);
1963 
1964  return result;
1965 }
1966 
1967 /* \todo fix it. We have disabled this unittest because 599 exposes 608,
1968  * which is why these unittests fail. When we fix 608, we need to renable
1969  * these sigs */
1970 #if 0
1971 /**
1972  * \test Test a set of ip only signatures making use a lot of
1973  * addresses for src and dst (all should match) with ipv4 and ipv6 mixed
1974  */
1975 static int IPOnlyTestSig11(void)
1976 {
1977  int result = 0;
1978  uint8_t *buf = (uint8_t *)"Hi all!";
1979  uint16_t buflen = strlen((char *)buf);
1980 
1981  uint8_t numpkts = 2;
1982  uint8_t numsigs = 7;
1983 
1984  Packet *p[2];
1985 
1986  p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565", "3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562");
1987  p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"192.168.1.1","192.168.1.5");
1988 
1989  char *sigs[numsigs];
1990  sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.5 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
1991  sigs[1]= "alert tcp [192.168.1.1,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.4,192.168.1.5,!192.168.1.0/24] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.0/24] any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)";
1992  sigs[2]= "alert tcp [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1993  sigs[3]= "alert tcp [3FFE:FFFF:0:0:0:0:0:0/32,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.0/24,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1994  sigs[4]= "alert tcp any any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1995  sigs[5]= "alert tcp any any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1996  sigs[6]= "alert tcp [78.129.202.0/24,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.0.0.0/8] any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */
1997 
1998  /* Sid numbers (we could extract them from the sig) */
1999  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2000  uint32_t results[2][7] = {{ 1, 1, 1, 1, 1, 1, 1}, { 1, 1, 1, 1, 1, 1, 1}};
2001 
2002  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2003 
2004  UTHFreePackets(p, numpkts);
2005 
2006  return result;
2007 }
2008 #endif
2009 
2010 /**
2011  * \test Test a set of ip only signatures making use a lot of
2012  * addresses for src and dst (none should match) with ipv4 and ipv6 mixed
2013  */
2014 static int IPOnlyTestSig12(void)
2015 {
2016  int result = 0;
2017  uint8_t *buf = (uint8_t *)"Hi all!";
2018  uint16_t buflen = strlen((char *)buf);
2019 
2020  uint8_t numpkts = 2;
2021  uint8_t numsigs = 7;
2022 
2023  Packet *p[2];
2024 
2025  p[0] = UTHBuildPacketIPV6SrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"3FBE:FFFF:7654:FEDA:1245:BA98:3210:4562","3FBE:FFFF:7654:FEDA:1245:BA98:3210:4565");
2026  p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"195.85.1.1","80.198.1.5");
2027 
2028  const char *sigs[numsigs];
2029  sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1 any -> 3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.5 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
2030  sigs[1]= "alert tcp [192.168.1.1,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.4,192.168.1.5,!192.168.1.0/24] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.0/24] any (msg:\"Testing src/dst ip (sid 2)\"; sid:2;)";
2031  sigs[2]= "alert tcp [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
2032  sigs[3]= "alert tcp [3FFE:FFFF:0:0:0:0:0:0/32,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.1] any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,192.168.1.0/24,!3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565] any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
2033  sigs[4]= "alert tcp any any -> [!3FBE:FFFF:7654:FEDA:1245:BA98:3210:4565,!80.198.1.5] any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
2034  sigs[5]= "alert tcp any any -> [3FFE:FFFF:7654:FEDA:0:0:0:0/64,!3FFE:FFFF:7654:FEDA:0:0:0:0/64,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.168.1.5] any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
2035  sigs[6]= "alert tcp [78.129.202.0/24,3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565,192.168.1.1,78.129.205.64,78.129.214.103,78.129.223.19,78.129.233.17,78.137.168.33,78.140.132.11,78.140.133.15,78.140.138.105,78.140.139.105,78.140.141.107,78.140.141.114,78.140.143.103,78.140.143.13,78.140.145.144,78.140.170.164,78.140.23.18,78.143.16.7,78.143.46.124,78.157.129.71] any -> [3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562,192.0.0.0/8] any (msg:\"ET RBN Known Russian Business Network IP TCP - BLOCKING (246)\"; sid:7;)"; /* real sid:"2407490" */
2036 
2037  /* Sid numbers (we could extract them from the sig) */
2038  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2039  uint32_t results[2][7] = {{ 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}};
2040 
2041  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2042 
2043  UTHFreePackets(p, numpkts);
2044 
2045  return result;
2046 }
2047 
2048 static int IPOnlyTestSig13(void)
2049 {
2051  FAIL_IF(de_ctx == NULL);
2052  de_ctx->flags |= DE_QUIET;
2053 
2054  Signature *s = SigInit(de_ctx,
2055  "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; "
2056  "flowbits:set,myflow1; sid:1; rev:1;)");
2057  FAIL_IF(s == NULL);
2058 
2059  FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
2060  SigFree(de_ctx, s);
2062  PASS;
2063 }
2064 
2065 static int IPOnlyTestSig14(void)
2066 {
2068  FAIL_IF(de_ctx == NULL);
2069  de_ctx->flags |= DE_QUIET;
2070 
2071  Signature *s = SigInit(de_ctx,
2072  "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; "
2073  "flowbits:set,myflow1; flowbits:isset,myflow2; sid:1; rev:1;)");
2074  FAIL_IF(s == NULL);
2075 
2076  FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 1);
2077  SigFree(de_ctx, s);
2079  PASS;
2080 }
2081 
2082 static int IPOnlyTestSig15(void)
2083 {
2084  int result = 0;
2085  uint8_t *buf = (uint8_t *)"Hi all!";
2086  uint16_t buflen = strlen((char *)buf);
2087 
2088  uint8_t numpkts = 1;
2089  uint8_t numsigs = 7;
2090 
2091  Packet *p[1];
2092  Flow f;
2093  GenericVar flowvar;
2094  memset(&f, 0, sizeof(Flow));
2095  memset(&flowvar, 0, sizeof(GenericVar));
2096  FLOW_INITIALIZE(&f);
2097 
2098  p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
2099 
2100  p[0]->flow = &f;
2101  p[0]->flow->flowvar = &flowvar;
2102  p[0]->flags |= PKT_HAS_FLOW;
2104 
2105  const char *sigs[numsigs];
2106  sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; "
2107  "flowbits:set,one; sid:1;)";
2108  sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; "
2109  "flowbits:set,two; sid:2;)";
2110  sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; "
2111  "flowbits:set,three; sid:3;)";
2112  sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; "
2113  "flowbits:set,four; sid:4;)";
2114  sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; "
2115  "flowbits:set,five; sid:5;)";
2116  sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; "
2117  "flowbits:set,six; sid:6;)";
2118  sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; "
2119  "flowbits:set,seven; content:\"Hi all\"; sid:7;)";
2120 
2121  /* Sid numbers (we could extract them from the sig) */
2122  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2123  uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
2124 
2125  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2126 
2127  UTHFreePackets(p, numpkts);
2128 
2129  FLOW_DESTROY(&f);
2130  return result;
2131 }
2132 
2133 /**
2134  * \brief Unittest to show #599. We fail to match if we have negated addresses.
2135  */
2136 static int IPOnlyTestSig16(void)
2137 {
2138  int result = 0;
2139  uint8_t *buf = (uint8_t *)"Hi all!";
2140  uint16_t buflen = strlen((char *)buf);
2141 
2142  uint8_t numpkts = 1;
2143  uint8_t numsigs = 2;
2144 
2145  Packet *p[1];
2146 
2147  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "100.100.0.0", "50.0.0.0");
2148 
2149  const char *sigs[numsigs];
2150  sigs[0]= "alert tcp !100.100.0.1 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
2151  sigs[1]= "alert tcp any any -> !50.0.0.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
2152 
2153  /* Sid numbers (we could extract them from the sig) */
2154  uint32_t sid[2] = { 1, 2};
2155  uint32_t results[2] = { 1, 1};
2156 
2157  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2158 
2159  UTHFreePackets(p, numpkts);
2160 
2161  return result;
2162 }
2163 
2164 /**
2165  * \brief Unittest to show #611. Ports on portless protocols.
2166  */
2167 static int IPOnlyTestSig17(void)
2168 {
2169  int result = 0;
2170  uint8_t *buf = (uint8_t *)"Hi all!";
2171  uint16_t buflen = strlen((char *)buf);
2172 
2173  uint8_t numpkts = 1;
2174  uint8_t numsigs = 2;
2175 
2176  Packet *p[1];
2177 
2178  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_ICMP, "100.100.0.0", "50.0.0.0");
2179 
2180  const char *sigs[numsigs];
2181  sigs[0]= "alert ip 100.100.0.0 80 -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
2182  sigs[1]= "alert ip any any -> 50.0.0.0 123 (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
2183 
2184  uint32_t sid[2] = { 1, 2};
2185  uint32_t results[2] = { 0, 0}; /* neither should match */
2186 
2187  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2188 
2189  UTHFreePackets(p, numpkts);
2190 
2191  return result;
2192 }
2193 
2194 /**
2195  * \brief Unittest to show #3568 -- IP address range handling
2196  */
2197 static int IPOnlyTestSig18(void)
2198 {
2199  int result = 0;
2200  uint8_t *buf = (uint8_t *)"Hi all!";
2201  uint16_t buflen = strlen((char *)buf);
2202 
2203  uint8_t numpkts = 4;
2204  uint8_t numsigs = 4;
2205 
2206  Packet *p[4];
2207 
2208  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "10.10.10.1", "50.0.0.1");
2209  p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "220.10.10.1", "5.0.0.1");
2210  p[2] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "0.0.0.1", "50.0.0.1");
2211  p[3] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "255.255.255.254", "5.0.0.1");
2212 
2213  const char *sigs[numsigs];
2214  // really many IP addresses
2215  sigs[0]= "alert ip 1.2.3.4-219.6.7.8 any -> any any (sid:1;)";
2216  sigs[1]= "alert ip 51.2.3.4-253.1.2.3 any -> any any (sid:2;)";
2217  sigs[2]= "alert ip 0.0.0.0-50.0.0.2 any -> any any (sid:3;)";
2218  sigs[3]= "alert ip 50.0.0.0-255.255.255.255 any -> any any (sid:4;)";
2219 
2220  uint32_t sid[4] = { 1, 2, 3, 4, };
2221  uint32_t results[4][4] = {
2222  { 1, 0, 1, 0, }, { 0, 1, 0, 1}, { 0, 0, 1, 0 }, { 0, 0, 0, 1}};
2223 
2224  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2225 
2226  UTHFreePackets(p, numpkts);
2227 
2228  FAIL_IF(result != 1);
2229 
2230  PASS;
2231 }
2232 
2233 /** \test build IP-only tree */
2234 static int IPOnlyTestBug5066v1(void)
2235 {
2237  FAIL_IF(de_ctx == NULL);
2238  de_ctx->flags |= DE_QUIET;
2239 
2241  de_ctx, "alert ip [1.2.3.4/24,1.2.3.64/27] any -> any any (sid:1;)");
2242  FAIL_IF_NULL(s);
2243  s = DetectEngineAppendSig(de_ctx, "alert ip [1.2.3.4/24] any -> any any (sid:2;)");
2244  FAIL_IF_NULL(s);
2245 
2247 
2249  PASS;
2250 }
2251 
2252 static int IPOnlyTestBug5066v2(void)
2253 {
2254  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2255  FAIL_IF_NULL(x);
2256 
2257  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.4/24") != 0);
2258 
2259  char ip[16];
2260  PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2261  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2262 
2263  FAIL_IF_NOT(strcmp(ip, "1.2.3.0") == 0);
2264  FAIL_IF_NOT(x->netmask == 24);
2265 
2266  IPOnlyCIDRListFree(x);
2267  PASS;
2268 }
2269 
2270 static int IPOnlyTestBug5066v3(void)
2271 {
2272  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2273  FAIL_IF_NULL(x);
2274 
2275  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.64/26") != 0);
2276 
2277  char ip[16];
2278  PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2279  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2280 
2281  FAIL_IF_NOT(strcmp(ip, "1.2.3.64") == 0);
2282  FAIL_IF_NOT(x->netmask == 26);
2283 
2284  IPOnlyCIDRListFree(x);
2285  PASS;
2286 }
2287 
2288 static int IPOnlyTestBug5066v4(void)
2289 {
2290  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2291  FAIL_IF_NULL(x);
2292 
2293  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "2000::1:1/122") != 0);
2294 
2295  char ip[64];
2296  PrintInet(AF_INET6, (const void *)&x->ip, ip, sizeof(ip));
2297  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2298 
2299  FAIL_IF_NOT(strcmp(ip, "2000:0000:0000:0000:0000:0000:0001:0000") == 0);
2300  FAIL_IF_NOT(x->netmask == 122);
2301 
2302  IPOnlyCIDRListFree(x);
2303  PASS;
2304 }
2305 
2306 static int IPOnlyTestBug5066v5(void)
2307 {
2308  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2309  FAIL_IF_NULL(x);
2310 
2311  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "2000::1:40/122") != 0);
2312 
2313  char ip[64];
2314  PrintInet(AF_INET6, (const void *)&x->ip, ip, sizeof(ip));
2315  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2316 
2317  FAIL_IF_NOT(strcmp(ip, "2000:0000:0000:0000:0000:0000:0001:0040") == 0);
2318  FAIL_IF_NOT(x->netmask == 122);
2319 
2320  IPOnlyCIDRListFree(x);
2321  PASS;
2322 }
2323 
2324 static int IPOnlyTestBug5168v1(void)
2325 {
2326  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2327  FAIL_IF_NULL(x);
2328 
2329  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.64/0.0.0.0") != 0);
2330 
2331  char ip[16];
2332  PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2333  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2334 
2335  FAIL_IF_NOT(strcmp(ip, "0.0.0.0") == 0);
2336  FAIL_IF_NOT(x->netmask == 0);
2337 
2338  IPOnlyCIDRListFree(x);
2339  PASS;
2340 }
2341 
2342 static int IPOnlyTestBug5168v2(void)
2343 {
2344  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2345  FAIL_IF_NULL(x);
2346  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "0.0.0.5/0.0.0.5") != -1);
2347  IPOnlyCIDRListFree(x);
2348  PASS;
2349 }
2350 
2351 #endif /* UNITTESTS */
2352 
2354 {
2355 #ifdef UNITTESTS
2356  UtRegisterTest("IPOnlyTestSig01", IPOnlyTestSig01);
2357  UtRegisterTest("IPOnlyTestSig02", IPOnlyTestSig02);
2358  UtRegisterTest("IPOnlyTestSig03", IPOnlyTestSig03);
2359  UtRegisterTest("IPOnlyTestSig04", IPOnlyTestSig04);
2360 
2361  UtRegisterTest("IPOnlyTestSig05", IPOnlyTestSig05);
2362  UtRegisterTest("IPOnlyTestSig06", IPOnlyTestSig06);
2363 /* \todo fix it. We have disabled this unittest because 599 exposes 608,
2364  * which is why these unittests fail. When we fix 608, we need to renable
2365  * these sigs */
2366 #if 0
2367  UtRegisterTest("IPOnlyTestSig07", IPOnlyTestSig07, 1);
2368 #endif
2369  UtRegisterTest("IPOnlyTestSig08", IPOnlyTestSig08);
2370 
2371  UtRegisterTest("IPOnlyTestSig09", IPOnlyTestSig09);
2372  UtRegisterTest("IPOnlyTestSig10", IPOnlyTestSig10);
2373 /* \todo fix it. We have disabled this unittest because 599 exposes 608,
2374  * which is why these unittests fail. When we fix 608, we need to renable
2375  * these sigs */
2376 #if 0
2377  UtRegisterTest("IPOnlyTestSig11", IPOnlyTestSig11, 1);
2378 #endif
2379  UtRegisterTest("IPOnlyTestSig12", IPOnlyTestSig12);
2380  UtRegisterTest("IPOnlyTestSig13", IPOnlyTestSig13);
2381  UtRegisterTest("IPOnlyTestSig14", IPOnlyTestSig14);
2382  UtRegisterTest("IPOnlyTestSig15", IPOnlyTestSig15);
2383  UtRegisterTest("IPOnlyTestSig16", IPOnlyTestSig16);
2384 
2385  UtRegisterTest("IPOnlyTestSig17", IPOnlyTestSig17);
2386  UtRegisterTest("IPOnlyTestSig18", IPOnlyTestSig18);
2387 
2388  UtRegisterTest("IPOnlyTestBug5066v1", IPOnlyTestBug5066v1);
2389  UtRegisterTest("IPOnlyTestBug5066v2", IPOnlyTestBug5066v2);
2390  UtRegisterTest("IPOnlyTestBug5066v3", IPOnlyTestBug5066v3);
2391  UtRegisterTest("IPOnlyTestBug5066v4", IPOnlyTestBug5066v4);
2392  UtRegisterTest("IPOnlyTestBug5066v5", IPOnlyTestBug5066v5);
2393 
2394  UtRegisterTest("IPOnlyTestBug5168v1", IPOnlyTestBug5168v1);
2395  UtRegisterTest("IPOnlyTestBug5168v2", IPOnlyTestBug5168v2);
2396 #endif
2397 }
IPOnlyRegisterTests
void IPOnlyRegisterTests(void)
Definition: detect-engine-iponly.c:2353
util-byte.h
Packet_::proto
uint8_t proto
Definition: decode.h:538
len
uint8_t len
Definition: app-layer-dnp3.h:2
SCRadix4Node_
Structure for the node in the radix tree.
Definition: util-radix4-tree.h:36
SCRadix6AddKeyIPV6Netblock
SCRadix6Node * SCRadix6AddKeyIPV6Netblock(SCRadix6Tree *tree, const SCRadix6Config *config, const uint8_t *key_stream, uint8_t netmask, void *user)
Adds a new IPV6 netblock to the Radix6 tree.
Definition: util-radix6-tree.c:213
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
detect-engine-proto.h
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:78
SCRadix6TreeFindExactMatch
SCRadix6Node * SCRadix6TreeFindExactMatch(const SCRadix6Tree *tree, const uint8_t *key, void **user_data)
Definition: util-radix6-tree.c:160
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1311
DetectEngineIPOnlyCtx_::tree_ipv6dst
SCRadix6Tree tree_ipv6dst
Definition: detect.h:879
flow-util.h
DETECT_PROTO_IPV6
#define DETECT_PROTO_IPV6
Definition: detect-engine-proto.h:32
detect-engine-siggroup.h
IPOnlyCIDRItem_::netmask
uint8_t netmask
Definition: detect.h:340
SCRadix6TreeFindBestMatch
SCRadix6Node * SCRadix6TreeFindBestMatch(const SCRadix6Tree *tree, const uint8_t *key, void **user_data)
Definition: util-radix6-tree.c:172
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:2377
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
DetectEngineIPOnlyCtx_::tree_ipv4dst
SCRadix4Tree tree_ipv4dst
Definition: detect.h:878
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:101
KEYWORD_PROFILING_SET_LIST
#define KEYWORD_PROFILING_SET_LIST(ctx, list)
Definition: util-profiling.h:46
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1533
SC_RULE_VARS_ADDRESS_GROUPS
@ SC_RULE_VARS_ADDRESS_GROUPS
Definition: util-rule-vars.h:31
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
IPOnlySigParseAddress
int IPOnlySigParseAddress(const DetectEngineCtx *de_ctx, Signature *s, const char *addrstr, char flag)
Parses an address group sent as a character string and updates the IPOnlyCIDRItem lists src and dst o...
Definition: detect-engine-iponly.c:868
IPOnlyDeinit
void IPOnlyDeinit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx)
Deinitialize the IP Only detection engine context.
Definition: detect-engine-iponly.c:953
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
SigMatchData_::is_last
bool is_last
Definition: detect.h:371
DetectEngineIPOnlyCtx_::ip_src
IPOnlyCIDRItem * ip_src
Definition: detect.h:882
IPOnlyCIDRItem_
Definition: detect.h:336
SCRadix4TreeInitialize
SCRadix4Tree SCRadix4TreeInitialize(void)
Definition: util-radix4-tree.c:165
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:372
Packet_::flags
uint32_t flags
Definition: decode.h:562
CIDRGet
uint32_t CIDRGet(int cidr)
Definition: util-cidr.c:56
Flow_
Flow data structure.
Definition: flow.h:359
UTHBuildPacketSrcDst
Packet * UTHBuildPacketSrcDst(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst)
UTHBuildPacketSrcDst is a wrapper that build packets specifying IPs and defaulting ports.
Definition: util-unittest-helper.c:403
DetectEngineIPOnlyCtx_::tree_ipv4src
SCRadix4Tree tree_ipv4src
Definition: detect.h:878
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:995
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2912
SIG_FLAG_DST_ANY
#define SIG_FLAG_DST_ANY
Definition: detect.h:245
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:236
SCRadix6TreeFindNetblock
SCRadix6Node * SCRadix6TreeFindNetblock(const SCRadix6Tree *tree, const uint8_t *key, const uint8_t netmask, void **user_data)
Definition: util-radix6-tree.c:166
DE_QUIET
#define DE_QUIET
Definition: detect.h:334
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:241
p
Packet * p
Definition: fuzz_dataset.c:30
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:759
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3965
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:547
SIG_FLAG_SRC_ANY
#define SIG_FLAG_SRC_ANY
Definition: detect.h:244
SigMatchData_
Data needed for Match()
Definition: detect.h:369
KEYWORD_PROFILING_START
#define KEYWORD_PROFILING_START
Definition: util-profiling.h:50
SigMatchData_::type
uint16_t type
Definition: detect.h:370
GET_IPV6_DST_ADDR
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:205
DetectEngineIPOnlyCtx_::tree_ipv6src
SCRadix6Tree tree_ipv6src
Definition: detect.h:879
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
SCRadix4TreeRelease
void SCRadix4TreeRelease(SCRadix4Tree *tree, const SCRadix4Config *config)
Definition: util-radix4-tree.c:171
KEYWORD_PROFILING_END
#define KEYWORD_PROFILING_END(ctx, type, m)
Definition: util-profiling.h:64
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
DETECT_SM_LIST_POSTMATCH
@ DETECT_SM_LIST_POSTMATCH
Definition: detect.h:128
util-cidr.h
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:38
decode.h
util-debug.h
SCRadix4TreeFindExactMatch
SCRadix4Node * SCRadix4TreeFindExactMatch(const SCRadix4Tree *tree, const uint8_t *key, void **user_data)
Definition: util-radix4-tree.c:141
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
IPOnlyCIDRItem_::negated
uint8_t negated
Definition: detect.h:342
IPOnlyInit
void IPOnlyInit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx)
Setup the IP Only detection engine context.
Definition: detect-engine-iponly.c:914
DetectEngineThreadCtx_
Definition: detect.h:1316
SIG_TYPE_IPONLY
@ SIG_TYPE_IPONLY
Definition: detect.h:67
PKT_IS_FRAGMENT
#define PKT_IS_FRAGMENT
Definition: decode.h:1335
SignatureInitData_::cidr_dst
IPOnlyCIDRItem * cidr_dst
Definition: detect.h:635
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:238
Packet_::sp
Port sp
Definition: decode.h:523
detect-engine-port.h
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:118
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:3618
DetectPort_
Port structure for detection engine.
Definition: detect.h:223
SignatureInitData_::cidr_src
IPOnlyCIDRItem * cidr_src
Definition: detect.h:635
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:322
IPOnlyPrepare
void IPOnlyPrepare(DetectEngineCtx *de_ctx)
Build the radix trees from the lists of parsed addresses in CIDR format the result should be 4 radix ...
Definition: detect-engine-iponly.c:1141
CIDRFromMask
int CIDRFromMask(uint32_t netmask)
Turn 32 bit mask into CIDR.
Definition: util-cidr.c:34
util-profiling.h
util-rule-vars.h
SigIntId
#define SigIntId
Definition: detect-engine-state.h:38
SCReturn
#define SCReturn
Definition: util-debug.h:286
Signature_::flags
uint32_t flags
Definition: detect.h:693
IPOnlyCIDRItem_::next
struct IPOnlyCIDRItem_ * next
Definition: detect.h:348
DetectEngineIPOnlyCtx_::sig_mapping
uint32_t * sig_mapping
Definition: detect.h:887
Packet_
Definition: decode.h:516
SIGMATCH_IPONLY_COMPAT
#define SIGMATCH_IPONLY_COMPAT
Definition: detect-engine-register.h:310
detect-engine-build.h
IPOnlyPrint
void IPOnlyPrint(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx)
Print stats of the IP Only engine.
Definition: detect-engine-iponly.c:942
detect-engine-alert.h
IPOnlyAddSignature
void IPOnlyAddSignature(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx, Signature *s)
Add a signature to the lists of Addresses in CIDR format (sorted) this step is necessary to build the...
Definition: detect-engine-iponly.c:1413
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:775
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:300
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1504
SCRadix4AddKeyIPV4Netblock
SCRadix4Node * SCRadix4AddKeyIPV4Netblock(SCRadix4Tree *tree, const SCRadix4Config *config, const uint8_t *key_stream, uint8_t netmask, void *user)
Adds a new IPV4 netblock to the Radix4 tree.
Definition: util-radix4-tree.c:205
Signature_::sp
DetectPort * sp
Definition: detect.h:747
StringParseU8RangeCheck
int StringParseU8RangeCheck(uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
Definition: util-byte.c:426
IPOnlyCIDRListFree
void IPOnlyCIDRListFree(IPOnlyCIDRItem *tmphead)
This function free a IPOnlyCIDRItem list.
Definition: detect-engine-iponly.c:481
Flow_::flowvar
GenericVar * flowvar
Definition: flow.h:494
Flow_::next
struct Flow_ * next
Definition: flow.h:406
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2300
SigNumArray_::array
uint8_t * array
Definition: detect-engine-iponly.c:554
DetectEngineIPOnlyCtx_::ip_dst
IPOnlyCIDRItem * ip_dst
Definition: detect.h:882
CIDRGetIPv6
void CIDRGetIPv6(int cidr, struct in6_addr *in6)
Creates a cidr ipv6 netblock, based on the cidr netblock value.
Definition: util-cidr.c:81
DetectProto_::flags
uint8_t flags
Definition: detect-engine-proto.h:40
DETECT_PROTO_IPV4
#define DETECT_PROTO_IPV4
Definition: detect-engine-proto.h:31
Packet_::flow
struct Flow_ * flow
Definition: decode.h:564
SigNumArray_
user data for storing signature id's in the radix tree
Definition: detect-engine-iponly.c:553
SCRadix6Config_
Definition: util-radix6-tree.h:69
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
SCRadix4Config_
Definition: util-radix4-tree.h:71
suricata-common.h
SIG_FLAG_SP_ANY
#define SIG_FLAG_SP_ANY
Definition: detect.h:246
UTHBuildPacketIPV6SrcDst
Packet * UTHBuildPacketIPV6SrcDst(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst)
UTHBuildPacketSrcDst is a wrapper that build packets specifying IPs and defaulting ports (IPV6)
Definition: util-unittest-helper.c:421
GenericVar_
Definition: util-var.h:53
SCRadix6AddKeyIPV6
SCRadix6Node * SCRadix6AddKeyIPV6(SCRadix6Tree *tree, const SCRadix6Config *config, const uint8_t *key_stream, void *user)
Adds a new IPV6 address to the Radix6 tree.
Definition: util-radix6-tree.c:195
IPOnlyCIDRItem_::ip
uint32_t ip[4]
Definition: detect.h:344
Signature_::proto
DetectProto * proto
Definition: detect.h:711
util-classification-config.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(...)
Definition: util-debug.h:517
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:34
SCRadix4TreeFindBestMatch
SCRadix4Node * SCRadix4TreeFindBestMatch(const SCRadix4Tree *tree, const uint8_t *key, void **user_data)
Definition: util-radix4-tree.c:153
DetectEngineIPOnlyCtx_::sig_mapping_size
uint32_t sig_mapping_size
Definition: detect.h:888
SCRadix6Node_
Structure for the node in the radix tree.
Definition: util-radix6-tree.h:36
UTHGenericTest
int UTHGenericTest(Packet **pkt, int numpkts, const char *sigs[], uint32_t sids[], uint32_t *results, int numsigs)
UTHGenericTest: function that perform a generic check taking care of as maximum common unittest eleme...
Definition: util-unittest-helper.c:578
AlertQueueAppendPacket
void AlertQueueAppendPacket(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p, uint8_t alert_flags)
Append signature to local packet alert queue for later preprocessing.
Definition: detect-engine-alert.c:445
util-validate.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
HtpBodyChunk_::next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:124
Signature_::dp
DetectPort * dp
Definition: detect.h:747
str
#define str(s)
Definition: suricata-common.h:313
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
Signature_::iid
SigIntId iid
Definition: detect.h:704
head
Flow * head
Definition: flow-hash.h:1
GET_IPV6_SRC_ADDR
#define GET_IPV6_SRC_ADDR(p)
Definition: decode.h:204
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SignatureIsIPOnly
int SignatureIsIPOnly(DetectEngineCtx *de_ctx, const Signature *s)
Test is a initialized signature is IP only.
Definition: detect-engine-build.c:191
SCNtohl
#define SCNtohl(x)
Definition: suricata-common.h:435
IPOnlyTrackSigNum
SigIntId IPOnlyTrackSigNum(DetectEngineIPOnlyCtx *io_ctx, SigIntId signum)
Definition: detect-engine-iponly.c:928
SCRadix4AddKeyIPV4
SCRadix4Node * SCRadix4AddKeyIPV4(SCRadix4Tree *tree, const SCRadix4Config *config, const uint8_t *key_stream, void *user)
Adds a new IPV4 address to the Radix4 tree.
Definition: util-radix4-tree.c:187
Signature_::id
uint32_t id
Definition: detect.h:741
detect-engine-iponly.h
detect-parse.h
src
uint16_t src
Definition: app-layer-dnp3.h:5
Signature_
Signature container.
Definition: detect.h:692
detect-threshold.h
address
uint8_t address
Definition: decode-ppp.h:0
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2873
SCRadix6TreeInitialize
SCRadix6Tree SCRadix6TreeInitialize(void)
Definition: util-radix6-tree.c:359
IPOnlyMatchPacket
void IPOnlyMatchPacket(ThreadVars *tv, const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectEngineIPOnlyCtx *io_ctx, Packet *p)
Match a packet against the IP Only detection engine contexts.
Definition: detect-engine-iponly.c:999
DetectEngineCtx_::sig_array
Signature ** sig_array
Definition: detect.h:1014
Address_::family
char family
Definition: decode.h:114
Packet_::dst
Address dst
Definition: decode.h:521
SigNumArray
struct SigNumArray_ SigNumArray
user data for storing signature id's in the radix tree
DetectEngineIPOnlyCtx_
IP only rules matching ctx.
Definition: detect.h:876
SCRadix6TreeRelease
void SCRadix6TreeRelease(SCRadix6Tree *tree, const SCRadix6Config *config)
Definition: util-radix6-tree.c:365
IPPROTO_SCTP
#define IPPROTO_SCTP
Definition: decode.h:1273
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:997
GET_IPV4_SRC_ADDR_U32
#define GET_IPV4_SRC_ADDR_U32(p)
Definition: decode.h:197
DetectEngineCtx_::io_ctx
DetectEngineIPOnlyCtx io_ctx
Definition: detect.h:1037
GET_IPV4_DST_ADDR_U32
#define GET_IPV4_DST_ADDR_U32(p)
Definition: decode.h:198
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
SigNumArray_::size
uint32_t size
Definition: detect-engine-iponly.c:555
Signature_::msg
char * msg
Definition: detect.h:764
flow.h
Packet_::dp
Port dp
Definition: decode.h:531
SCRuleVarsGetConfVar
const char * SCRuleVarsGetConfVar(const DetectEngineCtx *de_ctx, const char *conf_var_name, SCRuleVarsType conf_vars_type)
Definition: util-rule-vars.c:64
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DetectEngineCtx_::sig_array_len
uint32_t sig_array_len
Definition: detect.h:1015
Signature_::type
enum SignatureType type
Definition: detect.h:695
IPOnlyCIDRItem_::signum
SigIntId signum
Definition: detect.h:345
FLOW_PKT_TOSERVER_FIRST
#define FLOW_PKT_TOSERVER_FIRST
Definition: flow.h:239
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:119
detect-engine-address.h
Packet_::src
Address src
Definition: decode.h:520
IPOnlyCIDRItem_::family
uint8_t family
Definition: detect.h:338
SIG_FLAG_DP_ANY
#define SIG_FLAG_DP_ANY
Definition: detect.h:247
DetectPortLookupGroup
DetectPort * DetectPortLookupGroup(DetectPort *dp, uint16_t port)
Function that find the group matching port in a group head.
Definition: detect-engine-port.c:584
detect-engine-threshold.h
f
Flow f
Definition: fuzz_dataset.c:32
SCRadix4TreeFindNetblock
SCRadix4Node * SCRadix4TreeFindNetblock(const SCRadix4Tree *tree, const uint8_t *key, const uint8_t netmask, void **user_data)
Definition: util-radix4-tree.c:147
DetectEngineIPOnlyCtx_::max_idx
uint32_t max_idx
Definition: detect.h:883
DetectProtoContainsProto
int DetectProtoContainsProto(const DetectProto *dp, int proto)
see if a DetectProto contains a certain proto
Definition: detect-engine-proto.c:114
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:453