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