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 
397 /**
398  * \test ThresholdTestParse01 is a test for a valid threshold options
399  *
400  * \retval 1 on success
401  * \retval 0 on failure
402  */
403 static int ThresholdTestParse01(void)
404 {
405  DetectThresholdData *de = NULL;
406  de = DetectThresholdParse("type limit,track by_dst,count 10,seconds 60");
407  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
408  (de->seconds == 60)) {
409  DetectThresholdFree(NULL, de);
410  return 1;
411  }
412 
413  return 0;
414 }
415 
416 static int ThresholdTestParseByFlow01(void)
417 {
418  DetectThresholdData *de = DetectThresholdParse("type limit,track by_flow,count 1,seconds 60");
419  FAIL_IF_NULL(de);
420  FAIL_IF_NOT(de->type == TYPE_LIMIT);
421  FAIL_IF_NOT(de->track == TRACK_FLOW);
422  FAIL_IF_NOT(de->count == 1);
423  FAIL_IF_NOT(de->seconds == 60);
424  DetectThresholdFree(NULL, de);
425  PASS;
426 }
427 
428 /**
429  * \test ThresholdTestParse02 is a test for a invalid threshold options
430  *
431  * \retval 1 on success
432  * \retval 0 on failure
433  */
434 static int ThresholdTestParse02(void)
435 {
436  DetectThresholdData *de = NULL;
437  de = DetectThresholdParse("type any,track by_dst,count 10,seconds 60");
438  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
439  (de->seconds == 60)) {
440  DetectThresholdFree(NULL, de);
441  return 0;
442  }
443 
444  return 1;
445 }
446 
447 /**
448  * \test ThresholdTestParse03 is a test for a valid threshold options in any order
449  *
450  * \retval 1 on success
451  * \retval 0 on failure
452  */
453 static int ThresholdTestParse03(void)
454 {
455  DetectThresholdData *de = NULL;
456  de = DetectThresholdParse("track by_dst, type limit, seconds 60, count 10");
457  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) &&
458  (de->seconds == 60)) {
459  DetectThresholdFree(NULL, de);
460  return 1;
461  }
462 
463  return 0;
464 }
465 
466 /**
467  * \test ThresholdTestParse04 is a test for an invalid threshold options in any order
468  *
469  * \retval 1 on success
470  * \retval 0 on failure
471  */
472 static int ThresholdTestParse04(void)
473 {
474  DetectThresholdData *de = NULL;
475  de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both, count 10");
476  if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) &&
477  (de->seconds == 60)) {
478  DetectThresholdFree(NULL, de);
479  return 0;
480  }
481 
482  return 1;
483 }
484 
485 /**
486  * \test ThresholdTestParse05 is a test for a valid threshold options in any order
487  *
488  * \retval 1 on success
489  * \retval 0 on failure
490  */
491 static int ThresholdTestParse05(void)
492 {
493  DetectThresholdData *de = NULL;
494  de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both");
495  if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) &&
496  (de->seconds == 60)) {
497  DetectThresholdFree(NULL, de);
498  return 1;
499  }
500 
501  return 0;
502 }
503 
504 /**
505  * \test ThresholdTestParse06 is a test for thresholding by_both
506  *
507  * \retval 1 on success
508  * \retval 0 on failure
509  */
510 static int ThresholdTestParse06(void)
511 {
512  DetectThresholdData *de = NULL;
513  de = DetectThresholdParse("count 10, track by_both, seconds 60, type limit");
514  FAIL_IF_NULL(de);
515  FAIL_IF_NOT(de->type == TYPE_LIMIT);
516  FAIL_IF_NOT(de->track == TRACK_BOTH);
517  FAIL_IF_NOT(de->count == 10);
518  FAIL_IF_NOT(de->seconds == 60);
519  DetectThresholdFree(NULL, de);
520  PASS;
521 }
522 
523 /**
524  * \test ThresholdTestParse07 is a test for thresholding by_rule
525  *
526  * \retval 1 on success
527  * \retval 0 on failure
528  */
529 static int ThresholdTestParse07(void)
530 {
531  DetectThresholdData *de = NULL;
532  de = DetectThresholdParse("count 10, track by_rule, seconds 60, type limit");
533  FAIL_IF_NULL(de);
534  FAIL_IF_NOT(de->type == TYPE_LIMIT);
535  FAIL_IF_NOT(de->track == TRACK_RULE);
536  FAIL_IF_NOT(de->count == 10);
537  FAIL_IF_NOT(de->seconds == 60);
538  DetectThresholdFree(NULL, de);
539  PASS;
540 }
541 
542 /** \test backoff by_flow */
543 static int ThresholdTestParse08(void)
544 {
545  DetectThresholdData *de =
546  DetectThresholdParse("count 10, track by_flow, multiplier 2, type backoff");
547  FAIL_IF_NULL(de);
548  FAIL_IF_NOT(de->type == TYPE_BACKOFF);
549  FAIL_IF_NOT(de->track == TRACK_FLOW);
550  FAIL_IF_NOT(de->count == 10);
551  FAIL_IF_NOT(de->multiplier == 2);
552  DetectThresholdFree(NULL, de);
553  PASS;
554 }
555 
556 /**
557  * \test DetectThresholdTestSig1 is a test for checking the working of limit keyword
558  * by setting up the signature and later testing its working by matching
559  * the received packet against the sig.
560  *
561  * \retval 1 on success
562  * \retval 0 on failure
563  */
564 
565 static int DetectThresholdTestSig1(void)
566 {
567  Packet *p = NULL;
568  Signature *s = NULL;
569  ThreadVars th_v;
570  DetectEngineThreadCtx *det_ctx;
571  int result = 0;
572  int alerts = 0;
573 
574  ThresholdInit();
575 
576  memset(&th_v, 0, sizeof(th_v));
577 
578  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
579 
581  if (de_ctx == NULL) {
582  goto end;
583  }
584 
585  de_ctx->flags |= DE_QUIET;
586 
587  s = de_ctx->sig_list =
588  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit\"; content:\"A\"; "
589  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
590  if (s == NULL) {
591  goto end;
592  }
593 
595 
597 
598  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
599 
600  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
601  alerts = PacketAlertCheck(p, 1);
602  if (alerts != 1) {
603  printf("alerts %" PRIi32 ", expected 1: ", alerts);
604  }
605  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
606  alerts += PacketAlertCheck(p, 1);
607  if (alerts != 2) {
608  printf("alerts %" PRIi32 ", expected 2: ", alerts);
609  }
610  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
611  alerts += PacketAlertCheck(p, 1);
612  if (alerts != 3) {
613  printf("alerts %" PRIi32 ", expected 3: ", alerts);
614  }
615  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
616  alerts += PacketAlertCheck(p, 1);
617  if (alerts != 4) {
618  printf("alerts %" PRIi32 ", expected 4: ", alerts);
619  }
620  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
621  alerts += PacketAlertCheck(p, 1);
622  if (alerts != 5) {
623  printf("alerts %" PRIi32 ", expected 5: ", alerts);
624  }
625  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
626  alerts += PacketAlertCheck(p, 1);
627  if (alerts != 5) {
628  printf("alerts %" PRIi32 ", expected 5: ", alerts);
629  }
630  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
631  alerts += PacketAlertCheck(p, 1);
632  if (alerts != 5) {
633  printf("alerts %" PRIi32 ", expected 5: ", alerts);
634  }
635  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
636  alerts += PacketAlertCheck(p, 1);
637  if (alerts != 5) {
638  printf("alerts %" PRIi32 ", expected 5: ", alerts);
639  }
640 
641  if (alerts == 5)
642  result = 1;
643  else
644  printf("alerts %" PRIi32 ", expected 5: ", alerts);
645 
646  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
648 
649  UTHFreePackets(&p, 1);
650 
651 end:
653  StatsThreadCleanup(&th_v);
654  return result;
655 }
656 
657 /**
658  * \test DetectThresholdTestSig2 is a test for checking the working of threshold keyword
659  * by setting up the signature and later testing its working by matching
660  * the received packet against the sig.
661  *
662  * \retval 1 on success
663  * \retval 0 on failure
664  */
665 
666 static int DetectThresholdTestSig2(void)
667 {
668  Packet *p = NULL;
669  Signature *s = NULL;
670  ThreadVars th_v;
671  DetectEngineThreadCtx *det_ctx;
672  int result = 0;
673  int alerts = 0;
674 
675  ThresholdInit();
676 
677  memset(&th_v, 0, sizeof(th_v));
678 
679  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
680 
682  if (de_ctx == NULL) {
683  goto end;
684  }
685 
686  de_ctx->flags |= DE_QUIET;
687 
688  s = de_ctx->sig_list =
689  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold\"; threshold: type "
690  "threshold, track by_dst, count 5, seconds 60; sid:1;)");
691  if (s == NULL) {
692  goto end;
693  }
694 
696  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
697 
698  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
699  alerts = PacketAlertCheck(p, 1);
700  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
701  alerts += PacketAlertCheck(p, 1);
702  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
703  alerts += PacketAlertCheck(p, 1);
704  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
705  alerts += PacketAlertCheck(p, 1);
706  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
707  alerts += PacketAlertCheck(p, 1);
708  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
709  alerts += PacketAlertCheck(p, 1);
710  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
711  alerts += PacketAlertCheck(p, 1);
712  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
713  alerts += PacketAlertCheck(p, 1);
714  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
715  alerts += PacketAlertCheck(p, 1);
716  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
717  alerts += PacketAlertCheck(p, 1);
718 
719  if (alerts == 2)
720  result = 1;
721  else
722  goto cleanup;
723 
724 cleanup:
725  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
727 
728 end:
729  UTHFreePackets(&p, 1);
731  StatsThreadCleanup(&th_v);
732  return result;
733 }
734 
735 /**
736  * \test DetectThresholdTestSig3 is a test for checking the working of limit keyword
737  * by setting up the signature and later testing its working by matching
738  * the received packet against the sig.
739  *
740  * \retval 1 on success
741  * \retval 0 on failure
742  */
743 
744 static int DetectThresholdTestSig3(void)
745 {
746  ThreadVars th_v;
747  memset(&th_v, 0, sizeof(th_v));
748 
749  ThresholdInit();
750  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
751 
754  de_ctx->flags |= DE_QUIET;
755 
757  "alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, "
758  "track by_dst, count 5, seconds 60; sid:10;)");
759  FAIL_IF_NULL(s);
760 
762  DetectEngineThreadCtx *det_ctx;
763  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
764 
765  p->ts = TimeGet();
766 
767  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
768  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
769  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
770  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
771  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
772  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
773 
775  p->ts = TimeGet();
776 
777  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
778  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
779  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
780  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
781  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
782  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
783 
784  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
786  UTHFreePackets(&p, 1);
788  StatsThreadCleanup(&th_v);
789  PASS;
790 }
791 
792 /**
793  * \test DetectThresholdTestSig4 is a test for checking the working of both keyword
794  * by setting up the signature and later testing its working by matching
795  * the received packet against the sig.
796  *
797  * \retval 1 on success
798  * \retval 0 on failure
799  */
800 
801 static int DetectThresholdTestSig4(void)
802 {
803  Packet *p = NULL;
804  Signature *s = NULL;
805  ThreadVars th_v;
806  DetectEngineThreadCtx *det_ctx;
807  int result = 0;
808  int alerts = 0;
809 
810  ThresholdInit();
811 
812  memset(&th_v, 0, sizeof(th_v));
813 
814  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
815 
817  if (de_ctx == NULL) {
818  goto end;
819  }
820 
821  de_ctx->flags |= DE_QUIET;
822 
823  s = de_ctx->sig_list =
824  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold both\"; threshold: type "
825  "both, track by_dst, count 2, seconds 60; sid:10;)");
826  if (s == NULL) {
827  goto end;
828  }
829 
831  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
832 
833  p->ts = TimeGet();
834  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
835  alerts = PacketAlertCheck(p, 10);
836  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
837  alerts += PacketAlertCheck(p, 10);
838  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
839  alerts += PacketAlertCheck(p, 10);
840 
842  p->ts = TimeGet();
843 
844  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
845  alerts += PacketAlertCheck(p, 10);
846  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
847  alerts += PacketAlertCheck(p, 10);
848  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
849  alerts += PacketAlertCheck(p, 10);
850 
851  if (alerts == 2)
852  result = 1;
853  else
854  goto cleanup;
855 
856 cleanup:
857  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
859 end:
860  UTHFreePackets(&p, 1);
862  StatsThreadCleanup(&th_v);
863  return result;
864 }
865 
866 /**
867  * \test DetectThresholdTestSig5 is a test for checking the working of limit keyword
868  * by setting up the signature and later testing its working by matching
869  * the received packet against the sig.
870  *
871  * \retval 1 on success
872  * \retval 0 on failure
873  */
874 
875 static int DetectThresholdTestSig5(void)
876 {
877  Packet *p = NULL;
878  Signature *s = NULL;
879  ThreadVars th_v;
880  DetectEngineThreadCtx *det_ctx;
881  int result = 0;
882  int alerts = 0;
883 
884  ThresholdInit();
885 
886  memset(&th_v, 0, sizeof(th_v));
887  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
888 
890  if (de_ctx == NULL) {
891  goto end;
892  }
893 
894  de_ctx->flags |= DE_QUIET;
895 
896  s = de_ctx->sig_list =
897  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
898  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
899  if (s == NULL) {
900  goto end;
901  }
902 
903  s = s->next =
904  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; "
905  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
906  if (s == NULL) {
907  goto end;
908  }
909 
911  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
912 
913  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
914  alerts = PacketAlertCheck(p, 1);
915  alerts += PacketAlertCheck(p, 1000);
916  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
917  alerts += PacketAlertCheck(p, 1);
918  alerts += PacketAlertCheck(p, 1000);
919  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
920  alerts += PacketAlertCheck(p, 1);
921  alerts += PacketAlertCheck(p, 1000);
922  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
923  alerts += PacketAlertCheck(p, 1);
924  alerts += PacketAlertCheck(p, 1000);
925  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
926  alerts += PacketAlertCheck(p, 1);
927  alerts += PacketAlertCheck(p, 1000);
928  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
929  alerts += PacketAlertCheck(p, 1);
930  alerts += PacketAlertCheck(p, 1000);
931  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
932  alerts += PacketAlertCheck(p, 1);
933  alerts += PacketAlertCheck(p, 1000);
934  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
935  alerts += PacketAlertCheck(p, 1);
936  alerts += PacketAlertCheck(p, 1000);
937 
938  if (alerts == 10)
939  result = 1;
940  else {
941  printf("alerts %d != 10: ", alerts);
942  goto cleanup;
943  }
944 
945 cleanup:
946  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
948 
949 end:
950  UTHFreePackets(&p, 1);
952  StatsThreadCleanup(&th_v);
953  return result;
954 }
955 
956 static int DetectThresholdTestSig6Ticks(void)
957 {
958  Packet *p = NULL;
959  Signature *s = NULL;
960  ThreadVars th_v;
961  DetectEngineThreadCtx *det_ctx;
962  int result = 0;
963  int alerts = 0;
964 
965  ThresholdInit();
966 
967  memset(&th_v, 0, sizeof(th_v));
968  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
969 
971  if (de_ctx == NULL) {
972  goto end;
973  }
974 
975  de_ctx->flags |= DE_QUIET;
976 
977  s = de_ctx->sig_list =
978  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
979  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
980  if (s == NULL) {
981  goto end;
982  }
983 
984  s = s->next =
985  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; "
986  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
987  if (s == NULL) {
988  goto end;
989  }
990 
992  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
993 
994  uint64_t ticks_start = 0;
995  uint64_t ticks_end = 0;
996 
997  ticks_start = UtilCpuGetTicks();
998  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
999  alerts = PacketAlertCheck(p, 1);
1000  alerts += PacketAlertCheck(p, 1000);
1001  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1002  alerts += PacketAlertCheck(p, 1);
1003  alerts += PacketAlertCheck(p, 1000);
1004  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1005  alerts += PacketAlertCheck(p, 1);
1006  alerts += PacketAlertCheck(p, 1000);
1007  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1008  alerts += PacketAlertCheck(p, 1);
1009  alerts += PacketAlertCheck(p, 1000);
1010  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1011  alerts += PacketAlertCheck(p, 1);
1012  alerts += PacketAlertCheck(p, 1000);
1013  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1014  alerts += PacketAlertCheck(p, 1);
1015  alerts += PacketAlertCheck(p, 1000);
1016  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1017  alerts += PacketAlertCheck(p, 1);
1018  alerts += PacketAlertCheck(p, 1000);
1019  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1020  alerts += PacketAlertCheck(p, 1);
1021  alerts += PacketAlertCheck(p, 1000);
1022  ticks_end = UtilCpuGetTicks();
1023  printf("test run %" PRIu64 "\n", (ticks_end - ticks_start));
1024 
1025  if (alerts == 10)
1026  result = 1;
1027  else
1028  goto cleanup;
1029 
1030 cleanup:
1031  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1033 
1034 end:
1035  UTHFreePackets(&p, 1);
1036  ThresholdDestroy();
1037  StatsThreadCleanup(&th_v);
1038  return result;
1039 }
1040 
1041 /**
1042  * \test Test drop action being set even if thresholded
1043  */
1044 static int DetectThresholdTestSig7(void)
1045 {
1046  Packet *p = NULL;
1047  Signature *s = NULL;
1048  ThreadVars th_v;
1049  DetectEngineThreadCtx *det_ctx;
1050  int result = 0;
1051  int alerts = 0;
1052  int drops = 0;
1053 
1054  ThresholdInit();
1055 
1056  memset(&th_v, 0, sizeof(th_v));
1057 
1058  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1059 
1061  if (de_ctx == NULL) {
1062  goto end;
1063  }
1064 
1065  de_ctx->flags |= DE_QUIET;
1066 
1067  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type limit, "
1068  "track by_src, count 1, seconds 300; sid:10;)");
1069  if (s == NULL) {
1070  goto end;
1071  }
1072 
1074  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1075 
1076  p->ts = TimeGet();
1077  SigMatchSignatures(&th_v, 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(&th_v, de_ctx, det_ctx, p);
1083  alerts += PacketAlertCheck(p, 10);
1084  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1085  p->action = 0;
1086 
1087  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1088  alerts += PacketAlertCheck(p, 10);
1089  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1090  p->action = 0;
1091 
1092  TimeSetIncrementTime(200);
1093  p->ts = TimeGet();
1094 
1095  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1096  alerts += PacketAlertCheck(p, 10);
1097  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1098  p->action = 0;
1099 
1100  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1101  alerts += PacketAlertCheck(p, 10);
1102  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1103  p->action = 0;
1104 
1105  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1106  alerts += PacketAlertCheck(p, 10);
1107  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1108  p->action = 0;
1109 
1110  if (alerts == 1 && drops == 6)
1111  result = 1;
1112  else {
1113  if (alerts != 1)
1114  printf("alerts: %d != 1: ", alerts);
1115  if (drops != 6)
1116  printf("drops: %d != 6: ", drops);
1117  goto cleanup;
1118  }
1119 
1120 cleanup:
1121  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1123 end:
1124  UTHFreePackets(&p, 1);
1125  ThresholdDestroy();
1126  StatsThreadCleanup(&th_v);
1127  return result;
1128 }
1129 
1130 /**
1131  * \test Test drop action being set even if thresholded
1132  */
1133 static int DetectThresholdTestSig8(void)
1134 {
1135  Packet *p = NULL;
1136  Signature *s = NULL;
1137  ThreadVars th_v;
1138  DetectEngineThreadCtx *det_ctx;
1139  int result = 0;
1140  int alerts = 0;
1141  int drops = 0;
1142 
1143  ThresholdInit();
1144 
1145  memset(&th_v, 0, sizeof(th_v));
1146 
1147  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1148 
1150  if (de_ctx == NULL) {
1151  goto end;
1152  }
1153 
1154  de_ctx->flags |= DE_QUIET;
1155 
1156  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type limit, "
1157  "track by_src, count 2, seconds 300; sid:10;)");
1158  if (s == NULL) {
1159  goto end;
1160  }
1161 
1163  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1164 
1165  p->ts = TimeGet();
1166  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1167  alerts = PacketAlertCheck(p, 10);
1168  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1169  p->action = 0;
1170 
1171  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1172  alerts += PacketAlertCheck(p, 10);
1173  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1174  p->action = 0;
1175 
1176  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1177  alerts += PacketAlertCheck(p, 10);
1178  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1179  p->action = 0;
1180 
1181  TimeSetIncrementTime(200);
1182  p->ts = TimeGet();
1183 
1184  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1185  alerts += PacketAlertCheck(p, 10);
1186  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1187  p->action = 0;
1188 
1189  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1190  alerts += PacketAlertCheck(p, 10);
1191  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1192  p->action = 0;
1193 
1194  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1195  alerts += PacketAlertCheck(p, 10);
1196  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1197  p->action = 0;
1198 
1199  if (alerts == 2 && drops == 6)
1200  result = 1;
1201  else {
1202  if (alerts != 1)
1203  printf("alerts: %d != 1: ", alerts);
1204  if (drops != 6)
1205  printf("drops: %d != 6: ", drops);
1206  goto cleanup;
1207  }
1208 
1209 cleanup:
1210  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1212 end:
1213  UTHFreePackets(&p, 1);
1214  ThresholdDestroy();
1215  StatsThreadCleanup(&th_v);
1216  return result;
1217 }
1218 
1219 /**
1220  * \test Test drop action being set even if thresholded
1221  */
1222 static int DetectThresholdTestSig9(void)
1223 {
1224  Packet *p = NULL;
1225  Signature *s = NULL;
1226  ThreadVars th_v;
1227  DetectEngineThreadCtx *det_ctx;
1228  int result = 0;
1229  int alerts = 0;
1230  int drops = 0;
1231 
1232  ThresholdInit();
1233 
1234  memset(&th_v, 0, sizeof(th_v));
1235 
1236  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1237 
1239  if (de_ctx == NULL) {
1240  goto end;
1241  }
1242 
1243  de_ctx->flags |= DE_QUIET;
1244 
1245  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type threshold, "
1246  "track by_src, count 3, seconds 100; sid:10;)");
1247  if (s == NULL) {
1248  goto end;
1249  }
1250 
1252  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1253 
1254  p->ts = TimeGet();
1255  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1256  alerts = PacketAlertCheck(p, 10);
1257  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1258  p->action = 0;
1259 
1260  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1261  alerts += PacketAlertCheck(p, 10);
1262  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1263  p->action = 0;
1264 
1265  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1266  alerts += PacketAlertCheck(p, 10);
1267  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1268  p->action = 0;
1269 
1270  TimeSetIncrementTime(200);
1271  p->ts = TimeGet();
1272 
1273  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1274  alerts += PacketAlertCheck(p, 10);
1275  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1276  p->action = 0;
1277 
1278  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1279  alerts += PacketAlertCheck(p, 10);
1280  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1281  p->action = 0;
1282 
1283  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1284  alerts += PacketAlertCheck(p, 10);
1285  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1286  p->action = 0;
1287 
1288  if (alerts == 2 && drops == 2)
1289  result = 1;
1290  else {
1291  if (alerts != 2)
1292  printf("alerts: %d != 2: ", alerts);
1293  if (drops != 2)
1294  printf("drops: %d != 2: ", drops);
1295  goto cleanup;
1296  }
1297 
1298 cleanup:
1299  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1301 end:
1302  UTHFreePackets(&p, 1);
1303  ThresholdDestroy();
1304  StatsThreadCleanup(&th_v);
1305  return result;
1306 }
1307 
1308 /**
1309  * \test Test drop action being set even if thresholded
1310  */
1311 static int DetectThresholdTestSig10(void)
1312 {
1313  Packet *p = NULL;
1314  Signature *s = NULL;
1315  ThreadVars th_v;
1316  DetectEngineThreadCtx *det_ctx;
1317  int result = 0;
1318  int alerts = 0;
1319  int drops = 0;
1320 
1321  ThresholdInit();
1322 
1323  memset(&th_v, 0, sizeof(th_v));
1324 
1325  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1326 
1328  if (de_ctx == NULL) {
1329  goto end;
1330  }
1331 
1332  de_ctx->flags |= DE_QUIET;
1333 
1334  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type threshold, "
1335  "track by_src, count 5, seconds 300; sid:10;)");
1336  if (s == NULL) {
1337  goto end;
1338  }
1339 
1341  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1342 
1343  p->ts = TimeGet();
1344  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1345  alerts = PacketAlertCheck(p, 10);
1346  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1347  p->action = 0;
1348 
1349  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1350  alerts += PacketAlertCheck(p, 10);
1351  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1352  p->action = 0;
1353 
1354  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1355  alerts += PacketAlertCheck(p, 10);
1356  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1357  p->action = 0;
1358 
1359  TimeSetIncrementTime(200);
1360  p->ts = TimeGet();
1361 
1362  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1363  alerts += PacketAlertCheck(p, 10);
1364  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1365  p->action = 0;
1366 
1367  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1368  alerts += PacketAlertCheck(p, 10);
1369  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1370  p->action = 0;
1371 
1372  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1373  alerts += PacketAlertCheck(p, 10);
1374  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1375  p->action = 0;
1376 
1377  if (alerts == 1 && drops == 1)
1378  result = 1;
1379  else {
1380  if (alerts != 1)
1381  printf("alerts: %d != 1: ", alerts);
1382  if (drops != 1)
1383  printf("drops: %d != 1: ", drops);
1384  goto cleanup;
1385  }
1386 
1387 cleanup:
1388  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1390 end:
1391  UTHFreePackets(&p, 1);
1392  ThresholdDestroy();
1393  StatsThreadCleanup(&th_v);
1394  return result;
1395 }
1396 
1397 /**
1398  * \test Test drop action being set even if thresholded
1399  */
1400 static int DetectThresholdTestSig11(void)
1401 {
1402  Packet *p = NULL;
1403  Signature *s = NULL;
1404  ThreadVars th_v;
1405  DetectEngineThreadCtx *det_ctx;
1406  int result = 0;
1407  int alerts = 0;
1408  int drops = 0;
1409 
1410  ThresholdInit();
1411 
1412  memset(&th_v, 0, sizeof(th_v));
1413 
1414  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1415 
1417  if (de_ctx == NULL) {
1418  goto end;
1419  }
1420 
1421  de_ctx->flags |= DE_QUIET;
1422 
1423  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type both, "
1424  "track by_src, count 3, seconds 300; sid:10;)");
1425  if (s == NULL) {
1426  goto end;
1427  }
1428 
1430  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1431 
1432  p->ts = TimeGet();
1433  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1434  alerts = PacketAlertCheck(p, 10);
1435  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1436  p->action = 0;
1437 
1438  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1439  alerts += PacketAlertCheck(p, 10);
1440  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1441  p->action = 0;
1442 
1443  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1444  alerts += PacketAlertCheck(p, 10);
1445  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1446  p->action = 0;
1447 
1448  TimeSetIncrementTime(200);
1449  p->ts = TimeGet();
1450 
1451  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1452  alerts += PacketAlertCheck(p, 10);
1453  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1454  p->action = 0;
1455 
1456  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1457  alerts += PacketAlertCheck(p, 10);
1458  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1459  p->action = 0;
1460 
1461  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1462  alerts += PacketAlertCheck(p, 10);
1463  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1464  p->action = 0;
1465 
1466  if (alerts == 1 && drops == 4)
1467  result = 1;
1468  else {
1469  if (alerts != 1)
1470  printf("alerts: %d != 1: ", alerts);
1471  if (drops != 4)
1472  printf("drops: %d != 4: ", drops);
1473  goto cleanup;
1474  }
1475 
1476 cleanup:
1477  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1479 end:
1480  UTHFreePackets(&p, 1);
1481  ThresholdDestroy();
1482  StatsThreadCleanup(&th_v);
1483  return result;
1484 }
1485 
1486 /**
1487  * \test Test drop action being set even if thresholded
1488  */
1489 static int DetectThresholdTestSig12(void)
1490 {
1491  Packet *p = NULL;
1492  Signature *s = NULL;
1493  ThreadVars th_v;
1494  DetectEngineThreadCtx *det_ctx;
1495  int result = 0;
1496  int alerts = 0;
1497  int drops = 0;
1498 
1499  ThresholdInit();
1500 
1501  memset(&th_v, 0, sizeof(th_v));
1502 
1503  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1504 
1506  if (de_ctx == NULL) {
1507  goto end;
1508  }
1509 
1510  de_ctx->flags |= DE_QUIET;
1511 
1512  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type both, "
1513  "track by_src, count 5, seconds 300; sid:10;)");
1514  if (s == NULL) {
1515  goto end;
1516  }
1517 
1519  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1520 
1521  p->ts = TimeGet();
1522  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1523  alerts = PacketAlertCheck(p, 10);
1524  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1525  p->action = 0;
1526 
1527  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1528  alerts += PacketAlertCheck(p, 10);
1529  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1530  p->action = 0;
1531 
1532  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1533  alerts += PacketAlertCheck(p, 10);
1534  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1535  p->action = 0;
1536 
1537  TimeSetIncrementTime(200);
1538  p->ts = TimeGet();
1539 
1540  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1541  alerts += PacketAlertCheck(p, 10);
1542  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1543  p->action = 0;
1544 
1545  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1546  alerts += PacketAlertCheck(p, 10);
1547  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1548  p->action = 0;
1549 
1550  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1551  alerts += PacketAlertCheck(p, 10);
1552  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1553  p->action = 0;
1554 
1555  if (alerts == 1 && drops == 2)
1556  result = 1;
1557  else {
1558  if (alerts != 1)
1559  printf("alerts: %d != 1: ", alerts);
1560  if (drops != 2)
1561  printf("drops: %d != 2: ", drops);
1562  goto cleanup;
1563  }
1564 
1565 cleanup:
1566  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1568 end:
1569  UTHFreePackets(&p, 1);
1570  HostShutdown();
1571  ThresholdDestroy();
1572  StatsThreadCleanup(&th_v);
1573  return result;
1574 }
1575 
1576 /**
1577  * \test DetectThresholdTestSig13 is a test for checking the working by_rule 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 DetectThresholdTestSig13(void)
1586 {
1587  Packet *p = NULL;
1588  Signature *s = NULL;
1589  ThreadVars th_v;
1590  DetectEngineThreadCtx *det_ctx;
1591  int alerts = 0;
1592 
1593  ThresholdInit();
1594 
1595  memset(&th_v, 0, sizeof(th_v));
1596  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1597  FAIL_IF_NULL(p);
1598 
1601 
1602  de_ctx->flags |= DE_QUIET;
1603 
1604  s = de_ctx->sig_list =
1605  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
1606  "threshold: type limit, track by_rule, count 2, seconds 60; sid:1;)");
1607  FAIL_IF_NULL(s);
1608 
1610  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1611 
1612  /* should alert twice */
1613  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1614  alerts += PacketAlertCheck(p, 1);
1615  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1616  alerts += PacketAlertCheck(p, 1);
1617  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1618  alerts += PacketAlertCheck(p, 1);
1619  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1620  alerts += PacketAlertCheck(p, 1);
1621 
1622  FAIL_IF(alerts != 2);
1623 
1625  p->ts = TimeGet();
1626 
1627  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1628  alerts += PacketAlertCheck(p, 1);
1629  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1630  alerts += PacketAlertCheck(p, 1);
1631  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1632  alerts += PacketAlertCheck(p, 1);
1633  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1634  alerts += PacketAlertCheck(p, 1);
1635 
1636  FAIL_IF(alerts != 4);
1637 
1638  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1640  UTHFreePackets(&p, 1);
1641  ThresholdDestroy();
1642  StatsThreadCleanup(&th_v);
1643  PASS;
1644 }
1645 
1646 /**
1647  * \test DetectThresholdTestSig14 is a test for checking the working by_both limits
1648  * by setting up the signature and later testing its working by matching
1649  * received packets against the sig.
1650  *
1651  * \retval 1 on success
1652  * \retval 0 on failure
1653  */
1654 
1655 static int DetectThresholdTestSig14(void)
1656 {
1657  Packet *p1 = NULL;
1658  Packet *p2 = NULL;
1659  Signature *s = NULL;
1660  ThreadVars th_v;
1661  DetectEngineThreadCtx *det_ctx;
1662  int alerts1 = 0;
1663  int alerts2 = 0;
1664 
1665  ThresholdInit();
1666 
1667  memset(&th_v, 0, sizeof(th_v));
1668  p1 = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1669  p2 = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "3.3.3.3", 1024, 80);
1670  FAIL_IF_NULL(p1);
1671  FAIL_IF_NULL(p2);
1672 
1675 
1676  de_ctx->flags |= DE_QUIET;
1677 
1678  s = de_ctx->sig_list =
1679  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
1680  "threshold: type limit, track by_both, count 2, seconds 60; sid:1;)");
1681  FAIL_IF_NULL(s);
1682 
1684  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1685 
1686  /* Both p1 and p2 should alert twice */
1687  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1688  alerts1 += PacketAlertCheck(p1, 1);
1689  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1690  alerts1 += PacketAlertCheck(p1, 1);
1691  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1692  alerts1 += PacketAlertCheck(p1, 1);
1693  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1694  alerts1 += PacketAlertCheck(p1, 1);
1695 
1696  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1697  alerts2 += PacketAlertCheck(p2, 1);
1698  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1699  alerts2 += PacketAlertCheck(p2, 1);
1700  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1701  alerts2 += PacketAlertCheck(p2, 1);
1702  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1703  alerts2 += PacketAlertCheck(p2, 1);
1704 
1705  FAIL_IF(alerts1 != 2);
1706  FAIL_IF(alerts2 != 2);
1707 
1709  p1->ts = TimeGet();
1710  p2->ts = TimeGet();
1711 
1712  /* Now they should both alert again after previous alerts expire */
1713  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1714  alerts1 += PacketAlertCheck(p1, 1);
1715  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1716  alerts2 += PacketAlertCheck(p2, 1);
1717 
1718  FAIL_IF(alerts1 != 3);
1719  FAIL_IF(alerts2 != 3);
1720 
1721  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1723  UTHFreePackets(&p1, 1);
1724  UTHFreePackets(&p2, 1);
1725  ThresholdDestroy();
1726  StatsThreadCleanup(&th_v);
1727  PASS;
1728 }
1729 
1730 static void ThresholdRegisterTests(void)
1731 {
1732  UtRegisterTest("ThresholdTestParse01", ThresholdTestParse01);
1733  UtRegisterTest("ThresholdTestParseByFlow01", ThresholdTestParseByFlow01);
1734  UtRegisterTest("ThresholdTestParse02", ThresholdTestParse02);
1735  UtRegisterTest("ThresholdTestParse03", ThresholdTestParse03);
1736  UtRegisterTest("ThresholdTestParse04", ThresholdTestParse04);
1737  UtRegisterTest("ThresholdTestParse05", ThresholdTestParse05);
1738  UtRegisterTest("ThresholdTestParse06", ThresholdTestParse06);
1739  UtRegisterTest("ThresholdTestParse07", ThresholdTestParse07);
1740  UtRegisterTest("ThresholdTestParse08", ThresholdTestParse08);
1741  UtRegisterTest("DetectThresholdTestSig1", DetectThresholdTestSig1);
1742  UtRegisterTest("DetectThresholdTestSig2", DetectThresholdTestSig2);
1743  UtRegisterTest("DetectThresholdTestSig3", DetectThresholdTestSig3);
1744  UtRegisterTest("DetectThresholdTestSig4", DetectThresholdTestSig4);
1745  UtRegisterTest("DetectThresholdTestSig5", DetectThresholdTestSig5);
1746  UtRegisterTest("DetectThresholdTestSig6Ticks", DetectThresholdTestSig6Ticks);
1747  UtRegisterTest("DetectThresholdTestSig7", DetectThresholdTestSig7);
1748  UtRegisterTest("DetectThresholdTestSig8", DetectThresholdTestSig8);
1749  UtRegisterTest("DetectThresholdTestSig9", DetectThresholdTestSig9);
1750  UtRegisterTest("DetectThresholdTestSig10", DetectThresholdTestSig10);
1751  UtRegisterTest("DetectThresholdTestSig11", DetectThresholdTestSig11);
1752  UtRegisterTest("DetectThresholdTestSig12", DetectThresholdTestSig12);
1753  UtRegisterTest("DetectThresholdTestSig13", DetectThresholdTestSig13);
1754  UtRegisterTest("DetectThresholdTestSig14", DetectThresholdTestSig14);
1755 }
1756 #endif /* UNITTESTS */
1757 
1758 /**
1759  * @}
1760  */
TRACK_BOTH
#define TRACK_BOTH
Definition: detect-threshold.h:39
util-byte.h
host.h
SigTableElmt_::url
const char * url
Definition: detect.h:1460
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
host-storage.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1459
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1444
util-hashlist.h
DetectParseRegex
Definition: detect-parse.h:93
SigTableElmt_::name
const char * name
Definition: detect.h:1457
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:1448
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
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:1477
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:142
DetectThresholdData_::count
uint32_t count
Definition: detect-threshold.h:56
action-globals.h
Packet_::action
uint8_t action
Definition: decode.h:609
DETECT_SM_LIST_THRESHOLD
@ DETECT_SM_LIST_THRESHOLD
Definition: detect.h:133
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:932
TYPE_LIMIT
#define TYPE_LIMIT
Definition: detect-threshold.h:27
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2634
TRACK_DST
#define TRACK_DST
Definition: detect-detection-filter.c:43
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
DetectThresholdData_::multiplier
uint32_t multiplier
Definition: detect-threshold.h:63
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:2416
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:3493
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3439
UTHBuildPacketReal
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
Definition: util-unittest-helper.c:260
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1439
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:58
DetectAddress_::prev
struct DetectAddress_ * prev
Definition: detect.h:177
Signature_::next
struct Signature_ * next
Definition: detect.h:750
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:18
DetectEngineThreadCtx_
Definition: detect.h:1244
util-cpu.h
Packet_::ts
SCTime_t ts
Definition: decode.h:555
SIG_TYPE_IPONLY
@ SIG_TYPE_IPONLY
Definition: detect.h:66
DETECT_THRESHOLD
@ DETECT_THRESHOLD
Definition: detect-engine-register.h:58
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:3619
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:388
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:3364
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:316
util-time.h
ThresholdDestroy
void ThresholdDestroy(void)
Definition: detect-engine-threshold.c:71
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:3097
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:180
Packet_
Definition: decode.h:501
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:1419
decode-events.h
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2194
DetectThresholdData_::track
uint8_t track
Definition: detect-threshold.h:59
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:55
packet.h
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3596
HostShutdown
void HostShutdown(void)
shutdown the flow engine
Definition: host.c:296
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:941
TYPE_THRESHOLD
#define TYPE_THRESHOLD
Definition: detect-threshold.h:29
DETECT_DETECTION_FILTER
@ DETECT_DETECTION_FILTER
Definition: detect-engine-register.h:120
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:271
SCFree
#define SCFree(p)
Definition: util-mem.h:61
detect-parse.h
Signature_
Signature container.
Definition: detect.h:668
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:2595
suricata.h
TRACK_SRC
#define TRACK_SRC
Definition: detect-detection-filter.c:44
DetectGetLastSMFromLists
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
Definition: detect-parse.c:564
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:934
DetectThresholdData_::seconds
uint32_t seconds
Definition: detect-threshold.h:57
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:285
Signature_::type
enum SignatureType type
Definition: detect.h:671
DetectThresholdDataCopy
DetectThresholdData * DetectThresholdDataCopy(DetectThresholdData *de)
Make a deep-copy of an extant DetectTHresholdData object.
Definition: detect-threshold.c:343
StatsThreadCleanup
void StatsThreadCleanup(ThreadVars *tv)
Definition: counters.c:1324
flow-var.h
ThresholdInit
void ThresholdInit(void)
Definition: detect-engine-threshold.c:66
SIGMATCH_IPONLY_COMPAT
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1651
DetectAddressHead_::ipv4_head
DetectAddress * ipv4_head
Definition: detect.h:184
detect-engine-address.h
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1446
detect-engine-threshold.h
DetectThresholdData_::addrs
DetectAddressHead addrs
Definition: detect-threshold.h:64
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:456