]> git.ipfire.org Git - people/ms/suricata.git/blame - src/detect-detection-filter.c
core: Remove unneeded consts
[people/ms/suricata.git] / src / detect-detection-filter.c
CommitLineData
7f6af10f 1/* Copyright (C) 2007-2020 Open Information Security Foundation
ce019275
WM
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 */
046c813f 17
ef2ae76c 18/**
046c813f 19 * \file
ce019275 20 *
ef2ae76c
GIG
21 * \author Gerardo Iglesias <iglesiasg@gmail.com>
22 *
ce019275 23 * Implements the detection_filter keyword
ef2ae76c
GIG
24 */
25
26#include "suricata-common.h"
27#include "suricata.h"
28#include "debug.h"
29#include "decode.h"
30#include "detect.h"
31
c0a2cbd4
VJ
32#include "host.h"
33
ef2ae76c
GIG
34#include "detect-detection-filter.h"
35#include "detect-threshold.h"
36#include "detect-parse.h"
37
38#include "util-byte.h"
39#include "util-unittest.h"
d1ce1c50 40#include "util-unittest-helper.h"
ef2ae76c
GIG
41#include "util-debug.h"
42
4dd01694
VJ
43#define TRACK_DST 1
44#define TRACK_SRC 2
45
ef2ae76c
GIG
46/**
47 *\brief Regex for parsing our detection_filter options
48 */
49#define PARSE_REGEX "^\\s*(track|count|seconds)\\s+(by_src|by_dst|\\d+)\\s*,\\s*(track|count|seconds)\\s+(by_src|by_dst|\\d+)\\s*,\\s*(track|count|seconds)\\s+(by_src|by_dst|\\d+)\\s*$"
50
4b0085b0 51static DetectParseRegex parse_regex;
ef2ae76c 52
14896365 53static int DetectDetectionFilterMatch(DetectEngineThreadCtx *,
bfd4bc82 54 Packet *, const Signature *, const SigMatchCtx *);
ab1200fb 55static int DetectDetectionFilterSetup(DetectEngineCtx *, Signature *, const char *);
6ab323d3 56#ifdef UNITTESTS
39613778 57static void DetectDetectionFilterRegisterTests(void);
6ab323d3 58#endif
d3a65fe1 59static void DetectDetectionFilterFree(DetectEngineCtx *, void *);
ef2ae76c
GIG
60
61/**
62 * \brief Registration function for detection_filter: keyword
63 */
8f1d7503
KS
64void DetectDetectionFilterRegister (void)
65{
ef2ae76c 66 sigmatch_table[DETECT_DETECTION_FILTER].name = "detection_filter";
68425453 67 sigmatch_table[DETECT_DETECTION_FILTER].desc = "alert on every match after a threshold has been reached";
26bcc975 68 sigmatch_table[DETECT_DETECTION_FILTER].url = "/rules/thresholding.html#detection-filter";
ef2ae76c
GIG
69 sigmatch_table[DETECT_DETECTION_FILTER].Match = DetectDetectionFilterMatch;
70 sigmatch_table[DETECT_DETECTION_FILTER].Setup = DetectDetectionFilterSetup;
71 sigmatch_table[DETECT_DETECTION_FILTER].Free = DetectDetectionFilterFree;
6ab323d3 72#ifdef UNITTESTS
ef2ae76c 73 sigmatch_table[DETECT_DETECTION_FILTER].RegisterTests = DetectDetectionFilterRegisterTests;
6ab323d3 74#endif
c1a19bcd
VJ
75 /* this is compatible to ip-only signatures */
76 sigmatch_table[DETECT_DETECTION_FILTER].flags |= SIGMATCH_IPONLY_COMPAT;
ef2ae76c 77
4b0085b0 78 DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
ef2ae76c
GIG
79}
80
14896365 81static int DetectDetectionFilterMatch (DetectEngineThreadCtx *det_ctx,
bfd4bc82 82 Packet *p, const Signature *s, const SigMatchCtx *ctx)
8f1d7503 83{
ef2ae76c
GIG
84 return 1;
85}
86
87/**
88 * \internal
89 * \brief This function is used to parse detection_filter options passed via detection_filter: keyword
90 *
91 * \param rawstr Pointer to the user provided detection_filter options
92 *
93 * \retval df pointer to DetectThresholdData on success
94 * \retval NULL on failure
95 */
ab1200fb 96static DetectThresholdData *DetectDetectionFilterParse (const char *rawstr)
8f1d7503 97{
ef2ae76c 98 DetectThresholdData *df = NULL;
ef2ae76c 99 int ret = 0, res = 0;
3de99a21 100 size_t pcre2_len;
ef2ae76c
GIG
101 const char *str_ptr = NULL;
102 char *args[6] = { NULL, NULL, NULL, NULL, NULL, NULL};
103 char *copy_str = NULL, *df_opt = NULL;
104 int seconds_found = 0, count_found = 0, track_found = 0;
105 int seconds_pos = 0, count_pos = 0;
106 uint16_t pos = 0;
107 int i = 0;
bc2b53f1 108 char *saveptr = NULL;
ef2ae76c
GIG
109
110 copy_str = SCStrdup(rawstr);
e176be6f 111 if (unlikely(copy_str == NULL)) {
e19f6eba
VJ
112 goto error;
113 }
ef2ae76c 114
bc2b53f1
VJ
115 for (pos = 0, df_opt = strtok_r(copy_str,",", &saveptr);
116 pos < strlen(copy_str) && df_opt != NULL;
117 pos++, df_opt = strtok_r(NULL,",", &saveptr))
118 {
ef2ae76c
GIG
119 if(strstr(df_opt,"count"))
120 count_found++;
121 if(strstr(df_opt,"second"))
122 seconds_found++;
123 if(strstr(df_opt,"track"))
124 track_found++;
125 }
38b6103f
VJ
126 SCFree(copy_str);
127 copy_str = NULL;
ef2ae76c 128
38b6103f 129 if (count_found != 1 || seconds_found != 1 || track_found != 1)
ef2ae76c
GIG
130 goto error;
131
3de99a21 132 ret = DetectParsePcreExec(&parse_regex, rawstr, 0, 0);
ef2ae76c
GIG
133 if (ret < 5) {
134 SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
135 goto error;
136 }
137
4dd01694 138 df = SCMalloc(sizeof(DetectThresholdData));
e176be6f 139 if (unlikely(df == NULL))
ef2ae76c 140 goto error;
9f4fae5b 141
4dd01694 142 memset(df,0,sizeof(DetectThresholdData));
ef2ae76c
GIG
143
144 df->type = TYPE_DETECTION;
145
146 for (i = 0; i < (ret - 1); i++) {
3de99a21
PA
147 res = pcre2_substring_get_bynumber(
148 parse_regex.match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
ef2ae76c 149 if (res < 0) {
3de99a21 150 SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
ef2ae76c
GIG
151 goto error;
152 }
153
154 args[i] = (char *)str_ptr;
155
156 if (strncasecmp(args[i],"by_dst",strlen("by_dst")) == 0)
157 df->track = TRACK_DST;
158 if (strncasecmp(args[i],"by_src",strlen("by_src")) == 0)
159 df->track = TRACK_SRC;
160 if (strncasecmp(args[i],"count",strlen("count")) == 0)
161 count_pos = i+1;
162 if (strncasecmp(args[i],"seconds",strlen("seconds")) == 0)
163 seconds_pos = i+1;
164 }
165
046c813f 166 if (args[count_pos] == NULL || args[seconds_pos] == NULL) {
ef2ae76c
GIG
167 goto error;
168 }
169
0e4f2612 170 if (StringParseUint32(&df->count, 10, strlen(args[count_pos]),
046c813f
VJ
171 args[count_pos]) <= 0) {
172 goto error;
173 }
174
0e4f2612 175 if (StringParseUint32(&df->seconds, 10, strlen(args[seconds_pos]),
046c813f 176 args[seconds_pos]) <= 0) {
ef2ae76c
GIG
177 goto error;
178 }
179
180 if (df->count == 0 || df->seconds == 0) {
181 SCLogError(SC_ERR_INVALID_VALUE, "found an invalid value");
182 goto error;
183 }
184
e19f6eba
VJ
185 for (i = 0; i < 6; i++){
186 if (args[i] != NULL)
3de99a21 187 pcre2_substring_free((PCRE2_UCHAR *)args[i]);
ef2ae76c
GIG
188 }
189 return df;
190
191error:
e19f6eba
VJ
192 for (i = 0; i < 6; i++){
193 if (args[i] != NULL)
3de99a21 194 pcre2_substring_free((PCRE2_UCHAR *)args[i]);
ef2ae76c 195 }
e19f6eba
VJ
196 if (df != NULL)
197 SCFree(df);
ef2ae76c
GIG
198 return NULL;
199}
200
201/**
202 * \internal
203 * \brief this function is used to add the parsed detection_filter into the current signature
204 *
205 * \param de_ctx pointer to the Detection Engine Context
206 * \param s pointer to the Current Signature
207 * \param m pointer to the Current SigMatch
208 * \param rawstr pointer to the user provided detection_filter options
209 *
210 * \retval 0 on Success
211 * \retval -1 on Failure
212 */
ab1200fb 213static int DetectDetectionFilterSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
8f1d7503 214{
ef2ae76c
GIG
215 SCEnter();
216 DetectThresholdData *df = NULL;
217 SigMatch *sm = NULL;
218 SigMatch *tmpm = NULL;
219
220 /* checks if there's a previous instance of threshold */
779d40ce 221 tmpm = DetectGetLastSMFromLists(s, DETECT_THRESHOLD, -1);
ef2ae76c
GIG
222 if (tmpm != NULL) {
223 SCLogError(SC_ERR_INVALID_SIGNATURE, "\"detection_filter\" and \"threshold\" are not allowed in the same rule");
224 SCReturnInt(-1);
225 }
226 /* checks there's no previous instance of detection_filter */
779d40ce 227 tmpm = DetectGetLastSMFromLists(s, DETECT_DETECTION_FILTER, -1);
ef2ae76c
GIG
228 if (tmpm != NULL) {
229 SCLogError(SC_ERR_INVALID_SIGNATURE, "At most one \"detection_filter\" is allowed per rule");
230 SCReturnInt(-1);
231 }
232
233 df = DetectDetectionFilterParse(rawstr);
234 if (df == NULL)
235 goto error;
236
237 sm = SigMatchAlloc();
238 if (sm == NULL)
239 goto error;
240
241 sm->type = DETECT_DETECTION_FILTER;
923a77e9 242 sm->ctx = (SigMatchCtx *)df;
ef2ae76c 243
eb07c345 244 SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_THRESHOLD);
ef2ae76c
GIG
245
246 return 0;
247
248error:
39613778
VJ
249 if (df)
250 SCFree(df);
251 if (sm)
252 SCFree(sm);
ef2ae76c
GIG
253 return -1;
254}
255
256/**
257 * \internal
258 * \brief this function will free memory associated with DetectThresholdData
259 *
260 * \param df_ptr pointer to DetectDetectionFilterData
261 */
d3a65fe1 262static void DetectDetectionFilterFree(DetectEngineCtx *de_ctx, void *df_ptr)
8f1d7503 263{
ef2ae76c 264 DetectThresholdData *df = (DetectThresholdData *)df_ptr;
39613778
VJ
265 if (df)
266 SCFree(df);
ef2ae76c
GIG
267}
268
269/*
270 * ONLY TESTS BELOW THIS COMMENT
271 */
272#ifdef UNITTESTS
ef2ae76c
GIG
273#include "detect-engine.h"
274#include "detect-engine-mpm.h"
275#include "detect-engine-threshold.h"
276#include "util-time.h"
277#include "util-hashlist.h"
278
279/**
280 * \test DetectDetectionFilterTestParse01 is a test for a valid detection_filter options
281 *
282 * \retval 1 on succces
283 * \retval 0 on failure
284 */
39613778 285static int DetectDetectionFilterTestParse01 (void)
8f1d7503 286{
ef2ae76c
GIG
287 DetectThresholdData *df = NULL;
288 df = DetectDetectionFilterParse("track by_dst,count 10,seconds 60");
289 if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 60)) {
d3a65fe1 290 DetectDetectionFilterFree(NULL, df);
ef2ae76c
GIG
291 return 1;
292 }
293
294 return 0;
295}
296
297/**
298 * \test DetectDetectionFilterTestParse02 is a test for a invalid detection_filter options
299 *
300 * \retval 1 on succces
301 * \retval 0 on failure
302 */
39613778 303static int DetectDetectionFilterTestParse02 (void)
8f1d7503 304{
ef2ae76c
GIG
305 DetectThresholdData *df = NULL;
306 df = DetectDetectionFilterParse("track both,count 10,seconds 60");
307 if (df && (df->track == TRACK_DST || df->track == TRACK_SRC) && (df->count == 10) && (df->seconds == 60)) {
d3a65fe1 308 DetectDetectionFilterFree(NULL, df);
52983bf3 309 return 0;
ef2ae76c
GIG
310 }
311
52983bf3 312 return 1;
ef2ae76c
GIG
313}
314
315/**
316 * \test DetectDetectionfilterTestParse03 is a test for a valid detection_filter options in any order
317 *
318 * \retval 1 on succces
319 * \retval 0 on failure
320 */
39613778 321static int DetectDetectionFilterTestParse03 (void)
8f1d7503 322{
ef2ae76c
GIG
323 DetectThresholdData *df = NULL;
324 df = DetectDetectionFilterParse("track by_dst, seconds 60, count 10");
325 if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 60)) {
d3a65fe1 326 DetectDetectionFilterFree(NULL, df);
ef2ae76c
GIG
327 return 1;
328 }
329
330 return 0;
331}
332
333
334/**
335 * \test DetectDetectionFilterTestParse04 is a test for an invalid detection_filter options in any order
336 *
337 * \retval 1 on succces
338 * \retval 0 on failure
339 */
39613778 340static int DetectDetectionFilterTestParse04 (void)
8f1d7503 341{
ef2ae76c
GIG
342 DetectThresholdData *df = NULL;
343 df = DetectDetectionFilterParse("count 10, track by_dst, seconds 60, count 10");
344 if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 60)) {
d3a65fe1 345 DetectDetectionFilterFree(NULL, df);
52983bf3 346 return 0;
ef2ae76c
GIG
347 }
348
52983bf3 349 return 1;
ef2ae76c
GIG
350}
351
352/**
353 * \test DetectDetectionFilterTestParse05 is a test for a valid detection_filter options in any order
354 *
355 * \retval 1 on succces
356 * \retval 0 on failure
357 */
39613778 358static int DetectDetectionFilterTestParse05 (void)
8f1d7503 359{
ef2ae76c
GIG
360 DetectThresholdData *df = NULL;
361 df = DetectDetectionFilterParse("count 10, track by_dst, seconds 60");
362 if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 60)) {
d3a65fe1 363 DetectDetectionFilterFree(NULL, df);
ef2ae76c
GIG
364 return 1;
365 }
366
367 return 0;
368}
369
370/**
371 * \test DetectDetectionFilterTestParse06 is a test for an invalid value in detection_filter
372 *
373 * \retval 1 on succces
374 * \retval 0 on failure
375 */
39613778 376static int DetectDetectionFilterTestParse06 (void)
8f1d7503 377{
ef2ae76c
GIG
378 DetectThresholdData *df = NULL;
379 df = DetectDetectionFilterParse("count 10, track by_dst, seconds 0");
380 if (df && (df->track == TRACK_DST) && (df->count == 10) && (df->seconds == 0)) {
d3a65fe1 381 DetectDetectionFilterFree(NULL, df);
52983bf3 382 return 0;
ef2ae76c
GIG
383 }
384
52983bf3 385 return 1;
ef2ae76c
GIG
386}
387
388/**
389 * \test DetectDetectionFilterTestSig1 is a test for checking the working of detection_filter keyword
390 * by setting up the signature and later testing its working by matching
391 * the received packet against the sig.
392 *
393 * \retval 1 on succces
394 * \retval 0 on failure
395 */
8f1d7503
KS
396static int DetectDetectionFilterTestSig1(void)
397{
1071a532 398 Packet *p = NULL;
ef2ae76c
GIG
399 Signature *s = NULL;
400 ThreadVars th_v;
401 DetectEngineThreadCtx *det_ctx;
402 int result = 0;
403 int alerts = 0;
ef2ae76c 404
c0a2cbd4
VJ
405 HostInitConfig(HOST_QUIET);
406
ef2ae76c 407 memset(&th_v, 0, sizeof(th_v));
1071a532
VJ
408
409 p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
ef2ae76c
GIG
410
411 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
412 if (de_ctx == NULL) {
413 goto end;
414 }
415
416 de_ctx->flags |= DE_QUIET;
417
c1a19bcd 418 s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"detection_filter Test\"; detection_filter: track by_dst, count 4, seconds 60; sid:1;)");
ef2ae76c
GIG
419 if (s == NULL) {
420 goto end;
421 }
422
423 SigGroupBuild(de_ctx);
424 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
425
1071a532
VJ
426 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
427 alerts = PacketAlertCheck(p, 1);
428 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
429 alerts += PacketAlertCheck(p, 1);
430 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
431 alerts += PacketAlertCheck(p, 1);
432 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
433 alerts += PacketAlertCheck(p, 1);
434 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
435 alerts += PacketAlertCheck(p, 1);
436 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
437 alerts += PacketAlertCheck(p, 1);
438 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
439 alerts += PacketAlertCheck(p, 1);
440 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
441 alerts += PacketAlertCheck(p, 1);
ef2ae76c 442
8742e51f 443 if(alerts == 4)
ef2ae76c
GIG
444 result = 1;
445
446 SigGroupCleanup(de_ctx);
447 SigCleanSignatures(de_ctx);
448
449 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
450 DetectEngineCtxFree(de_ctx);
451
452end:
1071a532 453 UTHFreePackets(&p, 1);
c0a2cbd4 454 HostShutdown();
ef2ae76c
GIG
455 return result;
456}
457
458/**
459 * \test DetectDetectionFilterTestSig2 is a test for checking the working of detection_filter keyword
460 * by setting up the signature and later testing its working by matching
461 * the received packet against the sig.
462 *
463 * \retval 1 on succces
464 * \retval 0 on failure
465 */
466
8f1d7503
KS
467static int DetectDetectionFilterTestSig2(void)
468{
1071a532 469 Packet *p = NULL;
ef2ae76c
GIG
470 Signature *s = NULL;
471 ThreadVars th_v;
472 DetectEngineThreadCtx *det_ctx;
473 int result = 0;
474 int alerts = 0;
ef2ae76c
GIG
475 struct timeval ts;
476
c0a2cbd4
VJ
477 HostInitConfig(HOST_QUIET);
478
ef2ae76c
GIG
479 memset (&ts, 0, sizeof(struct timeval));
480 TimeGet(&ts);
481
482 memset(&th_v, 0, sizeof(th_v));
1071a532
VJ
483
484 p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
ef2ae76c
GIG
485
486 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
487 if (de_ctx == NULL) {
488 goto end;
489 }
490
491 de_ctx->flags |= DE_QUIET;
492
c1a19bcd 493 s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"detection_filter Test 2\"; detection_filter: track by_dst, count 4, seconds 60; sid:10;)");
ef2ae76c
GIG
494 if (s == NULL) {
495 goto end;
496 }
497
498 SigGroupBuild(de_ctx);
499 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
500
1071a532 501 TimeGet(&p->ts);
85141328 502
1071a532
VJ
503 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
504 alerts = PacketAlertCheck(p, 10);
505 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
506 alerts += PacketAlertCheck(p, 10);
507 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
508 alerts += PacketAlertCheck(p, 10);
ef2ae76c
GIG
509
510 TimeSetIncrementTime(200);
1071a532 511 TimeGet(&p->ts);
ef2ae76c 512
1071a532
VJ
513 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
514 alerts += PacketAlertCheck(p, 10);
515 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
516 alerts += PacketAlertCheck(p, 10);
517 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
518 alerts += PacketAlertCheck(p, 10);
519 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
520 alerts += PacketAlertCheck(p, 10);
ef2ae76c 521
8742e51f 522 if (alerts == 0)
ef2ae76c
GIG
523 result = 1;
524
525 SigGroupCleanup(de_ctx);
526 SigCleanSignatures(de_ctx);
527
528 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
529 DetectEngineCtxFree(de_ctx);
530end:
1071a532 531 UTHFreePackets(&p, 1);
c0a2cbd4 532 HostShutdown();
ef2ae76c
GIG
533 return result;
534}
535
80d62b59
VJ
536/**
537 * \test drops
538 */
8f1d7503
KS
539static int DetectDetectionFilterTestSig3(void)
540{
80d62b59
VJ
541 Packet *p = NULL;
542 Signature *s = NULL;
543 ThreadVars th_v;
544 DetectEngineThreadCtx *det_ctx;
545 int result = 0;
546 int alerts = 0;
547 int drops = 0;
548 struct timeval ts;
549
550 HostInitConfig(HOST_QUIET);
551
552 memset (&ts, 0, sizeof(struct timeval));
553 TimeGet(&ts);
554
555 memset(&th_v, 0, sizeof(th_v));
556
557 p = UTHBuildPacketReal(NULL, 0, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
ef2ae76c 558
80d62b59
VJ
559 DetectEngineCtx *de_ctx = DetectEngineCtxInit();
560 if (de_ctx == NULL) {
561 goto end;
562 }
563
564 de_ctx->flags |= DE_QUIET;
565
566 s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (msg:\"detection_filter Test 2\"; detection_filter: track by_dst, count 2, seconds 60; sid:10;)");
567 if (s == NULL) {
568 goto end;
569 }
570
571 SigGroupBuild(de_ctx);
572 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
573
574 TimeGet(&p->ts);
575
576 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
577 alerts = PacketAlertCheck(p, 10);
4c7eb644 578 drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
80d62b59
VJ
579 p->action = 0;
580
581 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
582 alerts += PacketAlertCheck(p, 10);
4c7eb644 583 drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
80d62b59
VJ
584 p->action = 0;
585
586 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
587 alerts += PacketAlertCheck(p, 10);
4c7eb644 588 drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
80d62b59
VJ
589 p->action = 0;
590
591 TimeSetIncrementTime(200);
592 TimeGet(&p->ts);
593
594 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
595 alerts += PacketAlertCheck(p, 10);
4c7eb644 596 drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
80d62b59
VJ
597 p->action = 0;
598
599 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
600 alerts += PacketAlertCheck(p, 10);
4c7eb644 601 drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
80d62b59
VJ
602 p->action = 0;
603
604 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
605 alerts += PacketAlertCheck(p, 10);
4c7eb644 606 drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
80d62b59
VJ
607 p->action = 0;
608
609 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
610 alerts += PacketAlertCheck(p, 10);
4c7eb644 611 drops += ((PacketTestAction(p, ACTION_DROP)) ? 1 : 0);
80d62b59
VJ
612 p->action = 0;
613
614 if (alerts == 3 && drops == 3)
615 result = 1;
616 else {
617 if (alerts != 3)
618 printf("alerts: %d != 3: ", alerts);
619 if (drops != 3)
620 printf("drops: %d != 3: ", drops);
621 }
622
623 SigGroupCleanup(de_ctx);
624 SigCleanSignatures(de_ctx);
625
626 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
627 DetectEngineCtxFree(de_ctx);
628end:
629 UTHFreePackets(&p, 1);
630 HostShutdown();
631 return result;
632}
ef2ae76c 633
39613778 634static void DetectDetectionFilterRegisterTests(void)
8f1d7503 635{
796dd522
JI
636 UtRegisterTest("DetectDetectionFilterTestParse01",
637 DetectDetectionFilterTestParse01);
638 UtRegisterTest("DetectDetectionFilterTestParse02",
639 DetectDetectionFilterTestParse02);
640 UtRegisterTest("DetectDetectionFilterTestParse03",
641 DetectDetectionFilterTestParse03);
642 UtRegisterTest("DetectDetectionFilterTestParse04",
643 DetectDetectionFilterTestParse04);
644 UtRegisterTest("DetectDetectionFilterTestParse05",
645 DetectDetectionFilterTestParse05);
646 UtRegisterTest("DetectDetectionFilterTestParse06",
647 DetectDetectionFilterTestParse06);
648 UtRegisterTest("DetectDetectionFilterTestSig1",
649 DetectDetectionFilterTestSig1);
650 UtRegisterTest("DetectDetectionFilterTestSig2",
651 DetectDetectionFilterTestSig2);
652 UtRegisterTest("DetectDetectionFilterTestSig3",
653 DetectDetectionFilterTestSig3);
ef2ae76c 654}
6ab323d3 655#endif /* UNITTESTS */