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