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) {
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 #include "thread-storage.h"
397 
398 /**
399  * \test ThresholdTestParse01 is a test for a valid threshold options
400  *
401  * \retval 1 on success
402  * \retval 0 on failure
403  */
404 static int ThresholdTestParse01(void)
405 {
406  DetectThresholdData *de = NULL;
407  de = DetectThresholdParse("type limit,track by_dst,count 10,seconds 60");
408  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
409  (de->seconds == 60)) {
410  DetectThresholdFree(NULL, de);
411  return 1;
412  }
413 
414  return 0;
415 }
416 
417 static int ThresholdTestParseByFlow01(void)
418 {
419  DetectThresholdData *de = DetectThresholdParse("type limit,track by_flow,count 1,seconds 60");
420  FAIL_IF_NULL(de);
421  FAIL_IF_NOT(de->type == TYPE_LIMIT);
422  FAIL_IF_NOT(de->track == TRACK_FLOW);
423  FAIL_IF_NOT(de->count == 1);
424  FAIL_IF_NOT(de->seconds == 60);
425  DetectThresholdFree(NULL, de);
426  PASS;
427 }
428 
429 /**
430  * \test ThresholdTestParse02 is a test for a invalid threshold options
431  *
432  * \retval 1 on success
433  * \retval 0 on failure
434  */
435 static int ThresholdTestParse02(void)
436 {
437  DetectThresholdData *de = NULL;
438  de = DetectThresholdParse("type any,track by_dst,count 10,seconds 60");
439  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
440  (de->seconds == 60)) {
441  DetectThresholdFree(NULL, de);
442  return 0;
443  }
444 
445  return 1;
446 }
447 
448 /**
449  * \test ThresholdTestParse03 is a test for a valid threshold options in any order
450  *
451  * \retval 1 on success
452  * \retval 0 on failure
453  */
454 static int ThresholdTestParse03(void)
455 {
456  DetectThresholdData *de = NULL;
457  de = DetectThresholdParse("track by_dst, type limit, seconds 60, count 10");
458  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
459  (de->seconds == 60)) {
460  DetectThresholdFree(NULL, de);
461  return 1;
462  }
463 
464  return 0;
465 }
466 
467 /**
468  * \test ThresholdTestParse04 is a test for an invalid threshold options in any order
469  *
470  * \retval 1 on success
471  * \retval 0 on failure
472  */
473 static int ThresholdTestParse04(void)
474 {
475  DetectThresholdData *de = NULL;
476  de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both, count 10");
477  if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) &&
478  (de->seconds == 60)) {
479  DetectThresholdFree(NULL, de);
480  return 0;
481  }
482 
483  return 1;
484 }
485 
486 /**
487  * \test ThresholdTestParse05 is a test for a valid threshold options in any order
488  *
489  * \retval 1 on success
490  * \retval 0 on failure
491  */
492 static int ThresholdTestParse05(void)
493 {
494  DetectThresholdData *de = NULL;
495  de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both");
496  if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) &&
497  (de->seconds == 60)) {
498  DetectThresholdFree(NULL, de);
499  return 1;
500  }
501 
502  return 0;
503 }
504 
505 /**
506  * \test ThresholdTestParse06 is a test for thresholding by_both
507  *
508  * \retval 1 on success
509  * \retval 0 on failure
510  */
511 static int ThresholdTestParse06(void)
512 {
513  DetectThresholdData *de = NULL;
514  de = DetectThresholdParse("count 10, track by_both, seconds 60, type limit");
515  FAIL_IF_NULL(de);
516  FAIL_IF_NOT(de->type == TYPE_LIMIT);
517  FAIL_IF_NOT(de->track == TRACK_BOTH);
518  FAIL_IF_NOT(de->count == 10);
519  FAIL_IF_NOT(de->seconds == 60);
520  DetectThresholdFree(NULL, de);
521  PASS;
522 }
523 
524 /**
525  * \test ThresholdTestParse07 is a test for thresholding by_rule
526  *
527  * \retval 1 on success
528  * \retval 0 on failure
529  */
530 static int ThresholdTestParse07(void)
531 {
532  DetectThresholdData *de = NULL;
533  de = DetectThresholdParse("count 10, track by_rule, seconds 60, type limit");
534  FAIL_IF_NULL(de);
535  FAIL_IF_NOT(de->type == TYPE_LIMIT);
536  FAIL_IF_NOT(de->track == TRACK_RULE);
537  FAIL_IF_NOT(de->count == 10);
538  FAIL_IF_NOT(de->seconds == 60);
539  DetectThresholdFree(NULL, de);
540  PASS;
541 }
542 
543 /** \test backoff by_flow */
544 static int ThresholdTestParse08(void)
545 {
546  DetectThresholdData *de =
547  DetectThresholdParse("count 10, track by_flow, multiplier 2, type backoff");
548  FAIL_IF_NULL(de);
549  FAIL_IF_NOT(de->type == TYPE_BACKOFF);
550  FAIL_IF_NOT(de->track == TRACK_FLOW);
551  FAIL_IF_NOT(de->count == 10);
552  FAIL_IF_NOT(de->multiplier == 2);
553  DetectThresholdFree(NULL, de);
554  PASS;
555 }
556 
557 /**
558  * \test DetectThresholdTestSig1 is a test for checking the working of limit keyword
559  * by setting up the signature and later testing its working by matching
560  * the received packet against the sig.
561  *
562  * \retval 1 on success
563  * \retval 0 on failure
564  */
565 
566 static int DetectThresholdTestSig1(void)
567 {
568  DetectEngineThreadCtx *det_ctx;
569  int alerts = 0;
570 
572  SCStorageInit();
573  ThresholdInit();
575 
577  FAIL_IF_NULL(tv);
579 
580  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
581  FAIL_IF_NULL(p);
582 
585  de_ctx->flags |= DE_QUIET;
586 
588  "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  FAIL_IF_NULL(s);
591 
594 
595  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
596 
597  SigMatchSignatures(tv, de_ctx, det_ctx, p);
598  alerts = PacketAlertCheck(p, 1);
599  if (alerts != 1) {
600  printf("alerts %" PRIi32 ", expected 1: ", alerts);
601  }
602  SigMatchSignatures(tv, de_ctx, det_ctx, p);
603  alerts += PacketAlertCheck(p, 1);
604  if (alerts != 2) {
605  printf("alerts %" PRIi32 ", expected 2: ", alerts);
606  }
607  SigMatchSignatures(tv, de_ctx, det_ctx, p);
608  alerts += PacketAlertCheck(p, 1);
609  if (alerts != 3) {
610  printf("alerts %" PRIi32 ", expected 3: ", alerts);
611  }
612  SigMatchSignatures(tv, de_ctx, det_ctx, p);
613  alerts += PacketAlertCheck(p, 1);
614  if (alerts != 4) {
615  printf("alerts %" PRIi32 ", expected 4: ", alerts);
616  }
617  SigMatchSignatures(tv, de_ctx, det_ctx, p);
618  alerts += PacketAlertCheck(p, 1);
619  if (alerts != 5) {
620  printf("alerts %" PRIi32 ", expected 5: ", alerts);
621  }
622  SigMatchSignatures(tv, de_ctx, det_ctx, p);
623  alerts += PacketAlertCheck(p, 1);
624  if (alerts != 5) {
625  printf("alerts %" PRIi32 ", expected 5: ", alerts);
626  }
627  SigMatchSignatures(tv, de_ctx, det_ctx, p);
628  alerts += PacketAlertCheck(p, 1);
629  if (alerts != 5) {
630  printf("alerts %" PRIi32 ", expected 5: ", alerts);
631  }
632  SigMatchSignatures(tv, de_ctx, det_ctx, p);
633  alerts += PacketAlertCheck(p, 1);
634  if (alerts != 5) {
635  printf("alerts %" PRIi32 ", expected 5: ", alerts);
636  }
637 
638  FAIL_IF_NOT(alerts == 5);
639 
640  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
642 
643  UTHFreePackets(&p, 1);
644 
650  PASS;
651 }
652 
653 /**
654  * \test DetectThresholdTestSig2 is a test for checking the working of threshold keyword
655  * by setting up the signature and later testing its working by matching
656  * the received packet against the sig.
657  *
658  * \retval 1 on success
659  * \retval 0 on failure
660  */
661 
662 static int DetectThresholdTestSig2(void)
663 {
664  DetectEngineThreadCtx *det_ctx;
665  int alerts = 0;
666 
668  SCStorageInit();
669  ThresholdInit();
671 
673  FAIL_IF_NULL(tv);
675 
676  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
677  FAIL_IF_NULL(p);
678 
681  de_ctx->flags |= DE_QUIET;
682 
684  "alert tcp any any -> any 80 (msg:\"Threshold\"; threshold: type "
685  "threshold, track by_dst, count 5, seconds 60; sid:1;)");
686  FAIL_IF_NULL(s);
687 
689  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
690 
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  SigMatchSignatures(tv, de_ctx, det_ctx, p);
710  alerts += PacketAlertCheck(p, 1);
711 
712  FAIL_IF_NOT(alerts == 2);
713 
714  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
716  UTHFreePackets(&p, 1);
722  PASS;
723 }
724 
725 /**
726  * \test DetectThresholdTestSig3 is a test for checking the working of limit keyword
727  * by setting up the signature and later testing its working by matching
728  * the received packet against the sig.
729  *
730  * \retval 1 on success
731  * \retval 0 on failure
732  */
733 
734 static int DetectThresholdTestSig3(void)
735 {
737  SCStorageInit();
738  ThresholdInit();
740 
742  FAIL_IF_NULL(tv);
744 
745  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
746  FAIL_IF_NULL(p);
747 
750  de_ctx->flags |= DE_QUIET;
751 
753  "alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, "
754  "track by_dst, count 5, seconds 60; sid:10;)");
755  FAIL_IF_NULL(s);
756 
758  DetectEngineThreadCtx *det_ctx;
759  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
760 
761  p->ts = TimeGet();
762 
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  SigMatchSignatures(tv, de_ctx, det_ctx, p);
768  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
769 
771  p->ts = TimeGet();
772 
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  SigMatchSignatures(tv, de_ctx, det_ctx, p);
778  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
779 
780  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
782  UTHFreePackets(&p, 1);
788  PASS;
789 }
790 
791 /**
792  * \test DetectThresholdTestSig4 is a test for checking the working of both keyword
793  * by setting up the signature and later testing its working by matching
794  * the received packet against the sig.
795  *
796  * \retval 1 on success
797  * \retval 0 on failure
798  */
799 
800 static int DetectThresholdTestSig4(void)
801 {
802  DetectEngineThreadCtx *det_ctx;
803  int alerts = 0;
804 
806  SCStorageInit();
807  ThresholdInit();
809 
811  FAIL_IF_NULL(tv);
813 
814  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
815  FAIL_IF_NULL(p);
816 
819  de_ctx->flags |= DE_QUIET;
820 
822  "alert tcp any any -> any 80 (msg:\"Threshold both\"; threshold: type "
823  "both, track by_dst, count 2, seconds 60; sid:10;)");
824  FAIL_IF_NULL(s);
825 
827  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
828 
829  p->ts = TimeGet();
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  SigMatchSignatures(tv, de_ctx, det_ctx, p);
835  alerts += PacketAlertCheck(p, 10);
836 
838  p->ts = TimeGet();
839 
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  SigMatchSignatures(tv, de_ctx, det_ctx, p);
845  alerts += PacketAlertCheck(p, 10);
846 
847  FAIL_IF_NOT(alerts == 2);
848 
849  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
851 
852  UTHFreePackets(&p, 1);
858  PASS;
859 }
860 
861 /**
862  * \test DetectThresholdTestSig5 is a test for checking the working of limit keyword
863  * by setting up the signature and later testing its working by matching
864  * the received packet against the sig.
865  *
866  * \retval 1 on success
867  * \retval 0 on failure
868  */
869 
870 static int DetectThresholdTestSig5(void)
871 {
872  DetectEngineThreadCtx *det_ctx;
873  int alerts = 0;
874 
876  SCStorageInit();
877  ThresholdInit();
879 
881  FAIL_IF_NULL(tv);
883  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
884  FAIL_IF_NULL(p);
885 
888  de_ctx->flags |= DE_QUIET;
889 
891  "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
892  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
893  FAIL_IF_NULL(s);
894 
896  "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; "
897  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
898  FAIL_IF_NULL(s);
899 
901  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
902 
903  SigMatchSignatures(tv, de_ctx, det_ctx, p);
904  alerts = PacketAlertCheck(p, 1);
905  alerts += PacketAlertCheck(p, 1000);
906  SigMatchSignatures(tv, de_ctx, det_ctx, p);
907  alerts += PacketAlertCheck(p, 1);
908  alerts += PacketAlertCheck(p, 1000);
909  SigMatchSignatures(tv, de_ctx, det_ctx, p);
910  alerts += PacketAlertCheck(p, 1);
911  alerts += PacketAlertCheck(p, 1000);
912  SigMatchSignatures(tv, de_ctx, det_ctx, p);
913  alerts += PacketAlertCheck(p, 1);
914  alerts += PacketAlertCheck(p, 1000);
915  SigMatchSignatures(tv, de_ctx, det_ctx, p);
916  alerts += PacketAlertCheck(p, 1);
917  alerts += PacketAlertCheck(p, 1000);
918  SigMatchSignatures(tv, de_ctx, det_ctx, p);
919  alerts += PacketAlertCheck(p, 1);
920  alerts += PacketAlertCheck(p, 1000);
921  SigMatchSignatures(tv, de_ctx, det_ctx, p);
922  alerts += PacketAlertCheck(p, 1);
923  alerts += PacketAlertCheck(p, 1000);
924  SigMatchSignatures(tv, de_ctx, det_ctx, p);
925  alerts += PacketAlertCheck(p, 1);
926  alerts += PacketAlertCheck(p, 1000);
927 
928  FAIL_IF_NOT(alerts == 10);
929 
930  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
932  UTHFreePackets(&p, 1);
938  PASS;
939 }
940 
941 static int DetectThresholdTestSig6Ticks(void)
942 {
943  DetectEngineThreadCtx *det_ctx;
944  int alerts = 0;
945 
947  SCStorageInit();
948  ThresholdInit();
950 
952  FAIL_IF_NULL(tv);
954 
955  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
956  FAIL_IF_NULL(p);
957 
960  de_ctx->flags |= DE_QUIET;
961 
963  "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
964  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
965  FAIL_IF_NULL(s);
966 
968  "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; "
969  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
970  FAIL_IF_NULL(s);
971 
973  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
974 
975  uint64_t ticks_start = 0;
976  uint64_t ticks_end = 0;
977 
978  ticks_start = UtilCpuGetTicks();
979  SigMatchSignatures(tv, de_ctx, det_ctx, p);
980  alerts = PacketAlertCheck(p, 1);
981  alerts += PacketAlertCheck(p, 1000);
982  SigMatchSignatures(tv, de_ctx, det_ctx, p);
983  alerts += PacketAlertCheck(p, 1);
984  alerts += PacketAlertCheck(p, 1000);
985  SigMatchSignatures(tv, de_ctx, det_ctx, p);
986  alerts += PacketAlertCheck(p, 1);
987  alerts += PacketAlertCheck(p, 1000);
988  SigMatchSignatures(tv, de_ctx, det_ctx, p);
989  alerts += PacketAlertCheck(p, 1);
990  alerts += PacketAlertCheck(p, 1000);
991  SigMatchSignatures(tv, de_ctx, det_ctx, p);
992  alerts += PacketAlertCheck(p, 1);
993  alerts += PacketAlertCheck(p, 1000);
994  SigMatchSignatures(tv, de_ctx, det_ctx, p);
995  alerts += PacketAlertCheck(p, 1);
996  alerts += PacketAlertCheck(p, 1000);
997  SigMatchSignatures(tv, de_ctx, det_ctx, p);
998  alerts += PacketAlertCheck(p, 1);
999  alerts += PacketAlertCheck(p, 1000);
1000  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1001  alerts += PacketAlertCheck(p, 1);
1002  alerts += PacketAlertCheck(p, 1000);
1003  ticks_end = UtilCpuGetTicks();
1004  printf("test run %" PRIu64 "\n", (ticks_end - ticks_start));
1005 
1006  FAIL_IF_NOT(alerts == 10);
1007 
1008  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1010 
1011  UTHFreePackets(&p, 1);
1013  SCStorageCleanup();
1014  ThresholdDestroy();
1016  ThreadVarsFree(tv);
1017  PASS;
1018 }
1019 
1020 /**
1021  * \test Test drop action being set even if thresholded
1022  */
1023 static int DetectThresholdTestSig7(void)
1024 {
1025  DetectEngineThreadCtx *det_ctx;
1026  int alerts = 0;
1027  int drops = 0;
1028 
1029  SCStorageCleanup();
1030  SCStorageInit();
1031  ThresholdInit();
1033 
1035  FAIL_IF_NULL(tv);
1037 
1038  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1039  FAIL_IF_NULL(p);
1040 
1043  de_ctx->flags |= DE_QUIET;
1044 
1045  Signature *s =
1046  DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 (threshold: type limit, "
1047  "track by_src, count 1, seconds 300; sid:10;)");
1048  FAIL_IF_NULL(s);
1049 
1051  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
1052 
1053  p->ts = TimeGet();
1054  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1055  alerts = PacketAlertCheck(p, 10);
1056  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1057  p->action = 0;
1058 
1059  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1060  alerts += PacketAlertCheck(p, 10);
1061  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1062  p->action = 0;
1063 
1064  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1065  alerts += PacketAlertCheck(p, 10);
1066  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1067  p->action = 0;
1068 
1069  TimeSetIncrementTime(200);
1070  p->ts = TimeGet();
1071 
1072  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1073  alerts += PacketAlertCheck(p, 10);
1074  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1075  p->action = 0;
1076 
1077  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1078  alerts += PacketAlertCheck(p, 10);
1079  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1080  p->action = 0;
1081 
1082  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1083  alerts += PacketAlertCheck(p, 10);
1084  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1085  p->action = 0;
1086 
1087  FAIL_IF_NOT(alerts == 1 && drops == 6);
1088 
1089  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1091  UTHFreePackets(&p, 1);
1093  SCStorageCleanup();
1094  ThresholdDestroy();
1096  ThreadVarsFree(tv);
1097  PASS;
1098 }
1099 
1100 /**
1101  * \test Test drop action being set even if thresholded
1102  */
1103 static int DetectThresholdTestSig8(void)
1104 {
1105  DetectEngineThreadCtx *det_ctx;
1106  int alerts = 0;
1107  int drops = 0;
1108 
1109  SCStorageCleanup();
1110  SCStorageInit();
1111  ThresholdInit();
1113 
1115  FAIL_IF_NULL(tv);
1117 
1118  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1119  FAIL_IF_NULL(p);
1120 
1123  de_ctx->flags |= DE_QUIET;
1124 
1125  Signature *s =
1126  DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 (threshold: type limit, "
1127  "track by_src, count 2, seconds 300; sid:10;)");
1128  FAIL_IF_NULL(s);
1129 
1131  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
1132 
1133  p->ts = TimeGet();
1134  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1135  alerts = PacketAlertCheck(p, 10);
1136  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1137  p->action = 0;
1138 
1139  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1140  alerts += PacketAlertCheck(p, 10);
1141  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1142  p->action = 0;
1143 
1144  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1145  alerts += PacketAlertCheck(p, 10);
1146  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1147  p->action = 0;
1148 
1149  TimeSetIncrementTime(200);
1150  p->ts = TimeGet();
1151 
1152  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1153  alerts += PacketAlertCheck(p, 10);
1154  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1155  p->action = 0;
1156 
1157  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1158  alerts += PacketAlertCheck(p, 10);
1159  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1160  p->action = 0;
1161 
1162  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1163  alerts += PacketAlertCheck(p, 10);
1164  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1165  p->action = 0;
1166 
1167  FAIL_IF_NOT(alerts == 2 && drops == 6);
1168 
1169  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1171  UTHFreePackets(&p, 1);
1173  SCStorageCleanup();
1174  ThresholdDestroy();
1176  ThreadVarsFree(tv);
1177  PASS;
1178 }
1179 
1180 /**
1181  * \test Test drop action being set even if thresholded
1182  */
1183 static int DetectThresholdTestSig9(void)
1184 {
1185  DetectEngineThreadCtx *det_ctx;
1186  int alerts = 0;
1187  int drops = 0;
1188 
1189  SCStorageCleanup();
1190  SCStorageInit();
1191  ThresholdInit();
1193 
1195  FAIL_IF_NULL(tv);
1197 
1198  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1199  FAIL_IF_NULL(p);
1200 
1203  de_ctx->flags |= DE_QUIET;
1204 
1205  Signature *s =
1206  DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 (threshold: type threshold, "
1207  "track by_src, count 3, seconds 100; sid:10;)");
1208  FAIL_IF_NULL(s);
1209 
1211  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
1212 
1213  p->ts = TimeGet();
1214  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1215  alerts = PacketAlertCheck(p, 10);
1216  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1217  p->action = 0;
1218 
1219  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1220  alerts += PacketAlertCheck(p, 10);
1221  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1222  p->action = 0;
1223 
1224  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1225  alerts += PacketAlertCheck(p, 10);
1226  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1227  p->action = 0;
1228 
1229  TimeSetIncrementTime(200);
1230  p->ts = TimeGet();
1231 
1232  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1233  alerts += PacketAlertCheck(p, 10);
1234  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1235  p->action = 0;
1236 
1237  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1238  alerts += PacketAlertCheck(p, 10);
1239  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1240  p->action = 0;
1241 
1242  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1243  alerts += PacketAlertCheck(p, 10);
1244  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1245  p->action = 0;
1246 
1247  FAIL_IF_NOT(alerts == 2 && drops == 2);
1248 
1249  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1251  UTHFreePackets(&p, 1);
1253  SCStorageCleanup();
1254  ThresholdDestroy();
1256  ThreadVarsFree(tv);
1257  PASS;
1258 }
1259 
1260 /**
1261  * \test Test drop action being set even if thresholded
1262  */
1263 static int DetectThresholdTestSig10(void)
1264 {
1265  DetectEngineThreadCtx *det_ctx;
1266  int alerts = 0;
1267  int drops = 0;
1268 
1269  SCStorageCleanup();
1270  SCStorageInit();
1271  ThresholdInit();
1273 
1275  FAIL_IF_NULL(tv);
1277 
1278  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1279  FAIL_IF_NULL(p);
1280 
1283  de_ctx->flags |= DE_QUIET;
1284 
1285  Signature *s =
1286  DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 (threshold: type threshold, "
1287  "track by_src, count 5, seconds 300; sid:10;)");
1288  FAIL_IF_NULL(s);
1289 
1291  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
1292 
1293  p->ts = TimeGet();
1294  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1295  alerts = PacketAlertCheck(p, 10);
1296  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1297  p->action = 0;
1298 
1299  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1300  alerts += PacketAlertCheck(p, 10);
1301  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1302  p->action = 0;
1303 
1304  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1305  alerts += PacketAlertCheck(p, 10);
1306  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1307  p->action = 0;
1308 
1309  TimeSetIncrementTime(200);
1310  p->ts = TimeGet();
1311 
1312  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1313  alerts += PacketAlertCheck(p, 10);
1314  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1315  p->action = 0;
1316 
1317  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1318  alerts += PacketAlertCheck(p, 10);
1319  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1320  p->action = 0;
1321 
1322  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1323  alerts += PacketAlertCheck(p, 10);
1324  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1325  p->action = 0;
1326 
1327  FAIL_IF_NOT(alerts == 1 && drops == 1);
1328 
1329  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1331  UTHFreePackets(&p, 1);
1333  SCStorageCleanup();
1334  ThresholdDestroy();
1336  ThreadVarsFree(tv);
1337  PASS;
1338 }
1339 
1340 /**
1341  * \test Test drop action being set even if thresholded
1342  */
1343 static int DetectThresholdTestSig11(void)
1344 {
1345  DetectEngineThreadCtx *det_ctx;
1346  int alerts = 0;
1347  int drops = 0;
1348 
1349  SCStorageCleanup();
1350  SCStorageInit();
1351  ThresholdInit();
1353 
1355  FAIL_IF_NULL(tv);
1357 
1358  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1359  FAIL_IF_NULL(p);
1360 
1363  de_ctx->flags |= DE_QUIET;
1364 
1365  Signature *s =
1366  DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 (threshold: type both, "
1367  "track by_src, count 3, seconds 300; sid:10;)");
1368  FAIL_IF_NULL(s);
1369 
1371  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
1372 
1373  p->ts = TimeGet();
1374  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1375  alerts = PacketAlertCheck(p, 10);
1376  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1377  p->action = 0;
1378 
1379  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1380  alerts += PacketAlertCheck(p, 10);
1381  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1382  p->action = 0;
1383 
1384  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1385  alerts += PacketAlertCheck(p, 10);
1386  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1387  p->action = 0;
1388 
1389  TimeSetIncrementTime(200);
1390  p->ts = TimeGet();
1391 
1392  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1393  alerts += PacketAlertCheck(p, 10);
1394  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1395  p->action = 0;
1396 
1397  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1398  alerts += PacketAlertCheck(p, 10);
1399  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1400  p->action = 0;
1401 
1402  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1403  alerts += PacketAlertCheck(p, 10);
1404  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1405  p->action = 0;
1406 
1407  FAIL_IF_NOT(alerts == 1 && drops == 4);
1408 
1409  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1411  UTHFreePackets(&p, 1);
1413  SCStorageCleanup();
1414  ThresholdDestroy();
1416  ThreadVarsFree(tv);
1417  PASS;
1418 }
1419 
1420 /**
1421  * \test Test drop action being set even if thresholded
1422  */
1423 static int DetectThresholdTestSig12(void)
1424 {
1425  DetectEngineThreadCtx *det_ctx;
1426  int alerts = 0;
1427  int drops = 0;
1428 
1429  SCStorageCleanup();
1430  SCStorageInit();
1431  ThresholdInit();
1433 
1435  FAIL_IF_NULL(tv);
1437 
1438  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1439  FAIL_IF_NULL(p);
1440 
1443  de_ctx->flags |= DE_QUIET;
1444 
1445  Signature *s =
1446  DetectEngineAppendSig(de_ctx, "drop tcp any any -> any 80 (threshold: type both, "
1447  "track by_src, count 5, seconds 300; sid:10;)");
1448  FAIL_IF_NULL(s);
1449 
1451  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
1452 
1453  p->ts = TimeGet();
1454  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1455  alerts = PacketAlertCheck(p, 10);
1456  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1457  p->action = 0;
1458 
1459  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1460  alerts += PacketAlertCheck(p, 10);
1461  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1462  p->action = 0;
1463 
1464  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1465  alerts += PacketAlertCheck(p, 10);
1466  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1467  p->action = 0;
1468 
1469  TimeSetIncrementTime(200);
1470  p->ts = TimeGet();
1471 
1472  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1473  alerts += PacketAlertCheck(p, 10);
1474  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1475  p->action = 0;
1476 
1477  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1478  alerts += PacketAlertCheck(p, 10);
1479  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1480  p->action = 0;
1481 
1482  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1483  alerts += PacketAlertCheck(p, 10);
1484  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1485  p->action = 0;
1486 
1487  FAIL_IF_NOT(alerts == 1 && drops == 2);
1488 
1489  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1491  UTHFreePackets(&p, 1);
1492  HostShutdown();
1494  SCStorageCleanup();
1495  ThresholdDestroy();
1497  ThreadVarsFree(tv);
1498  PASS;
1499 }
1500 
1501 /**
1502  * \test DetectThresholdTestSig13 is a test for checking the working by_rule limits
1503  * by setting up the signature and later testing its working by matching
1504  * received packets against the sig.
1505  *
1506  * \retval 1 on success
1507  * \retval 0 on failure
1508  */
1509 
1510 static int DetectThresholdTestSig13(void)
1511 {
1512  DetectEngineThreadCtx *det_ctx;
1513  int alerts = 0;
1514 
1515  SCStorageCleanup();
1516  SCStorageInit();
1517  ThresholdInit();
1519 
1521  FAIL_IF_NULL(tv);
1523 
1524  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1525  FAIL_IF_NULL(p);
1526 
1529  de_ctx->flags |= DE_QUIET;
1530 
1532  "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
1533  "threshold: type limit, track by_rule, count 2, seconds 60; sid:1;)");
1534  FAIL_IF_NULL(s);
1535 
1537  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
1538 
1539  /* should alert twice */
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  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1547  alerts += PacketAlertCheck(p, 1);
1548 
1549  FAIL_IF(alerts != 2);
1550 
1552  p->ts = TimeGet();
1553 
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  SigMatchSignatures(tv, de_ctx, det_ctx, p);
1561  alerts += PacketAlertCheck(p, 1);
1562 
1563  FAIL_IF(alerts != 4);
1564 
1565  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1567  UTHFreePackets(&p, 1);
1569  SCStorageCleanup();
1570  ThresholdDestroy();
1572  ThreadVarsFree(tv);
1573  PASS;
1574 }
1575 
1576 /**
1577  * \test DetectThresholdTestSig14 is a test for checking the working by_both limits
1578  * by setting up the signature and later testing its working by matching
1579  * received packets against the sig.
1580  *
1581  * \retval 1 on success
1582  * \retval 0 on failure
1583  */
1584 
1585 static int DetectThresholdTestSig14(void)
1586 {
1587  DetectEngineThreadCtx *det_ctx;
1588  int alerts1 = 0;
1589  int alerts2 = 0;
1590 
1591  SCStorageCleanup();
1592  SCStorageInit();
1593  ThresholdInit();
1595 
1597  FAIL_IF_NULL(tv);
1599  Packet *p1 = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1600  FAIL_IF_NULL(p1);
1601  Packet *p2 = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "3.3.3.3", 1024, 80);
1602  FAIL_IF_NULL(p2);
1603 
1606  de_ctx->flags |= DE_QUIET;
1607 
1609  "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
1610  "threshold: type limit, track by_both, count 2, seconds 60; sid:1;)");
1611  FAIL_IF_NULL(s);
1612 
1614  DetectEngineThreadCtxInit(tv, (void *)de_ctx, (void *)&det_ctx);
1615 
1616  /* Both p1 and p2 should alert twice */
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  SigMatchSignatures(tv, de_ctx, det_ctx, p1);
1624  alerts1 += PacketAlertCheck(p1, 1);
1625 
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  SigMatchSignatures(tv, de_ctx, det_ctx, p2);
1633  alerts2 += PacketAlertCheck(p2, 1);
1634 
1635  FAIL_IF(alerts1 != 2);
1636  FAIL_IF(alerts2 != 2);
1637 
1639  p1->ts = TimeGet();
1640  p2->ts = TimeGet();
1641 
1642  /* Now they should both alert again after previous alerts expire */
1643  SigMatchSignatures(tv, de_ctx, det_ctx, p1);
1644  alerts1 += PacketAlertCheck(p1, 1);
1645  SigMatchSignatures(tv, de_ctx, det_ctx, p2);
1646  alerts2 += PacketAlertCheck(p2, 1);
1647 
1648  FAIL_IF(alerts1 != 3);
1649  FAIL_IF(alerts2 != 3);
1650 
1651  DetectEngineThreadCtxDeinit(tv, (void *)det_ctx);
1653  UTHFreePackets(&p1, 1);
1654  UTHFreePackets(&p2, 1);
1656  SCStorageCleanup();
1657  ThresholdDestroy();
1659  ThreadVarsFree(tv);
1660  PASS;
1661 }
1662 
1663 static void ThresholdRegisterTests(void)
1664 {
1665  UtRegisterTest("ThresholdTestParse01", ThresholdTestParse01);
1666  UtRegisterTest("ThresholdTestParseByFlow01", ThresholdTestParseByFlow01);
1667  UtRegisterTest("ThresholdTestParse02", ThresholdTestParse02);
1668  UtRegisterTest("ThresholdTestParse03", ThresholdTestParse03);
1669  UtRegisterTest("ThresholdTestParse04", ThresholdTestParse04);
1670  UtRegisterTest("ThresholdTestParse05", ThresholdTestParse05);
1671  UtRegisterTest("ThresholdTestParse06", ThresholdTestParse06);
1672  UtRegisterTest("ThresholdTestParse07", ThresholdTestParse07);
1673  UtRegisterTest("ThresholdTestParse08", ThresholdTestParse08);
1674  UtRegisterTest("DetectThresholdTestSig1", DetectThresholdTestSig1);
1675  UtRegisterTest("DetectThresholdTestSig2", DetectThresholdTestSig2);
1676  UtRegisterTest("DetectThresholdTestSig3", DetectThresholdTestSig3);
1677  UtRegisterTest("DetectThresholdTestSig4", DetectThresholdTestSig4);
1678  UtRegisterTest("DetectThresholdTestSig5", DetectThresholdTestSig5);
1679  UtRegisterTest("DetectThresholdTestSig6Ticks", DetectThresholdTestSig6Ticks);
1680  UtRegisterTest("DetectThresholdTestSig7", DetectThresholdTestSig7);
1681  UtRegisterTest("DetectThresholdTestSig8", DetectThresholdTestSig8);
1682  UtRegisterTest("DetectThresholdTestSig9", DetectThresholdTestSig9);
1683  UtRegisterTest("DetectThresholdTestSig10", DetectThresholdTestSig10);
1684  UtRegisterTest("DetectThresholdTestSig11", DetectThresholdTestSig11);
1685  UtRegisterTest("DetectThresholdTestSig12", DetectThresholdTestSig12);
1686  UtRegisterTest("DetectThresholdTestSig13", DetectThresholdTestSig13);
1687  UtRegisterTest("DetectThresholdTestSig14", DetectThresholdTestSig14);
1688 }
1689 #endif /* UNITTESTS */
1690 
1691 /**
1692  * @}
1693  */
TRACK_BOTH
#define TRACK_BOTH
Definition: detect-threshold.h:39
util-byte.h
host.h
SigTableElmt_::url
const char * url
Definition: detect.h:1512
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:68
SigTableElmt_::desc
const char * desc
Definition: detect.h:1511
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1496
util-hashlist.h
DetectParseRegex
Definition: detect-parse.h:94
SigTableElmt_::name
const char * name
Definition: detect.h:1509
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:168
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1500
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:1474
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:622
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:563
DETECT_SM_LIST_THRESHOLD
@ DETECT_SM_LIST_THRESHOLD
Definition: detect.h:133
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:973
TYPE_LIMIT
#define TYPE_LIMIT
Definition: detect-threshold.h:27
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2715
TRACK_DST
#define TRACK_DST
Definition: detect-detection-filter.c:44
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
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:2971
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:3634
p
Packet * p
Definition: fuzz_iprep.c:21
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3580
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:138
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1491
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
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:177
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:1291
util-cpu.h
Packet_::ts
SCTime_t ts
Definition: decode.h:568
SIG_TYPE_IPONLY
@ SIG_TYPE_IPONLY
Definition: detect.h:66
DETECT_THRESHOLD
@ DETECT_THRESHOLD
Definition: detect-engine-register.h:60
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:3760
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-threshold.c:67
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:387
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3461
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:269
util-time.h
ThresholdDestroy
void ThresholdDestroy(void)
Definition: detect-engine-threshold.c:145
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:127
TimeSetIncrementTime
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
Definition: util-time.c:181
Packet_
Definition: decode.h:514
SIGMATCH_IPONLY_COMPAT
#define SIGMATCH_IPONLY_COMPAT
Definition: detect-engine-register.h:308
detect-engine-build.h
TimeGet
SCTime_t TimeGet(void)
Definition: util-time.c:153
detect-engine-alert.h
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1471
decode-events.h
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2286
DetectThresholdData_::track
uint8_t track
Definition: detect-threshold.h:66
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1333
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
DetectAddressHead_::ipv6_head
DetectAddress * ipv6_head
Definition: detect.h:185
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:357
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:3706
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:33
TYPE_THRESHOLD
#define TYPE_THRESHOLD
Definition: detect-threshold.h:29
DETECT_DETECTION_FILTER
@ DETECT_DETECTION_FILTER
Definition: detect-engine-register.h:123
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:675
SigMatch_
a single match condition for a signature
Definition: detect.h:356
detect-threshold.h
DetectAddress_::next
struct DetectAddress_ * next
Definition: detect.h:179
DetectThresholdRegister
void DetectThresholdRegister(void)
Registration function for threshold: keyword.
Definition: detect-threshold.c:86
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2676
SCStorageCleanup
void SCStorageCleanup(void)
Definition: util-storage.c:76
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:45
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:975
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:121
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
Signature_::type
enum SignatureType type
Definition: detect.h:678
DetectThresholdDataCopy
DetectThresholdData * DetectThresholdDataCopy(DetectThresholdData *de)
Make a deep-copy of an extant DetectTHresholdData object.
Definition: detect-threshold.c:343
StatsThreadCleanup
void StatsThreadCleanup(StatsThreadContext *stats)
Definition: counters.c:1429
flow-var.h
ThresholdInit
void ThresholdInit(void)
Definition: detect-engine-threshold.c:128
DetectAddressHead_::ipv4_head
DetectAddress * ipv4_head
Definition: detect.h:184
detect-engine-address.h
SCThreadFreeStorage
void SCThreadFreeStorage(ThreadVars *tv)
Definition: thread-storage.c:45
SCStorageFinalize
int SCStorageFinalize(void)
Definition: util-storage.c:135
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1498
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:455