suricata
detect-detection-filter.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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  * \file
20  *
21  * \author Gerardo Iglesias <iglesiasg@gmail.com>
22  *
23  * Implements the detection_filter keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 #include "decode.h"
29 #include "detect.h"
30 
31 #include "host.h"
32 
34 #include "detect-threshold.h"
35 #include "detect-parse.h"
36 
37 #include "util-byte.h"
38 #include "util-unittest.h"
39 #include "util-unittest-helper.h"
40 #include "util-debug.h"
41 #include "detect-engine-build.h"
42 #include "detect-engine-proto.h"
43 
44 #define TRACK_DST 1
45 #define TRACK_SRC 2
46 
47 /**
48  *\brief Regex for parsing our detection_filter options
49  */
50 #define PARSE_REGEX \
51  "^\\s*(track|count|seconds)\\s+(by_src|by_dst|by_flow|\\d+)\\s*,\\s*(track|count|seconds)\\s+" \
52  "(by_src|" \
53  "by_dst|by_flow|\\d+)\\s*,\\s*(track|count|seconds)\\s+(by_src|by_dst|by_flow|\\d+)" \
54  "(?:\\s*,\\s*unique_on\\s+(src_port|dst_port))?\\s*$"
55 
56 /* minimum number of PCRE submatches expected for detection_filter parse */
57 #define DF_PARSE_MIN_SUBMATCHES 5
58 
59 static DetectParseRegex parse_regex;
60 
61 static int DetectDetectionFilterMatch(
62  DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *);
63 static int DetectDetectionFilterSetup(DetectEngineCtx *, Signature *, const char *);
64 #ifdef UNITTESTS
65 static void DetectDetectionFilterRegisterTests(void);
66 #endif
67 static void DetectDetectionFilterFree(DetectEngineCtx *, void *);
68 
69 /**
70  * \brief Registration function for detection_filter: keyword
71  */
73 {
74  sigmatch_table[DETECT_DETECTION_FILTER].name = "detection_filter";
76  "alert on every match after a threshold has been reached";
77  sigmatch_table[DETECT_DETECTION_FILTER].url = "/rules/thresholding.html#detection-filter";
78  sigmatch_table[DETECT_DETECTION_FILTER].Match = DetectDetectionFilterMatch;
79  sigmatch_table[DETECT_DETECTION_FILTER].Setup = DetectDetectionFilterSetup;
80  sigmatch_table[DETECT_DETECTION_FILTER].Free = DetectDetectionFilterFree;
81 #ifdef UNITTESTS
82  sigmatch_table[DETECT_DETECTION_FILTER].RegisterTests = DetectDetectionFilterRegisterTests;
83 #endif
84  /* this is compatible to ip-only signatures */
86 
87  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
88 }
89 
90 static int DetectDetectionFilterMatch(
91  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
92 {
93  return 1;
94 }
95 
96 /**
97  * \internal
98  * \brief This function is used to parse detection_filter options passed via detection_filter:
99  * keyword
100  *
101  * \param rawstr Pointer to the user provided detection_filter options
102  *
103  * \retval df pointer to DetectThresholdData on success
104  * \retval NULL on failure
105  */
106 static DetectThresholdData *DetectDetectionFilterParse(const char *rawstr)
107 {
108  DetectThresholdData *df = NULL;
109  int res = 0;
110  size_t pcre2_len;
111  const char *str_ptr = NULL;
112  char *args[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
113  char *copy_str = NULL, *df_opt = NULL;
114  int seconds_found = 0, count_found = 0, track_found = 0;
115  int seconds_pos = 0, count_pos = 0;
116  size_t pos = 0;
117  int i = 0;
118  int parsed_count = 0;
119  int ret = 0;
120  char *saveptr = NULL;
121  pcre2_match_data *match = NULL;
122 
123  copy_str = SCStrdup(rawstr);
124  if (unlikely(copy_str == NULL)) {
125  goto error;
126  }
127 
128  for (pos = 0, df_opt = strtok_r(copy_str, ",", &saveptr);
129  pos < strlen(copy_str) && df_opt != NULL;
130  pos++, df_opt = strtok_r(NULL, ",", &saveptr)) {
131  if (strstr(df_opt, "count"))
132  count_found++;
133  if (strstr(df_opt, "second"))
134  seconds_found++;
135  if (strstr(df_opt, "track"))
136  track_found++;
137  }
138  SCFree(copy_str);
139  copy_str = NULL;
140 
141  if (count_found != 1 || seconds_found != 1 || track_found != 1)
142  goto error;
143 
144  ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0);
145  if (ret < DF_PARSE_MIN_SUBMATCHES) {
146  SCLogError("pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
147  goto error;
148  }
149 
150  df = SCCalloc(1, sizeof(DetectThresholdData));
151  if (unlikely(df == NULL))
152  goto error;
153 
154  df->type = TYPE_DETECTION;
155 
156  for (i = 0; i < (ret - 1); i++) {
157  res = pcre2_substring_get_bynumber(match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
158  if (res < 0) {
159  SCLogError("pcre2_substring_get_bynumber failed");
160  goto error;
161  }
162 
163  args[i] = (char *)str_ptr;
164  parsed_count++;
165 
166  if (strncasecmp(args[i], "by_dst", strlen("by_dst")) == 0)
167  df->track = TRACK_DST;
168  if (strncasecmp(args[i], "by_src", strlen("by_src")) == 0)
169  df->track = TRACK_SRC;
170  if (strncasecmp(args[i], "by_flow", strlen("by_flow")) == 0)
171  df->track = TRACK_FLOW;
172  if (strncasecmp(args[i], "count", strlen("count")) == 0)
173  count_pos = i + 1;
174  if (strncasecmp(args[i], "seconds", strlen("seconds")) == 0)
175  seconds_pos = i + 1;
176  if (strcasecmp(args[i], "src_port") == 0)
178  if (strcasecmp(args[i], "dst_port") == 0)
180  }
181 
182  if (args[count_pos] == NULL || args[seconds_pos] == NULL) {
183  goto error;
184  }
185 
186  if (StringParseUint32(&df->count, 10, strlen(args[count_pos]), args[count_pos]) <= 0) {
187  goto error;
188  }
189 
190  if (StringParseUint32(&df->seconds, 10, strlen(args[seconds_pos]), args[seconds_pos]) <= 0) {
191  goto error;
192  }
193 
194  if (df->count == 0 || df->seconds == 0) {
195  SCLogError("found an invalid value");
196  goto error;
197  }
198 
199  for (i = 0; i < parsed_count; i++) {
200  if (args[i] != NULL)
201  pcre2_substring_free((PCRE2_UCHAR *)args[i]);
202  }
203 
204  pcre2_match_data_free(match);
205  return df;
206 
207 error:
208  for (i = 0; i < parsed_count; i++) {
209  if (args[i] != NULL)
210  pcre2_substring_free((PCRE2_UCHAR *)args[i]);
211  }
212  if (df != NULL)
213  SCFree(df);
214  if (match) {
215  pcre2_match_data_free(match);
216  }
217  return NULL;
218 }
219 
220 /**
221  * \internal
222  * \brief this function is used to add the parsed detection_filter into the current signature
223  *
224  * \param de_ctx pointer to the Detection Engine Context
225  * \param s pointer to the Current Signature
226  * \param m pointer to the Current SigMatch
227  * \param rawstr pointer to the user provided detection_filter options
228  *
229  * \retval 0 on Success
230  * \retval -1 on Failure
231  */
232 static int DetectDetectionFilterSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
233 {
234  SCEnter();
235  DetectThresholdData *df = NULL;
236  SigMatch *tmpm = NULL;
237 
238  /* checks if there's a previous instance of threshold */
240  if (tmpm != NULL) {
241  SCLogError("\"detection_filter\" and \"threshold\" are not allowed in the same rule");
242  SCReturnInt(-1);
243  }
244  /* checks there's no previous instance of detection_filter */
246  if (tmpm != NULL) {
247  SCLogError("At most one \"detection_filter\" is allowed per rule");
248  SCReturnInt(-1);
249  }
250 
251  df = DetectDetectionFilterParse(rawstr);
252  if (df == NULL)
253  goto error;
254 
255  /* unique_on requires a ported L4 protocol: tcp/udp/sctp */
256  if (df->unique_on != DF_UNIQUE_NONE) {
257  const int has_tcp = DetectProtoContainsProto(&s->proto, IPPROTO_TCP);
258  const int has_udp = DetectProtoContainsProto(&s->proto, IPPROTO_UDP);
259  const int has_sctp = DetectProtoContainsProto(&s->proto, IPPROTO_SCTP);
260  if (!(has_tcp || has_udp || has_sctp) || (s->proto.flags & DETECT_PROTO_ANY)) {
261  SCLogError("detection_filter unique_on requires protocol tcp/udp/sctp");
262  goto error;
263  }
264  }
265 
267  DETECT_SM_LIST_THRESHOLD) == NULL) {
268  goto error;
269  }
270 
271  return 0;
272 
273 error:
274  if (df)
275  SCFree(df);
276  return -1;
277 }
278 
279 /**
280  * \internal
281  * \brief this function will free memory associated with DetectThresholdData
282  *
283  * \param df_ptr pointer to DetectDetectionFilterData
284  */
285 static void DetectDetectionFilterFree(DetectEngineCtx *de_ctx, void *df_ptr)
286 {
288  if (df)
289  SCFree(df);
290 }
291 
292 /*
293  * ONLY TESTS BELOW THIS COMMENT
294  */
295 #ifdef UNITTESTS
296 #include "detect-engine.h"
297 #include "detect-engine-mpm.h"
298 #include "detect-engine-threshold.h"
299 #include "detect-engine-alert.h"
300 #include "util-time.h"
301 #include "util-hashlist.h"
302 #include "action-globals.h"
303 #include "packet.h"
304 
305 /* test seams from detect-engine-threshold.c */
306 void ThresholdForceAllocFail(int);
307 uint64_t ThresholdGetBitmapMemuse(void);
308 uint64_t ThresholdGetBitmapAllocFail(void);
309 
310 /**
311  * \test DetectDetectionFilterTestParse01 is a test for a valid detection_filter options
312  *
313  */
314 static int DetectDetectionFilterTestParse01(void)
315 {
316  DetectThresholdData *df = DetectDetectionFilterParse("track by_dst,count 10,seconds 60");
317  FAIL_IF_NULL(df);
318  FAIL_IF_NOT(df->track == TRACK_DST);
319  FAIL_IF_NOT(df->count == 10);
320  FAIL_IF_NOT(df->seconds == 60);
321  DetectDetectionFilterFree(NULL, df);
322 
323  PASS;
324 }
325 
326 /**
327  * \test DetectDetectionFilterTestParse02 is a test for a invalid detection_filter options
328  *
329  */
330 static int DetectDetectionFilterTestParse02(void)
331 {
332  DetectThresholdData *df = DetectDetectionFilterParse("track both,count 10,seconds 60");
333  FAIL_IF_NOT_NULL(df);
334 
335  PASS;
336 }
337 
338 /**
339  * \test DetectDetectionfilterTestParse03 is a test for a valid detection_filter options in any
340  * order
341  *
342  */
343 static int DetectDetectionFilterTestParse03(void)
344 {
345  DetectThresholdData *df = DetectDetectionFilterParse("track by_dst, seconds 60, count 10");
346  FAIL_IF_NULL(df);
347  FAIL_IF_NOT(df->track == TRACK_DST);
348  FAIL_IF_NOT(df->count == 10);
349  FAIL_IF_NOT(df->seconds == 60);
350  DetectDetectionFilterFree(NULL, df);
351 
352  PASS;
353 }
354 
355 /**
356  * \test DetectDetectionFilterTestParse04 is a test for an invalid detection_filter options in any
357  * order
358  *
359  */
360 static int DetectDetectionFilterTestParse04(void)
361 {
362  DetectThresholdData *df =
363  DetectDetectionFilterParse("count 10, track by_dst, seconds 60, count 10");
364  FAIL_IF_NOT_NULL(df);
365 
366  PASS;
367 }
368 
369 /**
370  * \test DetectDetectionFilterTestParse05 is a test for a valid detection_filter options in any
371  * order
372  *
373  */
374 static int DetectDetectionFilterTestParse05(void)
375 {
376  DetectThresholdData *df = DetectDetectionFilterParse("count 10, track by_dst, seconds 60");
377  FAIL_IF_NULL(df);
378  FAIL_IF_NOT(df->track == TRACK_DST);
379  FAIL_IF_NOT(df->count == 10);
380  FAIL_IF_NOT(df->seconds == 60);
381  DetectDetectionFilterFree(NULL, df);
382 
383  PASS;
384 }
385 
386 /**
387  * \test DetectDetectionFilterTestParse06 is a test for an invalid value in detection_filter
388  *
389  */
390 static int DetectDetectionFilterTestParse06(void)
391 {
392  DetectThresholdData *df = DetectDetectionFilterParse("count 10, track by_dst, seconds 0");
393  FAIL_IF_NOT_NULL(df);
394 
395  PASS;
396 }
397 /**
398  * \test unique_on requires tcp/udp/sctp protocol; alert ip should fail
399  */
400 static int DetectDetectionFilterUniqueOnProtoValidationFail(void)
401 {
402  ThresholdInit();
403 
406  de_ctx->flags |= DE_QUIET;
407 
409  "alert ip any any -> any any (msg:\"DF proto validation\"; "
410  "detection_filter: track by_dst, count 2, seconds 60, unique_on dst_port; sid:29;)");
411  /* setup should fail, append returns NULL */
412  FAIL_IF_NOT_NULL(s);
413 
416  PASS;
417 }
418 
419 /**
420  * \test DetectDetectionFilterTestParseUnique01 tests parsing unique_on dst_port
421  */
422 static int DetectDetectionFilterTestParseUnique01(void)
423 {
424  DetectThresholdData *df =
425  DetectDetectionFilterParse("track by_dst, count 10, seconds 60, unique_on dst_port");
426  FAIL_IF_NULL(df);
427  FAIL_IF_NOT(df->track == TRACK_DST);
428  FAIL_IF_NOT(df->count == 10);
429  FAIL_IF_NOT(df->seconds == 60);
431  DetectDetectionFilterFree(NULL, df);
432  PASS;
433 }
434 
435 /**
436  * \test Distinct boundary: exactly 'count' distinct should not alert
437  */
438 static int DetectDetectionFilterDistinctBoundaryNoAlert(void)
439 {
440  ThreadVars th_v;
441  DetectEngineThreadCtx *det_ctx;
442 
443  ThresholdInit();
444  memset(&th_v, 0, sizeof(th_v));
445  StatsThreadInit(&th_v.stats);
446 
447  Packet *p1 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
448  Packet *p2 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 81);
449 
452  de_ctx->flags |= DE_QUIET;
453 
455  "alert tcp any any -> any any (msg:\"DF distinct boundary no alert\"; "
456  "detection_filter: track by_dst, count 2, seconds 60, unique_on dst_port; sid:24;)");
457  FAIL_IF_NULL(s);
458 
460  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
461 
462  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
463  FAIL_IF(PacketAlertCheck(p1, 24));
464  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
465  FAIL_IF(PacketAlertCheck(p2, 24));
466 
467  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
469  UTHFreePackets(&p1, 1);
470  UTHFreePackets(&p2, 1);
472  StatsThreadCleanup(&th_v.stats);
473  PASS;
474 }
475 
476 /**
477  * \test Distinct window reset: expire and re-trigger after seconds
478  */
479 static int DetectDetectionFilterDistinctWindowReset(void)
480 {
481  ThreadVars th_v;
482  DetectEngineThreadCtx *det_ctx;
483 
484  ThresholdInit();
485  memset(&th_v, 0, sizeof(th_v));
486  StatsThreadInit(&th_v.stats);
487 
490  de_ctx->flags |= DE_QUIET;
491 
493  "alert tcp any any -> any any (msg:\"DF distinct window reset\"; "
494  "detection_filter: track by_dst, count 2, seconds 2, unique_on dst_port; sid:25;)");
495  FAIL_IF_NULL(s);
496 
498  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
499 
500  Packet *p1 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
501  p1->ts = TimeGet();
502  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
503  FAIL_IF(PacketAlertCheck(p1, 25));
504 
505  Packet *p2 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 81);
506  p2->ts = TimeGet();
507  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
508  FAIL_IF(PacketAlertCheck(p2, 25));
509 
510  Packet *p3 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 82);
511  p3->ts = TimeGet();
512  SigMatchSignatures(&th_v, de_ctx, det_ctx, p3);
513  FAIL_IF_NOT(PacketAlertCheck(p3, 25));
514 
515  /* advance time beyond window to force expiration */
517 
518  Packet *p4 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
519  p4->ts = TimeGet();
520  SigMatchSignatures(&th_v, de_ctx, det_ctx, p4);
521  FAIL_IF(PacketAlertCheck(p4, 25));
522 
523  Packet *p5 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 81);
524  p5->ts = TimeGet();
525  SigMatchSignatures(&th_v, de_ctx, det_ctx, p5);
526  FAIL_IF(PacketAlertCheck(p5, 25));
527 
528  Packet *p6 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 82);
529  p6->ts = TimeGet();
530  SigMatchSignatures(&th_v, de_ctx, det_ctx, p6);
531  FAIL_IF_NOT(PacketAlertCheck(p6, 25));
532 
533  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
535  UTHFreePackets(&p1, 1);
536  UTHFreePackets(&p2, 1);
537  UTHFreePackets(&p3, 1);
538  UTHFreePackets(&p4, 1);
539  UTHFreePackets(&p5, 1);
540  UTHFreePackets(&p6, 1);
542  StatsThreadCleanup(&th_v.stats);
543  PASS;
544 }
545 
546 /**
547  * \test When bitmap alloc fails, unique_on falls back to classic counting (> count)
548  */
549 static int DetectDetectionFilterDistinctAllocFailFallback(void)
550 {
551  ThreadVars th_v;
552  DetectEngineThreadCtx *det_ctx;
553 
554  ThresholdInit();
555  memset(&th_v, 0, sizeof(th_v));
556  StatsThreadInit(&th_v.stats);
557 
560  de_ctx->flags |= DE_QUIET;
561 
562  /* Force allocation failure for distinct bitmap */
564 
566  "alert tcp any any -> any any (msg:\"DF alloc fail fallback\"; "
567  "detection_filter: track by_dst, count 2, seconds 60, unique_on dst_port; sid:27;)");
568  FAIL_IF_NULL(s);
569 
571  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
572 
573  Packet *p1 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
574  Packet *p2 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
575  Packet *p3 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
576 
577  int result = 0;
578 
579  /* Classic detection_filter alerts when current_count > count (i.e., 3rd packet) */
580  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
581  if (PacketAlertCheck(p1, 27))
582  goto end;
583  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
584  if (PacketAlertCheck(p2, 27))
585  goto end;
586  SigMatchSignatures(&th_v, de_ctx, det_ctx, p3);
587  if (!PacketAlertCheck(p3, 27))
588  goto end;
589 
590  result = 1;
591 
592 end:
593  /* cleanup and restore hook */
595  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
597  UTHFreePackets(&p1, 1);
598  UTHFreePackets(&p2, 1);
599  UTHFreePackets(&p3, 1);
601  StatsThreadCleanup(&th_v.stats);
602  return result;
603 }
604 
605 /**
606  * \test DetectDetectionFilterTestSig1 is a test for checking the working of detection_filter
607  * keyword by setting up the signature and later testing its working by matching the received packet
608  * against the sig.
609  *
610  */
611 static int DetectDetectionFilterTestSig1(void)
612 {
613  ThreadVars th_v;
614  DetectEngineThreadCtx *det_ctx;
615 
616  ThresholdInit();
617 
618  memset(&th_v, 0, sizeof(th_v));
619  StatsThreadInit(&th_v.stats);
620 
621  Packet *p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
622 
625 
626  de_ctx->flags |= DE_QUIET;
627 
629  "alert tcp any any -> any 80 (msg:\"detection_filter Test\"; detection_filter: "
630  "track by_dst, count 4, seconds 60; sid:1;)");
631  FAIL_IF_NULL(s);
632 
634  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
635 
636  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
637  FAIL_IF(PacketAlertCheck(p, 1));
638  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
639  FAIL_IF(PacketAlertCheck(p, 1));
640  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
641  FAIL_IF(PacketAlertCheck(p, 1));
642  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
643  FAIL_IF(PacketAlertCheck(p, 1));
644  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
646  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
648  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
650  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
652 
653  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
655 
656  UTHFreePackets(&p, 1);
658  StatsThreadCleanup(&th_v.stats);
659  PASS;
660 }
661 
662 /**
663  * \test DetectDetectionFilterTestSig2 is a test for checking the working of detection_filter
664  * keyword by setting up the signature and later testing its working by matching the received packet
665  * against the sig.
666  *
667  */
668 
669 static int DetectDetectionFilterTestSig2(void)
670 {
671  ThreadVars th_v;
672  DetectEngineThreadCtx *det_ctx;
673 
674  ThresholdInit();
675 
676  memset(&th_v, 0, sizeof(th_v));
677  StatsThreadInit(&th_v.stats);
678 
679  Packet *p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
680 
682 
684 
685  de_ctx->flags |= DE_QUIET;
686 
688  "alert tcp any any -> any 80 (msg:\"detection_filter Test 2\"; "
689  "detection_filter: track by_dst, count 4, seconds 60; sid:10;)");
690  FAIL_IF_NULL(s);
691 
693  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
694 
695  p->ts = TimeGet();
696 
697  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
698  FAIL_IF(PacketAlertCheck(p, 10));
699  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
700  FAIL_IF(PacketAlertCheck(p, 10));
701  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
702  FAIL_IF(PacketAlertCheck(p, 10));
703 
705  p->ts = TimeGet();
706 
707  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
708  FAIL_IF(PacketAlertCheck(p, 10));
709  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
710  FAIL_IF(PacketAlertCheck(p, 10));
711  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
712  FAIL_IF(PacketAlertCheck(p, 10));
713  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
714  FAIL_IF(PacketAlertCheck(p, 10));
715 
716  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
718 
719  UTHFreePackets(&p, 1);
721  StatsThreadCleanup(&th_v.stats);
722  PASS;
723 }
724 
725 /**
726  * \test drops
727  */
728 static int DetectDetectionFilterTestSig3(void)
729 {
730  ThreadVars th_v;
731  DetectEngineThreadCtx *det_ctx;
732 
733  ThresholdInit();
734 
735  memset(&th_v, 0, sizeof(th_v));
736  StatsThreadInit(&th_v.stats);
737 
738  Packet *p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
739 
742 
743  de_ctx->flags |= DE_QUIET;
744 
746  "drop tcp any any -> any 80 (msg:\"detection_filter Test 2\"; "
747  "detection_filter: track by_dst, count 2, seconds 60; sid:10;)");
748  FAIL_IF_NULL(s);
749 
751  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
752 
753  p->ts = TimeGet();
754 
755  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
756  FAIL_IF(PacketAlertCheck(p, 10));
757  FAIL_IF(PacketTestAction(p, ACTION_DROP));
758  p->action = 0;
759 
760  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
761  FAIL_IF(PacketAlertCheck(p, 10));
762  FAIL_IF(PacketTestAction(p, ACTION_DROP));
763  p->action = 0;
764 
765  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
767  FAIL_IF_NOT(PacketTestAction(p, ACTION_DROP));
768  p->action = 0;
769 
771  p->ts = TimeGet();
772 
773  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
774  FAIL_IF(PacketAlertCheck(p, 10));
775  FAIL_IF(PacketTestAction(p, ACTION_DROP));
776  p->action = 0;
777 
778  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
779  FAIL_IF(PacketAlertCheck(p, 10));
780  FAIL_IF(PacketTestAction(p, ACTION_DROP));
781  p->action = 0;
782 
783  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
785  FAIL_IF_NOT(PacketTestAction(p, ACTION_DROP));
786  p->action = 0;
787 
788  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
790 
791  UTHFreePackets(&p, 1);
793  StatsThreadCleanup(&th_v.stats);
794  PASS;
795 }
796 
797 /**
798  * \test Verify bitmap memory is tracked in bitmap_memuse counter
799  */
800 static int DetectDetectionFilterDistinctBitmapMemuseTracking(void)
801 {
802  ThreadVars th_v;
803  DetectEngineThreadCtx *det_ctx;
804 
805  ThresholdInit();
806  memset(&th_v, 0, sizeof(th_v));
807  StatsThreadInit(&th_v.stats);
808 
809  /* Record baseline memuse */
810  uint64_t baseline_memuse = ThresholdGetBitmapMemuse();
811 
814  de_ctx->flags |= DE_QUIET;
815 
817  "alert tcp any any -> any any (msg:\"DF memuse tracking\"; "
818  "detection_filter: track by_dst, count 2, seconds 60, unique_on dst_port; sid:30;)");
819  FAIL_IF_NULL(s);
820 
822  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
823 
824  /* Send a packet to trigger threshold entry creation with bitmap */
825  Packet *p1 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
826  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
827 
828  /* Verify bitmap_memuse increased by 8192 bytes (65536/8) */
829  uint64_t after_memuse = ThresholdGetBitmapMemuse();
830  FAIL_IF_NOT(after_memuse == baseline_memuse + 8192);
831 
832  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
834  UTHFreePackets(&p1, 1);
836 
837  /* After destroy, bitmap_memuse should return to baseline */
838  uint64_t final_memuse = ThresholdGetBitmapMemuse();
839  FAIL_IF_NOT(final_memuse == baseline_memuse);
840 
841  StatsThreadCleanup(&th_v.stats);
842  PASS;
843 }
844 
845 /**
846  * \test Verify bitmap_alloc_fail counter increments on forced failure
847  */
848 static int DetectDetectionFilterDistinctAllocFailCounter(void)
849 {
850  ThreadVars th_v;
851  DetectEngineThreadCtx *det_ctx;
852 
853  ThresholdInit();
854  memset(&th_v, 0, sizeof(th_v));
855  StatsThreadInit(&th_v.stats);
856 
857  /* Record baseline alloc fail count */
858  uint64_t baseline_fail = ThresholdGetBitmapAllocFail();
859 
862  de_ctx->flags |= DE_QUIET;
863 
864  /* Force allocation failure */
866 
868  "alert tcp any any -> any any (msg:\"DF alloc fail counter\"; "
869  "detection_filter: track by_dst, count 2, seconds 60, unique_on dst_port; sid:31;)");
870  FAIL_IF_NULL(s);
871 
873  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
874 
875  /* Send packet to trigger threshold entry creation (bitmap alloc will fail) */
876  Packet *p1 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
877  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
878 
879  /* Verify alloc_fail counter increased */
880  uint64_t after_fail = ThresholdGetBitmapAllocFail();
881  FAIL_IF_NOT(after_fail == baseline_fail + 1);
882 
883  /* bitmap_memuse should NOT have increased since alloc failed */
884  uint64_t memuse = ThresholdGetBitmapMemuse();
885  FAIL_IF_NOT(memuse == 0);
886 
887  /* cleanup */
889  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
891  UTHFreePackets(&p1, 1);
893  StatsThreadCleanup(&th_v.stats);
894  PASS;
895 }
896 
897 /**
898  * \test Multiple distinct trackers should accumulate bitmap memory
899  */
900 static int DetectDetectionFilterDistinctMultipleTrackers(void)
901 {
902  ThreadVars th_v;
903  DetectEngineThreadCtx *det_ctx;
904 
905  ThresholdInit();
906  memset(&th_v, 0, sizeof(th_v));
907  StatsThreadInit(&th_v.stats);
908 
909  uint64_t baseline_memuse = ThresholdGetBitmapMemuse();
910 
913  de_ctx->flags |= DE_QUIET;
914 
916  "alert tcp any any -> any any (msg:\"DF multi tracker\"; "
917  "detection_filter: track by_dst, count 2, seconds 60, unique_on dst_port; sid:32;)");
918  FAIL_IF_NULL(s);
919 
921  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
922 
923  /* Create packets to different destinations - each will create a new threshold entry */
924  Packet *p1 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
925  Packet *p2 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "3.3.3.3", 1024, 80);
926  Packet *p3 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "4.4.4.4", 1024, 80);
927 
928  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
929  SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
930  SigMatchSignatures(&th_v, de_ctx, det_ctx, p3);
931 
932  /* Verify 3 bitmaps allocated = 3 * 8192 = 24576 bytes */
933  uint64_t after_memuse = ThresholdGetBitmapMemuse();
934  FAIL_IF_NOT(after_memuse == baseline_memuse + (3 * 8192));
935 
936  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
938  UTHFreePackets(&p1, 1);
939  UTHFreePackets(&p2, 1);
940  UTHFreePackets(&p3, 1);
942 
943  /* After destroy, should return to baseline */
944  uint64_t final_memuse = ThresholdGetBitmapMemuse();
945  FAIL_IF_NOT(final_memuse == baseline_memuse);
946 
947  StatsThreadCleanup(&th_v.stats);
948  PASS;
949 }
950 
951 /**
952  * \test Bitmap memory is freed when threshold entry expires
953  */
954 static int DetectDetectionFilterDistinctBitmapExpiry(void)
955 {
956  ThreadVars th_v;
957  DetectEngineThreadCtx *det_ctx;
958 
959  ThresholdInit();
960  memset(&th_v, 0, sizeof(th_v));
961  StatsThreadInit(&th_v.stats);
962 
963  uint64_t baseline_memuse = ThresholdGetBitmapMemuse();
964 
967  de_ctx->flags |= DE_QUIET;
968 
969  /* Use short timeout (2 seconds) */
971  "alert tcp any any -> any any (msg:\"DF bitmap expiry\"; "
972  "detection_filter: track by_dst, count 2, seconds 2, unique_on dst_port; sid:33;)");
973  FAIL_IF_NULL(s);
974 
976  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
977 
978  Packet *p1 = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
979  p1->ts = TimeGet();
980  SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
981 
982  /* Verify bitmap allocated */
983  uint64_t after_alloc = ThresholdGetBitmapMemuse();
984  FAIL_IF_NOT(after_alloc == baseline_memuse + 8192);
985 
986  /* Advance time beyond the timeout to expire the entry */
988 
989  /* Trigger expiration by calling ThresholdsExpire */
990  SCTime_t now = TimeGet();
991  ThresholdsExpire(now);
992 
993  /* After expiry, bitmap memory should be freed */
994  uint64_t after_expiry = ThresholdGetBitmapMemuse();
995  FAIL_IF_NOT(after_expiry == baseline_memuse);
996 
997  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
999  UTHFreePackets(&p1, 1);
1000  ThresholdDestroy();
1001  StatsThreadCleanup(&th_v.stats);
1002  PASS;
1003 }
1004 
1005 static void DetectDetectionFilterRegisterTests(void)
1006 {
1007  UtRegisterTest("DetectDetectionFilterTestParse01", DetectDetectionFilterTestParse01);
1008  UtRegisterTest("DetectDetectionFilterTestParse02", DetectDetectionFilterTestParse02);
1009  UtRegisterTest("DetectDetectionFilterTestParse03", DetectDetectionFilterTestParse03);
1010  UtRegisterTest("DetectDetectionFilterTestParse04", DetectDetectionFilterTestParse04);
1011  UtRegisterTest("DetectDetectionFilterTestParse05", DetectDetectionFilterTestParse05);
1012  UtRegisterTest("DetectDetectionFilterTestParse06", DetectDetectionFilterTestParse06);
1014  "DetectDetectionFilterTestParseUnique01", DetectDetectionFilterTestParseUnique01);
1015  UtRegisterTest("DetectDetectionFilterTestSig1", DetectDetectionFilterTestSig1);
1016  UtRegisterTest("DetectDetectionFilterTestSig2", DetectDetectionFilterTestSig2);
1017  UtRegisterTest("DetectDetectionFilterTestSig3", DetectDetectionFilterTestSig3);
1018  UtRegisterTest("DetectDetectionFilterDistinctBoundaryNoAlert",
1019  DetectDetectionFilterDistinctBoundaryNoAlert);
1021  "DetectDetectionFilterDistinctWindowReset", DetectDetectionFilterDistinctWindowReset);
1022  UtRegisterTest("DetectDetectionFilterDistinctAllocFailFallback",
1023  DetectDetectionFilterDistinctAllocFailFallback);
1024  UtRegisterTest("DetectDetectionFilterUniqueOnProtoValidationFail",
1025  DetectDetectionFilterUniqueOnProtoValidationFail);
1026  UtRegisterTest("DetectDetectionFilterDistinctBitmapMemuseTracking",
1027  DetectDetectionFilterDistinctBitmapMemuseTracking);
1028  UtRegisterTest("DetectDetectionFilterDistinctAllocFailCounter",
1029  DetectDetectionFilterDistinctAllocFailCounter);
1030  UtRegisterTest("DetectDetectionFilterDistinctMultipleTrackers",
1031  DetectDetectionFilterDistinctMultipleTrackers);
1033  "DetectDetectionFilterDistinctBitmapExpiry", DetectDetectionFilterDistinctBitmapExpiry);
1034 }
1035 #endif /* UNITTESTS */
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
detect-engine-proto.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
PARSE_REGEX
#define PARSE_REGEX
Regex for parsing our detection_filter options.
Definition: detect-detection-filter.c:50
DetectParseRegex
Definition: detect-parse.h:93
SigTableElmt_::name
const char * name
Definition: detect.h:1457
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1448
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:63
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
DETECT_PROTO_ANY
#define DETECT_PROTO_ANY
Definition: detect-engine-proto.h:28
DF_UNIQUE_DST_PORT
@ DF_UNIQUE_DST_PORT
Definition: detect-threshold.h:54
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2684
TRACK_DST
#define TRACK_DST
Definition: detect-detection-filter.c:44
DE_QUIET
#define DE_QUIET
Definition: detect.h:329
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:2420
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: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
DetectThresholdData_::unique_on
enum DetectThresholdUniqueOn unique_on
Definition: detect-threshold.h:71
DetectThresholdData_::type
uint8_t type
Definition: detect-threshold.h:65
ThresholdForceAllocFail
void ThresholdForceAllocFail(int)
Definition: detect-engine-threshold.c:71
ThresholdGetBitmapAllocFail
uint64_t ThresholdGetBitmapAllocFail(void)
Definition: detect-engine-threshold.c:81
decode.h
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
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:19
detect-detection-filter.h
DetectEngineThreadCtx_
Definition: detect.h:1244
Packet_::ts
SCTime_t ts
Definition: decode.h:555
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
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
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:3414
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:139
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
SCTime_t
Definition: util-time.h:40
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1419
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:66
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1333
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:350
DetectProto_::flags
uint8_t flags
Definition: detect-engine-proto.h:37
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
Signature_::proto
DetectProto proto
Definition: detect.h:686
suricata-common.h
DetectThresholdData_
Definition: detect-threshold.h:62
packet.h
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3651
DF_PARSE_MIN_SUBMATCHES
#define DF_PARSE_MIN_SUBMATCHES
Definition: detect-detection-filter.c:57
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
ThresholdGetBitmapMemuse
uint64_t ThresholdGetBitmapMemuse(void)
Definition: detect-engine-threshold.c:76
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:274
SCFree
#define SCFree(p)
Definition: util-mem.h:61
detect-parse.h
DetectDetectionFilterRegister
void DetectDetectionFilterRegister(void)
Registration function for detection_filter: keyword.
Definition: detect-detection-filter.c:72
Signature_
Signature container.
Definition: detect.h:667
SigMatch_
a single match condition for a signature
Definition: detect.h:355
DF_UNIQUE_NONE
@ DF_UNIQUE_NONE
Definition: detect-threshold.h:52
detect-threshold.h
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2645
suricata.h
TRACK_SRC
#define TRACK_SRC
Definition: detect-detection-filter.c:45
DF_UNIQUE_SRC_PORT
@ DF_UNIQUE_SRC_PORT
Definition: detect-threshold.h:53
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
IPPROTO_SCTP
#define IPPROTO_SCTP
Definition: decode.h:1229
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:934
DetectThresholdData_::seconds
uint32_t seconds
Definition: detect-threshold.h:64
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:121
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
StatsThreadCleanup
void StatsThreadCleanup(StatsThreadContext *stats)
Definition: counters.c:1429
ThresholdInit
void ThresholdInit(void)
Definition: detect-engine-threshold.c:123
SIGMATCH_IPONLY_COMPAT
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1651
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1446
detect-engine-threshold.h
ThresholdsExpire
uint32_t ThresholdsExpire(const SCTime_t ts)
Definition: detect-engine-threshold.c:377
TYPE_DETECTION
#define TYPE_DETECTION
Definition: detect-threshold.h:30
DetectProtoContainsProto
int DetectProtoContainsProto(const DetectProto *dp, int proto)
see if a DetectProto contains a certain proto
Definition: detect-engine-proto.c:109
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