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