suricata
detect-threshold.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 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  * \ingroup threshold
20  * @{
21  */
22 
23 /**
24  * \file
25  *
26  * \author Breno Silva <breno.silva@gmail.com>
27  * \author Victor Julien <victor@inliniac.net>
28  *
29  * Implements the threshold keyword.
30  *
31  * The feature depends on what is provided
32  * by detect-engine-threshold.c and util-threshold-config.c
33  */
34 
35 #include "suricata-common.h"
36 #include "suricata.h"
37 #include "decode.h"
38 
39 #include "host.h"
40 #include "host-storage.h"
41 
42 #include "detect.h"
43 #include "detect-parse.h"
44 
45 #include "flow-var.h"
46 #include "decode-events.h"
47 #include "stream-tcp.h"
48 
49 #include "detect-threshold.h"
51 #include "detect-engine-address.h"
52 #include "detect-engine-build.h"
53 
54 #include "util-unittest.h"
55 #include "util-unittest-helper.h"
56 #include "util-byte.h"
57 #include "util-debug.h"
58 
59 #ifdef UNITTESTS
60 #include "util-cpu.h"
61 #endif
62 
63 #define PARSE_REGEX_NAME "(track|type|count|seconds|multiplier)"
64 #define PARSE_REGEX_VALUE \
65  "(limit|both|threshold|backoff|by_dst|by_src|by_both|by_rule|by_flow|\\d+)"
66 
67 #define PARSE_REGEX \
68  "^\\s*" PARSE_REGEX_NAME "\\s+" PARSE_REGEX_VALUE "\\s*,\\s*" PARSE_REGEX_NAME \
69  "\\s+" PARSE_REGEX_VALUE "\\s*,\\s*" PARSE_REGEX_NAME "\\s+" PARSE_REGEX_VALUE \
70  "\\s*,\\s*" PARSE_REGEX_NAME "\\s+" PARSE_REGEX_VALUE "\\s*"
71 
72 static DetectParseRegex parse_regex;
73 
74 static int DetectThresholdMatch(
75  DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *);
76 static int DetectThresholdSetup(DetectEngineCtx *, Signature *, const char *);
77 static void DetectThresholdFree(DetectEngineCtx *, void *);
78 #ifdef UNITTESTS
79 static void ThresholdRegisterTests(void);
80 #endif
81 
82 /**
83  * \brief Registration function for threshold: keyword
84  */
85 
87 {
88  sigmatch_table[DETECT_THRESHOLD].name = "threshold";
89  sigmatch_table[DETECT_THRESHOLD].desc = "control the rule's alert frequency";
90  sigmatch_table[DETECT_THRESHOLD].url = "/rules/thresholding.html#threshold";
91  sigmatch_table[DETECT_THRESHOLD].Match = DetectThresholdMatch;
92  sigmatch_table[DETECT_THRESHOLD].Setup = DetectThresholdSetup;
93  sigmatch_table[DETECT_THRESHOLD].Free = DetectThresholdFree;
94 #ifdef UNITTESTS
95  sigmatch_table[DETECT_THRESHOLD].RegisterTests = ThresholdRegisterTests;
96 #endif
97  /* this is compatible to ip-only signatures */
99 
100  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
101 }
102 
103 static int DetectThresholdMatch(
104  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
105 {
106  return 1;
107 }
108 
109 /**
110  * \internal
111  * \brief This function is used to parse threshold options passed via threshold: keyword
112  *
113  * \param rawstr Pointer to the user provided threshold options
114  *
115  * \retval de pointer to DetectThresholdData on success
116  * \retval NULL on failure
117  */
118 static DetectThresholdData *DetectThresholdParse(const char *rawstr)
119 {
120  DetectThresholdData *de = NULL;
121  int ret = 0, res = 0;
122  size_t pcre2_len;
123  const char *str_ptr = NULL;
124  char *args[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
125  char *copy_str = NULL, *threshold_opt = NULL;
126  int second_found = 0, count_found = 0;
127  int type_found = 0, track_found = 0;
128  int multiplier_found = 0;
129  int second_pos = 0, count_pos = 0, multiplier_pos = 0;
130  size_t pos = 0;
131  int i = 0;
132  pcre2_match_data *match = NULL;
133 
134  copy_str = SCStrdup(rawstr);
135  if (unlikely(copy_str == NULL)) {
136  goto error;
137  }
138 
139  char *saveptr = NULL;
140  for (pos = 0, threshold_opt = strtok_r(copy_str, ",", &saveptr);
141  pos < strlen(copy_str) && threshold_opt != NULL;
142  pos++, threshold_opt = strtok_r(NULL, ",", &saveptr)) {
143  if (strstr(threshold_opt, "count"))
144  count_found++;
145  if (strstr(threshold_opt, "second"))
146  second_found++;
147  if (strstr(threshold_opt, "type"))
148  type_found++;
149  if (strstr(threshold_opt, "track"))
150  track_found++;
151  if (strstr(threshold_opt, "multiplier"))
152  multiplier_found++;
153  }
154  SCFree(copy_str);
155  copy_str = NULL;
156 
157  if (!(count_found == 1 && (second_found == 1 || multiplier_found == 1) && track_found == 1 &&
158  type_found == 1)) {
159  goto error;
160  }
161 
162  ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0);
163  if (ret < 5 || ret > 9) {
164  SCLogError("pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
165  goto error;
166  }
167 
168  de = SCCalloc(1, sizeof(DetectThresholdData));
169  if (unlikely(de == NULL))
170  goto error;
171 
172  for (i = 0; i < (ret - 1); i++) {
173 
174  res = pcre2_substring_get_bynumber(match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
175 
176  if (res < 0) {
177  SCLogError("pcre2_substring_get_bynumber failed");
178  goto error;
179  }
180 
181  args[i] = (char *)str_ptr;
182 
183  if (strncasecmp(args[i], "limit", strlen("limit")) == 0)
184  de->type = TYPE_LIMIT;
185  if (strncasecmp(args[i], "both", strlen("both")) == 0)
186  de->type = TYPE_BOTH;
187  if (strncasecmp(args[i], "threshold", strlen("threshold")) == 0)
188  de->type = TYPE_THRESHOLD;
189  if (strcasecmp(args[i], "backoff") == 0)
190  de->type = TYPE_BACKOFF;
191  if (strncasecmp(args[i], "by_dst", strlen("by_dst")) == 0)
192  de->track = TRACK_DST;
193  if (strncasecmp(args[i], "by_src", strlen("by_src")) == 0)
194  de->track = TRACK_SRC;
195  if (strncasecmp(args[i], "by_both", strlen("by_both")) == 0)
196  de->track = TRACK_BOTH;
197  if (strncasecmp(args[i], "by_rule", strlen("by_rule")) == 0)
198  de->track = TRACK_RULE;
199  if (strncasecmp(args[i], "by_flow", strlen("by_flow")) == 0)
200  de->track = TRACK_FLOW;
201  if (strncasecmp(args[i], "count", strlen("count")) == 0)
202  count_pos = i + 1;
203  if (strncasecmp(args[i], "seconds", strlen("seconds")) == 0)
204  second_pos = i + 1;
205  if (strcasecmp(args[i], "multiplier") == 0)
206  multiplier_pos = i + 1;
207  }
208 
209  if (de->type != TYPE_BACKOFF) {
210  if (args[count_pos] == NULL || args[second_pos] == NULL) {
211  goto error;
212  }
213 
214  if (StringParseUint32(&de->count, 10, strlen(args[count_pos]), args[count_pos]) <= 0) {
215  goto error;
216  }
217  if (StringParseUint32(&de->seconds, 10, strlen(args[second_pos]), args[second_pos]) <= 0) {
218  goto error;
219  }
220  } else {
221  if (args[count_pos] == NULL || args[multiplier_pos] == NULL) {
222  goto error;
223  }
224 
225  if (second_found) {
226  goto error;
227  }
228 
229  if (StringParseUint32(&de->count, 10, strlen(args[count_pos]), args[count_pos]) <= 0) {
230  goto error;
231  }
232  if (StringParseUint32(
233  &de->multiplier, 10, strlen(args[multiplier_pos]), args[multiplier_pos]) <= 0) {
234  goto error;
235  }
236 
237  /* impose some sanity limits on the count and multiplier values. Upper bounds are a bit
238  * artificial. */
239  if (!(de->count > 0 && de->count < 65536)) {
240  SCLogError("invalid count value '%u': must be in the range 1-65535", de->count);
241  goto error;
242  }
243  if (!(de->multiplier > 1 && de->multiplier < 65536)) {
244  SCLogError(
245  "invalid multiplier value '%u': must be in the range 2-65535", de->multiplier);
246  goto error;
247  }
248 
249  if (de->track != TRACK_FLOW) {
250  SCLogError("invalid track value: type backoff only supported for track by_flow");
251  goto error;
252  }
253 
254  SCLogDebug("TYPE_BACKOFF count %u multiplier %u", de->count, de->multiplier);
255  }
256 
257  for (i = 0; i < (ret - 1); i++) {
258  if (args[i] != NULL)
259  pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
260  }
261  pcre2_match_data_free(match);
262  return de;
263 
264 error:
265  if (match) {
266  pcre2_match_data_free(match);
267  }
268  for (i = 0; i < (ret - 1); i++) {
269  if (args[i] != NULL)
270  pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
271  }
272  if (de != NULL)
273  SCFree(de);
274  return NULL;
275 }
276 
277 /**
278  * \internal
279  * \brief this function is used to add the parsed threshold into the current signature
280  *
281  * \param de_ctx pointer to the Detection Engine Context
282  * \param s pointer to the Current Signature
283  * \param rawstr pointer to the user provided threshold options
284  *
285  * \retval 0 on Success
286  * \retval -1 on Failure
287  */
288 static int DetectThresholdSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
289 {
290  DetectThresholdData *de = NULL;
291  SigMatch *tmpm = NULL;
292 
293  /* checks if there is a previous instance of detection_filter */
295  if (tmpm != NULL) {
296  if (tmpm->type == DETECT_DETECTION_FILTER) {
297  SCLogError("\"detection_filter\" and "
298  "\"threshold\" are not allowed in the same rule");
299  } else {
300  SCLogError("multiple \"threshold\" "
301  "options are not allowed in the same rule");
302  }
303  SCReturnInt(-1);
304  }
305 
306  de = DetectThresholdParse(rawstr);
307  if (de == NULL)
308  goto error;
309 
312  goto error;
313  }
314 
315  return 0;
316 
317 error:
318  if (de)
319  SCFree(de);
320  return -1;
321 }
322 
323 /**
324  * \internal
325  * \brief this function will free memory associated with DetectThresholdData
326  *
327  * \param de pointer to DetectThresholdData
328  */
329 static void DetectThresholdFree(DetectEngineCtx *de_ctx, void *de_ptr)
330 {
332  if (de) {
333  DetectAddressHeadCleanup(&de->addrs);
334  SCFree(de);
335  }
336 }
337 
338 /**
339  * \brief Make a deep-copy of an extant DetectTHresholdData object.
340  *
341  * \param de pointer to DetectThresholdData
342  */
344 {
345  DetectThresholdData *new_de = SCCalloc(1, sizeof(DetectThresholdData));
346  if (unlikely(new_de == NULL))
347  return NULL;
348 
349  *new_de = *de;
350  new_de->addrs.ipv4_head = NULL;
351  new_de->addrs.ipv6_head = NULL;
352 
353  for (DetectAddress *last = NULL, *tmp_ad = de->addrs.ipv4_head; tmp_ad; tmp_ad = tmp_ad->next) {
354  DetectAddress *n_addr = DetectAddressCopy(tmp_ad);
355  if (n_addr == NULL)
356  goto error;
357  if (last == NULL) {
358  new_de->addrs.ipv4_head = n_addr;
359  } else {
360  last->next = n_addr;
361  n_addr->prev = last;
362  }
363  last = n_addr;
364  }
365  for (DetectAddress *last = NULL, *tmp_ad = de->addrs.ipv6_head; tmp_ad; tmp_ad = tmp_ad->next) {
366  DetectAddress *n_addr = DetectAddressCopy(tmp_ad);
367  if (n_addr == NULL)
368  goto error;
369  if (last == NULL) {
370  new_de->addrs.ipv6_head = n_addr;
371  } else {
372  last->next = n_addr;
373  n_addr->prev = last;
374  }
375  last = n_addr;
376  }
377 
378  return new_de;
379 
380 error:
381  DetectThresholdFree(NULL, new_de);
382  return NULL;
383 }
384 
385 /*
386  * ONLY TESTS BELOW THIS COMMENT
387  */
388 #ifdef UNITTESTS
389 #include "detect-engine.h"
390 #include "detect-engine-mpm.h"
391 #include "detect-engine-alert.h"
392 #include "util-time.h"
393 #include "util-hashlist.h"
394 #include "packet.h"
395 #include "action-globals.h"
396 
397 /**
398  * \test ThresholdTestParse01 is a test for a valid threshold options
399  *
400  * \retval 1 on success
401  * \retval 0 on failure
402  */
403 static int ThresholdTestParse01(void)
404 {
405  DetectThresholdData *de = NULL;
406  de = DetectThresholdParse("type limit,track by_dst,count 10,seconds 60");
407  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
408  (de->seconds == 60)) {
409  DetectThresholdFree(NULL, de);
410  return 1;
411  }
412 
413  return 0;
414 }
415 
416 static int ThresholdTestParseByFlow01(void)
417 {
418  DetectThresholdData *de = DetectThresholdParse("type limit,track by_flow,count 1,seconds 60");
419  FAIL_IF_NULL(de);
420  FAIL_IF_NOT(de->type == TYPE_LIMIT);
421  FAIL_IF_NOT(de->track == TRACK_FLOW);
422  FAIL_IF_NOT(de->count == 1);
423  FAIL_IF_NOT(de->seconds == 60);
424  DetectThresholdFree(NULL, de);
425  PASS;
426 }
427 
428 /**
429  * \test ThresholdTestParse02 is a test for a invalid threshold options
430  *
431  * \retval 1 on success
432  * \retval 0 on failure
433  */
434 static int ThresholdTestParse02(void)
435 {
436  DetectThresholdData *de = NULL;
437  de = DetectThresholdParse("type any,track by_dst,count 10,seconds 60");
438  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
439  (de->seconds == 60)) {
440  DetectThresholdFree(NULL, de);
441  return 0;
442  }
443 
444  return 1;
445 }
446 
447 /**
448  * \test ThresholdTestParse03 is a test for a valid threshold options in any order
449  *
450  * \retval 1 on success
451  * \retval 0 on failure
452  */
453 static int ThresholdTestParse03(void)
454 {
455  DetectThresholdData *de = NULL;
456  de = DetectThresholdParse("track by_dst, type limit, seconds 60, count 10");
457  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
458  (de->seconds == 60)) {
459  DetectThresholdFree(NULL, de);
460  return 1;
461  }
462 
463  return 0;
464 }
465 
466 /**
467  * \test ThresholdTestParse04 is a test for an invalid threshold options in any order
468  *
469  * \retval 1 on success
470  * \retval 0 on failure
471  */
472 static int ThresholdTestParse04(void)
473 {
474  DetectThresholdData *de = NULL;
475  de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both, count 10");
476  if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) &&
477  (de->seconds == 60)) {
478  DetectThresholdFree(NULL, de);
479  return 0;
480  }
481 
482  return 1;
483 }
484 
485 /**
486  * \test ThresholdTestParse05 is a test for a valid threshold options in any order
487  *
488  * \retval 1 on success
489  * \retval 0 on failure
490  */
491 static int ThresholdTestParse05(void)
492 {
493  DetectThresholdData *de = NULL;
494  de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both");
495  if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) &&
496  (de->seconds == 60)) {
497  DetectThresholdFree(NULL, de);
498  return 1;
499  }
500 
501  return 0;
502 }
503 
504 /**
505  * \test ThresholdTestParse06 is a test for thresholding by_both
506  *
507  * \retval 1 on success
508  * \retval 0 on failure
509  */
510 static int ThresholdTestParse06(void)
511 {
512  DetectThresholdData *de = NULL;
513  de = DetectThresholdParse("count 10, track by_both, seconds 60, type limit");
514  FAIL_IF_NULL(de);
515  FAIL_IF_NOT(de->type == TYPE_LIMIT);
516  FAIL_IF_NOT(de->track == TRACK_BOTH);
517  FAIL_IF_NOT(de->count == 10);
518  FAIL_IF_NOT(de->seconds == 60);
519  DetectThresholdFree(NULL, de);
520  PASS;
521 }
522 
523 /**
524  * \test ThresholdTestParse07 is a test for thresholding by_rule
525  *
526  * \retval 1 on success
527  * \retval 0 on failure
528  */
529 static int ThresholdTestParse07(void)
530 {
531  DetectThresholdData *de = NULL;
532  de = DetectThresholdParse("count 10, track by_rule, seconds 60, type limit");
533  FAIL_IF_NULL(de);
534  FAIL_IF_NOT(de->type == TYPE_LIMIT);
535  FAIL_IF_NOT(de->track == TRACK_RULE);
536  FAIL_IF_NOT(de->count == 10);
537  FAIL_IF_NOT(de->seconds == 60);
538  DetectThresholdFree(NULL, de);
539  PASS;
540 }
541 
542 /** \test backoff by_flow */
543 static int ThresholdTestParse08(void)
544 {
546  DetectThresholdParse("count 10, track by_flow, multiplier 2, type backoff");
547  FAIL_IF_NULL(de);
548  FAIL_IF_NOT(de->type == TYPE_BACKOFF);
549  FAIL_IF_NOT(de->track == TRACK_FLOW);
550  FAIL_IF_NOT(de->count == 10);
551  FAIL_IF_NOT(de->multiplier == 2);
552  DetectThresholdFree(NULL, de);
553  PASS;
554 }
555 
556 /**
557  * \test DetectThresholdTestSig1 is a test for checking the working of limit keyword
558  * by setting up the signature and later testing its working by matching
559  * the received packet against the sig.
560  *
561  * \retval 1 on success
562  * \retval 0 on failure
563  */
564 
565 static int DetectThresholdTestSig1(void)
566 {
567  Packet *p = NULL;
568  Signature *s = NULL;
569  ThreadVars th_v;
570  DetectEngineThreadCtx *det_ctx;
571  int result = 0;
572  int alerts = 0;
573 
574  ThresholdInit();
575 
576  memset(&th_v, 0, sizeof(th_v));
577 
578  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
579 
581  if (de_ctx == NULL) {
582  goto end;
583  }
584 
585  de_ctx->flags |= DE_QUIET;
586 
587  s = de_ctx->sig_list =
588  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit\"; content:\"A\"; "
589  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
590  if (s == NULL) {
591  goto end;
592  }
593 
595 
597 
598  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
599 
600  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
601  alerts = PacketAlertCheck(p, 1);
602  if (alerts != 1) {
603  printf("alerts %" PRIi32 ", expected 1: ", alerts);
604  }
605  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
606  alerts += PacketAlertCheck(p, 1);
607  if (alerts != 2) {
608  printf("alerts %" PRIi32 ", expected 2: ", alerts);
609  }
610  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
611  alerts += PacketAlertCheck(p, 1);
612  if (alerts != 3) {
613  printf("alerts %" PRIi32 ", expected 3: ", alerts);
614  }
615  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
616  alerts += PacketAlertCheck(p, 1);
617  if (alerts != 4) {
618  printf("alerts %" PRIi32 ", expected 4: ", alerts);
619  }
620  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
621  alerts += PacketAlertCheck(p, 1);
622  if (alerts != 5) {
623  printf("alerts %" PRIi32 ", expected 5: ", alerts);
624  }
625  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
626  alerts += PacketAlertCheck(p, 1);
627  if (alerts != 5) {
628  printf("alerts %" PRIi32 ", expected 5: ", alerts);
629  }
630  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
631  alerts += PacketAlertCheck(p, 1);
632  if (alerts != 5) {
633  printf("alerts %" PRIi32 ", expected 5: ", alerts);
634  }
635  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
636  alerts += PacketAlertCheck(p, 1);
637  if (alerts != 5) {
638  printf("alerts %" PRIi32 ", expected 5: ", alerts);
639  }
640 
641  if (alerts == 5)
642  result = 1;
643  else
644  printf("alerts %" PRIi32 ", expected 5: ", alerts);
645 
648 
649  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
651 
652  UTHFreePackets(&p, 1);
653 
654 end:
656  return result;
657 }
658 
659 /**
660  * \test DetectThresholdTestSig2 is a test for checking the working of threshold keyword
661  * by setting up the signature and later testing its working by matching
662  * the received packet against the sig.
663  *
664  * \retval 1 on success
665  * \retval 0 on failure
666  */
667 
668 static int DetectThresholdTestSig2(void)
669 {
670  Packet *p = NULL;
671  Signature *s = NULL;
672  ThreadVars th_v;
673  DetectEngineThreadCtx *det_ctx;
674  int result = 0;
675  int alerts = 0;
676 
677  ThresholdInit();
678 
679  memset(&th_v, 0, sizeof(th_v));
680 
681  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
682 
684  if (de_ctx == NULL) {
685  goto end;
686  }
687 
688  de_ctx->flags |= DE_QUIET;
689 
690  s = de_ctx->sig_list =
691  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold\"; threshold: type "
692  "threshold, track by_dst, count 5, seconds 60; sid:1;)");
693  if (s == NULL) {
694  goto end;
695  }
696 
698  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
699 
700  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
701  alerts = PacketAlertCheck(p, 1);
702  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
703  alerts += PacketAlertCheck(p, 1);
704  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
705  alerts += PacketAlertCheck(p, 1);
706  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
707  alerts += PacketAlertCheck(p, 1);
708  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
709  alerts += PacketAlertCheck(p, 1);
710  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
711  alerts += PacketAlertCheck(p, 1);
712  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
713  alerts += PacketAlertCheck(p, 1);
714  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
715  alerts += PacketAlertCheck(p, 1);
716  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
717  alerts += PacketAlertCheck(p, 1);
718  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
719  alerts += PacketAlertCheck(p, 1);
720 
721  if (alerts == 2)
722  result = 1;
723  else
724  goto cleanup;
725 
726 cleanup:
727  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
729 
730 end:
731  UTHFreePackets(&p, 1);
733  return result;
734 }
735 
736 /**
737  * \test DetectThresholdTestSig3 is a test for checking the working of limit keyword
738  * by setting up the signature and later testing its working by matching
739  * the received packet against the sig.
740  *
741  * \retval 1 on success
742  * \retval 0 on failure
743  */
744 
745 static int DetectThresholdTestSig3(void)
746 {
747  ThreadVars th_v;
748  memset(&th_v, 0, sizeof(th_v));
749 
750  ThresholdInit();
751  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
752 
755  de_ctx->flags |= DE_QUIET;
756 
758  "alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, "
759  "track by_dst, count 5, seconds 60; sid:10;)");
760  FAIL_IF_NULL(s);
761 
763  DetectEngineThreadCtx *det_ctx;
764  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
765 
766  p->ts = TimeGet();
767 
768  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
769  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
770  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
771  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
772  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
773  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
774 
776  p->ts = TimeGet();
777 
778  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
779  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
780  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
781  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
782  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
783  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
784 
785  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
787  UTHFreePackets(&p, 1);
789  PASS;
790 }
791 
792 /**
793  * \test DetectThresholdTestSig4 is a test for checking the working of both keyword
794  * by setting up the signature and later testing its working by matching
795  * the received packet against the sig.
796  *
797  * \retval 1 on success
798  * \retval 0 on failure
799  */
800 
801 static int DetectThresholdTestSig4(void)
802 {
803  Packet *p = NULL;
804  Signature *s = NULL;
805  ThreadVars th_v;
806  DetectEngineThreadCtx *det_ctx;
807  int result = 0;
808  int alerts = 0;
809 
810  ThresholdInit();
811 
812  memset(&th_v, 0, sizeof(th_v));
813 
814  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
815 
817  if (de_ctx == NULL) {
818  goto end;
819  }
820 
821  de_ctx->flags |= DE_QUIET;
822 
823  s = de_ctx->sig_list =
824  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold both\"; threshold: type "
825  "both, track by_dst, count 2, seconds 60; sid:10;)");
826  if (s == NULL) {
827  goto end;
828  }
829 
831  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
832 
833  p->ts = TimeGet();
834  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
835  alerts = PacketAlertCheck(p, 10);
836  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
837  alerts += PacketAlertCheck(p, 10);
838  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
839  alerts += PacketAlertCheck(p, 10);
840 
842  p->ts = TimeGet();
843 
844  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
845  alerts += PacketAlertCheck(p, 10);
846  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
847  alerts += PacketAlertCheck(p, 10);
848  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
849  alerts += PacketAlertCheck(p, 10);
850 
851  if (alerts == 2)
852  result = 1;
853  else
854  goto cleanup;
855 
856 cleanup:
857  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
859 end:
860  UTHFreePackets(&p, 1);
862  return result;
863 }
864 
865 /**
866  * \test DetectThresholdTestSig5 is a test for checking the working of limit keyword
867  * by setting up the signature and later testing its working by matching
868  * the received packet against the sig.
869  *
870  * \retval 1 on success
871  * \retval 0 on failure
872  */
873 
874 static int DetectThresholdTestSig5(void)
875 {
876  Packet *p = NULL;
877  Signature *s = NULL;
878  ThreadVars th_v;
879  DetectEngineThreadCtx *det_ctx;
880  int result = 0;
881  int alerts = 0;
882 
883  ThresholdInit();
884 
885  memset(&th_v, 0, sizeof(th_v));
886  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
887 
889  if (de_ctx == NULL) {
890  goto end;
891  }
892 
893  de_ctx->flags |= DE_QUIET;
894 
895  s = de_ctx->sig_list =
896  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
897  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
898  if (s == NULL) {
899  goto end;
900  }
901 
902  s = s->next =
903  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; "
904  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
905  if (s == NULL) {
906  goto end;
907  }
908 
910  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
911 
912  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
913  alerts = PacketAlertCheck(p, 1);
914  alerts += PacketAlertCheck(p, 1000);
915  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
916  alerts += PacketAlertCheck(p, 1);
917  alerts += PacketAlertCheck(p, 1000);
918  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
919  alerts += PacketAlertCheck(p, 1);
920  alerts += PacketAlertCheck(p, 1000);
921  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
922  alerts += PacketAlertCheck(p, 1);
923  alerts += PacketAlertCheck(p, 1000);
924  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
925  alerts += PacketAlertCheck(p, 1);
926  alerts += PacketAlertCheck(p, 1000);
927  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
928  alerts += PacketAlertCheck(p, 1);
929  alerts += PacketAlertCheck(p, 1000);
930  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
931  alerts += PacketAlertCheck(p, 1);
932  alerts += PacketAlertCheck(p, 1000);
933  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
934  alerts += PacketAlertCheck(p, 1);
935  alerts += PacketAlertCheck(p, 1000);
936 
937  if (alerts == 10)
938  result = 1;
939  else {
940  printf("alerts %d != 10: ", alerts);
941  goto cleanup;
942  }
943 
944 cleanup:
945  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
947 
948 end:
949  UTHFreePackets(&p, 1);
951  return result;
952 }
953 
954 static int DetectThresholdTestSig6Ticks(void)
955 {
956  Packet *p = NULL;
957  Signature *s = NULL;
958  ThreadVars th_v;
959  DetectEngineThreadCtx *det_ctx;
960  int result = 0;
961  int alerts = 0;
962 
963  ThresholdInit();
964 
965  memset(&th_v, 0, sizeof(th_v));
966  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
967 
969  if (de_ctx == NULL) {
970  goto end;
971  }
972 
973  de_ctx->flags |= DE_QUIET;
974 
975  s = de_ctx->sig_list =
976  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
977  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
978  if (s == NULL) {
979  goto end;
980  }
981 
982  s = s->next =
983  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; "
984  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
985  if (s == NULL) {
986  goto end;
987  }
988 
990  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
991 
992  uint64_t ticks_start = 0;
993  uint64_t ticks_end = 0;
994 
995  ticks_start = UtilCpuGetTicks();
996  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
997  alerts = PacketAlertCheck(p, 1);
998  alerts += PacketAlertCheck(p, 1000);
999  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1000  alerts += PacketAlertCheck(p, 1);
1001  alerts += PacketAlertCheck(p, 1000);
1002  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1003  alerts += PacketAlertCheck(p, 1);
1004  alerts += PacketAlertCheck(p, 1000);
1005  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1006  alerts += PacketAlertCheck(p, 1);
1007  alerts += PacketAlertCheck(p, 1000);
1008  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1009  alerts += PacketAlertCheck(p, 1);
1010  alerts += PacketAlertCheck(p, 1000);
1011  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1012  alerts += PacketAlertCheck(p, 1);
1013  alerts += PacketAlertCheck(p, 1000);
1014  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1015  alerts += PacketAlertCheck(p, 1);
1016  alerts += PacketAlertCheck(p, 1000);
1017  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1018  alerts += PacketAlertCheck(p, 1);
1019  alerts += PacketAlertCheck(p, 1000);
1020  ticks_end = UtilCpuGetTicks();
1021  printf("test run %" PRIu64 "\n", (ticks_end - ticks_start));
1022 
1023  if (alerts == 10)
1024  result = 1;
1025  else
1026  goto cleanup;
1027 
1028 cleanup:
1029  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1031 
1032 end:
1033  UTHFreePackets(&p, 1);
1034  ThresholdDestroy();
1035  return result;
1036 }
1037 
1038 /**
1039  * \test Test drop action being set even if thresholded
1040  */
1041 static int DetectThresholdTestSig7(void)
1042 {
1043  Packet *p = NULL;
1044  Signature *s = NULL;
1045  ThreadVars th_v;
1046  DetectEngineThreadCtx *det_ctx;
1047  int result = 0;
1048  int alerts = 0;
1049  int drops = 0;
1050 
1051  ThresholdInit();
1052 
1053  memset(&th_v, 0, sizeof(th_v));
1054 
1055  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1056 
1058  if (de_ctx == NULL) {
1059  goto end;
1060  }
1061 
1062  de_ctx->flags |= DE_QUIET;
1063 
1064  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type limit, "
1065  "track by_src, count 1, seconds 300; sid:10;)");
1066  if (s == NULL) {
1067  goto end;
1068  }
1069 
1071  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1072 
1073  p->ts = TimeGet();
1074  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1075  alerts = PacketAlertCheck(p, 10);
1076  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1077  p->action = 0;
1078 
1079  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1080  alerts += PacketAlertCheck(p, 10);
1081  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1082  p->action = 0;
1083 
1084  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1085  alerts += PacketAlertCheck(p, 10);
1086  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1087  p->action = 0;
1088 
1089  TimeSetIncrementTime(200);
1090  p->ts = TimeGet();
1091 
1092  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1093  alerts += PacketAlertCheck(p, 10);
1094  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1095  p->action = 0;
1096 
1097  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1098  alerts += PacketAlertCheck(p, 10);
1099  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1100  p->action = 0;
1101 
1102  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1103  alerts += PacketAlertCheck(p, 10);
1104  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1105  p->action = 0;
1106 
1107  if (alerts == 1 && drops == 6)
1108  result = 1;
1109  else {
1110  if (alerts != 1)
1111  printf("alerts: %d != 1: ", alerts);
1112  if (drops != 6)
1113  printf("drops: %d != 6: ", drops);
1114  goto cleanup;
1115  }
1116 
1117 cleanup:
1118  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1120 end:
1121  UTHFreePackets(&p, 1);
1122  ThresholdDestroy();
1123  return result;
1124 }
1125 
1126 /**
1127  * \test Test drop action being set even if thresholded
1128  */
1129 static int DetectThresholdTestSig8(void)
1130 {
1131  Packet *p = NULL;
1132  Signature *s = NULL;
1133  ThreadVars th_v;
1134  DetectEngineThreadCtx *det_ctx;
1135  int result = 0;
1136  int alerts = 0;
1137  int drops = 0;
1138 
1139  ThresholdInit();
1140 
1141  memset(&th_v, 0, sizeof(th_v));
1142 
1143  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1144 
1146  if (de_ctx == NULL) {
1147  goto end;
1148  }
1149 
1150  de_ctx->flags |= DE_QUIET;
1151 
1152  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type limit, "
1153  "track by_src, count 2, seconds 300; sid:10;)");
1154  if (s == NULL) {
1155  goto end;
1156  }
1157 
1159  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1160 
1161  p->ts = TimeGet();
1162  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1163  alerts = PacketAlertCheck(p, 10);
1164  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1165  p->action = 0;
1166 
1167  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1168  alerts += PacketAlertCheck(p, 10);
1169  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1170  p->action = 0;
1171 
1172  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1173  alerts += PacketAlertCheck(p, 10);
1174  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1175  p->action = 0;
1176 
1177  TimeSetIncrementTime(200);
1178  p->ts = TimeGet();
1179 
1180  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1181  alerts += PacketAlertCheck(p, 10);
1182  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1183  p->action = 0;
1184 
1185  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1186  alerts += PacketAlertCheck(p, 10);
1187  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1188  p->action = 0;
1189 
1190  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1191  alerts += PacketAlertCheck(p, 10);
1192  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1193  p->action = 0;
1194 
1195  if (alerts == 2 && drops == 6)
1196  result = 1;
1197  else {
1198  if (alerts != 1)
1199  printf("alerts: %d != 1: ", alerts);
1200  if (drops != 6)
1201  printf("drops: %d != 6: ", drops);
1202  goto cleanup;
1203  }
1204 
1205 cleanup:
1206  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1208 end:
1209  UTHFreePackets(&p, 1);
1210  ThresholdDestroy();
1211  return result;
1212 }
1213 
1214 /**
1215  * \test Test drop action being set even if thresholded
1216  */
1217 static int DetectThresholdTestSig9(void)
1218 {
1219  Packet *p = NULL;
1220  Signature *s = NULL;
1221  ThreadVars th_v;
1222  DetectEngineThreadCtx *det_ctx;
1223  int result = 0;
1224  int alerts = 0;
1225  int drops = 0;
1226 
1227  ThresholdInit();
1228 
1229  memset(&th_v, 0, sizeof(th_v));
1230 
1231  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1232 
1234  if (de_ctx == NULL) {
1235  goto end;
1236  }
1237 
1238  de_ctx->flags |= DE_QUIET;
1239 
1240  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type threshold, "
1241  "track by_src, count 3, seconds 100; sid:10;)");
1242  if (s == NULL) {
1243  goto end;
1244  }
1245 
1247  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1248 
1249  p->ts = TimeGet();
1250  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1251  alerts = PacketAlertCheck(p, 10);
1252  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1253  p->action = 0;
1254 
1255  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1256  alerts += PacketAlertCheck(p, 10);
1257  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1258  p->action = 0;
1259 
1260  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1261  alerts += PacketAlertCheck(p, 10);
1262  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1263  p->action = 0;
1264 
1265  TimeSetIncrementTime(200);
1266  p->ts = TimeGet();
1267 
1268  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1269  alerts += PacketAlertCheck(p, 10);
1270  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1271  p->action = 0;
1272 
1273  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1274  alerts += PacketAlertCheck(p, 10);
1275  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1276  p->action = 0;
1277 
1278  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1279  alerts += PacketAlertCheck(p, 10);
1280  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1281  p->action = 0;
1282 
1283  if (alerts == 2 && drops == 2)
1284  result = 1;
1285  else {
1286  if (alerts != 2)
1287  printf("alerts: %d != 2: ", alerts);
1288  if (drops != 2)
1289  printf("drops: %d != 2: ", drops);
1290  goto cleanup;
1291  }
1292 
1293 cleanup:
1294  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1296 end:
1297  UTHFreePackets(&p, 1);
1298  ThresholdDestroy();
1299  return result;
1300 }
1301 
1302 /**
1303  * \test Test drop action being set even if thresholded
1304  */
1305 static int DetectThresholdTestSig10(void)
1306 {
1307  Packet *p = NULL;
1308  Signature *s = NULL;
1309  ThreadVars th_v;
1310  DetectEngineThreadCtx *det_ctx;
1311  int result = 0;
1312  int alerts = 0;
1313  int drops = 0;
1314 
1315  ThresholdInit();
1316 
1317  memset(&th_v, 0, sizeof(th_v));
1318 
1319  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1320 
1322  if (de_ctx == NULL) {
1323  goto end;
1324  }
1325 
1326  de_ctx->flags |= DE_QUIET;
1327 
1328  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type threshold, "
1329  "track by_src, count 5, seconds 300; sid:10;)");
1330  if (s == NULL) {
1331  goto end;
1332  }
1333 
1335  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1336 
1337  p->ts = TimeGet();
1338  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1339  alerts = PacketAlertCheck(p, 10);
1340  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1341  p->action = 0;
1342 
1343  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1344  alerts += PacketAlertCheck(p, 10);
1345  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1346  p->action = 0;
1347 
1348  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1349  alerts += PacketAlertCheck(p, 10);
1350  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1351  p->action = 0;
1352 
1353  TimeSetIncrementTime(200);
1354  p->ts = TimeGet();
1355 
1356  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1357  alerts += PacketAlertCheck(p, 10);
1358  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1359  p->action = 0;
1360 
1361  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1362  alerts += PacketAlertCheck(p, 10);
1363  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1364  p->action = 0;
1365 
1366  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1367  alerts += PacketAlertCheck(p, 10);
1368  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1369  p->action = 0;
1370 
1371  if (alerts == 1 && drops == 1)
1372  result = 1;
1373  else {
1374  if (alerts != 1)
1375  printf("alerts: %d != 1: ", alerts);
1376  if (drops != 1)
1377  printf("drops: %d != 1: ", drops);
1378  goto cleanup;
1379  }
1380 
1381 cleanup:
1382  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1384 end:
1385  UTHFreePackets(&p, 1);
1386  ThresholdDestroy();
1387  return result;
1388 }
1389 
1390 /**
1391  * \test Test drop action being set even if thresholded
1392  */
1393 static int DetectThresholdTestSig11(void)
1394 {
1395  Packet *p = NULL;
1396  Signature *s = NULL;
1397  ThreadVars th_v;
1398  DetectEngineThreadCtx *det_ctx;
1399  int result = 0;
1400  int alerts = 0;
1401  int drops = 0;
1402 
1403  ThresholdInit();
1404 
1405  memset(&th_v, 0, sizeof(th_v));
1406 
1407  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1408 
1410  if (de_ctx == NULL) {
1411  goto end;
1412  }
1413 
1414  de_ctx->flags |= DE_QUIET;
1415 
1416  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type both, "
1417  "track by_src, count 3, seconds 300; sid:10;)");
1418  if (s == NULL) {
1419  goto end;
1420  }
1421 
1423  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1424 
1425  p->ts = TimeGet();
1426  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1427  alerts = PacketAlertCheck(p, 10);
1428  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1429  p->action = 0;
1430 
1431  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1432  alerts += PacketAlertCheck(p, 10);
1433  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1434  p->action = 0;
1435 
1436  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1437  alerts += PacketAlertCheck(p, 10);
1438  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1439  p->action = 0;
1440 
1441  TimeSetIncrementTime(200);
1442  p->ts = TimeGet();
1443 
1444  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1445  alerts += PacketAlertCheck(p, 10);
1446  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1447  p->action = 0;
1448 
1449  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1450  alerts += PacketAlertCheck(p, 10);
1451  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1452  p->action = 0;
1453 
1454  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1455  alerts += PacketAlertCheck(p, 10);
1456  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1457  p->action = 0;
1458 
1459  if (alerts == 1 && drops == 4)
1460  result = 1;
1461  else {
1462  if (alerts != 1)
1463  printf("alerts: %d != 1: ", alerts);
1464  if (drops != 4)
1465  printf("drops: %d != 4: ", drops);
1466  goto cleanup;
1467  }
1468 
1469 cleanup:
1470  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1472 end:
1473  UTHFreePackets(&p, 1);
1474  ThresholdDestroy();
1475  return result;
1476 }
1477 
1478 /**
1479  * \test Test drop action being set even if thresholded
1480  */
1481 static int DetectThresholdTestSig12(void)
1482 {
1483  Packet *p = NULL;
1484  Signature *s = NULL;
1485  ThreadVars th_v;
1486  DetectEngineThreadCtx *det_ctx;
1487  int result = 0;
1488  int alerts = 0;
1489  int drops = 0;
1490 
1491  ThresholdInit();
1492 
1493  memset(&th_v, 0, sizeof(th_v));
1494 
1495  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1496 
1498  if (de_ctx == NULL) {
1499  goto end;
1500  }
1501 
1502  de_ctx->flags |= DE_QUIET;
1503 
1504  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type both, "
1505  "track by_src, count 5, seconds 300; sid:10;)");
1506  if (s == NULL) {
1507  goto end;
1508  }
1509 
1511  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1512 
1513  p->ts = TimeGet();
1514  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1515  alerts = PacketAlertCheck(p, 10);
1516  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1517  p->action = 0;
1518 
1519  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1520  alerts += PacketAlertCheck(p, 10);
1521  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1522  p->action = 0;
1523 
1524  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1525  alerts += PacketAlertCheck(p, 10);
1526  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1527  p->action = 0;
1528 
1529  TimeSetIncrementTime(200);
1530  p->ts = TimeGet();
1531 
1532  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1533  alerts += PacketAlertCheck(p, 10);
1534  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1535  p->action = 0;
1536 
1537  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1538  alerts += PacketAlertCheck(p, 10);
1539  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1540  p->action = 0;
1541 
1542  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1543  alerts += PacketAlertCheck(p, 10);
1544  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1545  p->action = 0;
1546 
1547  if (alerts == 1 && drops == 2)
1548  result = 1;
1549  else {
1550  if (alerts != 1)
1551  printf("alerts: %d != 1: ", alerts);
1552  if (drops != 2)
1553  printf("drops: %d != 2: ", drops);
1554  goto cleanup;
1555  }
1556 
1557 cleanup:
1558  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1560 end:
1561  UTHFreePackets(&p, 1);
1562  HostShutdown();
1563  ThresholdDestroy();
1564  return result;
1565 }
1566 
1567 /**
1568  * \test DetectThresholdTestSig13 is a test for checking the working by_rule limits
1569  * by setting up the signature and later testing its working by matching
1570  * received packets against the sig.
1571  *
1572  * \retval 1 on success
1573  * \retval 0 on failure
1574  */
1575 
1576 static int DetectThresholdTestSig13(void)
1577 {
1578  Packet *p = NULL;
1579  Signature *s = NULL;
1580  ThreadVars th_v;
1581  DetectEngineThreadCtx *det_ctx;
1582  int alerts = 0;
1583 
1584  ThresholdInit();
1585 
1586  memset(&th_v, 0, sizeof(th_v));
1587  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1588  FAIL_IF_NULL(p);
1589 
1592 
1593  de_ctx->flags |= DE_QUIET;
1594 
1595  s = de_ctx->sig_list =
1596  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
1597  "threshold: type limit, track by_rule, count 2, seconds 60; sid:1;)");
1598  FAIL_IF_NULL(s);
1599 
1601  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1602 
1603  /* should alert twice */
1604  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1605  alerts += PacketAlertCheck(p, 1);
1606  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1607  alerts += PacketAlertCheck(p, 1);
1608  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1609  alerts += PacketAlertCheck(p, 1);
1610  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1611  alerts += PacketAlertCheck(p, 1);
1612 
1613  FAIL_IF(alerts != 2);
1614 
1616  p->ts = TimeGet();
1617 
1618  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1619  alerts += PacketAlertCheck(p, 1);
1620  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1621  alerts += PacketAlertCheck(p, 1);
1622  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1623  alerts += PacketAlertCheck(p, 1);
1624  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1625  alerts += PacketAlertCheck(p, 1);
1626 
1627  FAIL_IF(alerts != 4);
1628 
1629  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1631  UTHFreePackets(&p, 1);
1632  ThresholdDestroy();
1633  PASS;
1634 }
1635 
1636 /**
1637  * \test DetectThresholdTestSig14 is a test for checking the working by_both limits
1638  * by setting up the signature and later testing its working by matching
1639  * received packets against the sig.
1640  *
1641  * \retval 1 on success
1642  * \retval 0 on failure
1643  */
1644 
1645 static int DetectThresholdTestSig14(void)
1646 {
1647  Packet *p1 = NULL;
1648  Packet *p2 = NULL;
1649  Signature *s = NULL;
1650  ThreadVars th_v;
1651  DetectEngineThreadCtx *det_ctx;
1652  int alerts1 = 0;
1653  int alerts2 = 0;
1654 
1655  ThresholdInit();
1656 
1657  memset(&th_v, 0, sizeof(th_v));
1658  p1 = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1659  p2 = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "3.3.3.3", 1024, 80);
1660  FAIL_IF_NULL(p1);
1661  FAIL_IF_NULL(p2);
1662 
1665 
1666  de_ctx->flags |= DE_QUIET;
1667 
1668  s = de_ctx->sig_list =
1669  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
1670  "threshold: type limit, track by_both, count 2, seconds 60; sid:1;)");
1671  FAIL_IF_NULL(s);
1672 
1674  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1675 
1676  /* Both p1 and p2 should alert twice */
1677  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1678  alerts1 += PacketAlertCheck(p1, 1);
1679  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1680  alerts1 += PacketAlertCheck(p1, 1);
1681  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1682  alerts1 += PacketAlertCheck(p1, 1);
1683  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1684  alerts1 += PacketAlertCheck(p1, 1);
1685 
1686  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1687  alerts2 += PacketAlertCheck(p2, 1);
1688  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1689  alerts2 += PacketAlertCheck(p2, 1);
1690  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1691  alerts2 += PacketAlertCheck(p2, 1);
1692  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1693  alerts2 += PacketAlertCheck(p2, 1);
1694 
1695  FAIL_IF(alerts1 != 2);
1696  FAIL_IF(alerts2 != 2);
1697 
1699  p1->ts = TimeGet();
1700  p2->ts = TimeGet();
1701 
1702  /* Now they should both alert again after previous alerts expire */
1703  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1704  alerts1 += PacketAlertCheck(p1, 1);
1705  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1706  alerts2 += PacketAlertCheck(p2, 1);
1707 
1708  FAIL_IF(alerts1 != 3);
1709  FAIL_IF(alerts2 != 3);
1710 
1711  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1713  UTHFreePackets(&p1, 1);
1714  UTHFreePackets(&p2, 1);
1715  ThresholdDestroy();
1716  PASS;
1717 }
1718 
1719 static void ThresholdRegisterTests(void)
1720 {
1721  UtRegisterTest("ThresholdTestParse01", ThresholdTestParse01);
1722  UtRegisterTest("ThresholdTestParseByFlow01", ThresholdTestParseByFlow01);
1723  UtRegisterTest("ThresholdTestParse02", ThresholdTestParse02);
1724  UtRegisterTest("ThresholdTestParse03", ThresholdTestParse03);
1725  UtRegisterTest("ThresholdTestParse04", ThresholdTestParse04);
1726  UtRegisterTest("ThresholdTestParse05", ThresholdTestParse05);
1727  UtRegisterTest("ThresholdTestParse06", ThresholdTestParse06);
1728  UtRegisterTest("ThresholdTestParse07", ThresholdTestParse07);
1729  UtRegisterTest("ThresholdTestParse08", ThresholdTestParse08);
1730  UtRegisterTest("DetectThresholdTestSig1", DetectThresholdTestSig1);
1731  UtRegisterTest("DetectThresholdTestSig2", DetectThresholdTestSig2);
1732  UtRegisterTest("DetectThresholdTestSig3", DetectThresholdTestSig3);
1733  UtRegisterTest("DetectThresholdTestSig4", DetectThresholdTestSig4);
1734  UtRegisterTest("DetectThresholdTestSig5", DetectThresholdTestSig5);
1735  UtRegisterTest("DetectThresholdTestSig6Ticks", DetectThresholdTestSig6Ticks);
1736  UtRegisterTest("DetectThresholdTestSig7", DetectThresholdTestSig7);
1737  UtRegisterTest("DetectThresholdTestSig8", DetectThresholdTestSig8);
1738  UtRegisterTest("DetectThresholdTestSig9", DetectThresholdTestSig9);
1739  UtRegisterTest("DetectThresholdTestSig10", DetectThresholdTestSig10);
1740  UtRegisterTest("DetectThresholdTestSig11", DetectThresholdTestSig11);
1741  UtRegisterTest("DetectThresholdTestSig12", DetectThresholdTestSig12);
1742  UtRegisterTest("DetectThresholdTestSig13", DetectThresholdTestSig13);
1743  UtRegisterTest("DetectThresholdTestSig14", DetectThresholdTestSig14);
1744 }
1745 #endif /* UNITTESTS */
1746 
1747 /**
1748  * @}
1749  */
TRACK_BOTH
#define TRACK_BOTH
Definition: detect-threshold.h:39
util-byte.h
host.h
SigTableElmt_::url
const char * url
Definition: detect.h:1307
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
host-storage.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1306
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:127
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1294
util-hashlist.h
DetectParseRegex
Definition: detect-parse.h:62
SigTableElmt_::name
const char * name
Definition: detect.h:1304
stream-tcp.h
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
TYPE_BACKOFF
#define TYPE_BACKOFF
Definition: detect-threshold.h:33
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DetectAddress_
address structure for use in the detection engine.
Definition: detect.h:165
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DetectAddressHeadCleanup
void DetectAddressHeadCleanup(DetectAddressHead *gh)
Cleans a DetectAddressHead. The functions frees the address group heads(ipv4 and ipv6) inside the Det...
Definition: detect-engine-address.c:1476
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:141
action-globals.h
Packet_::action
uint8_t action
Definition: decode.h:577
DETECT_SM_LIST_THRESHOLD
@ DETECT_SM_LIST_THRESHOLD
Definition: detect.h:130
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1298
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:841
TYPE_LIMIT
#define TYPE_LIMIT
Definition: detect-threshold.h:27
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2597
TRACK_DST
#define TRACK_DST
Definition: detect-detection-filter.c:43
DE_QUIET
#define DE_QUIET
Definition: detect.h:323
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1938
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:2641
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:55
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2587
UTHBuildPacketReal
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
Definition: util-unittest-helper.c:260
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1289
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
UtilCpuGetTicks
uint64_t UtilCpuGetTicks(void)
Definition: util-cpu.c:161
DetectAddress_::prev
struct DetectAddress_ * prev
Definition: detect.h:174
Signature_::next
struct Signature_ * next
Definition: detect.h:673
TRACK_RULE
#define TRACK_RULE
Definition: detect-threshold.h:37
decode.h
util-debug.h
TRACK_FLOW
#define TRACK_FLOW
Definition: detect-threshold.h:40
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1093
util-cpu.h
Packet_::ts
SCTime_t ts
Definition: decode.h:523
SIG_TYPE_IPONLY
@ SIG_TYPE_IPONLY
Definition: detect.h:64
DETECT_THRESHOLD
@ DETECT_THRESHOLD
Definition: detect-engine-register.h:59
de
uint8_t de
Definition: app-layer-htp.c:568
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2767
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-threshold.c:67
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:313
util-time.h
ThresholdDestroy
void ThresholdDestroy(void)
Definition: detect-engine-threshold.c:71
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2285
TYPE_BOTH
#define TYPE_BOTH
Definition: detect-threshold.h:28
DetectAddressCopy
DetectAddress * DetectAddressCopy(DetectAddress *orig)
copy a DetectAddress
Definition: detect-engine-address.c:127
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2228
TimeSetIncrementTime
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
Definition: util-time.c:180
Packet_
Definition: decode.h:475
detect-engine-build.h
TimeGet
SCTime_t TimeGet(void)
Definition: util-time.c:152
detect-engine-alert.h
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1272
decode-events.h
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2161
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:344
DetectAddressHead_::ipv6_head
DetectAddress * ipv6_head
Definition: detect.h:182
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3323
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3550
SigMatch_::type
uint16_t type
Definition: detect.h:350
DetectThresholdData_
Definition: detect-threshold.h:55
packet.h
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
HostShutdown
void HostShutdown(void)
shutdown the flow engine
Definition: host.c:296
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:849
TYPE_THRESHOLD
#define TYPE_THRESHOLD
Definition: detect-threshold.h:29
DETECT_DETECTION_FILTER
@ DETECT_DETECTION_FILTER
Definition: detect-engine-register.h:118
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
detect-parse.h
Signature_
Signature container.
Definition: detect.h:601
SigMatch_
a single match condition for a signature
Definition: detect.h:349
detect-threshold.h
DetectAddress_::next
struct DetectAddress_ * next
Definition: detect.h:176
DetectThresholdRegister
void DetectThresholdRegister(void)
Registration function for threshold: keyword.
Definition: detect-threshold.c:86
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2558
suricata.h
TRACK_SRC
#define TRACK_SRC
Definition: detect-detection-filter.c:44
DetectGetLastSMFromLists
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
Definition: detect-parse.c:606
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:436
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:843
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
Signature_::type
enum SignatureType type
Definition: detect.h:604
DetectThresholdDataCopy
DetectThresholdData * DetectThresholdDataCopy(DetectThresholdData *de)
Make a deep-copy of an extant DetectTHresholdData object.
Definition: detect-threshold.c:343
flow-var.h
ThresholdInit
void ThresholdInit(void)
Definition: detect-engine-threshold.c:66
SIGMATCH_IPONLY_COMPAT
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1490
DetectAddressHead_::ipv4_head
DetectAddress * ipv4_head
Definition: detect.h:181
detect-engine-address.h
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1296
detect-engine-threshold.h
DetectThresholdData_::addrs
DetectAddressHead addrs
Definition: detect-threshold.h:64
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:450