suricata
detect-threshold.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 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 
53 #include "util-unittest.h"
54 #include "util-unittest-helper.h"
55 #include "util-byte.h"
56 #include "util-debug.h"
57 
58 #ifdef UNITTESTS
59 #include "util-cpu.h"
60 #endif
61 
62 #define PARSE_REGEX "^\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*,\\s*(track|type|count|seconds)\\s+(limit|both|threshold|by_dst|by_src|\\d+)\\s*"
63 
64 static pcre *parse_regex;
65 static pcre_extra *parse_regex_study;
66 
67 static int DetectThresholdMatch(DetectEngineThreadCtx *, Packet *,
68  const Signature *, const SigMatchCtx *);
69 static int DetectThresholdSetup(DetectEngineCtx *, Signature *, const char *);
70 static void DetectThresholdFree(void *);
71 
72 /**
73  * \brief Registration function for threshold: keyword
74  */
75 
77 {
78  sigmatch_table[DETECT_THRESHOLD].name = "threshold";
79  sigmatch_table[DETECT_THRESHOLD].desc = "control the rule's alert frequency";
80  sigmatch_table[DETECT_THRESHOLD].url = DOC_URL DOC_VERSION "/rules/thresholding.html#threshold";
81  sigmatch_table[DETECT_THRESHOLD].Match = DetectThresholdMatch;
82  sigmatch_table[DETECT_THRESHOLD].Setup = DetectThresholdSetup;
83  sigmatch_table[DETECT_THRESHOLD].Free = DetectThresholdFree;
85  /* this is compatible to ip-only signatures */
87 
88  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
89 }
90 
91 static int DetectThresholdMatch(DetectEngineThreadCtx *det_ctx, Packet *p,
92  const Signature *s, const SigMatchCtx *ctx)
93 {
94  return 1;
95 }
96 
97 /**
98  * \internal
99  * \brief This function is used to parse threshold options passed via threshold: keyword
100  *
101  * \param rawstr Pointer to the user provided threshold options
102  *
103  * \retval de pointer to DetectThresholdData on success
104  * \retval NULL on failure
105  */
106 static DetectThresholdData *DetectThresholdParse(const char *rawstr)
107 {
108  DetectThresholdData *de = NULL;
109 #define MAX_SUBSTRINGS 30
110  int ret = 0, res = 0;
111  int ov[MAX_SUBSTRINGS];
112  const char *str_ptr = NULL;
113  char *args[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
114  char *copy_str = NULL, *threshold_opt = NULL;
115  int second_found = 0, count_found = 0;
116  int type_found = 0, track_found = 0;
117  int second_pos = 0, count_pos = 0;
118  uint16_t pos = 0;
119  int i = 0;
120 
121  copy_str = SCStrdup(rawstr);
122  if (unlikely(copy_str == NULL)) {
123  goto error;
124  }
125 
126  char *saveptr = NULL;
127  for (pos = 0, threshold_opt = strtok_r(copy_str,",", &saveptr);
128  pos < strlen(copy_str) && threshold_opt != NULL;
129  pos++, threshold_opt = strtok_r(NULL,"," , &saveptr))
130  {
131  if(strstr(threshold_opt,"count"))
132  count_found++;
133  if(strstr(threshold_opt,"second"))
134  second_found++;
135  if(strstr(threshold_opt,"type"))
136  type_found++;
137  if(strstr(threshold_opt,"track"))
138  track_found++;
139  }
140  SCFree(copy_str);
141  copy_str = NULL;
142 
143  if(count_found != 1 || second_found != 1 || type_found != 1 || track_found != 1)
144  goto error;
145 
146  ret = pcre_exec(parse_regex, parse_regex_study, rawstr, strlen(rawstr), 0, 0, ov, MAX_SUBSTRINGS);
147 
148  if (ret < 5) {
149  SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
150  goto error;
151  }
152 
153  de = SCMalloc(sizeof(DetectThresholdData));
154  if (unlikely(de == NULL))
155  goto error;
156 
157  memset(de,0,sizeof(DetectThresholdData));
158 
159  for (i = 0; i < (ret - 1); i++) {
160 
161  res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS,i + 1, &str_ptr);
162 
163  if (res < 0) {
164  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
165  goto error;
166  }
167 
168  args[i] = (char *)str_ptr;
169 
170  if (strncasecmp(args[i],"limit",strlen("limit")) == 0)
171  de->type = TYPE_LIMIT;
172  if (strncasecmp(args[i],"both",strlen("both")) == 0)
173  de->type = TYPE_BOTH;
174  if (strncasecmp(args[i],"threshold",strlen("threshold")) == 0)
175  de->type = TYPE_THRESHOLD;
176  if (strncasecmp(args[i],"by_dst",strlen("by_dst")) == 0)
177  de->track = TRACK_DST;
178  if (strncasecmp(args[i],"by_src",strlen("by_src")) == 0)
179  de->track = TRACK_SRC;
180  if (strncasecmp(args[i],"count",strlen("count")) == 0)
181  count_pos = i+1;
182  if (strncasecmp(args[i],"seconds",strlen("seconds")) == 0)
183  second_pos = i+1;
184  }
185 
186  if (args[count_pos] == NULL || args[second_pos] == NULL) {
187  goto error;
188  }
189 
190  if (ByteExtractStringUint32(&de->count, 10, strlen(args[count_pos]),
191  args[count_pos]) <= 0) {
192  goto error;
193  }
194 
195  if (ByteExtractStringUint32(&de->seconds, 10, strlen(args[second_pos]),
196  args[second_pos]) <= 0) {
197  goto error;
198  }
199 
200  for (i = 0; i < (ret - 1); i++){
201  if (args[i] != NULL) SCFree(args[i]);
202  }
203  return de;
204 
205 error:
206  for (i = 0; i < (ret - 1); i++){
207  if (args[i] != NULL) SCFree(args[i]);
208  }
209  if (de != NULL)
210  SCFree(de);
211  return NULL;
212 }
213 
214 /**
215  * \internal
216  * \brief this function is used to add the parsed threshold into the current signature
217  *
218  * \param de_ctx pointer to the Detection Engine Context
219  * \param s pointer to the Current Signature
220  * \param rawstr pointer to the user provided threshold options
221  *
222  * \retval 0 on Success
223  * \retval -1 on Failure
224  */
225 static int DetectThresholdSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
226 {
227  DetectThresholdData *de = NULL;
228  SigMatch *sm = NULL;
229  SigMatch *tmpm = NULL;
230 
231  /* checks if there is a previous instance of detection_filter */
233  if (tmpm != NULL) {
234  SCLogError(SC_ERR_INVALID_SIGNATURE, "\"detection_filter\" and "
235  "\"threshold\" are not allowed in the same rule");
236  SCReturnInt(-1);
237  }
238 
239  de = DetectThresholdParse(rawstr);
240  if (de == NULL)
241  goto error;
242 
243  sm = SigMatchAlloc();
244  if (sm == NULL)
245  goto error;
246 
247  sm->type = DETECT_THRESHOLD;
248  sm->ctx = (SigMatchCtx *)de;
249 
251 
252  return 0;
253 
254 error:
255  if (de) SCFree(de);
256  if (sm) SCFree(sm);
257  return -1;
258 }
259 
260 /**
261  * \internal
262  * \brief this function will free memory associated with DetectThresholdData
263  *
264  * \param de pointer to DetectThresholdData
265  */
266 static void DetectThresholdFree(void *de_ptr)
267 {
269  if (de) {
271  SCFree(de);
272  }
273 }
274 
275 /*
276  * ONLY TESTS BELOW THIS COMMENT
277  */
278 #ifdef UNITTESTS
279 #include "detect-engine.h"
280 #include "detect-engine-mpm.h"
281 #include "util-time.h"
282 #include "util-hashlist.h"
283 
284 /**
285  * \test ThresholdTestParse01 is a test for a valid threshold options
286  *
287  * \retval 1 on succces
288  * \retval 0 on failure
289  */
290 static int ThresholdTestParse01(void)
291 {
292  DetectThresholdData *de = NULL;
293  de = DetectThresholdParse("type limit,track by_dst,count 10,seconds 60");
294  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) {
295  DetectThresholdFree(de);
296  return 1;
297  }
298 
299  return 0;
300 }
301 
302 /**
303  * \test ThresholdTestParse02 is a test for a invalid threshold options
304  *
305  * \retval 1 on succces
306  * \retval 0 on failure
307  */
308 static int ThresholdTestParse02(void)
309 {
310  DetectThresholdData *de = NULL;
311  de = DetectThresholdParse("type any,track by_dst,count 10,seconds 60");
312  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) {
313  DetectThresholdFree(de);
314  return 0;
315  }
316 
317  return 1;
318 }
319 
320 /**
321  * \test ThresholdTestParse03 is a test for a valid threshold options in any order
322  *
323  * \retval 1 on succces
324  * \retval 0 on failure
325  */
326 static int ThresholdTestParse03(void)
327 {
328  DetectThresholdData *de = NULL;
329  de = DetectThresholdParse("track by_dst, type limit, seconds 60, count 10");
330  if (de && (de->type == TYPE_LIMIT) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) {
331  DetectThresholdFree(de);
332  return 1;
333  }
334 
335  return 0;
336 }
337 
338 
339 /**
340  * \test ThresholdTestParse04 is a test for an invalid threshold options in any order
341  *
342  * \retval 1 on succces
343  * \retval 0 on failure
344  */
345 static int ThresholdTestParse04(void)
346 {
347  DetectThresholdData *de = NULL;
348  de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both, count 10");
349  if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) {
350  DetectThresholdFree(de);
351  return 0;
352  }
353 
354  return 1;
355 }
356 
357 /**
358  * \test ThresholdTestParse05 is a test for a valid threshold options in any order
359  *
360  * \retval 1 on succces
361  * \retval 0 on failure
362  */
363 static int ThresholdTestParse05(void)
364 {
365  DetectThresholdData *de = NULL;
366  de = DetectThresholdParse("count 10, track by_dst, seconds 60, type both");
367  if (de && (de->type == TYPE_BOTH) && (de->track == TRACK_DST) && (de->count == 10) && (de->seconds == 60)) {
368  DetectThresholdFree(de);
369  return 1;
370  }
371 
372  return 0;
373 }
374 
375 
376 /**
377  * \test DetectThresholdTestSig1 is a test for checking the working of limit keyword
378  * by setting up the signature and later testing its working by matching
379  * the received packet against the sig.
380  *
381  * \retval 1 on succces
382  * \retval 0 on failure
383  */
384 
385 static int DetectThresholdTestSig1(void)
386 {
387  Packet *p = NULL;
388  Signature *s = NULL;
389  ThreadVars th_v;
390  DetectEngineThreadCtx *det_ctx;
391  int result = 0;
392  int alerts = 0;
393 
395 
396  memset(&th_v, 0, sizeof(th_v));
397 
398  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
399 
401  if (de_ctx == NULL) {
402  goto end;
403  }
404 
405  de_ctx->flags |= DE_QUIET;
406 
407  s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; content:\"A\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
408  if (s == NULL) {
409  goto end;
410  }
411 
412  SigGroupBuild(de_ctx);
413 
414  if (s->flags & SIG_FLAG_IPONLY) {
415  printf("signature is ip-only: ");
416  goto end;
417  }
418 
419  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
420 
421  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
422  alerts = PacketAlertCheck(p, 1);
423  if (alerts != 1) {
424  printf("alerts %"PRIi32", expected 1: ", alerts);
425  }
426  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
427  alerts += PacketAlertCheck(p, 1);
428  if (alerts != 2) {
429  printf("alerts %"PRIi32", expected 2: ", alerts);
430  }
431  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
432  alerts += PacketAlertCheck(p, 1);
433  if (alerts != 3) {
434  printf("alerts %"PRIi32", expected 3: ", alerts);
435  }
436  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
437  alerts += PacketAlertCheck(p, 1);
438  if (alerts != 4) {
439  printf("alerts %"PRIi32", expected 4: ", alerts);
440  }
441  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
442  alerts += PacketAlertCheck(p, 1);
443  if (alerts != 5) {
444  printf("alerts %"PRIi32", expected 5: ", alerts);
445  }
446  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
447  alerts += PacketAlertCheck(p, 1);
448  if (alerts != 5) {
449  printf("alerts %"PRIi32", expected 5: ", alerts);
450  }
451  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
452  alerts += PacketAlertCheck(p, 1);
453  if (alerts != 5) {
454  printf("alerts %"PRIi32", expected 5: ", alerts);
455  }
456  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
457  alerts += PacketAlertCheck(p, 1);
458  if (alerts != 5) {
459  printf("alerts %"PRIi32", expected 5: ", alerts);
460  }
461 
462  if(alerts == 5)
463  result = 1;
464  else
465  printf("alerts %"PRIi32", expected 5: ", alerts);
466 
467  SigGroupCleanup(de_ctx);
468  SigCleanSignatures(de_ctx);
469 
470  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
471  DetectEngineCtxFree(de_ctx);
472 
473  UTHFreePackets(&p, 1);
474 
475  HostShutdown();
476 end:
477  return result;
478 }
479 
480 /**
481  * \test DetectThresholdTestSig2 is a test for checking the working of threshold keyword
482  * by setting up the signature and later testing its working by matching
483  * the received packet against the sig.
484  *
485  * \retval 1 on succces
486  * \retval 0 on failure
487  */
488 
489 static int DetectThresholdTestSig2(void)
490 {
491  Packet *p = NULL;
492  Signature *s = NULL;
493  ThreadVars th_v;
494  DetectEngineThreadCtx *det_ctx;
495  int result = 0;
496  int alerts = 0;
497 
499 
500  memset(&th_v, 0, sizeof(th_v));
501 
502  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
503 
505  if (de_ctx == NULL) {
506  goto end;
507  }
508 
509  de_ctx->flags |= DE_QUIET;
510 
511  s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold\"; threshold: type threshold, track by_dst, count 5, seconds 60; sid:1;)");
512  if (s == NULL) {
513  goto end;
514  }
515 
516  SigGroupBuild(de_ctx);
517  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
518 
519  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
520  alerts = PacketAlertCheck(p, 1);
521  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
522  alerts += PacketAlertCheck(p, 1);
523  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
524  alerts += PacketAlertCheck(p, 1);
525  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
526  alerts += PacketAlertCheck(p, 1);
527  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
528  alerts += PacketAlertCheck(p, 1);
529  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
530  alerts += PacketAlertCheck(p, 1);
531  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
532  alerts += PacketAlertCheck(p, 1);
533  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
534  alerts += PacketAlertCheck(p, 1);
535  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
536  alerts += PacketAlertCheck(p, 1);
537  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
538  alerts += PacketAlertCheck(p, 1);
539 
540  if (alerts == 2)
541  result = 1;
542  else
543  goto cleanup;
544 
545 cleanup:
546  SigGroupCleanup(de_ctx);
547  SigCleanSignatures(de_ctx);
548 
549  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
550  DetectEngineCtxFree(de_ctx);
551 
552 end:
553  UTHFreePackets(&p, 1);
554  HostShutdown();
555  return result;
556 }
557 
558 /**
559  * \test DetectThresholdTestSig3 is a test for checking the working of limit keyword
560  * by setting up the signature and later testing its working by matching
561  * the received packet against the sig.
562  *
563  * \retval 1 on succces
564  * \retval 0 on failure
565  */
566 
567 static int DetectThresholdTestSig3(void)
568 {
569  Packet *p = NULL;
570  Signature *s = NULL;
571  ThreadVars th_v;
572  DetectEngineThreadCtx *det_ctx;
573  int result = 0;
574  int alerts = 0;
575  struct timeval ts;
576  DetectThresholdEntry *lookup_tsh = NULL;
577 
579 
580  memset (&ts, 0, sizeof(struct timeval));
581  TimeGet(&ts);
582 
583  memset(&th_v, 0, sizeof(th_v));
584 
585  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
586 
588  if (de_ctx == NULL) {
589  goto end;
590  }
591 
592  de_ctx->flags |= DE_QUIET;
593 
594  s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:10;)");
595  if (s == NULL) {
596  goto end;
597  }
598 
599  SigGroupBuild(de_ctx);
600  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
601 
602  TimeGet(&p->ts);
603 
604  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
605  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
606  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
607 
608  Host *host = HostLookupHostFromHash(&p->dst);
609  if (host == NULL) {
610  printf("host not found: ");
611  goto cleanup;
612  }
613 
614  if (!(ThresholdHostHasThreshold(host))) {
615  HostRelease(host);
616  printf("host has no threshold: ");
617  goto cleanup;
618  }
619  HostRelease(host);
620 
622  TimeGet(&p->ts);
623 
624  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
625  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
626  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
627 
628  host = HostLookupHostFromHash(&p->dst);
629  if (host == NULL) {
630  printf("host not found: ");
631  goto cleanup;
632  }
633  HostRelease(host);
634 
635  lookup_tsh = HostGetStorageById(host, ThresholdHostStorageId());
636  if (lookup_tsh == NULL) {
637  HostRelease(host);
638  printf("lookup_tsh is NULL: ");
639  goto cleanup;
640  }
641 
642  alerts = lookup_tsh->current_count;
643 
644  if (alerts == 3)
645  result = 1;
646  else {
647  printf("alerts %u != 3: ", alerts);
648  goto cleanup;
649  }
650 
651 cleanup:
652  SigGroupCleanup(de_ctx);
653  SigCleanSignatures(de_ctx);
654 
655  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
656  DetectEngineCtxFree(de_ctx);
657 end:
658  UTHFreePackets(&p, 1);
659  HostShutdown();
660  return result;
661 }
662 
663 /**
664  * \test DetectThresholdTestSig4 is a test for checking the working of both keyword
665  * by setting up the signature and later testing its working by matching
666  * the received packet against the sig.
667  *
668  * \retval 1 on succces
669  * \retval 0 on failure
670  */
671 
672 static int DetectThresholdTestSig4(void)
673 {
674  Packet *p = NULL;
675  Signature *s = NULL;
676  ThreadVars th_v;
677  DetectEngineThreadCtx *det_ctx;
678  int result = 0;
679  int alerts = 0;
680  struct timeval ts;
681 
683 
684  memset (&ts, 0, sizeof(struct timeval));
685  TimeGet(&ts);
686 
687  memset(&th_v, 0, sizeof(th_v));
688 
689  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
690 
692  if (de_ctx == NULL) {
693  goto end;
694  }
695 
696  de_ctx->flags |= DE_QUIET;
697 
698  s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold both\"; threshold: type both, track by_dst, count 2, seconds 60; sid:10;)");
699  if (s == NULL) {
700  goto end;
701  }
702 
703  SigGroupBuild(de_ctx);
704  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
705 
706  TimeGet(&p->ts);
707  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
708  alerts = PacketAlertCheck(p, 10);
709  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
710  alerts += PacketAlertCheck(p, 10);
711  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
712  alerts += PacketAlertCheck(p, 10);
713 
715  TimeGet(&p->ts);
716 
717  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
718  alerts += PacketAlertCheck(p, 10);
719  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
720  alerts += PacketAlertCheck(p, 10);
721  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
722  alerts += PacketAlertCheck(p, 10);
723 
724  if (alerts == 2)
725  result = 1;
726  else
727  goto cleanup;
728 
729 cleanup:
730  SigGroupCleanup(de_ctx);
731  SigCleanSignatures(de_ctx);
732 
733  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
734  DetectEngineCtxFree(de_ctx);
735 end:
736  UTHFreePackets(&p, 1);
737  HostShutdown();
738  return result;
739 }
740 
741 /**
742  * \test DetectThresholdTestSig5 is a test for checking the working of limit keyword
743  * by setting up the signature and later testing its working by matching
744  * the received packet against the sig.
745  *
746  * \retval 1 on succces
747  * \retval 0 on failure
748  */
749 
750 static int DetectThresholdTestSig5(void)
751 {
752  Packet *p = NULL;
753  Signature *s = NULL;
754  ThreadVars th_v;
755  DetectEngineThreadCtx *det_ctx;
756  int result = 0;
757  int alerts = 0;
758 
760 
761  memset(&th_v, 0, sizeof(th_v));
762  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
763 
765  if (de_ctx == NULL) {
766  goto end;
767  }
768 
769  de_ctx->flags |= DE_QUIET;
770 
771  s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
772  if (s == NULL) {
773  goto end;
774  }
775 
776  s = s->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
777  if (s == NULL) {
778  goto end;
779  }
780 
781  SigGroupBuild(de_ctx);
782  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
783 
784  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
785  alerts = PacketAlertCheck(p, 1);
786  alerts += PacketAlertCheck(p, 1000);
787  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
788  alerts += PacketAlertCheck(p, 1);
789  alerts += PacketAlertCheck(p, 1000);
790  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
791  alerts += PacketAlertCheck(p, 1);
792  alerts += PacketAlertCheck(p, 1000);
793  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
794  alerts += PacketAlertCheck(p, 1);
795  alerts += PacketAlertCheck(p, 1000);
796  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
797  alerts += PacketAlertCheck(p, 1);
798  alerts += PacketAlertCheck(p, 1000);
799  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
800  alerts += PacketAlertCheck(p, 1);
801  alerts += PacketAlertCheck(p, 1000);
802  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
803  alerts += PacketAlertCheck(p, 1);
804  alerts += PacketAlertCheck(p, 1000);
805  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
806  alerts += PacketAlertCheck(p, 1);
807  alerts += PacketAlertCheck(p, 1000);
808 
809  if(alerts == 10)
810  result = 1;
811  else {
812  printf("alerts %d != 10: ", alerts);
813  goto cleanup;
814  }
815 
816 cleanup:
817  SigGroupCleanup(de_ctx);
818  SigCleanSignatures(de_ctx);
819 
820  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
821  DetectEngineCtxFree(de_ctx);
822 
823 end:
824  UTHFreePackets(&p, 1);
825  HostShutdown();
826  return result;
827 }
828 
829 static int DetectThresholdTestSig6Ticks(void)
830 {
831  Packet *p = NULL;
832  Signature *s = NULL;
833  ThreadVars th_v;
834  DetectEngineThreadCtx *det_ctx;
835  int result = 0;
836  int alerts = 0;
837 
839 
840  memset(&th_v, 0, sizeof(th_v));
841  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
842 
844  if (de_ctx == NULL) {
845  goto end;
846  }
847 
848  de_ctx->flags |= DE_QUIET;
849 
850  s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1;)");
851  if (s == NULL) {
852  goto end;
853  }
854 
855  s = s->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit sid 1000\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:1000;)");
856  if (s == NULL) {
857  goto end;
858  }
859 
860  SigGroupBuild(de_ctx);
861  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
862 
863  uint64_t ticks_start = 0;
864  uint64_t ticks_end = 0;
865 
866  ticks_start = UtilCpuGetTicks();
867  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
868  alerts = PacketAlertCheck(p, 1);
869  alerts += PacketAlertCheck(p, 1000);
870  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
871  alerts += PacketAlertCheck(p, 1);
872  alerts += PacketAlertCheck(p, 1000);
873  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
874  alerts += PacketAlertCheck(p, 1);
875  alerts += PacketAlertCheck(p, 1000);
876  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
877  alerts += PacketAlertCheck(p, 1);
878  alerts += PacketAlertCheck(p, 1000);
879  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
880  alerts += PacketAlertCheck(p, 1);
881  alerts += PacketAlertCheck(p, 1000);
882  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
883  alerts += PacketAlertCheck(p, 1);
884  alerts += PacketAlertCheck(p, 1000);
885  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
886  alerts += PacketAlertCheck(p, 1);
887  alerts += PacketAlertCheck(p, 1000);
888  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
889  alerts += PacketAlertCheck(p, 1);
890  alerts += PacketAlertCheck(p, 1000);
891  ticks_end = UtilCpuGetTicks();
892  printf("test run %"PRIu64"\n", (ticks_end - ticks_start));
893 
894  if(alerts == 10)
895  result = 1;
896  else
897  goto cleanup;
898 
899 cleanup:
900  SigGroupCleanup(de_ctx);
901  SigCleanSignatures(de_ctx);
902 
903  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
904  DetectEngineCtxFree(de_ctx);
905 
906 end:
907  UTHFreePackets(&p, 1);
908  HostShutdown();
909  return result;
910 }
911 
912 /**
913  * \test Test drop action being set even if thresholded
914  */
915 static int DetectThresholdTestSig7(void)
916 {
917  Packet *p = NULL;
918  Signature *s = NULL;
919  ThreadVars th_v;
920  DetectEngineThreadCtx *det_ctx;
921  int result = 0;
922  int alerts = 0;
923  int drops = 0;
924  struct timeval ts;
925 
927 
928  memset (&ts, 0, sizeof(struct timeval));
929  TimeGet(&ts);
930 
931  memset(&th_v, 0, sizeof(th_v));
932 
933  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
934 
936  if (de_ctx == NULL) {
937  goto end;
938  }
939 
940  de_ctx->flags |= DE_QUIET;
941 
942  s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 1, seconds 300; sid:10;)");
943  if (s == NULL) {
944  goto end;
945  }
946 
947  SigGroupBuild(de_ctx);
948  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
949 
950  TimeGet(&p->ts);
951  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
952  alerts = PacketAlertCheck(p, 10);
953  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
954  p->action = 0;
955 
956  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
957  alerts += PacketAlertCheck(p, 10);
958  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
959  p->action = 0;
960 
961  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
962  alerts += PacketAlertCheck(p, 10);
963  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
964  p->action = 0;
965 
967  TimeGet(&p->ts);
968 
969  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
970  alerts += PacketAlertCheck(p, 10);
971  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
972  p->action = 0;
973 
974  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
975  alerts += PacketAlertCheck(p, 10);
976  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
977  p->action = 0;
978 
979  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
980  alerts += PacketAlertCheck(p, 10);
981  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
982  p->action = 0;
983 
984  if (alerts == 1 && drops == 6)
985  result = 1;
986  else {
987  if (alerts != 1)
988  printf("alerts: %d != 1: ", alerts);
989  if (drops != 6)
990  printf("drops: %d != 6: ", drops);
991  goto cleanup;
992  }
993 
994 cleanup:
995  SigGroupCleanup(de_ctx);
996  SigCleanSignatures(de_ctx);
997 
998  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
999  DetectEngineCtxFree(de_ctx);
1000 end:
1001  UTHFreePackets(&p, 1);
1002  HostShutdown();
1003  return result;
1004 }
1005 
1006 /**
1007  * \test Test drop action being set even if thresholded
1008  */
1009 static int DetectThresholdTestSig8(void)
1010 {
1011  Packet *p = NULL;
1012  Signature *s = NULL;
1013  ThreadVars th_v;
1014  DetectEngineThreadCtx *det_ctx;
1015  int result = 0;
1016  int alerts = 0;
1017  int drops = 0;
1018  struct timeval ts;
1019 
1021 
1022  memset (&ts, 0, sizeof(struct timeval));
1023  TimeGet(&ts);
1024 
1025  memset(&th_v, 0, sizeof(th_v));
1026 
1027  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1028 
1030  if (de_ctx == NULL) {
1031  goto end;
1032  }
1033 
1034  de_ctx->flags |= DE_QUIET;
1035 
1036  s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type limit, track by_src, count 2, seconds 300; sid:10;)");
1037  if (s == NULL) {
1038  goto end;
1039  }
1040 
1041  SigGroupBuild(de_ctx);
1042  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1043 
1044  TimeGet(&p->ts);
1045  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1046  alerts = PacketAlertCheck(p, 10);
1047  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1048  p->action = 0;
1049 
1050  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1051  alerts += PacketAlertCheck(p, 10);
1052  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1053  p->action = 0;
1054 
1055  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1056  alerts += PacketAlertCheck(p, 10);
1057  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1058  p->action = 0;
1059 
1060  TimeSetIncrementTime(200);
1061  TimeGet(&p->ts);
1062 
1063  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1064  alerts += PacketAlertCheck(p, 10);
1065  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1066  p->action = 0;
1067 
1068  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1069  alerts += PacketAlertCheck(p, 10);
1070  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1071  p->action = 0;
1072 
1073  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1074  alerts += PacketAlertCheck(p, 10);
1075  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1076  p->action = 0;
1077 
1078  if (alerts == 2 && drops == 6)
1079  result = 1;
1080  else {
1081  if (alerts != 1)
1082  printf("alerts: %d != 1: ", alerts);
1083  if (drops != 6)
1084  printf("drops: %d != 6: ", drops);
1085  goto cleanup;
1086  }
1087 
1088 cleanup:
1089  SigGroupCleanup(de_ctx);
1090  SigCleanSignatures(de_ctx);
1091 
1092  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1093  DetectEngineCtxFree(de_ctx);
1094 end:
1095  UTHFreePackets(&p, 1);
1096  HostShutdown();
1097  return result;
1098 }
1099 
1100 /**
1101  * \test Test drop action being set even if thresholded
1102  */
1103 static int DetectThresholdTestSig9(void)
1104 {
1105  Packet *p = NULL;
1106  Signature *s = NULL;
1107  ThreadVars th_v;
1108  DetectEngineThreadCtx *det_ctx;
1109  int result = 0;
1110  int alerts = 0;
1111  int drops = 0;
1112  struct timeval ts;
1113 
1115 
1116  memset (&ts, 0, sizeof(struct timeval));
1117  TimeGet(&ts);
1118 
1119  memset(&th_v, 0, sizeof(th_v));
1120 
1121  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1122 
1124  if (de_ctx == NULL) {
1125  goto end;
1126  }
1127 
1128  de_ctx->flags |= DE_QUIET;
1129 
1130  s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type threshold, track by_src, count 3, seconds 100; sid:10;)");
1131  if (s == NULL) {
1132  goto end;
1133  }
1134 
1135  SigGroupBuild(de_ctx);
1136  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1137 
1138  TimeGet(&p->ts);
1139  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1140  alerts = PacketAlertCheck(p, 10);
1141  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1142  p->action = 0;
1143 
1144  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1145  alerts += PacketAlertCheck(p, 10);
1146  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1147  p->action = 0;
1148 
1149  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1150  alerts += PacketAlertCheck(p, 10);
1151  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1152  p->action = 0;
1153 
1154  TimeSetIncrementTime(200);
1155  TimeGet(&p->ts);
1156 
1157  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1158  alerts += PacketAlertCheck(p, 10);
1159  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1160  p->action = 0;
1161 
1162  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1163  alerts += PacketAlertCheck(p, 10);
1164  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1165  p->action = 0;
1166 
1167  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1168  alerts += PacketAlertCheck(p, 10);
1169  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1170  p->action = 0;
1171 
1172  if (alerts == 2 && drops == 2)
1173  result = 1;
1174  else {
1175  if (alerts != 2)
1176  printf("alerts: %d != 2: ", alerts);
1177  if (drops != 2)
1178  printf("drops: %d != 2: ", drops);
1179  goto cleanup;
1180  }
1181 
1182 cleanup:
1183  SigGroupCleanup(de_ctx);
1184  SigCleanSignatures(de_ctx);
1185 
1186  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1187  DetectEngineCtxFree(de_ctx);
1188 end:
1189  UTHFreePackets(&p, 1);
1190  HostShutdown();
1191  return result;
1192 }
1193 
1194 /**
1195  * \test Test drop action being set even if thresholded
1196  */
1197 static int DetectThresholdTestSig10(void)
1198 {
1199  Packet *p = NULL;
1200  Signature *s = NULL;
1201  ThreadVars th_v;
1202  DetectEngineThreadCtx *det_ctx;
1203  int result = 0;
1204  int alerts = 0;
1205  int drops = 0;
1206  struct timeval ts;
1207 
1209 
1210  memset (&ts, 0, sizeof(struct timeval));
1211  TimeGet(&ts);
1212 
1213  memset(&th_v, 0, sizeof(th_v));
1214 
1215  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1216 
1218  if (de_ctx == NULL) {
1219  goto end;
1220  }
1221 
1222  de_ctx->flags |= DE_QUIET;
1223 
1224  s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type threshold, track by_src, count 5, seconds 300; sid:10;)");
1225  if (s == NULL) {
1226  goto end;
1227  }
1228 
1229  SigGroupBuild(de_ctx);
1230  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1231 
1232  TimeGet(&p->ts);
1233  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1234  alerts = PacketAlertCheck(p, 10);
1235  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1236  p->action = 0;
1237 
1238  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1239  alerts += PacketAlertCheck(p, 10);
1240  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1241  p->action = 0;
1242 
1243  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1244  alerts += PacketAlertCheck(p, 10);
1245  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1246  p->action = 0;
1247 
1248  TimeSetIncrementTime(200);
1249  TimeGet(&p->ts);
1250 
1251  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1252  alerts += PacketAlertCheck(p, 10);
1253  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1254  p->action = 0;
1255 
1256  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1257  alerts += PacketAlertCheck(p, 10);
1258  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1259  p->action = 0;
1260 
1261  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1262  alerts += PacketAlertCheck(p, 10);
1263  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1264  p->action = 0;
1265 
1266  if (alerts == 1 && drops == 1)
1267  result = 1;
1268  else {
1269  if (alerts != 1)
1270  printf("alerts: %d != 1: ", alerts);
1271  if (drops != 1)
1272  printf("drops: %d != 1: ", drops);
1273  goto cleanup;
1274  }
1275 
1276 cleanup:
1277  SigGroupCleanup(de_ctx);
1278  SigCleanSignatures(de_ctx);
1279 
1280  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1281  DetectEngineCtxFree(de_ctx);
1282 end:
1283  UTHFreePackets(&p, 1);
1284  HostShutdown();
1285  return result;
1286 }
1287 
1288 /**
1289  * \test Test drop action being set even if thresholded
1290  */
1291 static int DetectThresholdTestSig11(void)
1292 {
1293  Packet *p = NULL;
1294  Signature *s = NULL;
1295  ThreadVars th_v;
1296  DetectEngineThreadCtx *det_ctx;
1297  int result = 0;
1298  int alerts = 0;
1299  int drops = 0;
1300  struct timeval ts;
1301 
1303 
1304  memset (&ts, 0, sizeof(struct timeval));
1305  TimeGet(&ts);
1306 
1307  memset(&th_v, 0, sizeof(th_v));
1308 
1309  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1310 
1312  if (de_ctx == NULL) {
1313  goto end;
1314  }
1315 
1316  de_ctx->flags |= DE_QUIET;
1317 
1318  s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type both, track by_src, count 3, seconds 300; sid:10;)");
1319  if (s == NULL) {
1320  goto end;
1321  }
1322 
1323  SigGroupBuild(de_ctx);
1324  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1325 
1326  TimeGet(&p->ts);
1327  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1328  alerts = PacketAlertCheck(p, 10);
1329  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1330  p->action = 0;
1331 
1332  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1333  alerts += PacketAlertCheck(p, 10);
1334  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1335  p->action = 0;
1336 
1337  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1338  alerts += PacketAlertCheck(p, 10);
1339  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1340  p->action = 0;
1341 
1342  TimeSetIncrementTime(200);
1343  TimeGet(&p->ts);
1344 
1345  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1346  alerts += PacketAlertCheck(p, 10);
1347  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1348  p->action = 0;
1349 
1350  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1351  alerts += PacketAlertCheck(p, 10);
1352  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1353  p->action = 0;
1354 
1355  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1356  alerts += PacketAlertCheck(p, 10);
1357  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1358  p->action = 0;
1359 
1360  if (alerts == 1 && drops == 4)
1361  result = 1;
1362  else {
1363  if (alerts != 1)
1364  printf("alerts: %d != 1: ", alerts);
1365  if (drops != 4)
1366  printf("drops: %d != 4: ", drops);
1367  goto cleanup;
1368  }
1369 
1370 cleanup:
1371  SigGroupCleanup(de_ctx);
1372  SigCleanSignatures(de_ctx);
1373 
1374  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1375  DetectEngineCtxFree(de_ctx);
1376 end:
1377  UTHFreePackets(&p, 1);
1378  HostShutdown();
1379  return result;
1380 }
1381 
1382 /**
1383  * \test Test drop action being set even if thresholded
1384  */
1385 static int DetectThresholdTestSig12(void)
1386 {
1387  Packet *p = NULL;
1388  Signature *s = NULL;
1389  ThreadVars th_v;
1390  DetectEngineThreadCtx *det_ctx;
1391  int result = 0;
1392  int alerts = 0;
1393  int drops = 0;
1394  struct timeval ts;
1395 
1397 
1398  memset (&ts, 0, sizeof(struct timeval));
1399  TimeGet(&ts);
1400 
1401  memset(&th_v, 0, sizeof(th_v));
1402 
1403  p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
1404 
1406  if (de_ctx == NULL) {
1407  goto end;
1408  }
1409 
1410  de_ctx->flags |= DE_QUIET;
1411 
1412  s = de_ctx->sig_list = SigInit(de_ctx,"drop tcp any any -> any 80 (threshold: type both, track by_src, count 5, seconds 300; sid:10;)");
1413  if (s == NULL) {
1414  goto end;
1415  }
1416 
1417  SigGroupBuild(de_ctx);
1418  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1419 
1420  TimeGet(&p->ts);
1421  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1422  alerts = PacketAlertCheck(p, 10);
1423  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1424  p->action = 0;
1425 
1426  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1427  alerts += PacketAlertCheck(p, 10);
1428  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1429  p->action = 0;
1430 
1431  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1432  alerts += PacketAlertCheck(p, 10);
1433  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1434  p->action = 0;
1435 
1436  TimeSetIncrementTime(200);
1437  TimeGet(&p->ts);
1438 
1439  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1440  alerts += PacketAlertCheck(p, 10);
1441  drops += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1442  p->action = 0;
1443 
1444  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1445  alerts += PacketAlertCheck(p, 10);
1446  drops += ((PACKET_TEST_ACTION(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 += ((PACKET_TEST_ACTION(p, ACTION_DROP))?1:0);
1452  p->action = 0;
1453 
1454  if (alerts == 1 && drops == 2)
1455  result = 1;
1456  else {
1457  if (alerts != 1)
1458  printf("alerts: %d != 1: ", alerts);
1459  if (drops != 2)
1460  printf("drops: %d != 2: ", drops);
1461  goto cleanup;
1462  }
1463 
1464 cleanup:
1465  SigGroupCleanup(de_ctx);
1466  SigCleanSignatures(de_ctx);
1467 
1468  DetectEngineThreadCtxDeinit(&th_v, (void*)det_ctx);
1469  DetectEngineCtxFree(de_ctx);
1470 end:
1471  UTHFreePackets(&p, 1);
1472  HostShutdown();
1473  return result;
1474 }
1475 
1476 #endif /* UNITTESTS */
1477 
1479 {
1480 #ifdef UNITTESTS
1481  UtRegisterTest("ThresholdTestParse01", ThresholdTestParse01);
1482  UtRegisterTest("ThresholdTestParse02", ThresholdTestParse02);
1483  UtRegisterTest("ThresholdTestParse03", ThresholdTestParse03);
1484  UtRegisterTest("ThresholdTestParse04", ThresholdTestParse04);
1485  UtRegisterTest("ThresholdTestParse05", ThresholdTestParse05);
1486  UtRegisterTest("DetectThresholdTestSig1", DetectThresholdTestSig1);
1487  UtRegisterTest("DetectThresholdTestSig2", DetectThresholdTestSig2);
1488  UtRegisterTest("DetectThresholdTestSig3", DetectThresholdTestSig3);
1489  UtRegisterTest("DetectThresholdTestSig4", DetectThresholdTestSig4);
1490  UtRegisterTest("DetectThresholdTestSig5", DetectThresholdTestSig5);
1491  UtRegisterTest("DetectThresholdTestSig6Ticks",
1492  DetectThresholdTestSig6Ticks);
1493  UtRegisterTest("DetectThresholdTestSig7", DetectThresholdTestSig7);
1494  UtRegisterTest("DetectThresholdTestSig8", DetectThresholdTestSig8);
1495  UtRegisterTest("DetectThresholdTestSig9", DetectThresholdTestSig9);
1496  UtRegisterTest("DetectThresholdTestSig10", DetectThresholdTestSig10);
1497  UtRegisterTest("DetectThresholdTestSig11", DetectThresholdTestSig11);
1498  UtRegisterTest("DetectThresholdTestSig12", DetectThresholdTestSig12);
1499 #endif /* UNITTESTS */
1500 }
1501 
1502 /**
1503  * @}
1504  */
void HostShutdown(void)
shutdown the flow engine
Definition: host.c:300
void HostRelease(Host *h)
Definition: host.c:475
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
#define HOST_QUIET
Definition: host.h:93
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
#define TRACK_DST
#define PACKET_TEST_ACTION(p, a)
Definition: decode.h:857
uint32_t flags
Definition: detect.h:523
#define unlikely(expr)
Definition: util-optimize.h:35
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Signature * sig_list
Definition: detect.h:767
Address dst
Definition: decode.h:413
void SigCleanSignatures(DetectEngineCtx *de_ctx)
uint64_t UtilCpuGetTicks(void)
Definition: util-cpu.c:183
int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:244
void ThresholdRegisterTests(void)
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
const char * name
Definition: detect.h:1200
Signature container.
Definition: detect.h:522
#define PARSE_REGEX
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:313
main detection engine ctx
Definition: detect.h:761
void HostInitConfig(char quiet)
initialize the configuration
Definition: host.c:168
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
void * HostGetStorageById(Host *h, int id)
Get a value from a given Host storage.
Definition: host-storage.c:84
#define DE_QUIET
Definition: detect.h:292
int de
uint8_t flags
Definition: detect.h:762
#define SIG_FLAG_IPONLY
Definition: detect.h:219
void TimeGet(struct timeval *tv)
Definition: util-time.c:146
#define TYPE_THRESHOLD
void(* Free)(void *)
Definition: detect.h:1191
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1669
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
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...
#define TYPE_BOTH
DetectAddressHead addrs
#define TYPE_LIMIT
#define MAX_SUBSTRINGS
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1170
int SigGroupCleanup(DetectEngineCtx *de_ctx)
int ThresholdHostHasThreshold(Host *host)
struct Signature_ * next
Definition: detect.h:594
uint8_t type
Definition: detect.h:319
#define SCReturnInt(x)
Definition: util-debug.h:341
const char * desc
Definition: detect.h:1202
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:346
void DetectAddressHeadCleanup(DetectAddressHead *gh)
Cleans a DetectAddressHead. The functions frees the address group heads(ipv4 and ipv6) inside the Det...
SigMatchCtx * ctx
Definition: detect.h:321
#define SCMalloc(a)
Definition: util-mem.h:222
void TimeSetIncrementTime(uint32_t tv_sec)
increment the time in the engine
Definition: util-time.c:175
#define SCFree(a)
Definition: util-mem.h:322
PoolThreadReserved res
Definition: host.h:58
#define TRACK_SRC
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us. ...
Definition: detect-parse.c:465
const char * url
Definition: detect.h:1203
#define SCStrdup(a)
Definition: util-mem.h:268
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1371
#define DOC_URL
Definition: suricata.h:86
void DetectThresholdRegister(void)
Registration function for threshold: keyword.
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
Per thread variable structure.
Definition: threadvars.h:57
struct timeval ts
Definition: decode.h:451
#define ACTION_DROP
Host * HostLookupHostFromHash(Address *a)
look up a host in the hash
Definition: host.c:599
#define DOC_VERSION
Definition: suricata.h:91
uint16_t flags
Definition: detect.h:1194
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
void(* RegisterTests)(void)
Definition: detect.h:1192
a single match condition for a signature
Definition: detect.h:318
int ThresholdHostStorageId(void)
DetectEngineCtx * DetectEngineCtxInit(void)
uint8_t action
Definition: decode.h:544