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