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  StatsThreadInit(&th_v.stats);
578 
579  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
580 
582  if (de_ctx == NULL) {
583  goto end;
584  }
585 
586  de_ctx->flags |= DE_QUIET;
587 
588  s = de_ctx->sig_list =
589  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit\"; content:\"A\"; "
590  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
591  if (s == NULL) {
592  goto end;
593  }
594 
596 
598 
599  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
600 
601  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
602  alerts = PacketAlertCheck(p, 1);
603  if (alerts != 1) {
604  printf("alerts %" PRIi32 ", expected 1: ", alerts);
605  }
606  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
607  alerts += PacketAlertCheck(p, 1);
608  if (alerts != 2) {
609  printf("alerts %" PRIi32 ", expected 2: ", alerts);
610  }
611  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
612  alerts += PacketAlertCheck(p, 1);
613  if (alerts != 3) {
614  printf("alerts %" PRIi32 ", expected 3: ", alerts);
615  }
616  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
617  alerts += PacketAlertCheck(p, 1);
618  if (alerts != 4) {
619  printf("alerts %" PRIi32 ", expected 4: ", alerts);
620  }
621  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
622  alerts += PacketAlertCheck(p, 1);
623  if (alerts != 5) {
624  printf("alerts %" PRIi32 ", expected 5: ", alerts);
625  }
626  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
627  alerts += PacketAlertCheck(p, 1);
628  if (alerts != 5) {
629  printf("alerts %" PRIi32 ", expected 5: ", alerts);
630  }
631  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
632  alerts += PacketAlertCheck(p, 1);
633  if (alerts != 5) {
634  printf("alerts %" PRIi32 ", expected 5: ", alerts);
635  }
636  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
637  alerts += PacketAlertCheck(p, 1);
638  if (alerts != 5) {
639  printf("alerts %" PRIi32 ", expected 5: ", alerts);
640  }
641 
642  if (alerts == 5)
643  result = 1;
644  else
645  printf("alerts %" PRIi32 ", expected 5: ", alerts);
646 
647  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
649 
650  UTHFreePackets(&p, 1);
651 
652 end:
654  StatsThreadCleanup(&th_v.stats);
655  return result;
656 }
657 
658 /**
659  * \test DetectThresholdTestSig2 is a test for checking the working of threshold keyword
660  * by setting up the signature and later testing its working by matching
661  * the received packet against the sig.
662  *
663  * \retval 1 on success
664  * \retval 0 on failure
665  */
666 
667 static int DetectThresholdTestSig2(void)
668 {
669  Packet *p = NULL;
670  Signature *s = NULL;
671  ThreadVars th_v;
672  DetectEngineThreadCtx *det_ctx;
673  int result = 0;
674  int alerts = 0;
675 
676  ThresholdInit();
677 
678  memset(&th_v, 0, sizeof(th_v));
679  StatsThreadInit(&th_v.stats);
680 
681  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
682 
684  if (de_ctx == NULL) {
685  goto end;
686  }
687 
688  de_ctx->flags |= DE_QUIET;
689 
690  s = de_ctx->sig_list =
691  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold\"; threshold: type "
692  "threshold, track by_dst, count 5, seconds 60; sid:1;)");
693  if (s == NULL) {
694  goto end;
695  }
696 
698  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
699 
700  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
701  alerts = PacketAlertCheck(p, 1);
702  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
703  alerts += PacketAlertCheck(p, 1);
704  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
705  alerts += PacketAlertCheck(p, 1);
706  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
707  alerts += PacketAlertCheck(p, 1);
708  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
709  alerts += PacketAlertCheck(p, 1);
710  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
711  alerts += PacketAlertCheck(p, 1);
712  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
713  alerts += PacketAlertCheck(p, 1);
714  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
715  alerts += PacketAlertCheck(p, 1);
716  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
717  alerts += PacketAlertCheck(p, 1);
718  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
719  alerts += PacketAlertCheck(p, 1);
720 
721  if (alerts == 2)
722  result = 1;
723  else
724  goto cleanup;
725 
726 cleanup:
727  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
729 
730 end:
731  UTHFreePackets(&p, 1);
733  StatsThreadCleanup(&th_v.stats);
734  return result;
735 }
736 
737 /**
738  * \test DetectThresholdTestSig3 is a test for checking the working of limit keyword
739  * by setting up the signature and later testing its working by matching
740  * the received packet against the sig.
741  *
742  * \retval 1 on success
743  * \retval 0 on failure
744  */
745 
746 static int DetectThresholdTestSig3(void)
747 {
748  ThreadVars th_v;
749  memset(&th_v, 0, sizeof(th_v));
750  StatsThreadInit(&th_v.stats);
751 
752  ThresholdInit();
753  Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
754 
757  de_ctx->flags |= DE_QUIET;
758 
760  "alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, "
761  "track by_dst, count 5, seconds 60; sid:10;)");
762  FAIL_IF_NULL(s);
763 
765  DetectEngineThreadCtx *det_ctx;
766  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
767 
768  p->ts = TimeGet();
769 
770  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
771  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
772  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
773  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
774  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
775  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
776 
778  p->ts = TimeGet();
779 
780  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
781  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
782  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
783  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
784  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
785  FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
786 
787  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
789  UTHFreePackets(&p, 1);
791  StatsThreadCleanup(&th_v.stats);
792  PASS;
793 }
794 
795 /**
796  * \test DetectThresholdTestSig4 is a test for checking the working of both keyword
797  * by setting up the signature and later testing its working by matching
798  * the received packet against the sig.
799  *
800  * \retval 1 on success
801  * \retval 0 on failure
802  */
803 
804 static int DetectThresholdTestSig4(void)
805 {
806  Packet *p = NULL;
807  Signature *s = NULL;
808  ThreadVars th_v;
809  DetectEngineThreadCtx *det_ctx;
810  int result = 0;
811  int alerts = 0;
812 
813  ThresholdInit();
814 
815  memset(&th_v, 0, sizeof(th_v));
816  StatsThreadInit(&th_v.stats);
817 
818  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
819 
821  if (de_ctx == NULL) {
822  goto end;
823  }
824 
825  de_ctx->flags |= DE_QUIET;
826 
827  s = de_ctx->sig_list =
828  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold both\"; threshold: type "
829  "both, track by_dst, count 2, seconds 60; sid:10;)");
830  if (s == NULL) {
831  goto end;
832  }
833 
835  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
836 
837  p->ts = TimeGet();
838  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
839  alerts = PacketAlertCheck(p, 10);
840  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
841  alerts += PacketAlertCheck(p, 10);
842  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
843  alerts += PacketAlertCheck(p, 10);
844 
846  p->ts = TimeGet();
847 
848  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
849  alerts += PacketAlertCheck(p, 10);
850  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
851  alerts += PacketAlertCheck(p, 10);
852  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
853  alerts += PacketAlertCheck(p, 10);
854 
855  if (alerts == 2)
856  result = 1;
857  else
858  goto cleanup;
859 
860 cleanup:
861  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
863 end:
864  UTHFreePackets(&p, 1);
866  StatsThreadCleanup(&th_v.stats);
867  return result;
868 }
869 
870 /**
871  * \test DetectThresholdTestSig5 is a test for checking the working of limit keyword
872  * by setting up the signature and later testing its working by matching
873  * the received packet against the sig.
874  *
875  * \retval 1 on success
876  * \retval 0 on failure
877  */
878 
879 static int DetectThresholdTestSig5(void)
880 {
881  Packet *p = NULL;
882  Signature *s = NULL;
883  ThreadVars th_v;
884  DetectEngineThreadCtx *det_ctx;
885  int result = 0;
886  int alerts = 0;
887 
888  ThresholdInit();
889 
890  memset(&th_v, 0, sizeof(th_v));
891  StatsThreadInit(&th_v.stats);
892  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
893 
895  if (de_ctx == NULL) {
896  goto end;
897  }
898 
899  de_ctx->flags |= DE_QUIET;
900 
901  s = de_ctx->sig_list =
902  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
903  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
904  if (s == NULL) {
905  goto end;
906  }
907 
908  s = s->next =
909  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; "
910  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
911  if (s == NULL) {
912  goto end;
913  }
914 
916  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
917 
918  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
919  alerts = PacketAlertCheck(p, 1);
920  alerts += PacketAlertCheck(p, 1000);
921  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
922  alerts += PacketAlertCheck(p, 1);
923  alerts += PacketAlertCheck(p, 1000);
924  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
925  alerts += PacketAlertCheck(p, 1);
926  alerts += PacketAlertCheck(p, 1000);
927  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
928  alerts += PacketAlertCheck(p, 1);
929  alerts += PacketAlertCheck(p, 1000);
930  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
931  alerts += PacketAlertCheck(p, 1);
932  alerts += PacketAlertCheck(p, 1000);
933  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
934  alerts += PacketAlertCheck(p, 1);
935  alerts += PacketAlertCheck(p, 1000);
936  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
937  alerts += PacketAlertCheck(p, 1);
938  alerts += PacketAlertCheck(p, 1000);
939  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
940  alerts += PacketAlertCheck(p, 1);
941  alerts += PacketAlertCheck(p, 1000);
942 
943  if (alerts == 10)
944  result = 1;
945  else {
946  printf("alerts %d != 10: ", alerts);
947  goto cleanup;
948  }
949 
950 cleanup:
951  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
953 
954 end:
955  UTHFreePackets(&p, 1);
957  StatsThreadCleanup(&th_v.stats);
958  return result;
959 }
960 
961 static int DetectThresholdTestSig6Ticks(void)
962 {
963  Packet *p = NULL;
964  Signature *s = NULL;
965  ThreadVars th_v;
966  DetectEngineThreadCtx *det_ctx;
967  int result = 0;
968  int alerts = 0;
969 
970  ThresholdInit();
971 
972  memset(&th_v, 0, sizeof(th_v));
973  StatsThreadInit(&th_v.stats);
974  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
975 
977  if (de_ctx == NULL) {
978  goto end;
979  }
980 
981  de_ctx->flags |= DE_QUIET;
982 
983  s = de_ctx->sig_list =
984  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
985  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
986  if (s == NULL) {
987  goto end;
988  }
989 
990  s = s->next =
991  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; "
992  "threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
993  if (s == NULL) {
994  goto end;
995  }
996 
998  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
999 
1000  uint64_t ticks_start = 0;
1001  uint64_t ticks_end = 0;
1002 
1003  ticks_start = UtilCpuGetTicks();
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  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1023  alerts += PacketAlertCheck(p, 1);
1024  alerts += PacketAlertCheck(p, 1000);
1025  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1026  alerts += PacketAlertCheck(p, 1);
1027  alerts += PacketAlertCheck(p, 1000);
1028  ticks_end = UtilCpuGetTicks();
1029  printf("test run %" PRIu64 "\n", (ticks_end - ticks_start));
1030 
1031  if (alerts == 10)
1032  result = 1;
1033  else
1034  goto cleanup;
1035 
1036 cleanup:
1037  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1039 
1040 end:
1041  UTHFreePackets(&p, 1);
1042  ThresholdDestroy();
1043  StatsThreadCleanup(&th_v.stats);
1044  return result;
1045 }
1046 
1047 /**
1048  * \test Test drop action being set even if thresholded
1049  */
1050 static int DetectThresholdTestSig7(void)
1051 {
1052  Packet *p = NULL;
1053  Signature *s = NULL;
1054  ThreadVars th_v;
1055  DetectEngineThreadCtx *det_ctx;
1056  int result = 0;
1057  int alerts = 0;
1058  int drops = 0;
1059 
1060  ThresholdInit();
1061 
1062  memset(&th_v, 0, sizeof(th_v));
1063  StatsThreadInit(&th_v.stats);
1064 
1065  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1066 
1068  if (de_ctx == NULL) {
1069  goto end;
1070  }
1071 
1072  de_ctx->flags |= DE_QUIET;
1073 
1074  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type limit, "
1075  "track by_src, count 1, seconds 300; sid:10;)");
1076  if (s == NULL) {
1077  goto end;
1078  }
1079 
1081  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1082 
1083  p->ts = TimeGet();
1084  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1085  alerts = PacketAlertCheck(p, 10);
1086  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1087  p->action = 0;
1088 
1089  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1090  alerts += PacketAlertCheck(p, 10);
1091  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1092  p->action = 0;
1093 
1094  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1095  alerts += PacketAlertCheck(p, 10);
1096  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1097  p->action = 0;
1098 
1099  TimeSetIncrementTime(200);
1100  p->ts = TimeGet();
1101 
1102  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1103  alerts += PacketAlertCheck(p, 10);
1104  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1105  p->action = 0;
1106 
1107  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1108  alerts += PacketAlertCheck(p, 10);
1109  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1110  p->action = 0;
1111 
1112  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1113  alerts += PacketAlertCheck(p, 10);
1114  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1115  p->action = 0;
1116 
1117  if (alerts == 1 && drops == 6)
1118  result = 1;
1119  else {
1120  if (alerts != 1)
1121  printf("alerts: %d != 1: ", alerts);
1122  if (drops != 6)
1123  printf("drops: %d != 6: ", drops);
1124  goto cleanup;
1125  }
1126 
1127 cleanup:
1128  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1130 end:
1131  UTHFreePackets(&p, 1);
1132  ThresholdDestroy();
1133  StatsThreadCleanup(&th_v.stats);
1134  return result;
1135 }
1136 
1137 /**
1138  * \test Test drop action being set even if thresholded
1139  */
1140 static int DetectThresholdTestSig8(void)
1141 {
1142  Packet *p = NULL;
1143  Signature *s = NULL;
1144  ThreadVars th_v;
1145  DetectEngineThreadCtx *det_ctx;
1146  int result = 0;
1147  int alerts = 0;
1148  int drops = 0;
1149 
1150  ThresholdInit();
1151 
1152  memset(&th_v, 0, sizeof(th_v));
1153  StatsThreadInit(&th_v.stats);
1154 
1155  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1156 
1158  if (de_ctx == NULL) {
1159  goto end;
1160  }
1161 
1162  de_ctx->flags |= DE_QUIET;
1163 
1164  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type limit, "
1165  "track by_src, count 2, seconds 300; sid:10;)");
1166  if (s == NULL) {
1167  goto end;
1168  }
1169 
1171  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1172 
1173  p->ts = TimeGet();
1174  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1175  alerts = PacketAlertCheck(p, 10);
1176  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1177  p->action = 0;
1178 
1179  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1180  alerts += PacketAlertCheck(p, 10);
1181  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1182  p->action = 0;
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  TimeSetIncrementTime(200);
1190  p->ts = TimeGet();
1191 
1192  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1193  alerts += PacketAlertCheck(p, 10);
1194  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1195  p->action = 0;
1196 
1197  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1198  alerts += PacketAlertCheck(p, 10);
1199  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1200  p->action = 0;
1201 
1202  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1203  alerts += PacketAlertCheck(p, 10);
1204  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1205  p->action = 0;
1206 
1207  if (alerts == 2 && drops == 6)
1208  result = 1;
1209  else {
1210  if (alerts != 1)
1211  printf("alerts: %d != 1: ", alerts);
1212  if (drops != 6)
1213  printf("drops: %d != 6: ", drops);
1214  goto cleanup;
1215  }
1216 
1217 cleanup:
1218  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1220 end:
1221  UTHFreePackets(&p, 1);
1222  ThresholdDestroy();
1223  StatsThreadCleanup(&th_v.stats);
1224  return result;
1225 }
1226 
1227 /**
1228  * \test Test drop action being set even if thresholded
1229  */
1230 static int DetectThresholdTestSig9(void)
1231 {
1232  Packet *p = NULL;
1233  Signature *s = NULL;
1234  ThreadVars th_v;
1235  DetectEngineThreadCtx *det_ctx;
1236  int result = 0;
1237  int alerts = 0;
1238  int drops = 0;
1239 
1240  ThresholdInit();
1241 
1242  memset(&th_v, 0, sizeof(th_v));
1243  StatsThreadInit(&th_v.stats);
1244 
1245  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1246 
1248  if (de_ctx == NULL) {
1249  goto end;
1250  }
1251 
1252  de_ctx->flags |= DE_QUIET;
1253 
1254  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type threshold, "
1255  "track by_src, count 3, seconds 100; sid:10;)");
1256  if (s == NULL) {
1257  goto end;
1258  }
1259 
1261  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1262 
1263  p->ts = TimeGet();
1264  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1265  alerts = PacketAlertCheck(p, 10);
1266  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1267  p->action = 0;
1268 
1269  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1270  alerts += PacketAlertCheck(p, 10);
1271  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1272  p->action = 0;
1273 
1274  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1275  alerts += PacketAlertCheck(p, 10);
1276  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1277  p->action = 0;
1278 
1279  TimeSetIncrementTime(200);
1280  p->ts = TimeGet();
1281 
1282  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1283  alerts += PacketAlertCheck(p, 10);
1284  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1285  p->action = 0;
1286 
1287  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1288  alerts += PacketAlertCheck(p, 10);
1289  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1290  p->action = 0;
1291 
1292  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1293  alerts += PacketAlertCheck(p, 10);
1294  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1295  p->action = 0;
1296 
1297  if (alerts == 2 && drops == 2)
1298  result = 1;
1299  else {
1300  if (alerts != 2)
1301  printf("alerts: %d != 2: ", alerts);
1302  if (drops != 2)
1303  printf("drops: %d != 2: ", drops);
1304  goto cleanup;
1305  }
1306 
1307 cleanup:
1308  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1310 end:
1311  UTHFreePackets(&p, 1);
1312  ThresholdDestroy();
1313  StatsThreadCleanup(&th_v.stats);
1314  return result;
1315 }
1316 
1317 /**
1318  * \test Test drop action being set even if thresholded
1319  */
1320 static int DetectThresholdTestSig10(void)
1321 {
1322  Packet *p = NULL;
1323  Signature *s = NULL;
1324  ThreadVars th_v;
1325  DetectEngineThreadCtx *det_ctx;
1326  int result = 0;
1327  int alerts = 0;
1328  int drops = 0;
1329 
1330  ThresholdInit();
1331 
1332  memset(&th_v, 0, sizeof(th_v));
1333  StatsThreadInit(&th_v.stats);
1334 
1335  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1336 
1338  if (de_ctx == NULL) {
1339  goto end;
1340  }
1341 
1342  de_ctx->flags |= DE_QUIET;
1343 
1344  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type threshold, "
1345  "track by_src, count 5, seconds 300; sid:10;)");
1346  if (s == NULL) {
1347  goto end;
1348  }
1349 
1351  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1352 
1353  p->ts = TimeGet();
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  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1360  alerts += PacketAlertCheck(p, 10);
1361  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1362  p->action = 0;
1363 
1364  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1365  alerts += PacketAlertCheck(p, 10);
1366  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1367  p->action = 0;
1368 
1369  TimeSetIncrementTime(200);
1370  p->ts = TimeGet();
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  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1378  alerts += PacketAlertCheck(p, 10);
1379  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1380  p->action = 0;
1381 
1382  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1383  alerts += PacketAlertCheck(p, 10);
1384  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1385  p->action = 0;
1386 
1387  if (alerts == 1 && drops == 1)
1388  result = 1;
1389  else {
1390  if (alerts != 1)
1391  printf("alerts: %d != 1: ", alerts);
1392  if (drops != 1)
1393  printf("drops: %d != 1: ", drops);
1394  goto cleanup;
1395  }
1396 
1397 cleanup:
1398  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1400 end:
1401  UTHFreePackets(&p, 1);
1402  ThresholdDestroy();
1403  StatsThreadCleanup(&th_v.stats);
1404  return result;
1405 }
1406 
1407 /**
1408  * \test Test drop action being set even if thresholded
1409  */
1410 static int DetectThresholdTestSig11(void)
1411 {
1412  Packet *p = NULL;
1413  Signature *s = NULL;
1414  ThreadVars th_v;
1415  DetectEngineThreadCtx *det_ctx;
1416  int result = 0;
1417  int alerts = 0;
1418  int drops = 0;
1419 
1420  ThresholdInit();
1421 
1422  memset(&th_v, 0, sizeof(th_v));
1423  StatsThreadInit(&th_v.stats);
1424 
1425  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1426 
1428  if (de_ctx == NULL) {
1429  goto end;
1430  }
1431 
1432  de_ctx->flags |= DE_QUIET;
1433 
1434  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type both, "
1435  "track by_src, count 3, seconds 300; sid:10;)");
1436  if (s == NULL) {
1437  goto end;
1438  }
1439 
1441  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1442 
1443  p->ts = TimeGet();
1444  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1445  alerts = PacketAlertCheck(p, 10);
1446  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1447  p->action = 0;
1448 
1449  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1450  alerts += PacketAlertCheck(p, 10);
1451  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1452  p->action = 0;
1453 
1454  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1455  alerts += PacketAlertCheck(p, 10);
1456  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1457  p->action = 0;
1458 
1459  TimeSetIncrementTime(200);
1460  p->ts = TimeGet();
1461 
1462  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1463  alerts += PacketAlertCheck(p, 10);
1464  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1465  p->action = 0;
1466 
1467  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1468  alerts += PacketAlertCheck(p, 10);
1469  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1470  p->action = 0;
1471 
1472  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1473  alerts += PacketAlertCheck(p, 10);
1474  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1475  p->action = 0;
1476 
1477  if (alerts == 1 && drops == 4)
1478  result = 1;
1479  else {
1480  if (alerts != 1)
1481  printf("alerts: %d != 1: ", alerts);
1482  if (drops != 4)
1483  printf("drops: %d != 4: ", drops);
1484  goto cleanup;
1485  }
1486 
1487 cleanup:
1488  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1490 end:
1491  UTHFreePackets(&p, 1);
1492  ThresholdDestroy();
1493  StatsThreadCleanup(&th_v.stats);
1494  return result;
1495 }
1496 
1497 /**
1498  * \test Test drop action being set even if thresholded
1499  */
1500 static int DetectThresholdTestSig12(void)
1501 {
1502  Packet *p = NULL;
1503  Signature *s = NULL;
1504  ThreadVars th_v;
1505  DetectEngineThreadCtx *det_ctx;
1506  int result = 0;
1507  int alerts = 0;
1508  int drops = 0;
1509 
1510  ThresholdInit();
1511 
1512  memset(&th_v, 0, sizeof(th_v));
1513  StatsThreadInit(&th_v.stats);
1514 
1515  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1516 
1518  if (de_ctx == NULL) {
1519  goto end;
1520  }
1521 
1522  de_ctx->flags |= DE_QUIET;
1523 
1524  s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any 80 (threshold: type both, "
1525  "track by_src, count 5, seconds 300; sid:10;)");
1526  if (s == NULL) {
1527  goto end;
1528  }
1529 
1531  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1532 
1533  p->ts = TimeGet();
1534  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1535  alerts = PacketAlertCheck(p, 10);
1536  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1537  p->action = 0;
1538 
1539  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1540  alerts += PacketAlertCheck(p, 10);
1541  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1542  p->action = 0;
1543 
1544  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1545  alerts += PacketAlertCheck(p, 10);
1546  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1547  p->action = 0;
1548 
1549  TimeSetIncrementTime(200);
1550  p->ts = TimeGet();
1551 
1552  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1553  alerts += PacketAlertCheck(p, 10);
1554  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1555  p->action = 0;
1556 
1557  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1558  alerts += PacketAlertCheck(p, 10);
1559  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1560  p->action = 0;
1561 
1562  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1563  alerts += PacketAlertCheck(p, 10);
1564  drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
1565  p->action = 0;
1566 
1567  if (alerts == 1 && drops == 2)
1568  result = 1;
1569  else {
1570  if (alerts != 1)
1571  printf("alerts: %d != 1: ", alerts);
1572  if (drops != 2)
1573  printf("drops: %d != 2: ", drops);
1574  goto cleanup;
1575  }
1576 
1577 cleanup:
1578  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1580 end:
1581  UTHFreePackets(&p, 1);
1582  HostShutdown();
1583  ThresholdDestroy();
1584  StatsThreadCleanup(&th_v.stats);
1585  return result;
1586 }
1587 
1588 /**
1589  * \test DetectThresholdTestSig13 is a test for checking the working by_rule limits
1590  * by setting up the signature and later testing its working by matching
1591  * received packets against the sig.
1592  *
1593  * \retval 1 on success
1594  * \retval 0 on failure
1595  */
1596 
1597 static int DetectThresholdTestSig13(void)
1598 {
1599  Packet *p = NULL;
1600  Signature *s = NULL;
1601  ThreadVars th_v;
1602  DetectEngineThreadCtx *det_ctx;
1603  int alerts = 0;
1604 
1605  ThresholdInit();
1606 
1607  memset(&th_v, 0, sizeof(th_v));
1608  StatsThreadInit(&th_v.stats);
1609  p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1610  FAIL_IF_NULL(p);
1611 
1614 
1615  de_ctx->flags |= DE_QUIET;
1616 
1617  s = de_ctx->sig_list =
1618  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
1619  "threshold: type limit, track by_rule, count 2, seconds 60; sid:1;)");
1620  FAIL_IF_NULL(s);
1621 
1623  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1624 
1625  /* should alert twice */
1626  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1627  alerts += PacketAlertCheck(p, 1);
1628  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1629  alerts += PacketAlertCheck(p, 1);
1630  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1631  alerts += PacketAlertCheck(p, 1);
1632  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1633  alerts += PacketAlertCheck(p, 1);
1634 
1635  FAIL_IF(alerts != 2);
1636 
1638  p->ts = TimeGet();
1639 
1640  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1641  alerts += PacketAlertCheck(p, 1);
1642  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1643  alerts += PacketAlertCheck(p, 1);
1644  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1645  alerts += PacketAlertCheck(p, 1);
1646  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1647  alerts += PacketAlertCheck(p, 1);
1648 
1649  FAIL_IF(alerts != 4);
1650 
1651  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1653  UTHFreePackets(&p, 1);
1654  ThresholdDestroy();
1655  StatsThreadCleanup(&th_v.stats);
1656  PASS;
1657 }
1658 
1659 /**
1660  * \test DetectThresholdTestSig14 is a test for checking the working by_both limits
1661  * by setting up the signature and later testing its working by matching
1662  * received packets against the sig.
1663  *
1664  * \retval 1 on success
1665  * \retval 0 on failure
1666  */
1667 
1668 static int DetectThresholdTestSig14(void)
1669 {
1670  Packet *p1 = NULL;
1671  Packet *p2 = NULL;
1672  Signature *s = NULL;
1673  ThreadVars th_v;
1674  DetectEngineThreadCtx *det_ctx;
1675  int alerts1 = 0;
1676  int alerts2 = 0;
1677 
1678  ThresholdInit();
1679 
1680  memset(&th_v, 0, sizeof(th_v));
1681  StatsThreadInit(&th_v.stats);
1682  p1 = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1683  p2 = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "3.3.3.3", 1024, 80);
1684  FAIL_IF_NULL(p1);
1685  FAIL_IF_NULL(p2);
1686 
1689 
1690  de_ctx->flags |= DE_QUIET;
1691 
1692  s = de_ctx->sig_list =
1693  SigInit(de_ctx, "alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; "
1694  "threshold: type limit, track by_both, count 2, seconds 60; sid:1;)");
1695  FAIL_IF_NULL(s);
1696 
1698  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1699 
1700  /* Both p1 and p2 should alert twice */
1701  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1702  alerts1 += PacketAlertCheck(p1, 1);
1703  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1704  alerts1 += PacketAlertCheck(p1, 1);
1705  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1706  alerts1 += PacketAlertCheck(p1, 1);
1707  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1708  alerts1 += PacketAlertCheck(p1, 1);
1709 
1710  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1711  alerts2 += PacketAlertCheck(p2, 1);
1712  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1713  alerts2 += PacketAlertCheck(p2, 1);
1714  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1715  alerts2 += PacketAlertCheck(p2, 1);
1716  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1717  alerts2 += PacketAlertCheck(p2, 1);
1718 
1719  FAIL_IF(alerts1 != 2);
1720  FAIL_IF(alerts2 != 2);
1721 
1723  p1->ts = TimeGet();
1724  p2->ts = TimeGet();
1725 
1726  /* Now they should both alert again after previous alerts expire */
1727  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
1728  alerts1 += PacketAlertCheck(p1, 1);
1729  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
1730  alerts2 += PacketAlertCheck(p2, 1);
1731 
1732  FAIL_IF(alerts1 != 3);
1733  FAIL_IF(alerts2 != 3);
1734 
1735  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1737  UTHFreePackets(&p1, 1);
1738  UTHFreePackets(&p2, 1);
1739  ThresholdDestroy();
1740  StatsThreadCleanup(&th_v.stats);
1741  PASS;
1742 }
1743 
1744 static void ThresholdRegisterTests(void)
1745 {
1746  UtRegisterTest("ThresholdTestParse01", ThresholdTestParse01);
1747  UtRegisterTest("ThresholdTestParseByFlow01", ThresholdTestParseByFlow01);
1748  UtRegisterTest("ThresholdTestParse02", ThresholdTestParse02);
1749  UtRegisterTest("ThresholdTestParse03", ThresholdTestParse03);
1750  UtRegisterTest("ThresholdTestParse04", ThresholdTestParse04);
1751  UtRegisterTest("ThresholdTestParse05", ThresholdTestParse05);
1752  UtRegisterTest("ThresholdTestParse06", ThresholdTestParse06);
1753  UtRegisterTest("ThresholdTestParse07", ThresholdTestParse07);
1754  UtRegisterTest("ThresholdTestParse08", ThresholdTestParse08);
1755  UtRegisterTest("DetectThresholdTestSig1", DetectThresholdTestSig1);
1756  UtRegisterTest("DetectThresholdTestSig2", DetectThresholdTestSig2);
1757  UtRegisterTest("DetectThresholdTestSig3", DetectThresholdTestSig3);
1758  UtRegisterTest("DetectThresholdTestSig4", DetectThresholdTestSig4);
1759  UtRegisterTest("DetectThresholdTestSig5", DetectThresholdTestSig5);
1760  UtRegisterTest("DetectThresholdTestSig6Ticks", DetectThresholdTestSig6Ticks);
1761  UtRegisterTest("DetectThresholdTestSig7", DetectThresholdTestSig7);
1762  UtRegisterTest("DetectThresholdTestSig8", DetectThresholdTestSig8);
1763  UtRegisterTest("DetectThresholdTestSig9", DetectThresholdTestSig9);
1764  UtRegisterTest("DetectThresholdTestSig10", DetectThresholdTestSig10);
1765  UtRegisterTest("DetectThresholdTestSig11", DetectThresholdTestSig11);
1766  UtRegisterTest("DetectThresholdTestSig12", DetectThresholdTestSig12);
1767  UtRegisterTest("DetectThresholdTestSig13", DetectThresholdTestSig13);
1768  UtRegisterTest("DetectThresholdTestSig14", DetectThresholdTestSig14);
1769 }
1770 #endif /* UNITTESTS */
1771 
1772 /**
1773  * @}
1774  */
TRACK_BOTH
#define TRACK_BOTH
Definition: detect-threshold.h:39
util-byte.h
host.h
SigTableElmt_::url
const char * url
Definition: detect.h:1461
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:1460
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1445
util-hashlist.h
DetectParseRegex
Definition: detect-parse.h:93
SigTableElmt_::name
const char * name
Definition: detect.h:1458
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:1449
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:933
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:2418
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:3501
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:3447
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:1440
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:1245
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:3627
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:269
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:3105
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:1420
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
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1258
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:3601
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:942
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:935
DetectThresholdData_::seconds
uint32_t seconds
Definition: detect-threshold.h:57
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: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(StatsThreadContext *stats)
Definition: counters.c:1354
flow-var.h
ThresholdInit
void ThresholdInit(void)
Definition: detect-engine-threshold.c:66
SIGMATCH_IPONLY_COMPAT
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1652
DetectAddressHead_::ipv4_head
DetectAddress * ipv4_head
Definition: detect.h:184
detect-engine-address.h
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1447
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