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 "debug.h"
32 #include "detect.h"
33 #include "decode.h"
34 #include "flow.h"
35 
36 #include "detect-parse.h"
37 #include "detect-engine.h"
38 
39 #include "detect-engine-siggroup.h"
40 #include "detect-engine-address.h"
41 #include "detect-engine-proto.h"
42 #include "detect-engine-port.h"
43 #include "detect-engine-mpm.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) {
343  "address parsing error \"%s\"", s);
344  goto error;
345  }
346 
347  return 0;
348 
349 error:
350  return -1;
351 }
352 
353 
354 /**
355  * \brief This function insert a IPOnlyCIDRItem
356  * to a list of IPOnlyCIDRItems sorted by netmask
357  * ascending
358  * \param head Pointer to the head of IPOnlyCIDRItems list
359  * \param item Pointer to the item to insert in the list
360  *
361  * \retval IPOnlyCIDRItem address of the new head if apply
362  */
363 static IPOnlyCIDRItem *IPOnlyCIDRItemInsertReal(IPOnlyCIDRItem *head,
364  IPOnlyCIDRItem *item)
365 {
366  IPOnlyCIDRItem *it, *prev = NULL;
367 
368  if (item == NULL)
369  return head;
370 
371  /* Compare with the head */
372  if (item->netmask < head->netmask || (item->netmask == head->netmask && IPOnlyCIDRItemCompare(head, item))) {
373  item->next = head;
374  return item;
375  }
376 
377  if (item->netmask == head->netmask && !IPOnlyCIDRItemCompare(head, item)) {
378  item->next = head->next;
379  head->next = item;
380  return head;
381  }
382 
383  for (prev = it = head;
384  it != NULL && it->netmask < item->netmask;
385  it = it->next)
386  prev = it;
387 
388  if (it == NULL) {
389  prev->next = item;
390  item->next = NULL;
391  } else {
392  item->next = it;
393  prev->next = item;
394  }
395 
396  return head;
397 }
398 
399 /**
400  * \brief This function insert a IPOnlyCIDRItem list
401  * to a list of IPOnlyCIDRItems sorted by netmask
402  * ascending
403  * \param head Pointer to the head of IPOnlyCIDRItems list
404  * \param item Pointer to the list of items to insert in the list
405  *
406  * \retval IPOnlyCIDRItem address of the new head if apply
407  */
408 static IPOnlyCIDRItem *IPOnlyCIDRItemInsert(IPOnlyCIDRItem *head,
409  IPOnlyCIDRItem *item)
410 {
411  IPOnlyCIDRItem *it, *prev = NULL;
412 
413  /* The first element */
414  if (head == NULL) {
415  SCLogDebug("Head is NULL to insert item (%p)",item);
416  return item;
417  }
418 
419  if (item == NULL) {
420  SCLogDebug("Item is NULL");
421  return head;
422  }
423 
424  SCLogDebug("Inserting item(%p)->netmask %u head %p", item, item->netmask, head);
425 
426  prev = item;
427  while (prev != NULL) {
428  it = prev->next;
429 
430  /* Separate from the item list */
431  prev->next = NULL;
432 
433  //SCLogDebug("Before:");
434  //IPOnlyCIDRListPrint(head);
435  head = IPOnlyCIDRItemInsertReal(head, prev);
436  //SCLogDebug("After:");
437  //IPOnlyCIDRListPrint(head);
438  prev = it;
439  }
440 
441  return head;
442 }
443 
444 /**
445  * \brief This function free a IPOnlyCIDRItem list
446  * \param tmphead Pointer to the list
447  */
449 {
450  SCEnter();
451  uint32_t i = 0;
452 
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  i++;
465  SCLogDebug("Item(%p) %"PRIu32" removed", it, i);
466  SCFree(it);
467  it = next;
468 
469  if (next != NULL)
470  next = next->next;
471  }
472  SCReturn;
473 }
474 
475 /**
476  * \brief This function update a list of IPOnlyCIDRItems
477  * setting the signature internal id (signum) to "i"
478  *
479  * \param tmphead Pointer to the list
480  * \param i number of signature internal id
481  */
482 static void IPOnlyCIDRListSetSigNum(IPOnlyCIDRItem *tmphead, SigIntId i)
483 {
484  while (tmphead != NULL) {
485  tmphead->signum = i;
486  tmphead = tmphead->next;
487  }
488 }
489 
490 #ifdef UNITTESTS
491 /**
492  * \brief This function print a IPOnlyCIDRItem list
493  * \param tmphead Pointer to the head of IPOnlyCIDRItems list
494  */
495 static void IPOnlyCIDRListPrint(IPOnlyCIDRItem *tmphead)
496 {
497  uint32_t i = 0;
498 
499  while (tmphead != NULL) {
500  i++;
501  SCLogDebug("Item %"PRIu32" has netmask %"PRIu8" negated:"
502  " %s; IP: %s; signum: %"PRIu32, i, tmphead->netmask,
503  (tmphead->negated) ? "yes":"no",
504  inet_ntoa(*(struct in_addr*)&tmphead->ip[0]),
505  tmphead->signum);
506  tmphead = tmphead->next;
507  }
508 }
509 #endif
510 
511 /** \brief user data for storing signature id's in the radix tree
512  *
513  * Bit array representing signature internal id's (Signature::num).
514  */
515 typedef struct SigNumArray_ {
516  uint8_t *array; /* bit array of sig nums */
517  uint32_t size; /* size in bytes of the array */
519 
520 /**
521  * \brief This function print a SigNumArray, it's used with the
522  * radix tree print function to help debugging
523  * \param tmp Pointer to the head of SigNumArray
524  */
525 static void SigNumArrayPrint(void *tmp)
526 {
527  SigNumArray *sna = (SigNumArray *)tmp;
528  for (uint32_t u = 0; u < sna->size; u++) {
529  uint8_t bitarray = sna->array[u];
530  for (uint8_t i = 0; i < 8; i++) {
531  if (bitarray & 0x01)
532  printf("%" PRIu32 " ", u * 8 + i);
533  bitarray = bitarray >> 1;
534  }
535  }
536 }
537 
538 /**
539  * \brief This function creates a new SigNumArray with the
540  * size fixed to the io_ctx->max_idx
541  * \param de_ctx Pointer to the current detection context
542  * \param io_ctx Pointer to the current ip only context
543  *
544  * \retval SigNumArray address of the new instance
545  */
546 static SigNumArray *SigNumArrayNew(DetectEngineCtx *de_ctx,
547  DetectEngineIPOnlyCtx *io_ctx)
548 {
549  SigNumArray *new = SCMalloc(sizeof(SigNumArray));
550 
551  if (unlikely(new == NULL)) {
553  "Fatal error encountered in SigNumArrayNew. Exiting...");
554  }
555  memset(new, 0, sizeof(SigNumArray));
556 
557  new->array = SCMalloc(io_ctx->max_idx / 8 + 1);
558  if (new->array == NULL) {
559  exit(EXIT_FAILURE);
560  }
561 
562  memset(new->array, 0, io_ctx->max_idx / 8 + 1);
563  new->size = io_ctx->max_idx / 8 + 1;
564 
565  SCLogDebug("max idx= %u", io_ctx->max_idx);
566 
567  return new;
568 }
569 
570 /**
571  * \brief This function creates a new SigNumArray with the
572  * same data as the argument
573  *
574  * \param orig Pointer to the original SigNumArray to copy
575  *
576  * \retval SigNumArray address of the new instance
577  */
578 static SigNumArray *SigNumArrayCopy(SigNumArray *orig)
579 {
580  SigNumArray *new = SCMalloc(sizeof(SigNumArray));
581 
582  if (unlikely(new == NULL)) {
584  "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(SC_ERR_ADDRESS_ENGINE_GENERIC,"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(SC_ERR_ADDRESS_ENGINE_GENERIC, "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,
879  SigNumArrayPrint);
880  io_ctx->tree_ipv4dst = SCRadixCreateRadixTree(SigNumArrayFree,
881  SigNumArrayPrint);
882  io_ctx->tree_ipv6src = SCRadixCreateRadixTree(SigNumArrayFree,
883  SigNumArrayPrint);
884  io_ctx->tree_ipv6dst = SCRadixCreateRadixTree(SigNumArrayFree,
885  SigNumArrayPrint);
886 }
887 
888 /**
889  * \brief Setup the IP Only thread detection engine context
890  *
891  * \param de_ctx Pointer to the current detection engine
892  * \param io_ctx Pointer to the current ip only thread detection engine
893  */
896 {
897  /* initialize the signature bitarray */
898  io_tctx->sig_match_size = de_ctx->io_ctx.max_idx / 8 + 1;
899  io_tctx->sig_match_array = SCMalloc(io_tctx->sig_match_size);
900  if (io_tctx->sig_match_array == NULL) {
901  exit(EXIT_FAILURE);
902  }
903 
904  memset(io_tctx->sig_match_array, 0, io_tctx->sig_match_size);
905 }
906 
907 /**
908  * \brief Print stats of the IP Only engine
909  *
910  * \param de_ctx Pointer to the current detection engine
911  * \param io_ctx Pointer to the current ip only detection engine
912  */
914 {
915  /* XXX: how are we going to print the stats now? */
916 }
917 
918 /**
919  * \brief Deinitialize the IP Only detection engine context
920  *
921  * \param de_ctx Pointer to the current detection engine
922  * \param io_ctx Pointer to the current ip only detection engine
923  */
925 {
926 
927  if (io_ctx == NULL)
928  return;
929 
930  if (io_ctx->tree_ipv4src != NULL)
932  io_ctx->tree_ipv4src = NULL;
933 
934  if (io_ctx->tree_ipv4dst != NULL)
936  io_ctx->tree_ipv4dst = NULL;
937 
938  if (io_ctx->tree_ipv6src != NULL)
940  io_ctx->tree_ipv6src = NULL;
941 
942  if (io_ctx->tree_ipv6dst != NULL)
944  io_ctx->tree_ipv6dst = NULL;
945 }
946 
947 /**
948  * \brief Deinitialize the IP Only thread detection engine context
949  *
950  * \param de_ctx Pointer to the current detection engine
951  * \param io_ctx Pointer to the current ip only detection engine
952  */
954 {
955  SCFree(io_tctx->sig_match_array);
956 }
957 
958 static inline
959 int IPOnlyMatchCompatSMs(ThreadVars *tv,
960  DetectEngineThreadCtx *det_ctx,
961  Signature *s, Packet *p)
962 {
965  if (smd) {
966  while (1) {
969  if (sigmatch_table[smd->type].Match(det_ctx, p, s, smd->ctx) > 0) {
970  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
971  if (smd->is_last)
972  break;
973  smd++;
974  continue;
975  }
976  KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
977  return 0;
978  }
979  }
980  return 1;
981 }
982 
983 /**
984  * \brief Match a packet against the IP Only detection engine contexts
985  *
986  * \param de_ctx Pointer to the current detection engine
987  * \param io_ctx Pointer to the current ip only detection engine
988  * \param io_ctx Pointer to the current ip only thread detection engine
989  * \param p Pointer to the Packet to match against
990  */
992  const DetectEngineCtx *de_ctx,
993  DetectEngineThreadCtx *det_ctx,
994  const DetectEngineIPOnlyCtx *io_ctx,
995  DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p)
996 {
997  SigNumArray *src = NULL;
998  SigNumArray *dst = NULL;
999  void *user_data_src = NULL, *user_data_dst = NULL;
1000 
1001  SCEnter();
1002 
1003  if (p->src.family == AF_INET) {
1005  io_ctx->tree_ipv4src, &user_data_src);
1006  } else if (p->src.family == AF_INET6) {
1007  (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)&GET_IPV6_SRC_ADDR(p),
1008  io_ctx->tree_ipv6src, &user_data_src);
1009  }
1010 
1011  if (p->dst.family == AF_INET) {
1013  io_ctx->tree_ipv4dst, &user_data_dst);
1014  } else if (p->dst.family == AF_INET6) {
1015  (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)&GET_IPV6_DST_ADDR(p),
1016  io_ctx->tree_ipv6dst, &user_data_dst);
1017  }
1018 
1019  src = user_data_src;
1020  dst = user_data_dst;
1021 
1022  if (src == NULL || dst == NULL)
1023  SCReturn;
1024 
1025  uint32_t u;
1026  for (u = 0; u < src->size; u++) {
1027  SCLogDebug("And %"PRIu8" & %"PRIu8, src->array[u], dst->array[u]);
1028 
1029  /* The final results will be at io_tctx */
1030  io_tctx->sig_match_array[u] = dst->array[u] & src->array[u];
1031 
1032  /* We have to move the logic of the signature checking
1033  * to the main detect loop, in order to apply the
1034  * priority of actions (pass, drop, reject, alert) */
1035  if (io_tctx->sig_match_array[u] != 0) {
1036  /* We have a match :) Let's see from which signum's */
1037  uint8_t bitarray = io_tctx->sig_match_array[u];
1038  uint8_t i = 0;
1039 
1040  for (; i < 8; i++, bitarray = bitarray >> 1) {
1041  if (bitarray & 0x01) {
1042  Signature *s = de_ctx->sig_array[u * 8 + i];
1043 
1044  if ((s->proto.flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) {
1045  SCLogDebug("ip version didn't match");
1046  continue;
1047  }
1048  if ((s->proto.flags & DETECT_PROTO_IPV6) && !PKT_IS_IPV6(p)) {
1049  SCLogDebug("ip version didn't match");
1050  continue;
1051  }
1052 
1053  if (DetectProtoContainsProto(&s->proto, IP_GET_IPPROTO(p)) == 0) {
1054  SCLogDebug("proto didn't match");
1055  continue;
1056  }
1057 
1058  /* check the source & dst port in the sig */
1059  if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) {
1060  if (!(s->flags & SIG_FLAG_DP_ANY)) {
1061  if (p->flags & PKT_IS_FRAGMENT)
1062  continue;
1063 
1064  DetectPort *dport = DetectPortLookupGroup(s->dp,p->dp);
1065  if (dport == NULL) {
1066  SCLogDebug("dport didn't match.");
1067  continue;
1068  }
1069  }
1070  if (!(s->flags & SIG_FLAG_SP_ANY)) {
1071  if (p->flags & PKT_IS_FRAGMENT)
1072  continue;
1073 
1074  DetectPort *sport = DetectPortLookupGroup(s->sp,p->sp);
1075  if (sport == NULL) {
1076  SCLogDebug("sport didn't match.");
1077  continue;
1078  }
1079  }
1081  SCLogDebug("port-less protocol and sig needs ports");
1082  continue;
1083  }
1084 
1085  if (!IPOnlyMatchCompatSMs(tv, det_ctx, s, p)) {
1086  continue;
1087  }
1088 
1089  SCLogDebug("Signum %"PRIu32" match (sid: %"PRIu32", msg: %s)",
1090  u * 8 + i, s->id, s->msg);
1091 
1092  if (s->sm_arrays[DETECT_SM_LIST_POSTMATCH] != NULL) {
1095 
1096  SCLogDebug("running match functions, sm %p", smd);
1097 
1098  if (smd != NULL) {
1099  while (1) {
1101  (void)sigmatch_table[smd->type].Match(det_ctx, p, s, smd->ctx);
1102  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
1103  if (smd->is_last)
1104  break;
1105  smd++;
1106  }
1107  }
1108  }
1109  AlertQueueAppend(det_ctx, s, p, 0, 0);
1110  }
1111  }
1112  }
1113  }
1114  SCReturn;
1115 }
1116 
1117 /**
1118  * \brief Build the radix trees from the lists of parsed addresses in CIDR format
1119  * the result should be 4 radix trees: src/dst ipv4 and src/dst ipv6
1120  * holding SigNumArrays, each of them with a hierarchical relation
1121  * of subnets and hosts
1122  *
1123  * \param de_ctx Pointer to the current detection engine
1124  */
1126 {
1127  SCLogDebug("Preparing Final Lists");
1128 
1129  /*
1130  IPOnlyCIDRListPrint((de_ctx->io_ctx).ip_src);
1131  IPOnlyCIDRListPrint((de_ctx->io_ctx).ip_dst);
1132  */
1133 
1134  IPOnlyCIDRItem *src, *dst;
1135  SCRadixNode *node = NULL;
1136 
1137  /* Prepare Src radix trees */
1138  for (src = (de_ctx->io_ctx).ip_src; src != NULL; ) {
1139  if (src->family == AF_INET) {
1140  /*
1141  SCLogDebug("To IPv4");
1142  SCLogDebug("Item has netmask %"PRIu16" negated: %s; IP: %s; "
1143  "signum: %"PRIu16, src->netmask,
1144  (src->negated) ? "yes":"no",
1145  inet_ntoa( *(struct in_addr*)&src->ip[0]),
1146  src->signum);
1147  */
1148 
1149  void *user_data = NULL;
1150  if (src->netmask == 32)
1151  (void)SCRadixFindKeyIPV4ExactMatch((uint8_t *)&src->ip[0],
1152  (de_ctx->io_ctx).tree_ipv4src,
1153  &user_data);
1154  else
1155  (void)SCRadixFindKeyIPV4Netblock((uint8_t *)&src->ip[0],
1156  (de_ctx->io_ctx).tree_ipv4src,
1157  src->netmask, &user_data);
1158  if (user_data == NULL) {
1159  SCLogDebug("Exact match not found");
1160 
1161  /** Not found, look if there's a subnet of this range with
1162  * bigger netmask */
1163  (void)SCRadixFindKeyIPV4BestMatch((uint8_t *)&src->ip[0],
1164  (de_ctx->io_ctx).tree_ipv4src,
1165  &user_data);
1166  if (user_data == NULL) {
1167  SCLogDebug("best match not found");
1168 
1169  /* Not found, insert a new one */
1170  SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
1171 
1172  /* Update the sig */
1173  uint8_t tmp = (uint8_t)(1 << (src->signum % 8));
1174 
1175  if (src->negated > 0)
1176  /* Unset it */
1177  sna->array[src->signum / 8] &= ~tmp;
1178  else
1179  /* Set it */
1180  sna->array[src->signum / 8] |= tmp;
1181 
1182  if (src->netmask == 32)
1183  node = SCRadixAddKeyIPV4((uint8_t *)&src->ip[0],
1184  (de_ctx->io_ctx).tree_ipv4src, sna);
1185  else
1186  node = SCRadixAddKeyIPV4Netblock((uint8_t *)&src->ip[0],
1187  (de_ctx->io_ctx).tree_ipv4src,
1188  sna, src->netmask);
1189 
1190  if (node == NULL)
1191  SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the "
1192  "src ipv4 radix tree");
1193  } else {
1194  SCLogDebug("Best match found");
1195 
1196  /* Found, copy the sig num table, add this signum and insert */
1197  SigNumArray *sna = NULL;
1198  sna = SigNumArrayCopy((SigNumArray *) user_data);
1199 
1200  /* Update the sig */
1201  uint8_t tmp = (uint8_t)(1 << (src->signum % 8));
1202 
1203  if (src->negated > 0)
1204  /* Unset it */
1205  sna->array[src->signum / 8] &= ~tmp;
1206  else
1207  /* Set it */
1208  sna->array[src->signum / 8] |= tmp;
1209 
1210  if (src->netmask == 32)
1211  node = SCRadixAddKeyIPV4((uint8_t *)&src->ip[0],
1212  (de_ctx->io_ctx).tree_ipv4src, sna);
1213  else
1214  node = SCRadixAddKeyIPV4Netblock((uint8_t *)&src->ip[0],
1215  (de_ctx->io_ctx).tree_ipv4src, sna,
1216  src->netmask);
1217 
1218  if (node == NULL) {
1219  char tmpstr[64];
1220  PrintInet(src->family, &src->ip[0], tmpstr, sizeof(tmpstr));
1221  SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the"
1222  " src ipv4 radix tree ip %s netmask %"PRIu8, tmpstr, src->netmask);
1223  //SCRadixPrintTree((de_ctx->io_ctx).tree_ipv4src);
1224  exit(-1);
1225  }
1226  }
1227  } else {
1228  SCLogDebug("Exact match found");
1229 
1230  /* it's already inserted. Update it */
1231  SigNumArray *sna = (SigNumArray *)user_data;
1232 
1233  /* Update the sig */
1234  uint8_t tmp = (uint8_t)(1 << (src->signum % 8));
1235 
1236  if (src->negated > 0)
1237  /* Unset it */
1238  sna->array[src->signum / 8] &= ~tmp;
1239  else
1240  /* Set it */
1241  sna->array[src->signum / 8] |= tmp;
1242  }
1243  } else if (src->family == AF_INET6) {
1244  SCLogDebug("To IPv6");
1245 
1246  void *user_data = NULL;
1247  if (src->netmask == 128)
1248  (void)SCRadixFindKeyIPV6ExactMatch((uint8_t *)&src->ip[0],
1249  (de_ctx->io_ctx).tree_ipv6src,
1250  &user_data);
1251  else
1252  (void)SCRadixFindKeyIPV6Netblock((uint8_t *)&src->ip[0],
1253  (de_ctx->io_ctx).tree_ipv6src,
1254  src->netmask, &user_data);
1255 
1256  if (user_data == NULL) {
1257  /* Not found, look if there's a subnet of this range with bigger netmask */
1258  (void)SCRadixFindKeyIPV6BestMatch((uint8_t *)&src->ip[0],
1259  (de_ctx->io_ctx).tree_ipv6src,
1260  &user_data);
1261 
1262  if (user_data == NULL) {
1263  /* Not found, insert a new one */
1264  SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
1265 
1266  /* Update the sig */
1267  uint8_t tmp = (uint8_t)(1 << (src->signum % 8));
1268 
1269  if (src->negated > 0)
1270  /* Unset it */
1271  sna->array[src->signum / 8] &= ~tmp;
1272  else
1273  /* Set it */
1274  sna->array[src->signum / 8] |= tmp;
1275 
1276  if (src->netmask == 128)
1277  node = SCRadixAddKeyIPV6((uint8_t *)&src->ip[0],
1278  (de_ctx->io_ctx).tree_ipv6src, sna);
1279  else
1280  node = SCRadixAddKeyIPV6Netblock((uint8_t *)&src->ip[0],
1281  (de_ctx->io_ctx).tree_ipv6src,
1282  sna, src->netmask);
1283  if (node == NULL)
1284  SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the src "
1285  "ipv6 radix tree");
1286  } else {
1287  /* Found, copy the sig num table, add this signum and insert */
1288  SigNumArray *sna = NULL;
1289  sna = SigNumArrayCopy((SigNumArray *)user_data);
1290 
1291  /* Update the sig */
1292  uint8_t tmp = (uint8_t)(1 << (src->signum % 8));
1293  if (src->negated > 0)
1294  /* Unset it */
1295  sna->array[src->signum / 8] &= ~tmp;
1296  else
1297  /* Set it */
1298  sna->array[src->signum / 8] |= tmp;
1299 
1300  if (src->netmask == 128)
1301  node = SCRadixAddKeyIPV6((uint8_t *)&src->ip[0],
1302  (de_ctx->io_ctx).tree_ipv6src, sna);
1303  else
1304  node = SCRadixAddKeyIPV6Netblock((uint8_t *)&src->ip[0],
1305  (de_ctx->io_ctx).tree_ipv6src,
1306  sna, src->netmask);
1307  if (node == NULL)
1308  SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the src "
1309  "ipv6 radix tree");
1310  }
1311  } else {
1312  /* it's already inserted. Update it */
1313  SigNumArray *sna = (SigNumArray *)user_data;
1314 
1315  /* Update the sig */
1316  uint8_t tmp = (uint8_t)(1 << (src->signum % 8));
1317  if (src->negated > 0)
1318  /* Unset it */
1319  sna->array[src->signum / 8] &= ~tmp;
1320  else
1321  /* Set it */
1322  sna->array[src->signum / 8] |= tmp;
1323  }
1324  }
1325  IPOnlyCIDRItem *tmpaux = src;
1326  src = src->next;
1327  SCFree(tmpaux);
1328  }
1329 
1330  SCLogDebug("dsts:");
1331 
1332  /* Prepare Dst radix trees */
1333  for (dst = (de_ctx->io_ctx).ip_dst; dst != NULL; ) {
1334  if (dst->family == AF_INET) {
1335 
1336  SCLogDebug("To IPv4");
1337  SCLogDebug("Item has netmask %"PRIu8" negated: %s; IP: %s; signum:"
1338  " %"PRIu32"", dst->netmask, (dst->negated)?"yes":"no",
1339  inet_ntoa(*(struct in_addr*)&dst->ip[0]), dst->signum);
1340 
1341  void *user_data = NULL;
1342  if (dst->netmask == 32)
1343  (void) SCRadixFindKeyIPV4ExactMatch((uint8_t *) &dst->ip[0],
1344  (de_ctx->io_ctx).tree_ipv4dst,
1345  &user_data);
1346  else
1347  (void) SCRadixFindKeyIPV4Netblock((uint8_t *) &dst->ip[0],
1348  (de_ctx->io_ctx).tree_ipv4dst,
1349  dst->netmask,
1350  &user_data);
1351 
1352  if (user_data == NULL) {
1353  SCLogDebug("Exact match not found");
1354 
1355  /**
1356  * Not found, look if there's a subnet of this range
1357  * with bigger netmask
1358  */
1359  (void) SCRadixFindKeyIPV4BestMatch((uint8_t *)&dst->ip[0],
1360  (de_ctx->io_ctx).tree_ipv4dst,
1361  &user_data);
1362  if (user_data == NULL) {
1363  SCLogDebug("Best match not found");
1364 
1365  /** Not found, insert a new one */
1366  SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
1367 
1368  /** Update the sig */
1369  uint8_t tmp = (uint8_t)(1 << (dst->signum % 8));
1370  if (dst->negated > 0)
1371  /** Unset it */
1372  sna->array[dst->signum / 8] &= ~tmp;
1373  else
1374  /** Set it */
1375  sna->array[dst->signum / 8] |= tmp;
1376 
1377  if (dst->netmask == 32)
1378  node = SCRadixAddKeyIPV4((uint8_t *)&dst->ip[0],
1379  (de_ctx->io_ctx).tree_ipv4dst, sna);
1380  else
1381  node = SCRadixAddKeyIPV4Netblock((uint8_t *)&dst->ip[0],
1382  (de_ctx->io_ctx).tree_ipv4dst,
1383  sna, dst->netmask);
1384 
1385  if (node == NULL)
1386  SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the dst "
1387  "ipv4 radix tree");
1388  } else {
1389  SCLogDebug("Best match found");
1390 
1391  /* Found, copy the sig num table, add this signum and insert */
1392  SigNumArray *sna = NULL;
1393  sna = SigNumArrayCopy((SigNumArray *) user_data);
1394 
1395  /* Update the sig */
1396  uint8_t tmp = (uint8_t)(1 << (dst->signum % 8));
1397  if (dst->negated > 0)
1398  /* Unset it */
1399  sna->array[dst->signum / 8] &= ~tmp;
1400  else
1401  /* Set it */
1402  sna->array[dst->signum / 8] |= tmp;
1403 
1404  if (dst->netmask == 32)
1405  node = SCRadixAddKeyIPV4((uint8_t *)&dst->ip[0],
1406  (de_ctx->io_ctx).tree_ipv4dst, sna);
1407  else
1408  node = SCRadixAddKeyIPV4Netblock((uint8_t *)&dst->ip[0],
1409  (de_ctx->io_ctx).tree_ipv4dst,
1410  sna, dst->netmask);
1411 
1412  if (node == NULL)
1413  SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the dst "
1414  "ipv4 radix tree");
1415  }
1416  } else {
1417  SCLogDebug("Exact match found");
1418 
1419  /* it's already inserted. Update it */
1420  SigNumArray *sna = (SigNumArray *)user_data;
1421 
1422  /* Update the sig */
1423  uint8_t tmp = (uint8_t)(1 << (dst->signum % 8));
1424  if (dst->negated > 0)
1425  /* Unset it */
1426  sna->array[dst->signum / 8] &= ~tmp;
1427  else
1428  /* Set it */
1429  sna->array[dst->signum / 8] |= tmp;
1430  }
1431  } else if (dst->family == AF_INET6) {
1432  SCLogDebug("To IPv6");
1433 
1434  void *user_data = NULL;
1435  if (dst->netmask == 128)
1436  (void) SCRadixFindKeyIPV6ExactMatch((uint8_t *)&dst->ip[0],
1437  (de_ctx->io_ctx).tree_ipv6dst,
1438  &user_data);
1439  else
1440  (void) SCRadixFindKeyIPV6Netblock((uint8_t *)&dst->ip[0],
1441  (de_ctx->io_ctx).tree_ipv6dst,
1442  dst->netmask, &user_data);
1443 
1444  if (user_data == NULL) {
1445  /** Not found, look if there's a subnet of this range with
1446  * bigger netmask
1447  */
1448  (void) SCRadixFindKeyIPV6BestMatch((uint8_t *)&dst->ip[0],
1449  (de_ctx->io_ctx).tree_ipv6dst,
1450  &user_data);
1451 
1452  if (user_data == NULL) {
1453  /* Not found, insert a new one */
1454  SigNumArray *sna = SigNumArrayNew(de_ctx, &de_ctx->io_ctx);
1455 
1456  /* Update the sig */
1457  uint8_t tmp = (uint8_t)(1 << (dst->signum % 8));
1458  if (dst->negated > 0)
1459  /* Unset it */
1460  sna->array[dst->signum / 8] &= ~tmp;
1461  else
1462  /* Set it */
1463  sna->array[dst->signum / 8] |= tmp;
1464 
1465  if (dst->netmask == 128)
1466  node = SCRadixAddKeyIPV6((uint8_t *)&dst->ip[0],
1467  (de_ctx->io_ctx).tree_ipv6dst, sna);
1468  else
1469  node = SCRadixAddKeyIPV6Netblock((uint8_t *)&dst->ip[0],
1470  (de_ctx->io_ctx).tree_ipv6dst,
1471  sna, dst->netmask);
1472 
1473  if (node == NULL)
1474  SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the dst "
1475  "ipv6 radix tree");
1476  } else {
1477  /* Found, copy the sig num table, add this signum and insert */
1478  SigNumArray *sna = NULL;
1479  sna = SigNumArrayCopy((SigNumArray *)user_data);
1480 
1481  /* Update the sig */
1482  uint8_t tmp = (uint8_t)(1 << (dst->signum % 8));
1483  if (dst->negated > 0)
1484  /* Unset it */
1485  sna->array[dst->signum / 8] &= ~tmp;
1486  else
1487  /* Set it */
1488  sna->array[dst->signum / 8] |= tmp;
1489 
1490  if (dst->netmask == 128)
1491  node = SCRadixAddKeyIPV6((uint8_t *)&dst->ip[0],
1492  (de_ctx->io_ctx).tree_ipv6dst, sna);
1493  else
1494  node = SCRadixAddKeyIPV6Netblock((uint8_t *)&dst->ip[0],
1495  (de_ctx->io_ctx).tree_ipv6dst,
1496  sna, dst->netmask);
1497 
1498  if (node == NULL)
1499  SCLogError(SC_ERR_IPONLY_RADIX, "Error inserting in the dst "
1500  "ipv6 radix tree");
1501  }
1502  } else {
1503  /* it's already inserted. Update it */
1504  SigNumArray *sna = (SigNumArray *)user_data;
1505 
1506  /* Update the sig */
1507  uint8_t tmp = (uint8_t)(1 << (dst->signum % 8));
1508  if (dst->negated > 0)
1509  /* Unset it */
1510  sna->array[dst->signum / 8] &= ~tmp;
1511  else
1512  /* Set it */
1513  sna->array[dst->signum / 8] |= tmp;
1514  }
1515  }
1516  IPOnlyCIDRItem *tmpaux = dst;
1517  dst = dst->next;
1518  SCFree(tmpaux);
1519  }
1520 
1521  /* print all the trees: for debugging it might print too much info
1522  SCLogDebug("Radix tree src ipv4:");
1523  SCRadixPrintTree((de_ctx->io_ctx).tree_ipv4src);
1524  SCLogDebug("Radix tree src ipv6:");
1525  SCRadixPrintTree((de_ctx->io_ctx).tree_ipv6src);
1526  SCLogDebug("__________________");
1527 
1528  SCLogDebug("Radix tree dst ipv4:");
1529  SCRadixPrintTree((de_ctx->io_ctx).tree_ipv4dst);
1530  SCLogDebug("Radix tree dst ipv6:");
1531  SCRadixPrintTree((de_ctx->io_ctx).tree_ipv6dst);
1532  SCLogDebug("__________________");
1533  */
1534 }
1535 
1536 /**
1537  * \brief Add a signature to the lists of Addresses in CIDR format (sorted)
1538  * this step is necessary to build the radix tree with a hierarchical
1539  * relation between nodes
1540  * \param de_ctx Pointer to the current detection engine context
1541  * \param de_ctx Pointer to the current ip only detection engine contest
1542  * \param s Pointer to the current signature
1543  */
1545  Signature *s)
1546 {
1547  if (!(s->flags & SIG_FLAG_IPONLY))
1548  return;
1549 
1550  /* Set the internal signum to the list before merging */
1551  IPOnlyCIDRListSetSigNum(s->cidr_src, s->num);
1552 
1553  IPOnlyCIDRListSetSigNum(s->cidr_dst, s->num);
1554 
1555  /**
1556  * ipv4 and ipv6 are mixed, but later we will separate them into
1557  * different trees
1558  */
1559  io_ctx->ip_src = IPOnlyCIDRItemInsert(io_ctx->ip_src, s->cidr_src);
1560  io_ctx->ip_dst = IPOnlyCIDRItemInsert(io_ctx->ip_dst, s->cidr_dst);
1561 
1562  if (s->num > io_ctx->max_idx)
1563  io_ctx->max_idx = s->num;
1564 
1565  /** no longer ref to this, it's in the table now */
1566  s->cidr_src = NULL;
1567  s->cidr_dst = NULL;
1568 }
1569 
1570 #ifdef UNITTESTS
1571 /**
1572  * \test check that we set a Signature as IPOnly because it has no rule
1573  * option appending a SigMatch and no port is fixed
1574  */
1575 
1576 static int IPOnlyTestSig01(void)
1577 {
1579  FAIL_IF(de_ctx == NULL);
1580  de_ctx->flags |= DE_QUIET;
1581 
1582  Signature *s = SigInit(de_ctx,"alert tcp any any -> any any (sid:400001; rev:1;)");
1583  FAIL_IF(s == NULL);
1584 
1585  FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
1586  SigFree(de_ctx, s);
1588  PASS;
1589 }
1590 
1591 /**
1592  * \test check that we don't set a Signature as IPOnly because it has no rule
1593  * option appending a SigMatch but a port is fixed
1594  */
1595 
1596 static int IPOnlyTestSig02 (void)
1597 {
1599  FAIL_IF(de_ctx == NULL);
1600  de_ctx->flags |= DE_QUIET;
1601 
1602  Signature *s = SigInit(de_ctx,"alert tcp any any -> any 80 (sid:400001; rev:1;)");
1603  FAIL_IF(s == NULL);
1604 
1605  FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
1606  SigFree(de_ctx, s);
1608  PASS;
1609 }
1610 
1611 /**
1612  * \test check that we set don't set a Signature as IPOnly
1613  * because it has rule options appending a SigMatch like content, and pcre
1614  */
1615 
1616 static int IPOnlyTestSig03 (void)
1617 {
1618  int result = 1;
1620  Signature *s=NULL;
1621 
1623  if (de_ctx == NULL)
1624  goto end;
1625  de_ctx->flags |= DE_QUIET;
1626 
1627  /* combination of pcre and content */
1628  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;)");
1629  if (s == NULL) {
1630  goto end;
1631  }
1632  if(SignatureIsIPOnly(de_ctx, s))
1633  {
1634  printf("got a IPOnly signature (content): ");
1635  result=0;
1636  }
1637  SigFree(de_ctx, s);
1638 
1639  /* content */
1640  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;)");
1641  if (s == NULL) {
1642  goto end;
1643  }
1644  if(SignatureIsIPOnly(de_ctx, s))
1645  {
1646  printf("got a IPOnly signature (content): ");
1647  result=0;
1648  }
1649  SigFree(de_ctx, s);
1650 
1651  /* uricontent */
1652  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;)");
1653  if (s == NULL) {
1654  goto end;
1655  }
1656  if(SignatureIsIPOnly(de_ctx, s))
1657  {
1658  printf("got a IPOnly signature (uricontent): ");
1659  result=0;
1660  }
1661  SigFree(de_ctx, s);
1662 
1663  /* pcre */
1664  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;)");
1665  if (s == NULL) {
1666  goto end;
1667  }
1668  if(SignatureIsIPOnly(de_ctx, s))
1669  {
1670  printf("got a IPOnly signature (pcre): ");
1671  result=0;
1672  }
1673  SigFree(de_ctx, s);
1674 
1675  /* flow */
1676  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;)");
1677  if (s == NULL) {
1678  goto end;
1679  }
1680  if(SignatureIsIPOnly(de_ctx, s))
1681  {
1682  printf("got a IPOnly signature (flow): ");
1683  result=0;
1684  }
1685  SigFree(de_ctx, s);
1686 
1687  /* dsize */
1688  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;)");
1689  if (s == NULL) {
1690  goto end;
1691  }
1692  if(SignatureIsIPOnly(de_ctx, s))
1693  {
1694  printf("got a IPOnly signature (dsize): ");
1695  result=0;
1696  }
1697  SigFree(de_ctx, s);
1698 
1699  /* flowbits */
1700  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;)");
1701  if (s == NULL) {
1702  goto end;
1703  }
1704  if(SignatureIsIPOnly(de_ctx, s))
1705  {
1706  printf("got a IPOnly signature (flowbits): ");
1707  result=0;
1708  }
1709  SigFree(de_ctx, s);
1710 
1711  /* flowvar */
1712  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;)");
1713  if (s == NULL) {
1714  goto end;
1715  }
1716  if(SignatureIsIPOnly(de_ctx, s))
1717  {
1718  printf("got a IPOnly signature (flowvar): ");
1719  result=0;
1720  }
1721  SigFree(de_ctx, s);
1722 
1723  /* pktvar */
1724  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;)");
1725  if (s == NULL) {
1726  goto end;
1727  }
1728  if(SignatureIsIPOnly(de_ctx, s))
1729  {
1730  printf("got a IPOnly signature (pktvar): ");
1731  result=0;
1732  }
1733  SigFree(de_ctx, s);
1734 
1735 end:
1736  if (de_ctx != NULL)
1738  return result;
1739 }
1740 
1741 /**
1742  * \test
1743  */
1744 static int IPOnlyTestSig04 (void)
1745 {
1746  int result = 1;
1747 
1748  IPOnlyCIDRItem *head = NULL;
1749  IPOnlyCIDRItem *new;
1750 
1751  new = IPOnlyCIDRItemNew();
1752  new->netmask= 10;
1753 
1754  head = IPOnlyCIDRItemInsert(head, new);
1755 
1756  new = IPOnlyCIDRItemNew();
1757  new->netmask= 11;
1758 
1759  head = IPOnlyCIDRItemInsert(head, new);
1760 
1761  new = IPOnlyCIDRItemNew();
1762  new->netmask= 9;
1763 
1764  head = IPOnlyCIDRItemInsert(head, new);
1765 
1766  new = IPOnlyCIDRItemNew();
1767  new->netmask= 10;
1768 
1769  head = IPOnlyCIDRItemInsert(head, new);
1770 
1771  new = IPOnlyCIDRItemNew();
1772  new->netmask= 10;
1773 
1774  head = IPOnlyCIDRItemInsert(head, new);
1775 
1776  IPOnlyCIDRListPrint(head);
1777  new = head;
1778  if (new->netmask != 9) {
1779  result = 0;
1780  goto end;
1781  }
1782  new = new->next;
1783  if (new->netmask != 10) {
1784  result = 0;
1785  goto end;
1786  }
1787  new = new->next;
1788  if (new->netmask != 10) {
1789  result = 0;
1790  goto end;
1791  }
1792  new = new->next;
1793  if (new->netmask != 10) {
1794  result = 0;
1795  goto end;
1796  }
1797  new = new->next;
1798  if (new->netmask != 11) {
1799  result = 0;
1800  goto end;
1801  }
1802 
1803 end:
1805  return result;
1806 }
1807 
1808 /**
1809  * \test Test a set of ip only signatures making use a lot of
1810  * addresses for src and dst (all should match)
1811  */
1812 static int IPOnlyTestSig05(void)
1813 {
1814  int result = 0;
1815  uint8_t *buf = (uint8_t *)"Hi all!";
1816  uint16_t buflen = strlen((char *)buf);
1817 
1818  uint8_t numpkts = 1;
1819  uint8_t numsigs = 7;
1820 
1821  Packet *p[1];
1822 
1823  p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1824 
1825  const char *sigs[numsigs];
1826  sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1827  sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1828  sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1829  sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1830  sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1831  sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1832  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;)";
1833 
1834  /* Sid numbers (we could extract them from the sig) */
1835  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1836  uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1837 
1838  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1839 
1840  UTHFreePackets(p, numpkts);
1841 
1842  return result;
1843 }
1844 
1845 /**
1846  * \test Test a set of ip only signatures making use a lot of
1847  * addresses for src and dst (none should match)
1848  */
1849 static int IPOnlyTestSig06(void)
1850 {
1851  int result = 0;
1852  uint8_t *buf = (uint8_t *)"Hi all!";
1853  uint16_t buflen = strlen((char *)buf);
1854 
1855  uint8_t numpkts = 1;
1856  uint8_t numsigs = 7;
1857 
1858  Packet *p[1];
1859 
1860  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "80.58.0.33", "195.235.113.3");
1861 
1862  const char *sigs[numsigs];
1863  sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1864  sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1865  sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; sid:3;)";
1866  sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; sid:4;)";
1867  sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1868  sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; sid:6;)";
1869  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;)";
1870 
1871  /* Sid numbers (we could extract them from the sig) */
1872  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1873  uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
1874 
1875  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1876 
1877  UTHFreePackets(p, numpkts);
1878 
1879  return result;
1880 }
1881 
1882 /* \todo fix it. We have disabled this unittest because 599 exposes 608,
1883  * which is why these unittests fail. When we fix 608, we need to renable
1884  * these sigs */
1885 #if 0
1886 /**
1887  * \test Test a set of ip only signatures making use a lot of
1888  * addresses for src and dst (all should match)
1889  */
1890 static int IPOnlyTestSig07(void)
1891 {
1892  int result = 0;
1893  uint8_t *buf = (uint8_t *)"Hi all!";
1894  uint16_t buflen = strlen((char *)buf);
1895 
1896  uint8_t numpkts = 1;
1897  uint8_t numsigs = 7;
1898 
1899  Packet *p[1];
1900 
1901  p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1902 
1903  char *sigs[numsigs];
1904  sigs[0]= "alert tcp 192.168.1.5 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
1905  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;)";
1906  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;)";
1907  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;)";
1908  sigs[4]= "alert tcp any any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1909  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;)";
1910  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" */
1911 
1912  /* Sid numbers (we could extract them from the sig) */
1913  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1914  uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1915 
1916  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1917 
1918  UTHFreePackets(p, numpkts);
1919 
1920  return result;
1921 }
1922 #endif
1923 
1924 /**
1925  * \test Test a set of ip only signatures making use a lot of
1926  * addresses for src and dst (none should match)
1927  */
1928 static int IPOnlyTestSig08(void)
1929 {
1930  int result = 0;
1931  uint8_t *buf = (uint8_t *)"Hi all!";
1932  uint16_t buflen = strlen((char *)buf);
1933 
1934  uint8_t numpkts = 1;
1935  uint8_t numsigs = 7;
1936 
1937  Packet *p[1];
1938 
1939  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"192.168.1.1","192.168.1.5");
1940 
1941  const char *sigs[numsigs];
1942  sigs[0]= "alert tcp 192.168.1.5 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 1)\"; sid:1;)";
1943  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;)";
1944  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;)";
1945  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;)";
1946  sigs[4]= "alert tcp any any -> !192.168.1.5 any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
1947  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;)";
1948  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" */
1949 
1950  /* Sid numbers (we could extract them from the sig) */
1951  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1952  uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
1953 
1954  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1955 
1956  UTHFreePackets(p, numpkts);
1957 
1958  return result;
1959 }
1960 
1961 /**
1962  * \test Test a set of ip only signatures making use a lot of
1963  * addresses for src and dst (all should match)
1964  */
1965 static int IPOnlyTestSig09(void)
1966 {
1967  int result = 0;
1968  uint8_t *buf = (uint8_t *)"Hi all!";
1969  uint16_t buflen = strlen((char *)buf);
1970 
1971  uint8_t numpkts = 1;
1972  uint8_t numsigs = 7;
1973 
1974  Packet *p[1];
1975 
1976  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");
1977 
1978  const char *sigs[numsigs];
1979  sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
1980  sigs[1]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
1981  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;)";
1982  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;)";
1983  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;)";
1984  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;)";
1985  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;)";
1986 
1987  /* Sid numbers (we could extract them from the sig) */
1988  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
1989  uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
1990 
1991  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
1992 
1993  UTHFreePackets(p, numpkts);
1994 
1995  return result;
1996 }
1997 
1998 /**
1999  * \test Test a set of ip only signatures making use a lot of
2000  * addresses for src and dst (none should match)
2001  */
2002 static int IPOnlyTestSig10(void)
2003 {
2004  int result = 0;
2005  uint8_t *buf = (uint8_t *)"Hi all!";
2006  uint16_t buflen = strlen((char *)buf);
2007 
2008  uint8_t numpkts = 1;
2009  uint8_t numsigs = 7;
2010 
2011  Packet *p[1];
2012 
2013  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");
2014 
2015  const char *sigs[numsigs];
2016  sigs[0]= "alert tcp 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4565 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
2017  sigs[1]= "alert tcp any any -> 3FFE:FFFF:7654:FEDA:1245:BA98:3210:4562 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
2018  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;)";
2019  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;)";
2020  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;)";
2021  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;)";
2022  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;)";
2023 
2024  /* Sid numbers (we could extract them from the sig) */
2025  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2026  uint32_t results[7] = { 0, 0, 0, 0, 0, 0, 0};
2027 
2028  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2029 
2030  UTHFreePackets(p, numpkts);
2031 
2032  return result;
2033 }
2034 
2035 /* \todo fix it. We have disabled this unittest because 599 exposes 608,
2036  * which is why these unittests fail. When we fix 608, we need to renable
2037  * these sigs */
2038 #if 0
2039 /**
2040  * \test Test a set of ip only signatures making use a lot of
2041  * addresses for src and dst (all should match) with ipv4 and ipv6 mixed
2042  */
2043 static int IPOnlyTestSig11(void)
2044 {
2045  int result = 0;
2046  uint8_t *buf = (uint8_t *)"Hi all!";
2047  uint16_t buflen = strlen((char *)buf);
2048 
2049  uint8_t numpkts = 2;
2050  uint8_t numsigs = 7;
2051 
2052  Packet *p[2];
2053 
2054  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");
2055  p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"192.168.1.1","192.168.1.5");
2056 
2057  char *sigs[numsigs];
2058  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;)";
2059  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;)";
2060  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;)";
2061  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;)";
2062  sigs[4]= "alert tcp any any -> any any (msg:\"Testing src/dst ip (sid 5)\"; sid:5;)";
2063  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;)";
2064  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" */
2065 
2066  /* Sid numbers (we could extract them from the sig) */
2067  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2068  uint32_t results[2][7] = {{ 1, 1, 1, 1, 1, 1, 1}, { 1, 1, 1, 1, 1, 1, 1}};
2069 
2070  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2071 
2072  UTHFreePackets(p, numpkts);
2073 
2074  return result;
2075 }
2076 #endif
2077 
2078 /**
2079  * \test Test a set of ip only signatures making use a lot of
2080  * addresses for src and dst (none should match) with ipv4 and ipv6 mixed
2081  */
2082 static int IPOnlyTestSig12(void)
2083 {
2084  int result = 0;
2085  uint8_t *buf = (uint8_t *)"Hi all!";
2086  uint16_t buflen = strlen((char *)buf);
2087 
2088  uint8_t numpkts = 2;
2089  uint8_t numsigs = 7;
2090 
2091  Packet *p[2];
2092 
2093  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");
2094  p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP,"195.85.1.1","80.198.1.5");
2095 
2096  const char *sigs[numsigs];
2097  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;)";
2098  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;)";
2099  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;)";
2100  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;)";
2101  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;)";
2102  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;)";
2103  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" */
2104 
2105  /* Sid numbers (we could extract them from the sig) */
2106  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2107  uint32_t results[2][7] = {{ 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}};
2108 
2109  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2110 
2111  UTHFreePackets(p, numpkts);
2112 
2113  return result;
2114 }
2115 
2116 static int IPOnlyTestSig13(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; sid:1; rev:1;)");
2125  FAIL_IF(s == NULL);
2126 
2127  FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 0);
2128  SigFree(de_ctx, s);
2130  PASS;
2131 }
2132 
2133 static int IPOnlyTestSig14(void)
2134 {
2136  FAIL_IF(de_ctx == NULL);
2137  de_ctx->flags |= DE_QUIET;
2138 
2139  Signature *s = SigInit(de_ctx,
2140  "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; "
2141  "flowbits:set,myflow1; flowbits:isset,myflow2; sid:1; rev:1;)");
2142  FAIL_IF(s == NULL);
2143 
2144  FAIL_IF(SignatureIsIPOnly(de_ctx, s) == 1);
2145  SigFree(de_ctx, s);
2147  PASS;
2148 }
2149 
2150 static int IPOnlyTestSig15(void)
2151 {
2152  int result = 0;
2153  uint8_t *buf = (uint8_t *)"Hi all!";
2154  uint16_t buflen = strlen((char *)buf);
2155 
2156  uint8_t numpkts = 1;
2157  uint8_t numsigs = 7;
2158 
2159  Packet *p[1];
2160  Flow f;
2161  GenericVar flowvar;
2162  memset(&f, 0, sizeof(Flow));
2163  memset(&flowvar, 0, sizeof(GenericVar));
2164  FLOW_INITIALIZE(&f);
2165 
2166  p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
2167 
2168  p[0]->flow = &f;
2169  p[0]->flow->flowvar = &flowvar;
2170  p[0]->flags |= PKT_HAS_FLOW;
2171  p[0]->flowflags |= FLOW_PKT_TOSERVER;
2172 
2173  const char *sigs[numsigs];
2174  sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; "
2175  "flowbits:set,one; sid:1;)";
2176  sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; "
2177  "flowbits:set,two; sid:2;)";
2178  sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; "
2179  "flowbits:set,three; sid:3;)";
2180  sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; "
2181  "flowbits:set,four; sid:4;)";
2182  sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; "
2183  "flowbits:set,five; sid:5;)";
2184  sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; "
2185  "flowbits:set,six; sid:6;)";
2186  sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; "
2187  "flowbits:set,seven; content:\"Hi all\"; sid:7;)";
2188 
2189  /* Sid numbers (we could extract them from the sig) */
2190  uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7};
2191  uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1};
2192 
2193  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2194 
2195  UTHFreePackets(p, numpkts);
2196 
2197  FLOW_DESTROY(&f);
2198  return result;
2199 }
2200 
2201 /**
2202  * \brief Unittest to show #599. We fail to match if we have negated addresses.
2203  */
2204 static int IPOnlyTestSig16(void)
2205 {
2206  int result = 0;
2207  uint8_t *buf = (uint8_t *)"Hi all!";
2208  uint16_t buflen = strlen((char *)buf);
2209 
2210  uint8_t numpkts = 1;
2211  uint8_t numsigs = 2;
2212 
2213  Packet *p[1];
2214 
2215  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "100.100.0.0", "50.0.0.0");
2216 
2217  const char *sigs[numsigs];
2218  sigs[0]= "alert tcp !100.100.0.1 any -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
2219  sigs[1]= "alert tcp any any -> !50.0.0.1 any (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
2220 
2221  /* Sid numbers (we could extract them from the sig) */
2222  uint32_t sid[2] = { 1, 2};
2223  uint32_t results[2] = { 1, 1};
2224 
2225  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2226 
2227  UTHFreePackets(p, numpkts);
2228 
2229  return result;
2230 }
2231 
2232 /**
2233  * \brief Unittest to show #611. Ports on portless protocols.
2234  */
2235 static int IPOnlyTestSig17(void)
2236 {
2237  int result = 0;
2238  uint8_t *buf = (uint8_t *)"Hi all!";
2239  uint16_t buflen = strlen((char *)buf);
2240 
2241  uint8_t numpkts = 1;
2242  uint8_t numsigs = 2;
2243 
2244  Packet *p[1];
2245 
2246  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_ICMP, "100.100.0.0", "50.0.0.0");
2247 
2248  const char *sigs[numsigs];
2249  sigs[0]= "alert ip 100.100.0.0 80 -> any any (msg:\"Testing src ip (sid 1)\"; sid:1;)";
2250  sigs[1]= "alert ip any any -> 50.0.0.0 123 (msg:\"Testing dst ip (sid 2)\"; sid:2;)";
2251 
2252  uint32_t sid[2] = { 1, 2};
2253  uint32_t results[2] = { 0, 0}; /* neither should match */
2254 
2255  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2256 
2257  UTHFreePackets(p, numpkts);
2258 
2259  return result;
2260 }
2261 
2262 /**
2263  * \brief Unittest to show #3568 -- IP address range handling
2264  */
2265 static int IPOnlyTestSig18(void)
2266 {
2267  int result = 0;
2268  uint8_t *buf = (uint8_t *)"Hi all!";
2269  uint16_t buflen = strlen((char *)buf);
2270 
2271  uint8_t numpkts = 4;
2272  uint8_t numsigs = 4;
2273 
2274  Packet *p[4];
2275 
2276  p[0] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "10.10.10.1", "50.0.0.1");
2277  p[1] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "220.10.10.1", "5.0.0.1");
2278  p[2] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "0.0.0.1", "50.0.0.1");
2279  p[3] = UTHBuildPacketSrcDst((uint8_t *)buf, buflen, IPPROTO_TCP, "255.255.255.254", "5.0.0.1");
2280 
2281  const char *sigs[numsigs];
2282  // really many IP addresses
2283  sigs[0]= "alert ip 1.2.3.4-219.6.7.8 any -> any any (sid:1;)";
2284  sigs[1]= "alert ip 51.2.3.4-253.1.2.3 any -> any any (sid:2;)";
2285  sigs[2]= "alert ip 0.0.0.0-50.0.0.2 any -> any any (sid:3;)";
2286  sigs[3]= "alert ip 50.0.0.0-255.255.255.255 any -> any any (sid:4;)";
2287 
2288  uint32_t sid[4] = { 1, 2, 3, 4, };
2289  uint32_t results[4][4] = {
2290  { 1, 0, 1, 0, }, { 0, 1, 0, 1}, { 0, 0, 1, 0 }, { 0, 0, 0, 1}};
2291 
2292  result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs);
2293 
2294  UTHFreePackets(p, numpkts);
2295 
2296  FAIL_IF(result != 1);
2297 
2298  PASS;
2299 }
2300 
2301 /** \test build IP-only tree */
2302 static int IPOnlyTestBug5066v1(void)
2303 {
2305  FAIL_IF(de_ctx == NULL);
2306  de_ctx->flags |= DE_QUIET;
2307 
2309  de_ctx, "alert ip [1.2.3.4/24,1.2.3.64/27] any -> any any (sid:1;)");
2310  FAIL_IF_NULL(s);
2311  s = DetectEngineAppendSig(de_ctx, "alert ip [1.2.3.4/24] any -> any any (sid:2;)");
2312  FAIL_IF_NULL(s);
2313 
2315 
2317  PASS;
2318 }
2319 
2320 static int IPOnlyTestBug5066v2(void)
2321 {
2322  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2323  FAIL_IF_NULL(x);
2324 
2325  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.4/24") != 0);
2326 
2327  char ip[16];
2328  PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2329  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2330 
2331  FAIL_IF_NOT(strcmp(ip, "1.2.3.0") == 0);
2332  FAIL_IF_NOT(x->netmask == 24);
2333 
2334  IPOnlyCIDRListFree(x);
2335  PASS;
2336 }
2337 
2338 static int IPOnlyTestBug5066v3(void)
2339 {
2340  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2341  FAIL_IF_NULL(x);
2342 
2343  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.64/26") != 0);
2344 
2345  char ip[16];
2346  PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2347  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2348 
2349  FAIL_IF_NOT(strcmp(ip, "1.2.3.64") == 0);
2350  FAIL_IF_NOT(x->netmask == 26);
2351 
2352  IPOnlyCIDRListFree(x);
2353  PASS;
2354 }
2355 
2356 static int IPOnlyTestBug5066v4(void)
2357 {
2358  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2359  FAIL_IF_NULL(x);
2360 
2361  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "2000::1:1/122") != 0);
2362 
2363  char ip[64];
2364  PrintInet(AF_INET6, (const void *)&x->ip, ip, sizeof(ip));
2365  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2366 
2367  FAIL_IF_NOT(strcmp(ip, "2000:0000:0000:0000:0000:0000:0001:0000") == 0);
2368  FAIL_IF_NOT(x->netmask == 122);
2369 
2370  IPOnlyCIDRListFree(x);
2371  PASS;
2372 }
2373 
2374 static int IPOnlyTestBug5066v5(void)
2375 {
2376  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2377  FAIL_IF_NULL(x);
2378 
2379  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "2000::1:40/122") != 0);
2380 
2381  char ip[64];
2382  PrintInet(AF_INET6, (const void *)&x->ip, ip, sizeof(ip));
2383  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2384 
2385  FAIL_IF_NOT(strcmp(ip, "2000:0000:0000:0000:0000:0000:0001:0040") == 0);
2386  FAIL_IF_NOT(x->netmask == 122);
2387 
2388  IPOnlyCIDRListFree(x);
2389  PASS;
2390 }
2391 
2392 static int IPOnlyTestBug5168v1(void)
2393 {
2394  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2395  FAIL_IF_NULL(x);
2396 
2397  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "1.2.3.64/0.0.0.0") != 0);
2398 
2399  char ip[16];
2400  PrintInet(AF_INET, (const void *)&x->ip[0], ip, sizeof(ip));
2401  SCLogDebug("ip %s netmask %d", ip, x->netmask);
2402 
2403  FAIL_IF_NOT(strcmp(ip, "0.0.0.0") == 0);
2404  FAIL_IF_NOT(x->netmask == 0);
2405 
2406  IPOnlyCIDRListFree(x);
2407  PASS;
2408 }
2409 
2410 static int IPOnlyTestBug5168v2(void)
2411 {
2412  IPOnlyCIDRItem *x = IPOnlyCIDRItemNew();
2413  FAIL_IF_NULL(x);
2414  FAIL_IF(IPOnlyCIDRItemParseSingle(&x, "0.0.0.5/0.0.0.5") != -1);
2415  IPOnlyCIDRListFree(x);
2416  PASS;
2417 }
2418 
2419 #endif /* UNITTESTS */
2420 
2422 {
2423 #ifdef UNITTESTS
2424  UtRegisterTest("IPOnlyTestSig01", IPOnlyTestSig01);
2425  UtRegisterTest("IPOnlyTestSig02", IPOnlyTestSig02);
2426  UtRegisterTest("IPOnlyTestSig03", IPOnlyTestSig03);
2427  UtRegisterTest("IPOnlyTestSig04", IPOnlyTestSig04);
2428 
2429  UtRegisterTest("IPOnlyTestSig05", IPOnlyTestSig05);
2430  UtRegisterTest("IPOnlyTestSig06", IPOnlyTestSig06);
2431 /* \todo fix it. We have disabled this unittest because 599 exposes 608,
2432  * which is why these unittests fail. When we fix 608, we need to renable
2433  * these sigs */
2434 #if 0
2435  UtRegisterTest("IPOnlyTestSig07", IPOnlyTestSig07, 1);
2436 #endif
2437  UtRegisterTest("IPOnlyTestSig08", IPOnlyTestSig08);
2438 
2439  UtRegisterTest("IPOnlyTestSig09", IPOnlyTestSig09);
2440  UtRegisterTest("IPOnlyTestSig10", IPOnlyTestSig10);
2441 /* \todo fix it. We have disabled this unittest because 599 exposes 608,
2442  * which is why these unittests fail. When we fix 608, we need to renable
2443  * these sigs */
2444 #if 0
2445  UtRegisterTest("IPOnlyTestSig11", IPOnlyTestSig11, 1);
2446 #endif
2447  UtRegisterTest("IPOnlyTestSig12", IPOnlyTestSig12);
2448  UtRegisterTest("IPOnlyTestSig13", IPOnlyTestSig13);
2449  UtRegisterTest("IPOnlyTestSig14", IPOnlyTestSig14);
2450  UtRegisterTest("IPOnlyTestSig15", IPOnlyTestSig15);
2451  UtRegisterTest("IPOnlyTestSig16", IPOnlyTestSig16);
2452 
2453  UtRegisterTest("IPOnlyTestSig17", IPOnlyTestSig17);
2454  UtRegisterTest("IPOnlyTestSig18", IPOnlyTestSig18);
2455 
2456  UtRegisterTest("IPOnlyTestBug5066v1", IPOnlyTestBug5066v1);
2457  UtRegisterTest("IPOnlyTestBug5066v2", IPOnlyTestBug5066v2);
2458  UtRegisterTest("IPOnlyTestBug5066v3", IPOnlyTestBug5066v3);
2459  UtRegisterTest("IPOnlyTestBug5066v4", IPOnlyTestBug5066v4);
2460  UtRegisterTest("IPOnlyTestBug5066v5", IPOnlyTestBug5066v5);
2461 
2462  UtRegisterTest("IPOnlyTestBug5168v1", IPOnlyTestBug5168v1);
2463  UtRegisterTest("IPOnlyTestBug5168v2", IPOnlyTestBug5168v2);
2464 #endif
2465 
2466  return;
2467 }
2468 
IPOnlyRegisterTests
void IPOnlyRegisterTests(void)
Definition: detect-engine-iponly.c:2421
Signature_::cidr_src
IPOnlyCIDRItem * cidr_src
Definition: detect.h:596
util-byte.h
Packet_::proto
uint8_t proto
Definition: decode.h:464
DetectEngineIPOnlyThreadDeinit
void DetectEngineIPOnlyThreadDeinit(DetectEngineIPOnlyThreadCtx *io_tctx)
Deinitialize the IP Only thread detection engine context.
Definition: detect-engine-iponly.c:953
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:1185
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:1566
DETECT_PROTO_IPV6
#define DETECT_PROTO_IPV6
Definition: detect-engine-proto.h:34
detect-engine-siggroup.h
IPOnlyMatchPacket
void IPOnlyMatchPacket(ThreadVars *tv, const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectEngineIPOnlyCtx *io_ctx, DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p)
Match a packet against the IP Only detection engine contexts.
Definition: detect-engine-iponly.c:991
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:263
Signature_::num
SigIntId num
Definition: detect.h:560
IPOnlyCIDRItem_::netmask
uint8_t netmask
Definition: detect.h:303
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1389
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:65
SC_RULE_VARS_ADDRESS_GROUPS
@ SC_RULE_VARS_ADDRESS_GROUPS
Definition: util-rule-vars.h:29
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
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:924
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
DetectEngineIPOnlyCtx_::ip_src
IPOnlyCIDRItem * ip_src
Definition: detect.h:726
IPOnlyCIDRItem_
Definition: detect.h:299
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:335
Packet_::flags
uint32_t flags
Definition: decode.h:477
CIDRGet
uint32_t CIDRGet(int cidr)
Definition: util-cidr.c:55
Flow_
Flow data structure.
Definition: flow.h:356
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2116
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:1244
DetectEngineIPOnlyCtx_::tree_ipv6dst
SCRadixTree * tree_ipv6dst
Definition: detect.h:723
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:794
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2439
SC_ERR_IPONLY_RADIX
@ SC_ERR_IPONLY_RADIX
Definition: util-error.h:121
DetectEngineIPOnlyCtx_::tree_ipv4src
SCRadixTree * tree_ipv4src
Definition: detect.h:722
SIG_FLAG_DST_ANY
#define SIG_FLAG_DST_ANY
Definition: detect.h:212
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:226
DE_QUIET
#define DE_QUIET
Definition: detect.h:297
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:858
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:604
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:1537
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:473
SIG_FLAG_SRC_ANY
#define SIG_FLAG_SRC_ANY
Definition: detect.h:211
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:1595
SigMatchData_
Data needed for Match()
Definition: detect.h:332
KEYWORD_PROFILING_START
#define KEYWORD_PROFILING_START
Definition: util-profiling.h:69
SigMatchData_::type
uint16_t type
Definition: detect.h:333
GET_IPV6_DST_ADDR
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:231
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:83
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:921
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:98
util-cidr.h
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:40
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:305
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:1043
SCRadixReleaseRadixTree
void SCRadixReleaseRadixTree(SCRadixTree *tree)
Frees a Radix tree and all its nodes.
Definition: util-radix-tree.c:465
PKT_IS_FRAGMENT
#define PKT_IS_FRAGMENT
Definition: decode.h:1209
DetectEngineIPOnlyThreadCtx_::sig_match_array
uint8_t * sig_match_array
Definition: detect.h:715
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:274
Packet_::sp
Port sp
Definition: decode.h:449
detect-engine-port.h
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:89
DetectPort_
Port structure for detection engine.
Definition: detect.h:191
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:281
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:1125
CIDRFromMask
int CIDRFromMask(uint32_t netmask)
turn 32 bit mask into CIDR
Definition: util-cidr.c:33
util-profiling.h
util-rule-vars.h
SCReturn
#define SCReturn
Definition: util-debug.h:302
Signature_::flags
uint32_t flags
Definition: detect.h:550
IPOnlyCIDRItem_::next
struct IPOnlyCIDRItem_ * next
Definition: detect.h:311
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:260
Packet_
Definition: decode.h:442
SIG_FLAG_IPONLY
#define SIG_FLAG_IPONLY
Definition: detect.h:219
IPOnlyPrint
void IPOnlyPrint(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx)
Print stats of the IP Only engine.
Definition: detect-engine-iponly.c:913
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:1544
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:316
SC_ERR_ADDRESS_ENGINE_GENERIC
@ SC_ERR_ADDRESS_ENGINE_GENERIC
Definition: util-error.h:119
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1218
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:1583
Signature_::sp
DetectPort * sp
Definition: detect.h:589
StringParseU8RangeCheck
int StringParseU8RangeCheck(uint8_t *res, int base, size_t len, const char *str, uint8_t min, uint8_t max)
Definition: util-byte.c:457
IPOnlyCIDRListFree
void IPOnlyCIDRListFree(IPOnlyCIDRItem *tmphead)
This function free a IPOnlyCIDRItem list.
Definition: detect-engine-iponly.c:448
Flow_::flowvar
GenericVar * flowvar
Definition: flow.h:499
Flow_::next
struct Flow_ * next
Definition: flow.h:407
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1954
SigNumArray_::array
uint8_t * array
Definition: detect-engine-iponly.c:516
DetectEngineIPOnlyCtx_::ip_dst
IPOnlyCIDRItem * ip_dst
Definition: detect.h:726
CIDRGetIPv6
void CIDRGetIPv6(int cidr, struct in6_addr *in6)
Creates a cidr ipv6 netblock, based on the cidr netblock value.
Definition: util-cidr.c:80
DetectProto_::flags
uint8_t flags
Definition: detect-engine-proto.h:38
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2421
DETECT_PROTO_IPV4
#define DETECT_PROTO_IPV4
Definition: detect-engine-proto.h:33
Packet_::flow
struct Flow_ * flow
Definition: decode.h:479
SigNumArray_
user data for storing signature id's in the radix tree
Definition: detect-engine-iponly.c:515
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:567
SigMatchData_::is_last
uint8_t is_last
Definition: detect.h:334
suricata-common.h
SIG_FLAG_SP_ANY
#define SIG_FLAG_SP_ANY
Definition: detect.h:213
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:1549
GenericVar_
Definition: util-var.h:48
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
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:944
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
DetectEngineIPOnlyCtx_::tree_ipv4dst
SCRadixTree * tree_ipv4dst
Definition: detect.h:722
IPOnlyCIDRItem_::ip
uint32_t ip[4]
Definition: detect.h:307
util-classification-config.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
UTHGenericTest
int UTHGenericTest(Packet **pkt, int numpkts, const char *sigs[], uint32_t sids[], uint32_t *results, int numsigs)
UTHGenericTest: function that perfom a generic check taking care of as maximum common unittest elemen...
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:184
Signature_::dp
DetectPort * dp
Definition: detect.h:589
str
#define str(s)
Definition: suricata-common.h:272
SCRadixNode_
Structure for the node in the radix tree.
Definition: util-radix-tree.h:61
head
Flow * head
Definition: flow-hash.h:1
GET_IPV6_SRC_ADDR
#define GET_IPV6_SRC_ADDR(p)
Definition: decode.h:230
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SignatureIsIPOnly
int SignatureIsIPOnly(DetectEngineCtx *de_ctx, const Signature *s)
Test is a initialized signature is IP only.
Definition: detect-engine-build.c:191
Signature_::cidr_dst
IPOnlyCIDRItem * cidr_dst
Definition: detect.h:596
SCNtohl
#define SCNtohl(x)
Definition: suricata-common.h:394
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
Signature_::id
uint32_t id
Definition: detect.h:583
detect-engine-iponly.h
detect-parse.h
src
uint16_t src
Definition: app-layer-dnp3.h:5
Signature_
Signature container.
Definition: detect.h:549
IP_GET_IPPROTO
#define IP_GET_IPPROTO(p)
Definition: decode.h:274
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:1525
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:839
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2400
DetectEngineCtx_::sig_array
Signature ** sig_array
Definition: detect.h:809
Address_::family
char family
Definition: decode.h:123
Packet_::dst
Address dst
Definition: decode.h:447
SigNumArray
struct SigNumArray_ SigNumArray
user data for storing signature id's in the radix tree
DetectEngineIPOnlyCtx_
IP only rules matching ctx.
Definition: detect.h:720
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:795
DetectEngineIPOnlyThreadInit
void DetectEngineIPOnlyThreadInit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyThreadCtx *io_tctx)
Setup the IP Only thread detection engine context.
Definition: detect-engine-iponly.c:894
GET_IPV4_SRC_ADDR_U32
#define GET_IPV4_SRC_ADDR_U32(p)
Definition: decode.h:223
DetectEngineCtx_::io_ctx
DetectEngineIPOnlyCtx io_ctx
Definition: detect.h:841
GET_IPV4_DST_ADDR_U32
#define GET_IPV4_DST_ADDR_U32(p)
Definition: decode.h:224
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
SigNumArray_::size
uint32_t size
Definition: detect-engine-iponly.c:517
Signature_::msg
char * msg
Definition: detect.h:609
flow.h
SigIntId
#define SigIntId
Definition: suricata-common.h:296
Packet_::dp
Port dp
Definition: decode.h:457
SCRuleVarsGetConfVar
const char * SCRuleVarsGetConfVar(const DetectEngineCtx *de_ctx, const char *conf_var_name, SCRuleVarsType conf_vars_type)
Definition: util-rule-vars.c:65
DetectEngineIPOnlyCtx_::tree_ipv6src
SCRadixTree * tree_ipv6src
Definition: detect.h:723
IPOnlyCIDRItem_::signum
SigIntId signum
Definition: detect.h:308
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:262
SIGMATCH_IPONLY_COMPAT
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1438
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:131
detect-engine-address.h
Packet_::src
Address src
Definition: decode.h:446
IPOnlyCIDRItem_::family
uint8_t family
Definition: detect.h:301
debug.h
SIG_FLAG_DP_ANY
#define SIG_FLAG_DP_ANY
Definition: detect.h:214
DetectPortLookupGroup
DetectPort * DetectPortLookupGroup(DetectPort *dp, uint16_t port)
Function that find the group matching address in a group head.
Definition: detect-engine-port.c:674
detect-engine-threshold.h
DetectEngineIPOnlyCtx_::max_idx
uint32_t max_idx
Definition: detect.h:727
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
DetectEngineIPOnlyThreadCtx_::sig_match_size
uint32_t sig_match_size
Definition: detect.h:716
DetectEngineIPOnlyThreadCtx_
Definition: detect.h:714