suricata
detect-engine-alert.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2022 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 
20 #include "detect.h"
21 #include "detect-engine-alert.h"
23 #include "detect-engine-tag.h"
24 
25 #include "decode.h"
26 
27 #include "flow.h"
28 #include "flow-private.h"
29 
30 #include "util-profiling.h"
31 
32 /** tag signature we use for tag alerts */
33 static Signature g_tag_signature;
34 /** tag packet alert structure for tag alerts */
35 static PacketAlert g_tag_pa;
36 
38 {
39  memset(&g_tag_signature, 0x00, sizeof(g_tag_signature));
40 
41  g_tag_signature.id = TAG_SIG_ID;
42  g_tag_signature.gid = TAG_SIG_GEN;
43  g_tag_signature.num = TAG_SIG_ID;
44  g_tag_signature.rev = 1;
45  g_tag_signature.prio = 2;
46 
47  memset(&g_tag_pa, 0x00, sizeof(g_tag_pa));
48 
49  g_tag_pa.action = ACTION_ALERT;
50  g_tag_pa.s = &g_tag_signature;
51 }
52 
54 {
55  return &g_tag_pa;
56 }
57 
58 /**
59  * \brief Handle a packet and check if needs a threshold logic
60  * Also apply rule action if necessary.
61  *
62  * \param de_ctx Detection Context
63  * \param sig Signature pointer
64  * \param p Packet structure
65  *
66  * \retval 1 alert is not suppressed
67  * \retval 0 alert is suppressed
68  */
69 static int PacketAlertHandle(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
70  const Signature *s, Packet *p, PacketAlert *pa)
71 {
72  SCEnter();
73  int ret = 1;
74  const DetectThresholdData *td = NULL;
75  const SigMatchData *smd;
76 
77  if (!(PKT_IS_IPV4(p) || PKT_IS_IPV6(p))) {
78  SCReturnInt(1);
79  }
80 
81  /* handle suppressions first */
82  if (s->sm_arrays[DETECT_SM_LIST_SUPPRESS] != NULL) {
84  smd = NULL;
85  do {
87  if (td != NULL) {
88  SCLogDebug("td %p", td);
89 
90  /* PacketAlertThreshold returns 2 if the alert is suppressed but
91  * we do need to apply rule actions to the packet. */
93  ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s, pa);
94  if (ret == 0 || ret == 2) {
96  /* It doesn't match threshold, remove it */
97  SCReturnInt(ret);
98  }
100  }
101  } while (smd != NULL);
102  }
103 
104  /* if we're still here, consider thresholding */
105  if (s->sm_arrays[DETECT_SM_LIST_THRESHOLD] != NULL) {
107  smd = NULL;
108  do {
110  if (td != NULL) {
111  SCLogDebug("td %p", td);
112 
113  /* PacketAlertThreshold returns 2 if the alert is suppressed but
114  * we do need to apply rule actions to the packet. */
116  ret = PacketAlertThreshold(de_ctx, det_ctx, td, p, s, pa);
117  if (ret == 0 || ret == 2) {
119  /* It doesn't match threshold, remove it */
120  SCReturnInt(ret);
121  }
123  }
124  } while (smd != NULL);
125  }
126  SCReturnInt(1);
127 }
128 
129 /**
130  * \brief Check if a certain sid alerted, this is used in the test functions
131  *
132  * \param p Packet on which we want to check if the signature alerted or not
133  * \param sid Signature id of the signature that has to be checked for a match
134  *
135  * \retval match A value > 0 on a match; 0 on no match
136  */
137 int PacketAlertCheck(Packet *p, uint32_t sid)
138 {
139  uint16_t i = 0;
140  int match = 0;
141 
142  for (i = 0; i < p->alerts.cnt; i++) {
143  if (p->alerts.alerts[i].s == NULL)
144  continue;
145 
146  if (p->alerts.alerts[i].s->id == sid)
147  match++;
148  }
149 
150  return match;
151 }
152 
153 static inline void RuleActionToFlow(const uint8_t action, Flow *f)
154 {
155  if (action & (ACTION_DROP | ACTION_REJECT_ANY | ACTION_PASS)) {
156  if (f->flags & (FLOW_ACTION_DROP | FLOW_ACTION_PASS)) {
157  /* drop or pass already set. First to set wins. */
158  SCLogDebug("not setting %s flow already set to %s",
159  (action & ACTION_PASS) ? "pass" : "drop",
160  (f->flags & FLOW_ACTION_DROP) ? "drop" : "pass");
161  } else {
162  if (action & (ACTION_DROP | ACTION_REJECT_ANY)) {
163  f->flags |= FLOW_ACTION_DROP;
164  SCLogDebug("setting flow action drop");
165  }
166  if (action & ACTION_PASS) {
167  f->flags |= FLOW_ACTION_PASS;
168  SCLogDebug("setting flow action pass");
169  FlowSetNoPacketInspectionFlag(f);
170  }
171  }
172  }
173 }
174 
175 /** \brief Apply action(s) and Set 'drop' sig info,
176  * if applicable */
177 static void PacketApplySignatureActions(Packet *p, const Signature *s, const uint8_t alert_flags)
178 {
179  SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x", p->pcap_cnt, s->id,
180  s->action, alert_flags);
181 
182  if (s->action & ACTION_DROP) {
183  PacketDrop(p, PKT_DROP_REASON_RULES);
184 
185  if (p->alerts.drop.action == 0) {
186  p->alerts.drop.num = s->num;
187  p->alerts.drop.action = s->action;
188  p->alerts.drop.s = (Signature *)s;
189  }
190  if ((p->flow != NULL) && (alert_flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
191  RuleActionToFlow(s->action, p->flow);
192  }
193  } else {
194  PacketUpdateAction(p, s->action);
195 
196  if ((s->action & ACTION_PASS) && (p->flow != NULL) &&
197  (alert_flags & PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)) {
198  RuleActionToFlow(s->action, p->flow);
199  }
200  }
201 }
202 
204 {
205  det_ctx->alert_queue_size = 0;
206  det_ctx->alert_queue = SCCalloc(packet_alert_max, sizeof(PacketAlert));
207  if (det_ctx->alert_queue == NULL) {
208  FatalError(SC_ERR_MEM_ALLOC, "failed to allocate %" PRIu64 " bytes for the alert queue",
209  (uint64_t)(packet_alert_max * sizeof(PacketAlert)));
210  }
212  SCLogDebug("alert queue initialized to %u elements (%" PRIu64 " bytes)", packet_alert_max,
213  (uint64_t)(packet_alert_max * sizeof(PacketAlert)));
214 }
215 
217 {
218  SCFree(det_ctx->alert_queue);
219  det_ctx->alert_queue_capacity = 0;
220 }
221 
222 /** \internal
223  * \retval the new capacity
224  */
225 static uint16_t AlertQueueExpand(DetectEngineThreadCtx *det_ctx)
226 {
227  uint16_t new_cap = det_ctx->alert_queue_capacity * 2;
228  void *tmp_queue = SCRealloc(det_ctx->alert_queue, (size_t)(sizeof(PacketAlert) * new_cap));
229  if (unlikely(tmp_queue == NULL)) {
230  /* queue capacity didn't change */
231  return det_ctx->alert_queue_capacity;
232  }
233  det_ctx->alert_queue = tmp_queue;
234  det_ctx->alert_queue_capacity = new_cap;
235  SCLogDebug("Alert queue size doubled: %u elements, bytes: %" PRIuMAX "",
236  det_ctx->alert_queue_capacity,
237  (uintmax_t)(sizeof(PacketAlert) * det_ctx->alert_queue_capacity));
238  return new_cap;
239 }
240 
241 /** \internal
242  */
243 static inline PacketAlert PacketAlertSet(
244  DetectEngineThreadCtx *det_ctx, const Signature *s, uint64_t tx_id, uint8_t alert_flags)
245 {
246  PacketAlert pa;
247  pa.num = s->num;
248  pa.action = s->action;
249  pa.s = (Signature *)s;
250  pa.flags = alert_flags;
251  /* Set tx_id if the frame has it */
252  pa.tx_id = (tx_id == UINT64_MAX) ? 0 : tx_id;
253  pa.frame_id = (alert_flags & PACKET_ALERT_FLAG_FRAME) ? det_ctx->frame_id : 0;
254  return pa;
255 }
256 
257 /**
258  * \brief Append signature to local packet alert queue for later preprocessing
259  */
260 void AlertQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p, uint64_t tx_id,
261  uint8_t alert_flags)
262 {
263  /* first time we see a drop action signature, set that in the packet */
264  /* we do that even before inserting into the queue, so we save it even if appending fails */
265  if (p->alerts.drop.action == 0 && s->action & ACTION_DROP) {
266  p->alerts.drop = PacketAlertSet(det_ctx, s, tx_id, alert_flags);
267  SCLogDebug("Set PacketAlert drop action. s->num %" PRIu32 "", s->num);
268  }
269 
270  uint16_t pos = det_ctx->alert_queue_size;
271  if (pos == det_ctx->alert_queue_capacity) {
272  /* we must grow the alert queue */
273  if (pos == AlertQueueExpand(det_ctx)) {
274  /* this means we failed to expand the queue */
275  p->alerts.discarded++;
276  return;
277  }
278  }
279  det_ctx->alert_queue[pos] = PacketAlertSet(det_ctx, s, tx_id, alert_flags);
280 
281  SCLogDebug("Appending sid %" PRIu32 ", s->num %" PRIu32 " to alert queue", s->id, s->num);
282  det_ctx->alert_queue_size++;
283  return;
284 }
285 
286 /** \internal
287  * \brief sort helper for sorting alerts by priority
288  *
289  * Sorting is done first based on num and then using tx_id, if nums are equal.
290  * The Signature::num field is set based on internal priority. Higher priority
291  * rules have lower nums.
292  */
293 static int AlertQueueSortHelper(const void *a, const void *b)
294 {
295  const PacketAlert *pa0 = a;
296  const PacketAlert *pa1 = b;
297  if (pa1->num == pa0->num)
298  return pa0->tx_id < pa1->tx_id ? 1 : -1;
299  else
300  return pa0->num > pa1->num ? 1 : -1;
301 }
302 
303 /** \internal
304  * \brief Check if Signature action should be applied to flow and apply
305  *
306  */
307 static inline void FlowApplySignatureActions(
308  Packet *p, PacketAlert *pa, const Signature *s, uint8_t alert_flags)
309 {
310  /* For DROP and PASS sigs we need to apply the action to the flow if
311  * - sig is IP or PD only
312  * - match is in applayer
313  * - match is in stream */
314  if (s->action & (ACTION_DROP | ACTION_PASS)) {
317  SIG_FLAG_APPLAYER))) {
319  SCLogDebug("packet %" PRIu64 " sid %u action %02x alert_flags %02x (set "
320  "PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW)",
321  p->pcap_cnt, s->id, s->action, pa->flags);
322  }
323  }
324 }
325 
326 /**
327  * \brief Check the threshold of the sigs that match, set actions, break on pass action
328  * This function iterate the packet alerts array, removing those that didn't match
329  * the threshold, and those that match after a signature with the action "pass".
330  * The array is sorted by action priority/order
331  * \param de_ctx detection engine context
332  * \param det_ctx detection engine thread context
333  * \param p pointer to the packet
334  */
336 {
337  SCEnter();
338 
339  /* sort the alert queue before thresholding and appending to Packet */
340  qsort(det_ctx->alert_queue, det_ctx->alert_queue_size, sizeof(PacketAlert),
341  AlertQueueSortHelper);
342 
343  uint16_t i = 0;
344  uint16_t max_pos = det_ctx->alert_queue_size;
345 
346  while (i < max_pos) {
347  const Signature *s = de_ctx->sig_array[det_ctx->alert_queue[i].num];
348  int res = PacketAlertHandle(de_ctx, det_ctx, s, p, &det_ctx->alert_queue[i]);
349 
350  if (res > 0) {
351  /* Now, if we have an alert, we have to check if we want
352  * to tag this session or src/dst host */
353  if (s->sm_arrays[DETECT_SM_LIST_TMATCH] != NULL) {
356  while (1) {
357  /* tags are set only for alerts */
359  sigmatch_table[smd->type].Match(det_ctx, p, (Signature *)s, smd->ctx);
360  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
361  if (smd->is_last)
362  break;
363  smd++;
364  }
365  }
366 
367  /* set actions on the flow */
368  FlowApplySignatureActions(
369  p, &det_ctx->alert_queue[i], s, det_ctx->alert_queue[i].flags);
370 
371  /* set actions on packet */
372  PacketApplySignatureActions(p, s, det_ctx->alert_queue[i].flags);
373  }
374 
375  /* Thresholding removes this alert */
376  if (res == 0 || res == 2 || (s->flags & SIG_FLAG_NOALERT)) {
377  /* we will not copy this to the AlertQueue */
378  p->alerts.suppressed++;
379  } else if (p->alerts.cnt < packet_alert_max) {
380  p->alerts.alerts[p->alerts.cnt] = det_ctx->alert_queue[i];
381  SCLogDebug("Appending sid %" PRIu32 " alert to Packet::alerts at pos %u", s->id, i);
382 
383  if (PacketTestAction(p, ACTION_PASS)) {
384  /* Ok, reset the alert cnt to end in the previous of pass
385  * so we ignore the rest with less prio */
386  break;
387  }
388  p->alerts.cnt++;
389  } else {
390  p->alerts.discarded++;
391  }
392  i++;
393  }
394 
395  /* At this point, we should have all the new alerts. Now check the tag
396  * keyword context for sessions and hosts */
397  if (!(p->flags & PKT_PSEUDO_STREAM_END))
398  TagHandlePacket(de_ctx, det_ctx, p);
399 
400  /* Set flag on flow to indicate that it has alerts */
401  if (p->flow != NULL && p->alerts.cnt > 0) {
402  if (!FlowHasAlerts(p->flow)) {
404  p->flags |= PKT_FIRST_ALERTS;
405  }
406  }
407 
408 }
409 
410 
DetectEngineThreadCtx_::alert_queue_size
uint16_t alert_queue_size
Definition: detect.h:1120
FlowSetHasAlertsFlag
void FlowSetHasAlertsFlag(Flow *f)
Set flag to indicate that flow has alerts.
Definition: flow.c:169
PACKET_ALERT_FLAG_STREAM_MATCH
#define PACKET_ALERT_FLAG_STREAM_MATCH
Definition: decode.h:294
PacketAlert_::s
const struct Signature_ * s
Definition: decode.h:284
AlertQueueFree
void AlertQueueFree(DetectEngineThreadCtx *det_ctx)
Definition: detect-engine-alert.c:216
SIG_FLAG_PDONLY
#define SIG_FLAG_PDONLY
Definition: detect.h:250
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:263
Signature_::num
SigIntId num
Definition: detect.h:560
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:65
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:603
PacketAlerts_::cnt
uint16_t cnt
Definition: decode.h:306
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:137
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:335
Packet_::flags
uint32_t flags
Definition: decode.h:477
flow-private.h
Flow_
Flow data structure.
Definition: flow.h:356
DETECT_SM_LIST_THRESHOLD
@ DETECT_SM_LIST_THRESHOLD
Definition: detect.h:104
SIG_FLAG_LIKE_IPONLY
#define SIG_FLAG_LIKE_IPONLY
Definition: detect.h:220
TAG_SIG_ID
#define TAG_SIG_ID
Definition: detect-engine-tag.h:43
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:794
PacketAlerts_::alerts
PacketAlert * alerts
Definition: decode.h:309
ACTION_REJECT_ANY
#define ACTION_REJECT_ANY
Definition: action-globals.h:37
PacketAlerts_::drop
PacketAlert drop
Definition: decode.h:312
FLOW_ACTION_DROP
#define FLOW_ACTION_DROP
Definition: flow.h:69
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:604
SigMatchData_
Data needed for Match()
Definition: detect.h:332
KEYWORD_PROFILING_START
#define KEYWORD_PROFILING_START
Definition: util-profiling.h:69
SigMatchData_::type
uint16_t type
Definition: detect.h:333
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:597
SIG_FLAG_APPLAYER
#define SIG_FLAG_APPLAYER
Definition: detect.h:218
KEYWORD_PROFILING_END
#define KEYWORD_PROFILING_END(ctx, type, m)
Definition: util-profiling.h:83
PacketAlert_::tx_id
uint64_t tx_id
Definition: decode.h:285
PacketAlert_::action
uint8_t action
Definition: decode.h:282
AlertQueueInit
void AlertQueueInit(DetectEngineThreadCtx *det_ctx)
Definition: detect-engine-alert.c:203
Signature_::gid
uint32_t gid
Definition: detect.h:584
PacketAlertGetTag
PacketAlert * PacketAlertGetTag(void)
Definition: detect-engine-alert.c:53
FLOW_ACTION_PASS
#define FLOW_ACTION_PASS
Definition: flow.h:116
decode.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1043
PacketAlert_::num
SigIntId num
Definition: decode.h:281
DETECT_THRESHOLD
@ DETECT_THRESHOLD
Definition: detect-engine-register.h:55
PKT_PSEUDO_STREAM_END
#define PKT_PSEUDO_STREAM_END
Definition: decode.h:1187
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect.h
PacketAlerts_::discarded
uint16_t discarded
Definition: decode.h:307
detect-engine-tag.h
PKT_DROP_REASON_RULES
@ PKT_DROP_REASON_RULES
Definition: decode.h:418
Signature_::action
uint8_t action
Definition: detect.h:563
util-profiling.h
Signature_::flags
uint32_t flags
Definition: detect.h:550
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:260
ACTION_ALERT
#define ACTION_ALERT
Definition: action-globals.h:29
Packet_
Definition: decode.h:442
SIG_FLAG_IPONLY
#define SIG_FLAG_IPONLY
Definition: detect.h:219
DetectEngineThreadCtx_::frame_id
int64_t frame_id
Definition: detect.h:1117
detect-engine-alert.h
DetectEngineThreadCtx_::alert_queue_capacity
uint16_t alert_queue_capacity
Definition: detect.h:1121
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1218
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:605
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
PacketAlert_::frame_id
int64_t frame_id
Definition: decode.h:286
PacketAlert_::flags
uint8_t flags
Definition: decode.h:283
Packet_::flow
struct Flow_ * flow
Definition: decode.h:479
SigMatchData_::is_last
uint8_t is_last
Definition: detect.h:334
suricata-common.h
DetectThresholdData_
Definition: detect-threshold.h:57
PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW
#define PACKET_ALERT_FLAG_APPLY_ACTION_TO_FLOW
Definition: decode.h:290
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
Signature_::rev
uint32_t rev
Definition: detect.h:585
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
SIG_FLAG_NOALERT
#define SIG_FLAG_NOALERT
Definition: detect.h:216
DETECT_SM_LIST_TMATCH
@ DETECT_SM_LIST_TMATCH
Definition: detect.h:100
Signature_::prio
int prio
Definition: detect.h:586
SigGetThresholdTypeIter
const DetectThresholdData * SigGetThresholdTypeIter(const Signature *sig, const SigMatchData **psm, int list)
Return next DetectThresholdData for signature.
Definition: detect-engine-threshold.c:113
TagHandlePacket
void TagHandlePacket(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:503
DetectEngineThreadCtx_::alert_queue
PacketAlert * alert_queue
Definition: detect.h:1122
PacketAlerts_::suppressed
uint16_t suppressed
Definition: decode.h:308
PACKET_ALERT_FLAG_FRAME
#define PACKET_ALERT_FLAG_FRAME
Definition: decode.h:300
SCFree
#define SCFree(p)
Definition: util-mem.h:61
PacketAlertFinalize
void PacketAlertFinalize(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:335
Signature_::id
uint32_t id
Definition: detect.h:583
Flow_::flags
uint32_t flags
Definition: flow.h:434
Signature_
Signature container.
Definition: detect.h:549
PacketAlertTagInit
void PacketAlertTagInit(void)
Definition: detect-engine-alert.c:37
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
DetectEngineCtx_::sig_array
Signature ** sig_array
Definition: detect.h:809
PacketAlert_
Definition: decode.h:280
FlowHasAlerts
int FlowHasAlerts(const Flow *f)
Check if flow has alerts.
Definition: flow.c:180
packet_alert_max
uint16_t packet_alert_max
Definition: decode.c:77
TAG_SIG_GEN
#define TAG_SIG_GEN
Definition: detect-engine-tag.h:42
flow.h
PKT_FIRST_ALERTS
#define PKT_FIRST_ALERTS
Definition: decode.h:1234
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:262
PACKET_ALERT_FLAG_STATE_MATCH
#define PACKET_ALERT_FLAG_STATE_MATCH
Definition: decode.h:292
DETECT_SM_LIST_SUPPRESS
@ DETECT_SM_LIST_SUPPRESS
Definition: detect.h:103
detect-engine-threshold.h