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