suricata
detect-engine-alert.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2026 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 #include "suricata-common.h"
19 #include "suricata.h"
20 
21 #include "detect.h"
22 #include "detect-engine-alert.h"
24 #include "detect-engine-tag.h"
25 
26 #include "decode.h"
27 #include "packet.h"
28 
29 #include "flow.h"
30 #include "flow-private.h"
31 
32 #ifdef QA_SIMULATION
33 #include "util-exception-policy.h"
34 #endif
35 
36 #include "util-profiling.h"
37 #include "util-validate.h"
38 
39 #include "action-globals.h"
40 #include "capture-hooks.h"
41 
42 /** tag signature we use for tag alerts */
43 static Signature g_tag_signature;
44 /** tag packet alert structure for tag alerts */
45 static PacketAlert g_tag_pa;
46 
48 {
49  memset(&g_tag_signature, 0x00, sizeof(g_tag_signature));
50 
51  g_tag_signature.id = TAG_SIG_ID;
52  g_tag_signature.gid = TAG_SIG_GEN;
53  g_tag_signature.iid = TAG_SIG_ID;
54  g_tag_signature.rev = 1;
55  g_tag_signature.prio = 2;
56 
57  memset(&g_tag_pa, 0x00, sizeof(g_tag_pa));
58 
59  g_tag_pa.action = ACTION_ALERT;
60  g_tag_pa.s = &g_tag_signature;
61 }
62 
63 /**
64  * \brief Handle a packet and check if needs a threshold logic
65  * Also apply rule action if necessary.
66  *
67  * \param de_ctx Detection Context
68  * \param sig Signature pointer
69  * \param p Packet structure
70  *
71  * \retval 1 alert is not suppressed
72  * \retval 0 alert is suppressed
73  */
74 static int PacketAlertHandle(const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
75  const Signature *s, Packet *p, PacketAlert *pa)
76 {
77  SCEnter();
78  int ret = 1;
79  const DetectThresholdData *td = NULL;
80  const SigMatchData *smd;
81 
82  if (!(PacketIsIPv4(p) || PacketIsIPv6(p))) {
83  SCReturnInt(1);
84  }
85 
86  /* handle suppressions first */
87  if (s->sm_arrays[DETECT_SM_LIST_SUPPRESS] != NULL) {
89  smd = NULL;
90  do {
92  if (td != NULL) {
93  SCLogDebug("td %p", td);
94 
95  /* PacketAlertThreshold returns 2 if the alert is suppressed but
96  * we do need to apply rule actions to the packet. */
98  ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s, pa);
99  if (ret == 0 || ret == 2) {
101  /* It doesn't match threshold, remove it */
102  SCReturnInt(ret);
103  }
105  }
106  } while (smd != NULL);
107  }
108 
109  /* if we're still here, consider thresholding */
110  if (s->sm_arrays[DETECT_SM_LIST_THRESHOLD] != NULL) {
112  smd = NULL;
113  do {
115  if (td != NULL) {
116  SCLogDebug("td %p", td);
117 
118  /* PacketAlertThreshold returns 2 if the alert is suppressed but
119  * we do need to apply rule actions to the packet. */
121  ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s, pa);
122  if (ret == 0 || ret == 2) {
124  /* It doesn't match threshold, remove it */
125  SCReturnInt(ret);
126  }
128  }
129  } while (smd != NULL);
130  }
131  SCReturnInt(1);
132 }
133 
134 #ifdef UNITTESTS
135 /**
136  * \brief Check if a certain sid alerted, this is used in the test functions
137  *
138  * \param p Packet on which we want to check if the signature alerted or not
139  * \param sid Signature id of the signature that has to be checked for a match
140  *
141  * \retval match A value > 0 on a match; 0 on no match
142  */
143 int PacketAlertCheck(Packet *p, uint32_t sid)
144 {
145  int match = 0;
146 
147  for (uint16_t i = 0; i < p->alerts.cnt; i++) {
148  BUG_ON(p->alerts.alerts[i].s == NULL);
149  if (p->alerts.alerts[i].s->id == sid)
150  match++;
151  }
152 
153  return match;
154 }
155 #endif
156 
157 static inline void RuleActionToFlow(const uint8_t action, Flow *f)
158 {
159  if (action & ACTION_ACCEPT) {
161  SCLogDebug("setting flow action pass");
162  }
163 
164  /* pass:flow can be set if accept:flow is present */
165  if (action & ACTION_PASS) {
166  if (f->flags & (FLOW_ACTION_DROP | FLOW_ACTION_PASS)) {
167  /* drop or pass already set. First to set wins. */
168  SCLogDebug("not setting %s flow already set to %s",
169  (action & ACTION_PASS) ? "pass" : "drop",
170  (f->flags & FLOW_ACTION_DROP) ? "drop" : "pass");
171  } else {
172  f->flags |= FLOW_ACTION_PASS;
173  SCLogDebug("setting flow action pass");
174  }
175 
176  // TODO firewall drop:flow should override FLOW_ACTION_PASS
177  } else if (action & (ACTION_DROP | ACTION_REJECT_ANY)) {
179  /* drop or pass already set. First to set wins. */
180  SCLogDebug("not setting %s flow already set to %s",
181  (action & ACTION_PASS) ? "pass" : "drop",
182  (f->flags & FLOW_ACTION_DROP) ? "drop" : "pass");
183  } else {
184  if (action & (ACTION_DROP | ACTION_REJECT_ANY)) {
185  f->flags |= FLOW_ACTION_DROP;
186  SCLogDebug("setting flow action drop");
187  }
188  }
189  }
190 }
191 
192 /** \brief Apply action(s) and Set 'drop' sig info,
193  * if applicable
194  * \param p packet
195  * \param s signature -- for id, sig pointer, not actions
196  * \param pa packet alert struct -- match, including actions after thresholding (rate_filter) */
197 static void PacketApplySignatureActions(Packet *p, const Signature *s, const PacketAlert *pa)
198 {
199  SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x", PcapPacketCntGet(p), s->id,
200  pa->action, pa->flags);
201 
202  /* REJECT also sets ACTION_DROP, just make it more visible with this check */
203  if (pa->action & ACTION_DROP_REJECT) {
204  uint8_t drop_reason = PKT_DROP_REASON_RULES;
206  drop_reason = PKT_DROP_REASON_STREAM_PRE_HOOK;
207  } else if (s->detect_table == DETECT_TABLE_PACKET_PRE_FLOW) {
208  drop_reason = PKT_DROP_REASON_FLOW_PRE_HOOK;
209  }
210 
211  /* PacketDrop will update the packet action, too */
212  PacketDrop(p, pa->action,
215  : drop_reason);
216  SCLogDebug("[packet %p][DROP sid %u]", p, s->id);
217 
218  if (p->alerts.drop.action == 0) {
219  p->alerts.drop.iid = s->iid;
220  p->alerts.drop.action = pa->action;
221  p->alerts.drop.s = (Signature *)s;
222  }
223  if ((p->flow != NULL) && (pa->flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
224  RuleActionToFlow(pa->action, p->flow);
225  }
226 
228  } else {
229  if (pa->action & ACTION_ACCEPT) {
230  const enum ActionScope as = pa->s->action_scope;
231  SCLogDebug("packet %" PRIu64 ": ACCEPT %u as:%u flags:%02x", PcapPacketCntGet(p), s->id,
232  as, pa->flags);
233  if (as == ACTION_SCOPE_PACKET || as == ACTION_SCOPE_FLOW ||
235  SCLogDebug("packet %" PRIu64 ": sid:%u ACCEPT", PcapPacketCntGet(p), s->id);
236  p->action |= ACTION_ACCEPT;
237  }
238  } else if (pa->action & (ACTION_ALERT | ACTION_CONFIG)) {
239  // nothing to set in the packet
240  } else if (pa->action & ACTION_PASS) {
241  SCLogDebug("[packet %p][PASS sid %u]", p, s->id);
242  // nothing to set in the packet
243  } else if (pa->action != 0) {
244  DEBUG_VALIDATE_BUG_ON(1); // should be unreachable
245  }
246 
247  if ((pa->action & (ACTION_PASS | ACTION_ACCEPT)) && (p->flow != NULL) &&
249  RuleActionToFlow(pa->action, p->flow);
250  }
251  }
252 }
253 
255 {
256  det_ctx->alert_queue_size = 0;
257  det_ctx->alert_queue = SCCalloc(packet_alert_max, sizeof(PacketAlert));
258  if (det_ctx->alert_queue == NULL) {
259  FatalError("failed to allocate %" PRIu64 " bytes for the alert queue",
260  (uint64_t)(packet_alert_max * sizeof(PacketAlert)));
261  }
263  SCLogDebug("alert queue initialized to %u elements (%" PRIu64 " bytes)", packet_alert_max,
264  (uint64_t)(packet_alert_max * sizeof(PacketAlert)));
265 }
266 
268 {
269  SCFree(det_ctx->alert_queue);
270  det_ctx->alert_queue_capacity = 0;
271 }
272 
273 static inline uint16_t AlertQueueExpandDo(DetectEngineThreadCtx *det_ctx, uint16_t new_cap)
274 {
275  DEBUG_VALIDATE_BUG_ON(det_ctx->alert_queue_capacity >= new_cap);
276 
277  void *tmp_queue = SCRealloc(det_ctx->alert_queue, new_cap * sizeof(PacketAlert));
278  if (unlikely(tmp_queue == NULL)) {
279  /* queue capacity didn't change */
280  return det_ctx->alert_queue_capacity;
281  }
282  det_ctx->alert_queue = tmp_queue;
283  det_ctx->alert_queue_capacity = new_cap;
284  SCLogDebug("Alert queue size expanded: %u elements, bytes: %" PRIuMAX "",
285  det_ctx->alert_queue_capacity, (uintmax_t)(new_cap * sizeof(PacketAlert)));
286  return new_cap;
287 }
288 
289 /** \internal
290  * \retval the new capacity
291  */
292 static uint16_t AlertQueueExpand(DetectEngineThreadCtx *det_ctx)
293 {
294 #ifdef QA_SIMULATION
295  if (unlikely(g_eps_is_alert_queue_fail_mode))
296  return det_ctx->alert_queue_capacity;
297 #endif
298  if (det_ctx->alert_queue_capacity == UINT16_MAX) {
299  return det_ctx->alert_queue_capacity;
300  }
301 
302  uint16_t new_cap;
303  if (det_ctx->alert_queue_capacity > (UINT16_MAX / 2)) {
304  new_cap = UINT16_MAX;
305  } else {
306  new_cap = det_ctx->alert_queue_capacity * 2;
307  }
308  return AlertQueueExpandDo(det_ctx, new_cap);
309 }
310 
311 static inline int PacketAlertSetContext(
312  DetectEngineThreadCtx *det_ctx, PacketAlert *pa, const Signature *s)
313 {
314  pa->json_info = NULL;
315  if (det_ctx->json_content_len) {
316  /* We have some JSON attached in the current detection so let's try
317  to see if some need to be used for current signature. */
318  struct PacketContextData *current_json = NULL;
319  for (uint8_t i = 0; i < det_ctx->json_content_len; i++) {
320  if (s == det_ctx->json_content[i].id) {
321  SCLogDebug("signature %p, content index %u", s, i);
322  if (current_json == NULL) {
323  /* Allocate the first one */
324  current_json = SCCalloc(1, sizeof(struct PacketContextData));
325  if (current_json == NULL) {
326  /* Allocation error, let's return now */
327  return -1;
328  }
329  if (pa->json_info == NULL) {
330  /* If this is the first one, set it */
331  pa->json_info = current_json;
332  }
333  current_json->next = NULL;
334  } else {
335  /* Allocate the next one */
336  struct PacketContextData *next_json =
337  SCCalloc(1, sizeof(struct PacketContextData));
338  if (next_json) {
339  current_json->next = next_json;
340  current_json = next_json;
341  current_json->next = NULL;
342  } else {
343  /* Allocation error, let's return now */
344  return -1;
345  }
346  }
347  current_json->json_string = SCStrdup(det_ctx->json_content[i].json_content);
348  SCLogDebug("json content %u, value '%s' (%p)", (unsigned int)i,
349  current_json->json_string, s);
350  }
351  }
352  }
353 
354  return 0;
355 }
356 
357 /** \internal
358  */
359 static inline PacketAlert PacketAlertSet(
360  DetectEngineThreadCtx *det_ctx, const Signature *s, uint64_t tx_id, uint8_t alert_flags)
361 {
362  PacketAlert pa;
363  pa.iid = s->iid;
364  pa.action = s->action;
365  pa.s = (Signature *)s;
366  pa.flags = alert_flags;
367  /* Set tx_id if the frame has it */
368  pa.tx_id = tx_id;
369  pa.frame_id = (alert_flags & PACKET_ALERT_FLAG_FRAME) ? det_ctx->frame_id : 0;
370  PacketAlertSetContext(det_ctx, &pa, s);
371  return pa;
372 }
373 
374 /**
375  * \brief Append signature to local packet alert queue for later preprocessing
376  */
377 void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p, uint64_t tx_id,
378  uint8_t alert_flags)
379 {
380  /* first time we see a drop action signature, set that in the packet */
381  /* we do that even before inserting into the queue, so we save it even if appending fails */
382  if (p->alerts.drop.action == 0 && s->action & ACTION_DROP) {
383  p->alerts.drop = PacketAlertSet(det_ctx, s, tx_id, alert_flags);
384  SCLogDebug("Set PacketAlert drop action. s->iid %" PRIu32 "", s->iid);
385  }
386 
387  uint16_t pos = det_ctx->alert_queue_size;
388  if (pos == det_ctx->alert_queue_capacity) {
389  /* we must grow the alert queue */
390  if (pos == AlertQueueExpand(det_ctx)) {
391  /* this means we failed to expand the queue */
392  p->alerts.discarded++;
393  return;
394  }
395  }
396  det_ctx->alert_queue[pos] = PacketAlertSet(det_ctx, s, tx_id, alert_flags);
397 
398  SCLogDebug("Appending sid %" PRIu32 ", s->iid %" PRIu32 " to alert queue", s->id, s->iid);
399  det_ctx->alert_queue_size++;
400 }
401 
402 /** \internal
403  * \brief sort helper for sorting alerts by priority
404  *
405  * Sorting is done first based on num and then using tx_id, if nums are equal.
406  * The Signature::num field is set based on internal priority. Higher priority
407  * rules have lower nums.
408  */
409 static int AlertQueueSortHelperFirewall(const void *a, const void *b)
410 {
411  const PacketAlert *pa0 = a;
412  const PacketAlert *pa1 = b;
413  if (pa0->s->detect_table == pa1->s->detect_table) {
414  if (pa1->iid == pa0->iid) {
415  if (pa1->tx_id == PACKET_ALERT_NOTX) {
416  return -1;
417  } else if (pa0->tx_id == PACKET_ALERT_NOTX) {
418  return 1;
419  }
420  return pa0->tx_id < pa1->tx_id ? 1 : -1;
421  } else {
422  return pa0->iid < pa1->iid ? -1 : 1;
423  }
424  }
425  return pa0->s->detect_table < pa1->s->detect_table ? -1 : 1;
426 }
427 
428 static int AlertQueueSortHelper(const void *a, const void *b)
429 {
430  const PacketAlert *pa0 = a;
431  const PacketAlert *pa1 = b;
432  if (pa1->iid == pa0->iid) {
433  if (pa1->tx_id == PACKET_ALERT_NOTX) {
434  return -1;
435  } else if (pa0->tx_id == PACKET_ALERT_NOTX) {
436  return 1;
437  }
438  return pa0->tx_id < pa1->tx_id ? 1 : -1;
439  } else {
440  return pa0->iid < pa1->iid ? -1 : 1;
441  }
442 }
443 
444 /** \internal
445  * \brief Check if Signature action should be applied to flow and apply
446  *
447  */
448 static inline void FlowApplySignatureActions(
449  Packet *p, PacketAlert *pa, const Signature *s, uint8_t alert_flags)
450 {
451  /* For DROP and PASS sigs we need to apply the action to the flow if
452  * - sig is IP or PD only
453  * - match is in applayer
454  * - match is in stream */
455  if (pa->action & (ACTION_DROP | ACTION_PASS | ACTION_ACCEPT)) {
458 
459  if (s->action_scope == ACTION_SCOPE_FLOW) {
461  } else if (s->action_scope == ACTION_SCOPE_AUTO) {
462  enum SignaturePropertyFlowAction flow_action =
464  if (flow_action == SIG_PROP_FLOW_ACTION_FLOW) {
466  } else if (flow_action == SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL) {
469  }
470  }
471  }
472 
474  SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x (set "
475  "PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)",
476  PcapPacketCntGet(p), s->id, s->action, pa->flags);
477  }
478  }
479 }
480 
481 static inline void PacketAlertFinalizeProcessQueue(
482  const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
483 {
484  const bool have_fw_rules = EngineModeIsFirewall();
485 
486  if (det_ctx->alert_queue_size > 1) {
487  /* sort the alert queue before thresholding and appending to Packet */
488  qsort(det_ctx->alert_queue, det_ctx->alert_queue_size, sizeof(PacketAlert),
489  have_fw_rules ? AlertQueueSortHelperFirewall : AlertQueueSortHelper);
490  }
491 
492  bool alerted = false;
493  bool dropped = false;
494  bool skip_td = false;
495  for (uint16_t i = 0; i < det_ctx->alert_queue_size; i++) {
496  PacketAlert *pa = &det_ctx->alert_queue[i];
497  const Signature *s = pa->s;
498 
499  /* if a firewall rule told us to skip, we don't count the skipped
500  * alerts. */
501  if (have_fw_rules && skip_td && (s->flags & SIG_FLAG_FIREWALL) == 0) {
502  continue;
503  }
504 
505  int res = PacketAlertHandle(de_ctx, det_ctx, s, p, pa);
506  if (res > 0) {
507  /* Now, if we have an alert, we have to check if we want
508  * to tag this session or src/dst host */
509  if (s->sm_arrays[DETECT_SM_LIST_TMATCH] != NULL) {
512  while (1) {
513  /* tags are set only for alerts */
515  sigmatch_table[smd->type].Match(det_ctx, p, (Signature *)s, smd->ctx);
516  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
517  if (smd->is_last)
518  break;
519  smd++;
520  }
521  }
522 
523  bool skip_action_set = false;
524  if ((p->action & (ACTION_DROP | ACTION_ACCEPT)) != 0) {
525  if (p->action & ACTION_DROP) {
526  if (pa->action & (ACTION_PASS | ACTION_ACCEPT)) {
527  skip_action_set = true;
528  }
529  } else {
530  if (pa->action & (ACTION_DROP)) {
531  skip_action_set = true;
532  }
533  }
534  }
535  SCLogDebug("packet %" PRIu64 ": i:%u sid:%u skip_action_set %s", PcapPacketCntGet(p), i,
536  s->id, BOOL2STR(skip_action_set));
537  if (!skip_action_set) {
538  /* set actions on the flow */
539  FlowApplySignatureActions(p, pa, s, pa->flags);
540 
541  SCLogDebug("det_ctx->alert_queue[i].action %02x (DROP %s, PASS %s)", pa->action,
543 
544  /* set actions on packet */
545  PacketApplySignatureActions(p, s, pa);
546  }
547  }
548 
549  /* skip firewall sigs following a drop: IDS mode still shows alerts after an alert. */
550  if ((s->flags & SIG_FLAG_FIREWALL) && dropped) {
551  p->alerts.discarded++;
552 
553  /* Thresholding removes this alert */
554  } else if (res == 0 || res == 2 || (s->action & (ACTION_ALERT | ACTION_PASS)) == 0) {
555  SCLogDebug("sid:%u: skipping alert because of thresholding (res=%d) or NOALERT (%02x)",
556  s->id, res, s->action);
557  /* we will not copy this to the AlertQueue */
558  p->alerts.suppressed++;
559  } else if (p->alerts.cnt < packet_alert_max) {
560  p->alerts.alerts[p->alerts.cnt++] = *pa;
561  SCLogDebug("appending sid %" PRIu32 " alert to Packet::alerts at pos %u; action:%02x",
562  s->id, i, pa->action);
563 
564  if (pa->action & ACTION_ALERT) {
565  alerted = true;
566  }
567  /* pass with alert, we're done. Alert is logged. */
568  if (pa->action & ACTION_PASS) {
569  SCLogDebug("sid:%u: is a pass rule, so break out of loop", s->id);
570  if (!have_fw_rules)
571  break;
572  SCLogDebug("skipping td");
573  skip_td = true;
574  continue;
575  }
576 
577  // TODO we can also drop if alert is suppressed, right?
578  if (s->action & ACTION_DROP) {
579  dropped = true;
580  }
581  } else {
582  p->alerts.discarded++;
583  }
584  }
585 
586  /* Set flag on flow to indicate that it has alerts. We use the bool to
587  * exclude pass-only entries in `Packet::alerts` */
588  if (alerted && p->flow != NULL) {
589  if (!FlowHasAlerts(p->flow)) {
591  p->flags |= PKT_FIRST_ALERTS;
592  }
593  }
594 
595  /* Notify capture layer about packets with real alerts (not pass-only),
596  * so capture impl can update per-capture context (e.g. pcap-file alert counts). */
597  if (alerted) {
599  }
600 }
601 
602 /**
603  * \brief Check the threshold of the sigs that match, set actions, break on pass action
604  * This function iterate the packet alerts array, removing those that didn't match
605  * the threshold, and those that match after a signature with the action "pass".
606  * The array is sorted by action priority/order
607  * \param de_ctx detection engine context
608  * \param det_ctx detection engine thread context
609  * \param p pointer to the packet
610  */
612 {
613  SCEnter();
614 
615  if (det_ctx->alert_queue_size > 0) {
616  PacketAlertFinalizeProcessQueue(de_ctx, det_ctx, p);
617  if (det_ctx->json_content_len)
619  }
620 
621  /* At this point, we should have all the new alerts. Now check the tag
622  * keyword context for sessions and hosts */
623  if (!(p->flags & PKT_PSEUDO_STREAM_END))
624  TagHandlePacket(de_ctx, det_ctx, p);
625 }
626 
627 #ifdef UNITTESTS
629 #endif
PacketCheckAction
bool PacketCheckAction(const Packet *p, const uint8_t a)
Definition: packet.c:50
PKT_DROP_REASON_STREAM_PRE_HOOK
@ PKT_DROP_REASON_STREAM_PRE_HOOK
Definition: decode.h:401
PKT_DROP_REASON_RULES_THRESHOLD
@ PKT_DROP_REASON_RULES_THRESHOLD
Definition: decode.h:391
DetectEngineThreadCtx_::alert_queue_size
uint16_t alert_queue_size
Definition: detect.h:1367
FlowSetHasAlertsFlag
void FlowSetHasAlertsFlag(Flow *f)
Set flag to indicate that flow has alerts.
Definition: flow.c:154
PacketAlert_::s
const struct Signature_ * s
Definition: decode.h:253
AlertQueueFree
void AlertQueueFree(DetectEngineThreadCtx *det_ctx)
Definition: detect-engine-alert.c:267
Flow_::flags
uint64_t flags
Definition: flow.h:398
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
PACKET_ALERT_FLAG_STATE_MATCH
#define PACKET_ALERT_FLAG_STATE_MATCH
Definition: decode.h:269
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
ACTION_PASS
#define ACTION_PASS
Definition: action-globals.h:34
KEYWORD_PROFILING_SET_LIST
#define KEYWORD_PROFILING_SET_LIST(ctx, list)
Definition: util-profiling.h:46
PcapPacketCntGet
uint64_t PcapPacketCntGet(const Packet *p)
Definition: decode.c:1107
DETECT_TABLE_PACKET_PRE_STREAM
@ DETECT_TABLE_PACKET_PRE_STREAM
Definition: detect.h:556
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
SigMatchData_::is_last
bool is_last
Definition: detect.h:367
PacketAlerts_::cnt
uint16_t cnt
Definition: decode.h:288
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:143
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:368
action-globals.h
Packet_::flags
uint32_t flags
Definition: decode.h:551
Packet_::action
uint8_t action
Definition: decode.h:613
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:349
DETECT_SM_LIST_THRESHOLD
@ DETECT_SM_LIST_THRESHOLD
Definition: detect.h:133
TAG_SIG_ID
#define TAG_SIG_ID
Definition: detect-engine-tag.h:42
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:966
PKT_DROP_REASON_FLOW_PRE_HOOK
@ PKT_DROP_REASON_FLOW_PRE_HOOK
Definition: decode.h:402
PacketAlerts_::alerts
PacketAlert * alerts
Definition: decode.h:291
ACTION_SCOPE_FLOW
@ ACTION_SCOPE_FLOW
Definition: action-globals.h:45
ACTION_REJECT_ANY
#define ACTION_REJECT_ANY
Definition: action-globals.h:38
PacketAlerts_::drop
PacketAlert drop
Definition: decode.h:294
CaptureHooksOnPacketWithAlerts
void CaptureHooksOnPacketWithAlerts(const Packet *p)
Definition: capture-hooks.c:53
ACTION_DROP_REJECT
#define ACTION_DROP_REJECT
Definition: action-globals.h:40
FLOW_ACTION_DROP
#define FLOW_ACTION_DROP
Definition: flow.h:69
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:735
EngineModeIsFirewall
bool EngineModeIsFirewall(void)
Definition: suricata.c:239
SigMatchData_
Data needed for Match()
Definition: detect.h:365
KEYWORD_PROFILING_START
#define KEYWORD_PROFILING_START
Definition: util-profiling.h:50
SigMatchData_::type
uint16_t type
Definition: detect.h:366
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:626
KEYWORD_PROFILING_END
#define KEYWORD_PROFILING_END(ctx, type, m)
Definition: util-profiling.h:64
PacketAlert_::tx_id
uint64_t tx_id
Definition: decode.h:254
PacketAlert_::action
uint8_t action
Definition: decode.h:251
SIG_FLAG_FIREWALL
#define SIG_FLAG_FIREWALL
Definition: detect.h:245
AlertQueueInit
void AlertQueueInit(DetectEngineThreadCtx *det_ctx)
Definition: detect-engine-alert.c:254
Signature_::gid
uint32_t gid
Definition: detect.h:718
FLOW_ACTION_PASS
#define FLOW_ACTION_PASS
Definition: flow.h:116
SignaturePropertyFlowAction
SignaturePropertyFlowAction
Definition: detect.h:83
capture-hooks.h
PacketAlert_::json_info
struct PacketContextData * json_info
Definition: decode.h:256
decode.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
DetectEngineThreadCtx_
Definition: detect.h:1284
DETECT_THRESHOLD
@ DETECT_THRESHOLD
Definition: detect-engine-register.h:60
PKT_PSEUDO_STREAM_END
#define PKT_PSEUDO_STREAM_END
Definition: decode.h:1297
util-exception-policy.h
BOOL2STR
#define BOOL2STR(b)
Definition: util-debug.h:542
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
detect.h
PacketContextData
Definition: decode.h:242
DETECT_TABLE_PACKET_PRE_FLOW
@ DETECT_TABLE_PACKET_PRE_FLOW
Definition: detect.h:555
PacketAlerts_::discarded
uint16_t discarded
Definition: decode.h:289
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:322
detect-engine-tag.h
PKT_DROP_REASON_RULES
@ PKT_DROP_REASON_RULES
Definition: decode.h:390
Signature_::action
uint8_t action
Definition: detect.h:687
util-profiling.h
PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW
#define PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW
Definition: decode.h:267
Signature_::flags
uint32_t flags
Definition: detect.h:673
PKT_ALERT_CTX_USED
#define PKT_ALERT_CTX_USED
Definition: decode.h:1284
AlertQueueAppend
void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p, uint64_t tx_id, uint8_t alert_flags)
Append signature to local packet alert queue for later preprocessing.
Definition: detect-engine-alert.c:377
ACTION_ALERT
#define ACTION_ALERT
Definition: action-globals.h:29
Packet_
Definition: decode.h:505
DetectEngineThreadCtx_::frame_id
int64_t frame_id
Definition: detect.h:1359
ACTION_SCOPE_AUTO
@ ACTION_SCOPE_AUTO
Definition: action-globals.h:43
detect-engine-alert.h
DetectEngineThreadCtx_::alert_queue_capacity
uint16_t alert_queue_capacity
Definition: detect.h:1368
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1462
PacketAlert_::iid
SigIntId iid
Definition: decode.h:250
signature_properties
const struct SignatureProperties signature_properties[SIG_TYPE_MAX]
Definition: detect-engine.c:116
PACKET_ALERT_NOTX
#define PACKET_ALERT_NOTX
Definition: detect.h:55
SIG_TYPE_NOT_SET
@ SIG_TYPE_NOT_SET
Definition: detect.h:65
PACKET_ALERT_FLAG_APPLY_ACTION_TO_PACKET
#define PACKET_ALERT_FLAG_APPLY_ACTION_TO_PACKET
Definition: decode.h:281
PacketAlertFinalize
void PacketAlertFinalize(const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
Check the threshold of the sigs that match, set actions, break on pass action This function iterate t...
Definition: detect-engine-alert.c:611
PACKET_ALERT_FLAG_STREAM_MATCH
#define PACKET_ALERT_FLAG_STREAM_MATCH
Definition: decode.h:271
TagHandlePacket
void TagHandlePacket(const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
Search tags for src and dst. Update entries of the tag, remove if necessary.
Definition: detect-engine-tag.c:523
PACKET_ALERT_FLAG_FRAME
#define PACKET_ALERT_FLAG_FRAME
Definition: decode.h:277
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
PacketAlert_::frame_id
int64_t frame_id
Definition: decode.h:255
PacketAlert_::flags
uint8_t flags
Definition: decode.h:252
Packet_::flow
struct Flow_ * flow
Definition: decode.h:553
suricata-common.h
SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL
@ SIG_PROP_FLOW_ACTION_FLOW_IF_STATEFUL
Definition: detect.h:86
ActionScope
ActionScope
Definition: action-globals.h:42
DetectThresholdData_
Definition: detect-threshold.h:62
Signature_::action_scope
uint8_t action_scope
Definition: detect.h:694
packet.h
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
Signature_::rev
uint32_t rev
Definition: detect.h:719
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(...)
Definition: util-debug.h:517
ACTION_CONFIG
#define ACTION_CONFIG
Definition: action-globals.h:35
PacketContextData::next
struct PacketContextData * next
Definition: decode.h:244
DETECT_SM_LIST_TMATCH
@ DETECT_SM_LIST_TMATCH
Definition: detect.h:129
SIG_TYPE_MAX
@ SIG_TYPE_MAX
Definition: detect.h:79
Signature_::prio
int prio
Definition: detect.h:720
SigGetThresholdTypeIter
const DetectThresholdData * SigGetThresholdTypeIter(const Signature *sig, const SigMatchData **psm, int list)
Return next DetectThresholdData for signature.
Definition: detect-engine-threshold.c:614
FLOW_ACTION_ACCEPT
#define FLOW_ACTION_ACCEPT
Definition: flow.h:63
util-validate.h
DetectEngineThreadCtx_::alert_queue
PacketAlert * alert_queue
Definition: detect.h:1369
PACKET_ALERT_FLAG_RATE_FILTER_MODIFIED
#define PACKET_ALERT_FLAG_RATE_FILTER_MODIFIED
Definition: decode.h:275
DetectEngineThreadCtx_::json_content
SigJsonContent * json_content
Definition: detect.h:1321
PacketAlerts_::suppressed
uint16_t suppressed
Definition: decode.h:290
Signature_::iid
SigIntId iid
Definition: detect.h:684
SCFree
#define SCFree(p)
Definition: util-mem.h:61
detect-engine-alert.c
Signature_::id
uint32_t id
Definition: detect.h:717
ACTION_SCOPE_PACKET
@ ACTION_SCOPE_PACKET
Definition: action-globals.h:44
Signature_
Signature container.
Definition: detect.h:672
PacketAlertTagInit
void PacketAlertTagInit(void)
Definition: detect-engine-alert.c:47
PacketDrop
void PacketDrop(Packet *p, const uint8_t action, enum PacketDropReason r)
issue drop action
Definition: packet.c:34
ACTION_ACCEPT
#define ACTION_ACCEPT
Definition: action-globals.h:36
suricata.h
PacketAlert_
Definition: decode.h:249
Signature_::detect_table
uint8_t detect_table
Definition: detect.h:706
FlowHasAlerts
int FlowHasAlerts(const Flow *f)
Check if flow has alerts.
Definition: flow.c:165
packet_alert_max
uint16_t packet_alert_max
Definition: decode.c:82
DetectEngineThreadCtx_::json_content_len
uint8_t json_content_len
Definition: detect.h:1323
TAG_SIG_GEN
#define TAG_SIG_GEN
Definition: detect-engine-tag.h:41
PacketContextData::json_string
char * json_string
Definition: decode.h:243
SIG_PROP_FLOW_ACTION_FLOW
@ SIG_PROP_FLOW_ACTION_FLOW
Definition: detect.h:85
PacketAlertThreshold
int PacketAlertThreshold(const 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:1132
flow.h
PKT_FIRST_ALERTS
#define PKT_FIRST_ALERTS
Definition: decode.h:1344
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
Signature_::type
enum SignatureType type
Definition: detect.h:675
DETECT_SM_LIST_SUPPRESS
@ DETECT_SM_LIST_SUPPRESS
Definition: detect.h:132
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
SignatureProperties::flow_action
enum SignaturePropertyFlowAction flow_action
Definition: detect.h:90
SigJsonContent::json_content
char json_content[SIG_JSON_CONTENT_ITEM_LEN]
Definition: detect.h:1278
SigJsonContent::id
void * id
Definition: detect.h:1277
detect-engine-threshold.h