suricata
detect-engine-threshold.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \defgroup threshold Thresholding
20  *
21  * This feature is used to reduce the number of logged alerts for noisy rules.
22  * This can be tuned to significantly reduce false alarms, and it can also be
23  * used to write a newer breed of rules. Thresholding commands limit the number
24  * of times a particular event is logged during a specified time interval.
25  *
26  * @{
27  */
28 
29 /**
30  * \file
31  *
32  * \author Breno Silva <breno.silva@gmail.com>
33  * \author Victor Julien <victor@inliniac.net>
34  *
35  * Threshold part of the detection engine.
36  */
37 
38 #include "suricata-common.h"
39 #include "detect.h"
40 #include "flow.h"
41 
42 #include "host.h"
43 #include "host-storage.h"
44 
45 #include "ippair.h"
46 #include "ippair-storage.h"
47 
48 #include "detect-parse.h"
49 #include "detect-engine-sigorder.h"
50 
51 #include "detect-engine-siggroup.h"
52 #include "detect-engine-address.h"
53 #include "detect-engine-port.h"
54 #include "detect-engine-mpm.h"
55 #include "detect-engine-iponly.h"
56 
57 #include "detect-engine.h"
59 
60 #include "detect-content.h"
61 #include "detect-uricontent.h"
62 
63 #include "util-hash.h"
64 #include "util-time.h"
65 #include "util-error.h"
66 #include "util-debug.h"
67 
68 #include "util-var-name.h"
69 #include "tm-threads.h"
70 
71 #include "action-globals.h"
72 
73 static HostStorageId host_threshold_id = { .id = -1 }; /**< host storage id for thresholds */
74 static IPPairStorageId ippair_threshold_id = { .id = -1 }; /**< ip pair storage id for thresholds */
75 
77 {
78  return host_threshold_id;
79 }
80 
81 void ThresholdInit(void)
82 {
83  host_threshold_id = HostStorageRegister("threshold", sizeof(void *), NULL, ThresholdListFree);
84  if (host_threshold_id.id == -1) {
85  FatalError("Can't initiate host storage for thresholding");
86  }
87  ippair_threshold_id = IPPairStorageRegister("threshold", sizeof(void *), NULL, ThresholdListFree);
88  if (ippair_threshold_id.id == -1) {
89  FatalError("Can't initiate IP pair storage for thresholding");
90  }
91 }
92 
94 {
95  return HostGetStorageById(host, host_threshold_id) ? 1 : 0;
96 }
97 
99 {
100  return IPPairGetStorageById(pair, ippair_threshold_id) ? 1 : 0;
101 }
102 
103 /**
104  * \brief Return next DetectThresholdData for signature
105  *
106  * \param sig Signature pointer
107  * \param psm Pointer to a Signature Match pointer
108  * \param list List to return data from
109  *
110  * \retval tsh Return the threshold data from signature or NULL if not found
111  */
113  const Signature *sig, const SigMatchData **psm, int list)
114 {
115  const SigMatchData *smd = NULL;
116  const DetectThresholdData *tsh = NULL;
117 
118  if (sig == NULL)
119  return NULL;
120 
121  if (*psm == NULL) {
122  smd = sig->sm_arrays[list];
123  } else {
124  /* Iteration in progress, using provided value */
125  smd = *psm;
126  }
127 
128  while (1) {
129  if (smd->type == DETECT_THRESHOLD || smd->type == DETECT_DETECTION_FILTER) {
130  tsh = (DetectThresholdData *)smd->ctx;
131 
132  if (smd->is_last) {
133  *psm = NULL;
134  } else {
135  *psm = smd + 1;
136  }
137  return tsh;
138  }
139 
140  if (smd->is_last) {
141  break;
142  }
143  smd++;
144  }
145  *psm = NULL;
146  return NULL;
147 }
148 
149 /**
150  * \brief Remove timeout threshold hash elements
151  *
152  * \param head Current head element of storage
153  * \param tv Current time
154  *
155  * \retval DetectThresholdEntry Return new head element or NULL if all expired
156  *
157  */
158 
159 static DetectThresholdEntry *ThresholdTimeoutCheck(DetectThresholdEntry *head, SCTime_t ts)
160 {
161  DetectThresholdEntry *tmp = head;
162  DetectThresholdEntry *prev = NULL;
163  DetectThresholdEntry *new_head = head;
164 
165  while (tmp != NULL) {
166  /* check if the 'check' timestamp is not before the creation ts.
167  * This can happen due to the async nature of the host timeout
168  * code that also calls this code from a management thread. */
169  SCTime_t entry = SCTIME_ADD_SECS(tmp->tv1, (time_t)tmp->seconds);
170  if (SCTIME_CMP_LTE(ts, entry)) {
171  prev = tmp;
172  tmp = tmp->next;
173  continue;
174  }
175 
176  /* timed out */
177 
178  DetectThresholdEntry *tde = tmp;
179  if (prev != NULL) {
180  prev->next = tmp->next;
181  }
182  else {
183  new_head = tmp->next;
184  }
185  tmp = tde->next;
186  SCFree(tde);
187  }
188 
189  return new_head;
190 }
191 
193 {
194  DetectThresholdEntry* head = HostGetStorageById(host, host_threshold_id);
195  DetectThresholdEntry *new_head = ThresholdTimeoutCheck(head, ts);
196  if (new_head != head) {
197  HostSetStorageById(host, host_threshold_id, new_head);
198  }
199  return new_head == NULL;
200 }
201 
203 {
204  DetectThresholdEntry* head = IPPairGetStorageById(pair, ippair_threshold_id);
205  DetectThresholdEntry *new_head = ThresholdTimeoutCheck(head, ts);
206  if (new_head != head) {
207  IPPairSetStorageById(pair, ippair_threshold_id, new_head);
208  }
209  return new_head == NULL;
210 }
211 
212 static DetectThresholdEntry *
213 DetectThresholdEntryAlloc(const DetectThresholdData *td, Packet *p,
214  uint32_t sid, uint32_t gid)
215 {
216  SCEnter();
217 
219  if (unlikely(ste == NULL)) {
220  SCReturnPtr(NULL, "DetectThresholdEntry");
221  }
222 
223  ste->sid = sid;
224  ste->gid = gid;
225  ste->track = td->track;
226  ste->seconds = td->seconds;
227 
228  SCReturnPtr(ste, "DetectThresholdEntry");
229 }
230 
231 static DetectThresholdEntry *ThresholdHostLookupEntry(Host *h,
232  uint32_t sid, uint32_t gid)
233 {
235 
236  for (e = HostGetStorageById(h, host_threshold_id); e != NULL; e = e->next) {
237  if (e->sid == sid && e->gid == gid)
238  break;
239  }
240 
241  return e;
242 }
243 
244 static DetectThresholdEntry *ThresholdIPPairLookupEntry(IPPair *pair,
245  uint32_t sid, uint32_t gid)
246 {
248 
249  for (e = IPPairGetStorageById(pair, ippair_threshold_id); e != NULL; e = e->next) {
250  if (e->sid == sid && e->gid == gid)
251  break;
252  }
253 
254  return e;
255 }
256 
257 static int ThresholdHandlePacketSuppress(Packet *p,
258  const DetectThresholdData *td, uint32_t sid, uint32_t gid)
259 {
260  int ret = 0;
261  DetectAddress *m = NULL;
262  switch (td->track) {
263  case TRACK_DST:
264  m = DetectAddressLookupInHead(&td->addrs, &p->dst);
265  SCLogDebug("TRACK_DST");
266  break;
267  case TRACK_SRC:
268  m = DetectAddressLookupInHead(&td->addrs, &p->src);
269  SCLogDebug("TRACK_SRC");
270  break;
271  /* suppress if either src or dst is a match on the suppress
272  * address list */
273  case TRACK_EITHER:
274  m = DetectAddressLookupInHead(&td->addrs, &p->src);
275  if (m == NULL) {
276  m = DetectAddressLookupInHead(&td->addrs, &p->dst);
277  }
278  break;
279  case TRACK_RULE:
280  default:
281  SCLogError("track mode %d is not supported", td->track);
282  break;
283  }
284  if (m == NULL)
285  ret = 1;
286  else
287  ret = 2; /* suppressed but still need actions */
288 
289  return ret;
290 }
291 
292 static inline void RateFilterSetAction(Packet *p, PacketAlert *pa, uint8_t new_action)
293 {
294  switch (new_action) {
295  case TH_ACTION_ALERT:
297  pa->action = ACTION_ALERT;
298  break;
299  case TH_ACTION_DROP:
301  pa->action = ACTION_DROP;
302  break;
303  case TH_ACTION_REJECT:
305  pa->action = (ACTION_REJECT | ACTION_DROP);
306  break;
307  case TH_ACTION_PASS:
309  pa->action = ACTION_PASS;
310  break;
311  default:
312  /* Weird, leave the default action */
313  break;
314  }
315 }
316 
317 /**
318 * \brief Check if the entry reached threshold count limit
319 *
320 * \param lookup_tsh Current threshold entry
321 * \param td Threshold settings
322 * \param packet_time used to compare against previous detection and to set timeouts
323 *
324 * \retval int 1 if threshold reached for this entry
325 *
326 */
327 static int IsThresholdReached(
328  DetectThresholdEntry *lookup_tsh, const DetectThresholdData *td, SCTime_t packet_time)
329 {
330  int ret = 0;
331 
332  /* Check if we have a timeout enabled, if so,
333  * we still matching (and enabling the new_action) */
334  if (lookup_tsh->tv_timeout != 0) {
335  if ((SCTIME_SECS(packet_time) - lookup_tsh->tv_timeout) > td->timeout) {
336  /* Ok, we are done, timeout reached */
337  lookup_tsh->tv_timeout = 0;
338  } else {
339  /* Already matching */
340  ret = 1;
341  } /* else - if ((packet_time - lookup_tsh->tv_timeout) > td->timeout) */
342 
343  }
344  else {
345  /* Update the matching state with the timeout interval */
346  SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds);
347  if (SCTIME_CMP_LTE(packet_time, entry)) {
348  lookup_tsh->current_count++;
349  if (lookup_tsh->current_count > td->count) {
350  /* Then we must enable the new action by setting a
351  * timeout */
352  lookup_tsh->tv_timeout = SCTIME_SECS(packet_time);
353  ret = 1;
354  }
355  } else {
356  lookup_tsh->tv1 = packet_time;
357  lookup_tsh->current_count = 1;
358  }
359  } /* else - if (lookup_tsh->tv_timeout != 0) */
360 
361  return ret;
362 }
363 
364 static void AddEntryToHostStorage(Host *h, DetectThresholdEntry *e, SCTime_t packet_time)
365 {
366  if (h && e) {
367  e->current_count = 1;
368  e->tv1 = packet_time;
369  e->tv_timeout = 0;
370  e->next = HostGetStorageById(h, host_threshold_id);
371  HostSetStorageById(h, host_threshold_id, e);
372  }
373 }
374 
375 static void AddEntryToIPPairStorage(IPPair *pair, DetectThresholdEntry *e, SCTime_t packet_time)
376 {
377  if (pair && e) {
378  e->current_count = 1;
379  e->tv1 = packet_time;
380  e->tv_timeout = 0;
381  e->next = IPPairGetStorageById(pair, ippair_threshold_id);
382  IPPairSetStorageById(pair, ippair_threshold_id, e);
383  }
384 }
385 
386 /**
387  * \retval 2 silent match (no alert but apply actions)
388  * \retval 1 normal match
389  * \retval 0 no match
390  *
391  * If a new DetectThresholdEntry is generated to track the threshold
392  * for this rule, then it will be returned in new_tsh.
393  */
394 static int ThresholdHandlePacket(Packet *p, DetectThresholdEntry *lookup_tsh,
395  DetectThresholdEntry **new_tsh, const DetectThresholdData *td,
396  uint32_t sid, uint32_t gid, PacketAlert *pa)
397 {
398  int ret = 0;
399 
400  switch(td->type) {
401  case TYPE_LIMIT:
402  {
403  SCLogDebug("limit");
404 
405  if (lookup_tsh != NULL) {
406  SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds);
407  if (SCTIME_CMP_LTE(p->ts, entry)) {
408  lookup_tsh->current_count++;
409 
410  if (lookup_tsh->current_count <= td->count) {
411  ret = 1;
412  } else {
413  ret = 2;
414  }
415  } else {
416  lookup_tsh->tv1 = p->ts;
417  lookup_tsh->current_count = 1;
418 
419  ret = 1;
420  }
421  } else {
422  *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
423 
424  ret = 1;
425  }
426  break;
427  }
428  case TYPE_THRESHOLD:
429  {
430  SCLogDebug("threshold");
431 
432  if (lookup_tsh != NULL) {
433  SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds);
434  if (SCTIME_CMP_LTE(p->ts, entry)) {
435  lookup_tsh->current_count++;
436 
437  if (lookup_tsh->current_count >= td->count) {
438  ret = 1;
439  lookup_tsh->current_count = 0;
440  }
441  } else {
442  lookup_tsh->tv1 = p->ts;
443  lookup_tsh->current_count = 1;
444  }
445  } else {
446  if (td->count == 1) {
447  ret = 1;
448  } else {
449  *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
450  }
451  }
452  break;
453  }
454  case TYPE_BOTH:
455  {
456  SCLogDebug("both");
457 
458  if (lookup_tsh != NULL) {
459  SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds);
460  if (SCTIME_CMP_LTE(p->ts, entry)) {
461  /* within time limit */
462 
463  lookup_tsh->current_count++;
464  if (lookup_tsh->current_count == td->count) {
465  ret = 1;
466  } else if (lookup_tsh->current_count > td->count) {
467  /* silent match */
468  ret = 2;
469  }
470  } else {
471  /* expired, so reset */
472  lookup_tsh->tv1 = p->ts;
473  lookup_tsh->current_count = 1;
474 
475  /* if we have a limit of 1, this is a match */
476  if (lookup_tsh->current_count == td->count) {
477  ret = 1;
478  }
479  }
480  } else {
481  *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
482 
483  /* for the first match we return 1 to
484  * indicate we should alert */
485  if (td->count == 1) {
486  ret = 1;
487  }
488  }
489  break;
490  }
491  /* detection_filter */
492  case TYPE_DETECTION:
493  {
494  SCLogDebug("detection_filter");
495 
496  if (lookup_tsh != NULL) {
497  SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds);
498  if (SCTIME_CMP_LTE(p->ts, entry)) {
499  /* within timeout */
500  lookup_tsh->current_count++;
501  if (lookup_tsh->current_count > td->count) {
502  ret = 1;
503  }
504  } else {
505  /* expired, reset */
506  lookup_tsh->tv1 = p->ts;
507  lookup_tsh->current_count = 1;
508  }
509  } else {
510  *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
511  }
512  break;
513  }
514  /* rate_filter */
515  case TYPE_RATE:
516  {
517  SCLogDebug("rate_filter");
518  ret = 1;
519  if (lookup_tsh && IsThresholdReached(lookup_tsh, td, p->ts)) {
520  RateFilterSetAction(p, pa, td->new_action);
521  } else if (!lookup_tsh) {
522  *new_tsh = DetectThresholdEntryAlloc(td, p, sid, gid);
523  }
524  break;
525  }
526  /* case TYPE_SUPPRESS: is not handled here */
527  default:
528  SCLogError("type %d is not supported", td->type);
529  }
530  return ret;
531 }
532 
533 static int ThresholdHandlePacketIPPair(IPPair *pair, Packet *p, const DetectThresholdData *td,
534  uint32_t sid, uint32_t gid, PacketAlert *pa)
535 {
536  int ret = 0;
537 
538  DetectThresholdEntry *lookup_tsh = ThresholdIPPairLookupEntry(pair, sid, gid);
539  SCLogDebug("ippair lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);
540 
541  DetectThresholdEntry *new_tsh = NULL;
542  ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, sid, gid, pa);
543  if (new_tsh != NULL) {
544  AddEntryToIPPairStorage(pair, new_tsh, p->ts);
545  }
546 
547  return ret;
548 }
549 
550 /**
551  * \retval 2 silent match (no alert but apply actions)
552  * \retval 1 normal match
553  * \retval 0 no match
554  */
555 static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdData *td,
556  uint32_t sid, uint32_t gid, PacketAlert *pa)
557 {
558  int ret = 0;
559  DetectThresholdEntry *lookup_tsh = ThresholdHostLookupEntry(h, sid, gid);
560  SCLogDebug("lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);
561 
562  DetectThresholdEntry *new_tsh = NULL;
563  ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, sid, gid, pa);
564  if (new_tsh != NULL) {
565  AddEntryToHostStorage(h, new_tsh, p->ts);
566  }
567  return ret;
568 }
569 
570 static int ThresholdHandlePacketRule(DetectEngineCtx *de_ctx, Packet *p,
571  const DetectThresholdData *td, const Signature *s, PacketAlert *pa)
572 {
573  int ret = 0;
574 
576  SCLogDebug("by_rule lookup_tsh %p num %u", lookup_tsh, s->num);
577 
578  DetectThresholdEntry *new_tsh = NULL;
579  ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, s->id, s->gid, pa);
580  if (new_tsh != NULL) {
581  new_tsh->tv1 = p->ts;
582  new_tsh->current_count = 1;
583  new_tsh->tv_timeout = 0;
584  de_ctx->ths_ctx.th_entry[s->num] = new_tsh;
585  }
586 
587  return ret;
588 }
589 
590 /**
591  * \brief Make the threshold logic for signatures
592  *
593  * \param de_ctx Dectection Context
594  * \param tsh_ptr Threshold element
595  * \param p Packet structure
596  * \param s Signature structure
597  *
598  * \retval 2 silent match (no alert but apply actions)
599  * \retval 1 alert on this event
600  * \retval 0 do not alert on this event
601  */
603  const DetectThresholdData *td, Packet *p, const Signature *s, PacketAlert *pa)
604 {
605  SCEnter();
606 
607  int ret = 0;
608  if (td == NULL) {
609  SCReturnInt(0);
610  }
611 
612  if (td->type == TYPE_SUPPRESS) {
613  ret = ThresholdHandlePacketSuppress(p,td,s->id,s->gid);
614  } else if (td->track == TRACK_SRC) {
616  if (src) {
617  ret = ThresholdHandlePacketHost(src,p,td,s->id,s->gid,pa);
618  HostRelease(src);
619  }
620  } else if (td->track == TRACK_DST) {
622  if (dst) {
623  ret = ThresholdHandlePacketHost(dst,p,td,s->id,s->gid,pa);
624  HostRelease(dst);
625  }
626  } else if (td->track == TRACK_BOTH) {
627  IPPair *pair = IPPairGetIPPairFromHash(&p->src, &p->dst);
628  if (pair) {
629  ret = ThresholdHandlePacketIPPair(pair, p, td, s->id, s->gid, pa);
630  IPPairRelease(pair);
631  }
632  } else if (td->track == TRACK_RULE) {
634  ret = ThresholdHandlePacketRule(de_ctx,p,td,s,pa);
636  }
637 
638  SCReturnInt(ret);
639 }
640 
641 /**
642  * \brief Init threshold context hash tables
643  *
644  * \param de_ctx Dectection Context
645  *
646  */
648 {
649  if (SCMutexInit(&de_ctx->ths_ctx.threshold_table_lock, NULL) != 0) {
650  FatalError("Threshold: Failed to initialize hash table mutex.");
651  }
652 }
653 
654 /**
655  * \brief Allocate threshold context hash tables
656  *
657  * \param de_ctx Detection Context
658  */
660 {
661  Signature *s = de_ctx->sig_list;
662  bool has_by_rule_tracking = false;
663  const DetectThresholdData *td = NULL;
664  const SigMatchData *smd;
665 
666  /* Find the signature with the highest signature number that is using
667  thresholding with by_rule tracking. */
668  uint32_t highest_signum = 0;
669  while (s != NULL) {
670  if (s->sm_arrays[DETECT_SM_LIST_SUPPRESS] != NULL) {
671  smd = NULL;
672  do {
674  if (td == NULL) {
675  continue;
676  }
677  if (td->track != TRACK_RULE) {
678  continue;
679  }
680  if (s->num >= highest_signum) {
681  highest_signum = s->num;
682  has_by_rule_tracking = true;
683  }
684  } while (smd != NULL);
685  }
686 
687  if (s->sm_arrays[DETECT_SM_LIST_THRESHOLD] != NULL) {
688  smd = NULL;
689  do {
691  if (td == NULL) {
692  continue;
693  }
694  if (td->track != TRACK_RULE) {
695  continue;
696  }
697  if (s->num >= highest_signum) {
698  highest_signum = s->num;
699  has_by_rule_tracking = true;
700  }
701  } while (smd != NULL);
702  }
703 
704  s = s->next;
705  }
706 
707  /* Skip allocating if by_rule tracking is not used */
708  if (has_by_rule_tracking == false) {
709  return;
710  }
711 
712  de_ctx->ths_ctx.th_size = highest_signum + 1;
714  if (de_ctx->ths_ctx.th_entry == NULL) {
715  FatalError("Error allocating memory for rule "
716  "thresholds (tried to allocate %" PRIu32 " th_entrys for "
717  "rule tracking)",
719  }
720 }
721 
722 /**
723  * \brief Destroy threshold context hash tables
724  *
725  * \param de_ctx Dectection Context
726  *
727  */
729 {
730  if (de_ctx->ths_ctx.th_entry != NULL) {
731  for (uint32_t i = 0; i < de_ctx->ths_ctx.th_size; i++) {
732  if (de_ctx->ths_ctx.th_entry[i] != NULL) {
734  }
735  }
737  }
739 }
740 
741 /**
742  * \brief this function will free all the entries of a list
743  * DetectTagDataEntry
744  *
745  * \param td pointer to DetectTagDataEntryList
746  */
747 void ThresholdListFree(void *ptr)
748 {
749  if (ptr != NULL) {
750  DetectThresholdEntry *entry = ptr;
751 
752  while (entry != NULL) {
753  DetectThresholdEntry *next_entry = entry->next;
754  SCFree(entry);
755  entry = next_entry;
756  }
757  }
758 }
759 
760 /**
761  * @}
762  */
TRACK_BOTH
#define TRACK_BOTH
Definition: detect-threshold.h:39
DetectThresholdData_::timeout
uint32_t timeout
Definition: detect-threshold.h:60
IPPairStorageRegister
IPPairStorageId IPPairStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Definition: ippair-storage.c:61
host.h
tm-threads.h
detect-content.h
ts
uint64_t ts
Definition: source-erf-file.c:55
ippair.h
detect-engine.h
host-storage.h
ThresholdHostTimeoutCheck
int ThresholdHostTimeoutCheck(Host *host, SCTime_t ts)
Definition: detect-engine-threshold.c:192
detect-engine-siggroup.h
IPPairRelease
void IPPairRelease(IPPair *h)
Definition: ippair.c:521
Signature_::num
SigIntId num
Definition: detect.h:551
ThresholdCtx_::threshold_table_lock
SCMutex threshold_table_lock
Definition: detect.h:731
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
ACTION_PASS
#define ACTION_PASS
Definition: action-globals.h:34
ACTION_REJECT
#define ACTION_REJECT
Definition: action-globals.h:31
DetectAddress_
address structure for use in the detection engine.
Definition: detect.h:128
HostStorageRegister
HostStorageId HostStorageRegister(const char *name, const unsigned int size, void *(*Alloc)(unsigned int), void(*Free)(void *))
Register a Host storage.
Definition: host-storage.c:59
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
ThresholdHashAllocate
void ThresholdHashAllocate(DetectEngineCtx *de_ctx)
Allocate threshold context hash tables.
Definition: detect-engine-threshold.c:659
DetectThresholdData_::count
uint32_t count
Definition: detect-threshold.h:55
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:325
action-globals.h
DETECT_SM_LIST_THRESHOLD
@ DETECT_SM_LIST_THRESHOLD
Definition: detect.h:93
HostRelease
void HostRelease(Host *h)
Definition: host.c:477
util-hash.h
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:785
HostGetHostFromHash
Host * HostGetHostFromHash(Address *a)
Definition: host.c:502
TYPE_LIMIT
#define TYPE_LIMIT
Definition: detect-threshold.h:28
ThresholdCtx_::th_size
uint32_t th_size
Definition: detect.h:735
TRACK_DST
#define TRACK_DST
Definition: detect-detection-filter.c:43
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
util-var-name.h
HostGetStorageById
void * HostGetStorageById(Host *h, HostStorageId id)
Get a value from a given Host storage.
Definition: host-storage.c:88
DetectThresholdData_::new_action
uint8_t new_action
Definition: detect-threshold.h:59
DetectThresholdEntry_
Definition: detect-threshold.h:65
ThresholdIPPairTimeoutCheck
int ThresholdIPPairTimeoutCheck(IPPair *pair, SCTime_t ts)
Definition: detect-engine-threshold.c:202
TH_ACTION_ALERT
#define TH_ACTION_ALERT
Definition: detect-threshold.h:42
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:595
m
SCMutex m
Definition: flow-hash.h:6
IPPairSetStorageById
int IPPairSetStorageById(IPPair *h, IPPairStorageId id, void *ptr)
Definition: ippair-storage.c:40
DetectThresholdEntry_::sid
uint32_t sid
Definition: detect-threshold.h:66
SigMatchData_
Data needed for Match()
Definition: detect.h:322
IPPairStorageId::id
int id
Definition: ippair-storage.h:32
SigMatchData_::type
uint16_t type
Definition: detect.h:323
ThresholdHostHasThreshold
int ThresholdHostHasThreshold(Host *host)
Definition: detect-engine-threshold.c:93
ThresholdHashInit
void ThresholdHashInit(DetectEngineCtx *de_ctx)
Init threshold context hash tables.
Definition: detect-engine-threshold.c:647
DetectAddressLookupInHead
DetectAddress * DetectAddressLookupInHead(const DetectAddressHead *gh, Address *a)
Find the group matching address in a group head.
Definition: detect-engine-address.c:1818
DetectThresholdEntry_::seconds
uint32_t seconds
Definition: detect-threshold.h:71
DetectThresholdData_::type
uint8_t type
Definition: detect-threshold.h:57
PacketAlert_::action
uint8_t action
Definition: decode.h:265
Signature_::gid
uint32_t gid
Definition: detect.h:575
Signature_::next
struct Signature_ * next
Definition: detect.h:614
DetectThresholdEntry_::track
int track
Definition: detect-threshold.h:73
DetectThresholdEntry_::tv_timeout
uint32_t tv_timeout
Definition: detect-threshold.h:69
ThresholdIPPairHasThreshold
int ThresholdIPPairHasThreshold(IPPair *pair)
Definition: detect-engine-threshold.c:98
TRACK_RULE
#define TRACK_RULE
Definition: detect-threshold.h:37
util-debug.h
util-error.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
TYPE_RATE
#define TYPE_RATE
Definition: detect-threshold.h:32
DetectEngineThreadCtx_
Definition: detect.h:1025
Packet_::ts
SCTime_t ts
Definition: decode.h:471
DETECT_THRESHOLD
@ DETECT_THRESHOLD
Definition: detect-engine-register.h:57
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
TH_ACTION_PASS
#define TH_ACTION_PASS
Definition: detect-threshold.h:44
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect-engine-mpm.h
detect.h
DetectThresholdEntry_::tv1
SCTime_t tv1
Definition: detect-threshold.h:75
detect-engine-port.h
util-time.h
IPPairGetIPPairFromHash
IPPair * IPPairGetIPPairFromHash(Address *a, Address *b)
Definition: ippair.c:545
DetectEngineCtx_::ths_ctx
ThresholdCtx ths_ctx
Definition: detect.h:833
TYPE_BOTH
#define TYPE_BOTH
Definition: detect-threshold.h:29
ThresholdCtx_::th_entry
DetectThresholdEntry ** th_entry
Definition: detect.h:734
ThresholdHostStorageId
HostStorageId ThresholdHostStorageId(void)
Definition: detect-engine-threshold.c:76
ACTION_ALERT
#define ACTION_ALERT
Definition: action-globals.h:29
Packet_
Definition: decode.h:428
TRACK_EITHER
#define TRACK_EITHER
Definition: detect-threshold.h:38
SCTime_t
Definition: util-time.h:40
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:287
ThresholdListFree
void ThresholdListFree(void *ptr)
this function will free all the entries of a list DetectTagDataEntry
Definition: detect-engine-threshold.c:747
PacketAlertThreshold
int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectThresholdData *td, Packet *p, const Signature *s, PacketAlert *pa)
Make the threshold logic for signatures.
Definition: detect-engine-threshold.c:602
SCMutexInit
#define SCMutexInit(mut, mutattrs)
Definition: threads-debug.h:116
DetectThresholdData_::track
uint8_t track
Definition: detect-threshold.h:58
PacketAlert_::flags
uint8_t flags
Definition: decode.h:266
DetectThresholdEntry_::current_count
uint32_t current_count
Definition: detect-threshold.h:72
PACKET_ALERT_RATE_FILTER_MODIFIED
#define PACKET_ALERT_RATE_FILTER_MODIFIED
Definition: decode.h:281
TH_ACTION_REJECT
#define TH_ACTION_REJECT
Definition: detect-threshold.h:47
SigMatchData_::is_last
uint8_t is_last
Definition: detect.h:324
suricata-common.h
DetectThresholdData_
Definition: detect-threshold.h:54
IPPair_
Definition: ippair.h:58
TYPE_SUPPRESS
#define TYPE_SUPPRESS
Definition: detect-threshold.h:33
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
SCTIME_SECS
#define SCTIME_SECS(t)
Definition: util-time.h:51
TH_ACTION_DROP
#define TH_ACTION_DROP
Definition: detect-threshold.h:43
FatalError
#define FatalError(...)
Definition: util-debug.h:502
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:791
SigGetThresholdTypeIter
const DetectThresholdData * SigGetThresholdTypeIter(const Signature *sig, const SigMatchData **psm, int list)
Return next DetectThresholdData for signature.
Definition: detect-engine-threshold.c:112
IPPairGetStorageById
void * IPPairGetStorageById(IPPair *h, IPPairStorageId id)
Definition: ippair-storage.c:35
DetectThresholdEntry_::next
struct DetectThresholdEntry_ * next
Definition: detect-threshold.h:76
detect-engine-sigorder.h
TYPE_THRESHOLD
#define TYPE_THRESHOLD
Definition: detect-threshold.h:30
DetectThresholdEntry_::gid
uint32_t gid
Definition: detect-threshold.h:67
DETECT_DETECTION_FILTER
@ DETECT_DETECTION_FILTER
Definition: detect-engine-register.h:100
HostStorageId_
Definition: host-storage.h:31
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
head
Flow * head
Definition: flow-hash.h:1
HostStorageId_::id
int id
Definition: host-storage.h:32
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Signature_::id
uint32_t id
Definition: detect.h:574
detect-engine-iponly.h
detect-parse.h
src
uint16_t src
Definition: app-layer-dnp3.h:5
Signature_
Signature container.
Definition: detect.h:540
Packet_::dst
Address dst
Definition: decode.h:433
TRACK_SRC
#define TRACK_SRC
Definition: detect-detection-filter.c:44
PacketAlert_
Definition: decode.h:263
detect-uricontent.h
DetectThresholdData_::seconds
uint32_t seconds
Definition: detect-threshold.h:56
dst
uint16_t dst
Definition: app-layer-dnp3.h:4
flow.h
SCTIME_ADD_SECS
#define SCTIME_ADD_SECS(ts, s)
Definition: util-time.h:53
ThresholdContextDestroy
void ThresholdContextDestroy(DetectEngineCtx *de_ctx)
Destroy threshold context hash tables.
Definition: detect-engine-threshold.c:728
ippair-storage.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
Host_
Definition: host.h:58
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:275
SCMutexDestroy
#define SCMutexDestroy
Definition: threads-debug.h:120
IPPairStorageId
Definition: ippair-storage.h:31
ThresholdInit
void ThresholdInit(void)
Definition: detect-engine-threshold.c:81
HostSetStorageById
int HostSetStorageById(Host *h, HostStorageId id, void *ptr)
Store a pointer in a given Host storage.
Definition: host-storage.c:75
DETECT_SM_LIST_SUPPRESS
@ DETECT_SM_LIST_SUPPRESS
Definition: detect.h:92
SCTIME_CMP_LTE
#define SCTIME_CMP_LTE(a, b)
Definition: util-time.h:85
detect-engine-address.h
Packet_::src
Address src
Definition: decode.h:432
detect-engine-threshold.h
TYPE_DETECTION
#define TYPE_DETECTION
Definition: detect-threshold.h:31
DetectThresholdData_::addrs
DetectAddressHead addrs
Definition: detect-threshold.h:62