suricata
detect-engine-prefilter.c
Go to the documentation of this file.
1 /* Copyright (C) 2016-2025 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  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Prefilter engine
24  *
25  * Prefilter engines have as purpose to check for a critical common part of
26  * a set of rules. If the condition is present in the traffic, the rules
27  * will have to be inspected individually. Otherwise, the rules can be
28  * skipped.
29  *
30  * The best example of this is the MPM. From each rule take a pattern and
31  * add it to the MPM state machine. Inspect that in one step and only
32  * individually inspect the rules that had a match in MPM.
33  *
34  * This prefilter API is designed to abstract this logic so that it becomes
35  * easier to add other types of prefilters.
36  *
37  * The prefilter engines are structured as a simple list of engines. Each
38  * engine checks for a condition using it's callback function and private
39  * data. It then adds the rule match candidates to the PrefilterRuleStore
40  * structure.
41  *
42  * After the engines have run the resulting list of match candidates is
43  * sorted by the rule id's so that the individual inspection happens in
44  * the correct order.
45  */
46 
47 #include "suricata-common.h"
48 #include "suricata.h"
49 
50 #include "detect-engine.h"
52 #include "detect-engine-mpm.h"
53 #include "detect-engine-frame.h"
54 #include "detect-engine-uint.h"
55 
56 #include "app-layer-parser.h"
57 #include "app-layer-htp.h"
58 
59 #include "util-profiling.h"
60 #include "util-validate.h"
61 #include "util-hash-string.h"
62 
63 static int PrefilterStoreGetId(DetectEngineCtx *de_ctx,
64  const char *name, void (*FreeFunc)(void *));
65 static const PrefilterStore *PrefilterStoreGetStore(const DetectEngineCtx *de_ctx,
66  const uint32_t id);
67 
68 static inline void QuickSortSigIntId(SigIntId *sids, uint32_t n)
69 {
70  if (n < 2)
71  return;
72  SigIntId p = sids[n / 2];
73  SigIntId *l = sids;
74  SigIntId *r = sids + n - 1;
75  while (l <= r) {
76  if (*l < p)
77  l++;
78  else if (*r > p)
79  r--;
80  else {
81  SigIntId t = *l;
82  *l = *r;
83  *r = t;
84  l++;
85  r--;
86  }
87  }
88  QuickSortSigIntId(sids, (uint32_t)(r - sids) + 1);
89  QuickSortSigIntId(l, (uint32_t)(sids + n - l));
90 }
91 
92 /**
93  * \brief run prefilter engines on a transaction
94  */
96  const SigGroupHead *sgh,
97  Packet *p,
98  const uint8_t ipproto,
99  const uint8_t flow_flags,
100  const AppProto alproto,
101  void *alstate,
102  DetectTransaction *tx)
103 {
104  /* reset rule store */
105  det_ctx->pmq.rule_id_array_cnt = 0;
106 
107  SCLogDebug("packet %" PRIu64 " tx %p progress %d tx->detect_progress %02x", PcapPacketCntGet(p),
108  tx->tx_ptr, tx->tx_progress, tx->detect_progress);
109 
110  PrefilterEngine *engine = sgh->tx_engines;
111  do {
112  // based on flow alproto, and engine, we get right tx_ptr
113  void *tx_ptr = DetectGetInnerTx(tx->tx_ptr, alproto, engine->alproto, flow_flags);
114  if (tx_ptr == NULL) {
115  // incompatible engine->alproto with flow alproto
116  goto next;
117  }
118 
119  if (engine->ctx.tx_min_progress != -1) {
120 #ifdef DEBUG
121  const char *pname = AppLayerParserGetStateNameById(ipproto, engine->alproto,
122  engine->ctx.tx_min_progress, flow_flags & (STREAM_TOSERVER | STREAM_TOCLIENT));
123  SCLogDebug("engine %p min_progress %d %s:%s", engine, engine->ctx.tx_min_progress,
124  AppProtoToString(engine->alproto), pname);
125 #endif
126  /* if engine needs tx state to be higher, break out. */
127  if (engine->ctx.tx_min_progress > tx->tx_progress)
128  break;
129  if (tx->tx_progress > engine->ctx.tx_min_progress) {
130  SCLogDebug("tx->tx_progress %u > engine->ctx.tx_min_progress %d", tx->tx_progress,
131  engine->ctx.tx_min_progress);
132 
133  /* if state value is at or beyond engine state, we can skip it. It means we ran at
134  * least once already. */
135  if (tx->detect_progress > engine->ctx.tx_min_progress) {
136  SCLogDebug("tx already marked progress as beyond engine: %u > %u",
137  tx->detect_progress, engine->ctx.tx_min_progress);
138  goto next;
139  } else {
140  SCLogDebug("tx->tx_progress %u > engine->ctx.tx_min_progress %d: "
141  "tx->detect_progress %u",
142  tx->tx_progress, engine->ctx.tx_min_progress, tx->detect_progress);
143  }
144  }
145 #ifdef DEBUG
146  uint32_t old = det_ctx->pmq.rule_id_array_cnt;
147 #endif
148  PREFILTER_PROFILING_START(det_ctx);
149  engine->cb.PrefilterTx(det_ctx, engine->pectx, p, p->flow, tx_ptr, tx->tx_id,
150  tx->tx_data_ptr, flow_flags);
151  PREFILTER_PROFILING_END(det_ctx, engine->gid);
152  SCLogDebug("engine %p min_progress %d %s:%s: results %u", engine,
153  engine->ctx.tx_min_progress, AppProtoToString(engine->alproto), pname,
154  det_ctx->pmq.rule_id_array_cnt - old);
155 
156  if (tx->tx_progress > engine->ctx.tx_min_progress && engine->is_last_for_progress &&
157  tx->tx_ptr == tx_ptr) {
158  /* track with an offset of one, so that tx->progress 0 complete is tracked
159  * as 1, progress 1 as 2, etc. This is to allow 0 to mean: nothing tracked, even
160  * though a parser may use 0 as a valid value. */
161  // tx->tx_ptr == tx_ptr ensures we do not use a dns engine progress
162  // to update a HTTP2 tx detect_progress in case of DOH2
163  tx->detect_progress = engine->ctx.tx_min_progress + 1;
164  SCLogDebug("tx->tx_progress %d engine->ctx.tx_min_progress %d "
165  "engine->is_last_for_progress %d => tx->detect_progress updated to %02x",
166  tx->tx_progress, engine->ctx.tx_min_progress, engine->is_last_for_progress,
167  tx->detect_progress);
168  }
169  } else {
170  PREFILTER_PROFILING_START(det_ctx);
171  engine->cb.PrefilterTx(det_ctx, engine->pectx, p, p->flow, tx_ptr, tx->tx_id,
172  tx->tx_data_ptr, flow_flags);
173  PREFILTER_PROFILING_END(det_ctx, engine->gid);
174  }
175  next:
176  if (engine->is_last)
177  break;
178  engine++;
179  } while (1);
180 
181  /* Sort the rule list to lets look at pmq.
182  * NOTE due to merging of 'stream' pmqs we *MAY* have duplicate entries */
183  if (likely(det_ctx->pmq.rule_id_array_cnt > 1)) {
185  QuickSortSigIntId(det_ctx->pmq.rule_id_array, det_ctx->pmq.rule_id_array_cnt);
187  }
188 }
189 
190 /** \brief invoke post-rule match "prefilter" engines
191  *
192  * Invoke prefilter engines that depend on a rule match to run.
193  * e.g. the flowbits:set prefilter that adds sids that depend on
194  * a flowbit "set" to the match array.
195  */
197  DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, Packet *p, Flow *f)
198 {
199  SCLogDebug("post-rule-match engines %p", sgh->post_rule_match_engines);
200  if (sgh->post_rule_match_engines) {
202  do {
203  SCLogDebug("running post-rule-match engine");
204  PREFILTER_PROFILING_START(det_ctx);
205  engine->cb.PrefilterPostRule(det_ctx, engine->pectx, p, f);
206  PREFILTER_PROFILING_END(det_ctx, engine->gid);
207 
208  if (engine->is_last)
209  break;
210  engine++;
211  } while (1);
212 
213  if (det_ctx->pmq.rule_id_array_cnt > 1) {
214  QuickSortSigIntId(det_ctx->pmq.rule_id_array, det_ctx->pmq.rule_id_array_cnt);
215  }
216  }
217 }
218 
220  const uint8_t flags, const SignatureMask mask)
221 {
222  SCEnter();
223 #if 0
224  /* TODO review this check */
225  SCLogDebug("sgh %p frame_engines %p", sgh, sgh->frame_engines);
226  if (p->proto == IPPROTO_TCP && sgh->frame_engines && p->flow &&
227  p->flow->alproto != ALPROTO_UNKNOWN && p->flow->alparser != NULL) {
229  PrefilterFrames(det_ctx, sgh, p, flags, p->flow->alproto);
231  }
232 #endif
233  if (sgh->pkt_engines) {
235  /* run packet engines */
236  PrefilterEngine *engine = sgh->pkt_engines;
237  do {
238  /* run engine if:
239  * mask matches
240  * no hook is used OR hook matches
241  */
242  if (((engine->ctx.pkt.mask & mask) == engine->ctx.pkt.mask) &&
243  (engine->ctx.pkt.hook == 0 || (p->pkt_hooks & BIT_U16(engine->ctx.pkt.hook)))) {
244  PREFILTER_PROFILING_START(det_ctx);
245  engine->cb.Prefilter(det_ctx, p, engine->pectx);
246  PREFILTER_PROFILING_END(det_ctx, engine->gid);
247  }
248 
249  if (engine->is_last)
250  break;
251  engine++;
252  } while (1);
254  }
255 
256  /* run payload inspecting engines */
257  if (sgh->payload_engines &&
260  {
262  PrefilterEngine *engine = sgh->payload_engines;
263  while (1) {
264  PREFILTER_PROFILING_START(det_ctx);
265  engine->cb.Prefilter(det_ctx, p, engine->pectx);
266  PREFILTER_PROFILING_END(det_ctx, engine->gid);
267 
268  if (engine->is_last)
269  break;
270  engine++;
271  }
273  }
274 
275  /* Sort the rule list to lets look at pmq.
276  * NOTE due to merging of 'stream' pmqs we *MAY* have duplicate entries */
277  if (likely(det_ctx->pmq.rule_id_array_cnt > 1)) {
279  QuickSortSigIntId(det_ctx->pmq.rule_id_array, det_ctx->pmq.rule_id_array_cnt);
281  }
282  SCReturn;
283 }
284 
286  SignatureMask mask, enum SignatureHookPkt hook, void *pectx, void (*FreeFunc)(void *pectx),
287  const char *name)
288 {
289  if (sgh == NULL || PrefilterFunc == NULL || pectx == NULL)
290  return -1;
291 
292  PrefilterEngineList *e = SCMallocAligned(sizeof(*e), CLS);
293  if (e == NULL)
294  return -1;
295  memset(e, 0x00, sizeof(*e));
296 
297  // TODO right now we represent the hook in a u8 in the prefilter engine for space reasons.
298  BUG_ON(hook >= 8);
299 
300  e->Prefilter = PrefilterFunc;
301  e->pectx = pectx;
302  e->Free = FreeFunc;
303  e->pkt_mask = mask;
304  e->pkt_hook = hook;
305 
306  if (sgh->init->pkt_engines == NULL) {
307  sgh->init->pkt_engines = e;
308  } else {
310  while (t->next != NULL) {
311  t = t->next;
312  }
313 
314  t->next = e;
315  e->id = t->id + 1;
316  }
317 
318  e->name = name;
319  e->gid = PrefilterStoreGetId(de_ctx, e->name, e->Free);
320  SCLogDebug("sgh->init->pkt_engines %p", sgh->init->pkt_engines);
321  return 0;
322 }
323 
325  PrefilterPktFn PrefilterFunc, void *pectx, void (*FreeFunc)(void *pectx), const char *name)
326 {
327  if (sgh == NULL || PrefilterFunc == NULL || pectx == NULL)
328  return -1;
329 
330  PrefilterEngineList *e = SCMallocAligned(sizeof(*e), CLS);
331  if (e == NULL)
332  return -1;
333  memset(e, 0x00, sizeof(*e));
334 
335  e->Prefilter = PrefilterFunc;
336  e->pectx = pectx;
337  e->Free = FreeFunc;
338 
339  if (sgh->init->payload_engines == NULL) {
340  sgh->init->payload_engines = e;
341  } else {
343  while (t->next != NULL) {
344  t = t->next;
345  }
346 
347  t->next = e;
348  e->id = t->id + 1;
349  }
350 
351  e->name = name;
352  e->gid = PrefilterStoreGetId(de_ctx, e->name, e->Free);
353  return 0;
354 }
355 
357  PrefilterTxFn PrefilterTxFunc, AppProto alproto, int8_t tx_min_progress, void *pectx,
358  void (*FreeFunc)(void *pectx), const char *name)
359 {
360  if (sgh == NULL || PrefilterTxFunc == NULL || pectx == NULL)
361  return -1;
362 
363  PrefilterEngineList *e = SCMallocAligned(sizeof(*e), CLS);
364  if (e == NULL)
365  return -1;
366  memset(e, 0x00, sizeof(*e));
367 
368  e->PrefilterTx = PrefilterTxFunc;
369  e->pectx = pectx;
370  e->alproto = alproto;
371  e->tx_min_progress = tx_min_progress;
372  e->Free = FreeFunc;
373 
374  if (sgh->init->tx_engines == NULL) {
375  sgh->init->tx_engines = e;
376  } else {
378  while (t->next != NULL) {
379  t = t->next;
380  }
381 
382  t->next = e;
383  e->id = t->id + 1;
384  }
385 
386  e->name = name;
387  e->gid = PrefilterStoreGetId(de_ctx, e->name, e->Free);
388  return 0;
389 }
390 
392  PrefilterFrameFn PrefilterFrameFunc, AppProto alproto, uint8_t frame_type, void *pectx,
393  void (*FreeFunc)(void *pectx), const char *name)
394 {
395  if (sgh == NULL || PrefilterFrameFunc == NULL || pectx == NULL)
396  return -1;
397 
398  PrefilterEngineList *e = SCMallocAligned(sizeof(*e), CLS);
399  if (e == NULL)
400  return -1;
401  memset(e, 0x00, sizeof(*e));
402 
403  e->frame_type = frame_type;
404  e->alproto = alproto;
405  e->PrefilterFrame = PrefilterFrameFunc;
406  e->pectx = pectx;
407  e->Free = FreeFunc;
408 
409  if (sgh->init->frame_engines == NULL) {
410  sgh->init->frame_engines = e;
411  } else {
413  while (t->next != NULL) {
414  t = t->next;
415  }
416 
417  t->next = e;
418  e->id = t->id + 1;
419  }
420 
421  e->name = name;
422  e->gid = PrefilterStoreGetId(de_ctx, e->name, e->Free);
423  return 0;
424 }
425 
427  void (*PrefilterPostRuleFunc)(
428  DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f),
429  void *pectx, void (*FreeFunc)(void *pectx), const char *name)
430 {
431  if (sgh == NULL || PrefilterPostRuleFunc == NULL || pectx == NULL)
432  return -1;
433 
434  PrefilterEngineList *e = SCMallocAligned(sizeof(*e), CLS);
435  if (e == NULL)
436  return -1;
437  memset(e, 0x00, sizeof(*e));
438  e->PrefilterPostRule = PrefilterPostRuleFunc;
439  e->pectx = pectx;
440  e->Free = FreeFunc;
441 
442  if (sgh->init->post_rule_match_engines == NULL) {
443  sgh->init->post_rule_match_engines = e;
444  } else {
446  while (t->next != NULL) {
447  t = t->next;
448  }
449 
450  t->next = e;
451  e->id = t->id + 1;
452  }
453 
454  e->name = name;
455  e->gid = PrefilterStoreGetId(de_ctx, e->name, e->Free);
456  return 0;
457 }
458 
459 static void PrefilterFreeEngineList(PrefilterEngineList *e)
460 {
461  if (e->Free && e->pectx) {
462  e->Free(e->pectx);
463  }
464  SCFreeAligned(e);
465 }
466 
468 {
469  PrefilterEngineList *t = list;
470 
471  while (t != NULL) {
473  PrefilterFreeEngineList(t);
474  t = next;
475  }
476 }
477 
478 static void PrefilterFreeEngines(const DetectEngineCtx *de_ctx, PrefilterEngine *list)
479 {
480  PrefilterEngine *t = list;
481 
482  while (1) {
483  const PrefilterStore *s = PrefilterStoreGetStore(de_ctx, t->gid);
484  if (s && s->FreeFunc && t->pectx) {
485  s->FreeFunc(t->pectx);
486  }
487 
488  if (t->is_last)
489  break;
490  t++;
491  }
492  SCFreeAligned(list);
493 }
494 
496 {
497  if (sgh->pkt_engines) {
498  PrefilterFreeEngines(de_ctx, sgh->pkt_engines);
499  sgh->pkt_engines = NULL;
500  }
501  if (sgh->payload_engines) {
502  PrefilterFreeEngines(de_ctx, sgh->payload_engines);
503  sgh->payload_engines = NULL;
504  }
505  if (sgh->tx_engines) {
506  PrefilterFreeEngines(de_ctx, sgh->tx_engines);
507  sgh->tx_engines = NULL;
508  }
509  if (sgh->frame_engines) {
510  PrefilterFreeEngines(de_ctx, sgh->frame_engines);
511  sgh->frame_engines = NULL;
512  }
513  if (sgh->post_rule_match_engines) {
514  PrefilterFreeEngines(de_ctx, sgh->post_rule_match_engines);
515  sgh->post_rule_match_engines = NULL;
516  }
517 }
518 
519 static int PrefilterSetupRuleGroupSortHelper(const void *a, const void *b)
520 {
521  const PrefilterEngine *s0 = a;
522  const PrefilterEngine *s1 = b;
523  if (s1->ctx.tx_min_progress == s0->ctx.tx_min_progress) {
524  if (s1->alproto == s0->alproto) {
525  return s0->local_id > s1->local_id ? 1 : -1;
526  } else {
527  return s0->alproto > s1->alproto ? 1 : -1;
528  }
529  } else {
530  return s0->ctx.tx_min_progress > s1->ctx.tx_min_progress ? 1 : -1;
531  }
532 }
533 
534 /** prefilter engine data for the non-prefilter engine for the prefilter API */
536  uint32_t sid : 30;
537  uint32_t type : 2; /**< type for `value` field below: 0:alproto 1:dport 2:dsize */
538  uint16_t value;
539  /* since we have 2 more bytes available due to padding, we can add some additional
540  * filters here. */
541  union {
542  struct {
544  } pkt;
545  struct {
546  /* filter for frame type */
547  uint8_t type;
548  } frame;
549  struct {
550  uint8_t foo; // TODO unused
551  } app;
552  };
553 };
554 
556  uint32_t size;
557  struct PrefilterNonPFDataSig array[];
558 };
559 
561  uint32_t size;
562  uint32_t array[];
563 };
564 
565 /** \internal
566  * \brief wrapper for use in APIs */
567 static void PrefilterNonPFDataFree(void *data)
568 {
569  SCFree(data);
570 }
571 
572 static void PrefilterTxNonPF(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f,
573  void *tx, const uint64_t tx_id, const AppLayerTxData *tx_data, const uint8_t flags)
574 {
575  const struct PrefilterNonPFDataTx *data = (const struct PrefilterNonPFDataTx *)pectx;
576  SCLogDebug("adding %u sids", data->size);
577  PrefilterAddSids(&det_ctx->pmq, data->array, data->size);
578 }
579 
580 #ifdef NONPF_PKT_STATS
581 static thread_local uint64_t prefilter_pkt_nonpf_called = 0;
582 static thread_local uint64_t prefilter_pkt_nonpf_mask_fail = 0;
583 static thread_local uint64_t prefilter_pkt_nonpf_alproto_fail = 0;
584 static thread_local uint64_t prefilter_pkt_nonpf_dsize_fail = 0;
585 static thread_local uint64_t prefilter_pkt_nonpf_dport_fail = 0;
586 static thread_local uint64_t prefilter_pkt_nonpf_sids = 0;
587 #define NONPF_PKT_STATS_INCR(s) (s)++
588 #else
589 #define NONPF_PKT_STATS_INCR(s)
590 #endif
591 
593 {
594 #ifdef NONPF_PKT_STATS
595  SCLogDebug("prefilter non-pf: called:%" PRIu64 ", mask_fail:%" PRIu64 ", alproto fail:%" PRIu64
596  ", dport fail:%" PRIu64 ", dsize fail:%" PRIu64 ", sids:%" PRIu64
597  ", avg sids:%" PRIu64,
598  prefilter_pkt_nonpf_called, prefilter_pkt_nonpf_mask_fail,
599  prefilter_pkt_nonpf_alproto_fail, prefilter_pkt_nonpf_dport_fail,
600  prefilter_pkt_nonpf_dsize_fail, prefilter_pkt_nonpf_sids,
601  prefilter_pkt_nonpf_called ? prefilter_pkt_nonpf_sids / prefilter_pkt_nonpf_called : 0);
602 #endif
603 }
604 
605 static void PrefilterPktNonPF(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
606 {
607  const uint16_t alproto = p->flow ? p->flow->alproto : ALPROTO_UNKNOWN;
608  const SignatureMask mask = p->sig_mask;
609  const struct PrefilterNonPFData *data = (const struct PrefilterNonPFData *)pectx;
610  SCLogDebug("adding %u sids", data->size);
611  NONPF_PKT_STATS_INCR(prefilter_pkt_nonpf_called);
612  for (uint32_t i = 0; i < data->size; i++) {
613  const struct PrefilterNonPFDataSig *ds = &data->array[i];
614  const SignatureMask rule_mask = ds->pkt.sig_mask;
615  if ((rule_mask & mask) == rule_mask) {
616  switch (ds->type) {
617  case 0:
618  if (ds->value == ALPROTO_UNKNOWN || AppProtoEquals(ds->value, alproto)) {
619  const uint32_t sid = ds->sid;
620  PrefilterAddSids(&det_ctx->pmq, &sid, 1);
621  NONPF_PKT_STATS_INCR(prefilter_pkt_nonpf_sids);
622  } else {
623  NONPF_PKT_STATS_INCR(prefilter_pkt_nonpf_alproto_fail);
624  }
625  break;
626  case 1:
627  if (ds->value == p->dp) {
628  const uint32_t sid = ds->sid;
629  PrefilterAddSids(&det_ctx->pmq, &sid, 1);
630  NONPF_PKT_STATS_INCR(prefilter_pkt_nonpf_sids);
631  } else {
632  NONPF_PKT_STATS_INCR(prefilter_pkt_nonpf_dport_fail);
633  }
634  break;
635  case 2:
636  if (ds->value == p->payload_len) {
637  const uint32_t sid = ds->sid;
638  PrefilterAddSids(&det_ctx->pmq, &sid, 1);
639  NONPF_PKT_STATS_INCR(prefilter_pkt_nonpf_sids);
640  } else {
641  NONPF_PKT_STATS_INCR(prefilter_pkt_nonpf_dsize_fail);
642  }
643  break;
644  }
645  } else {
646  NONPF_PKT_STATS_INCR(prefilter_pkt_nonpf_mask_fail);
647  }
648  }
649 }
650 
651 static void PrefilterPktNonPFHookFlowStart(
652  DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
653 {
655  PrefilterPktNonPF(det_ctx, p, pectx);
656  }
657 }
658 
659 /** \internal
660  * \brief engine to select the non-prefilter rules for frames
661  * Checks the alproto and type as well.
662  * Direction needs no checking as the rule groups are per direction. */
663 static void PrefilterFrameNonPF(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p,
664  const Frames *frames, const Frame *frame)
665 {
666  DEBUG_VALIDATE_BUG_ON(p->flow == NULL);
667  const uint16_t alproto = p->flow->alproto;
668  const struct PrefilterNonPFData *data = (const struct PrefilterNonPFData *)pectx;
669  SCLogDebug("adding %u sids", data->size);
670  for (uint32_t i = 0; i < data->size; i++) {
671  const struct PrefilterNonPFDataSig *ds = &data->array[i];
672  if (ds->frame.type == frame->type &&
673  (ds->value == ALPROTO_UNKNOWN || AppProtoEquals(ds->value, alproto))) {
674  const uint32_t sid = ds->sid;
675  PrefilterAddSids(&det_ctx->pmq, &sid, 1);
676  }
677  }
678 }
679 
680 /* helper funcs for the non prefilter names hash */
681 
682 static uint32_t NonPFNamesHash(HashTable *h, void *data, uint16_t _len)
683 {
684  const char *str = data;
685  return StringHashDjb2((const uint8_t *)str, (uint16_t)strlen(str)) % h->array_size;
686 }
687 
688 static char NonPFNamesCompare(void *data1, uint16_t _len1, void *data2, uint16_t len2)
689 {
690  const char *s1 = data1;
691  const char *s2 = data2;
692  return StringHashCompareFunc(data1, (uint16_t)strlen(s1), data2, (uint16_t)strlen(s2));
693 }
694 
695 static void NonPFNamesFree(void *data)
696 {
697  SCFree(data);
698 }
699 
700 /* helper funcs for assembling non-prefilter engines */
701 
702 struct TxNonPFData {
704  int dir; /**< 0: toserver, 1: toclient */
705  uint8_t progress; /**< progress state value to register at */
706  int sig_list; /**< special handling: normally 0, but for special cases (app-layer-state,
707  app-layer-event) use the list id to create separate engines */
708  uint32_t sigs_cnt;
710  const char *engine_name; /**< pointer to name owned by DetectEngineCtx::non_pf_engine_names */
711 };
712 
713 static uint32_t TxNonPFHash(HashListTable *h, void *data, uint16_t _len)
714 {
715  struct TxNonPFData *d = data;
716  return (d->alproto + d->progress + d->dir + d->sig_list) % h->array_size;
717 }
718 
719 static char TxNonPFCompare(void *data1, uint16_t _len1, void *data2, uint16_t len2)
720 {
721  struct TxNonPFData *d1 = data1;
722  struct TxNonPFData *d2 = data2;
723  return d1->alproto == d2->alproto && d1->progress == d2->progress && d1->dir == d2->dir &&
724  d1->sig_list == d2->sig_list;
725 }
726 
727 static void TxNonPFFree(void *data)
728 {
729  struct TxNonPFData *d = data;
730  SCFree(d->sigs);
731  SCFree(d);
732 }
733 
734 static int TxNonPFAddSig(DetectEngineCtx *de_ctx, HashListTable *tx_engines_hash,
735  const AppProto alproto, const int dir, const uint8_t progress, const int sig_list,
736  const char *name, const Signature *s)
737 {
738  const uint32_t max_sids = DetectEngineGetMaxSigId(de_ctx);
739 
740  struct TxNonPFData lookup = {
741  .alproto = alproto,
742  .dir = dir,
743  .progress = progress,
744  .sig_list = sig_list,
745  .sigs_cnt = 0,
746  .sigs = NULL,
747  .engine_name = NULL,
748  };
749  struct TxNonPFData *e = HashListTableLookup(tx_engines_hash, &lookup, 0);
750  if (e != NULL) {
751  bool found = false;
752  // avoid adding same sid multiple times
753  for (uint32_t y = 0; y < e->sigs_cnt; y++) {
754  if (e->sigs[y].sid == s->iid) {
755  found = true;
756  break;
757  }
758  }
759  if (!found) {
760  BUG_ON(e->sigs_cnt == max_sids);
761  e->sigs[e->sigs_cnt].sid = s->iid;
762  e->sigs[e->sigs_cnt].value = alproto;
763  e->sigs_cnt++;
764  }
765  return 0;
766  }
767 
768  struct TxNonPFData *add = SCCalloc(1, sizeof(*add));
769  if (add == NULL) {
770  return -1;
771  }
772  add->dir = dir;
773  add->alproto = alproto;
774  add->progress = progress;
775  add->sig_list = sig_list;
776  add->sigs = SCCalloc(max_sids, sizeof(struct PrefilterNonPFDataSig));
777  if (add->sigs == NULL) {
778  SCFree(add);
779  return -1;
780  }
781  add->sigs_cnt = 0;
782  add->sigs[add->sigs_cnt].sid = s->iid;
783  add->sigs[add->sigs_cnt].value = alproto;
784  add->sigs_cnt++;
785 
786  char engine_name[128];
787  snprintf(engine_name, sizeof(engine_name), "%s:%s:non_pf:%s", AppProtoToString(alproto), name,
788  dir == 0 ? "toserver" : "toclient");
789  char *engine_name_heap = SCStrdup(engine_name);
790  if (engine_name_heap == NULL) {
791  SCFree(add->sigs);
792  SCFree(add);
793  return -1;
794  }
795  int result = HashTableAdd(
796  de_ctx->non_pf_engine_names, engine_name_heap, (uint16_t)strlen(engine_name_heap));
797  if (result != 0) {
798  SCFree(add->sigs);
799  SCFree(add);
800  return -1;
801  }
802 
803  add->engine_name = engine_name_heap;
804  SCLogDebug("engine_name_heap %s", engine_name_heap);
805 
806  int ret = HashListTableAdd(tx_engines_hash, add, 0);
807  if (ret != 0) {
808  SCFree(add->sigs);
809  SCFree(add);
810  return -1;
811  }
812 
813  return 0;
814 }
815 
816 /** \internal
817  * \brief setup non-prefilter rules in special "non-prefilter" engines that are registered in the
818  * prefilter logic.
819  *
820  * \retval 0 ok
821  * \retval -1 error
822  */
823 static int SetupNonPrefilter(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
824 {
825  const uint32_t max_sids = DetectEngineGetMaxSigId(de_ctx);
826  SCLogDebug("max_sids %u", max_sids);
827  struct PrefilterNonPFDataSig *pkt_non_pf_array = SCCalloc(max_sids, sizeof(*pkt_non_pf_array));
828  if (pkt_non_pf_array == NULL) {
829  return -1;
830  }
831  uint32_t pkt_non_pf_array_size = 0;
832  struct PrefilterNonPFDataSig *frame_non_pf_array =
833  SCCalloc(max_sids, sizeof(*frame_non_pf_array));
834  if (frame_non_pf_array == NULL) {
835  SCFree(pkt_non_pf_array);
836  return -1;
837  }
838  uint32_t frame_non_pf_array_size = 0;
839 
840  struct PrefilterNonPFDataSig *pkt_hook_flow_start_non_pf_array =
841  SCCalloc(max_sids, sizeof(*pkt_hook_flow_start_non_pf_array));
842  if (pkt_hook_flow_start_non_pf_array == NULL) {
843  SCFree(pkt_non_pf_array);
844  SCFree(frame_non_pf_array);
845  return -1;
846  }
847  uint32_t pkt_hook_flow_start_non_pf_array_size = 0;
848  SignatureMask pkt_hook_flow_start_mask = 0;
849  bool pkt_hook_flow_start_mask_init = false;
850 
851  HashListTable *tx_engines_hash =
852  HashListTableInit(256, TxNonPFHash, TxNonPFCompare, TxNonPFFree);
853  if (tx_engines_hash == NULL) {
854  SCFree(pkt_non_pf_array);
855  SCFree(pkt_hook_flow_start_non_pf_array);
856  SCFree(frame_non_pf_array);
857  return -1;
858  }
859 
860  if (de_ctx->non_pf_engine_names == NULL) {
862  HashTableInit(512, NonPFNamesHash, NonPFNamesCompare, NonPFNamesFree);
863  if (de_ctx->non_pf_engine_names == NULL) {
864  SCFree(pkt_non_pf_array);
865  SCFree(pkt_hook_flow_start_non_pf_array);
866  SCFree(frame_non_pf_array);
867  HashListTableFree(tx_engines_hash);
868  return -1;
869  }
870  }
871 
872  SignatureMask pkt_mask = 0;
873  bool pkt_mask_init = false;
874 #ifdef NONPF_PKT_STATS
875  uint32_t nonpf_pkt_alproto = 0;
876  uint32_t nonpf_pkt_dsize = 0;
877  uint32_t nonpf_pkt_dport = 0;
878 #endif
879  const int app_events_list_id = DetectBufferTypeGetByName("app-layer-events");
880  SCLogDebug("app_events_list_id %d", app_events_list_id);
881  const int app_state_list_id = DetectBufferTypeGetByName("app-layer-state");
882  SCLogDebug("app_state_list_id %d", app_state_list_id);
883  for (uint32_t sig = 0; sig < sgh->init->sig_cnt; sig++) {
884  Signature *s = sgh->init->match_array[sig];
885  if (s == NULL)
886  continue;
887  SCLogDebug("checking sid %u for non-prefilter", s->id);
888  if (s->init_data->mpm_sm != NULL && (s->flags & SIG_FLAG_MPM_NEG) == 0)
889  continue;
890  if (s->init_data->prefilter_sm != NULL)
891  continue;
893  continue;
894  SCLogDebug("setting up sid %u for non-prefilter", s->id);
895 
896  uint8_t frame_type = 0; /**< only a single type per rule */
897  bool tx_non_pf = false;
898  bool frame_non_pf = false;
899  bool pkt_non_pf = false;
900 
903  // TODO code duplication with regular pkt case below
904 
905  /* for pkt non prefilter, we have some space in the structure,
906  * so we can squeeze another filter */
907  uint8_t type;
908  uint16_t value;
909  if ((s->flags & SIG_FLAG_DSIZE) && s->dsize_mode == DETECT_UINT_EQ) {
910  SCLogDebug("dsize extra match");
911  type = 2;
912  value = s->dsize_low;
913  } else if (s->dp != NULL && s->dp->next == NULL && s->dp->port == s->dp->port2) {
914  type = 1;
915  value = s->dp->port;
916  } else {
917  type = 0;
918  value = s->alproto;
919  }
920  pkt_hook_flow_start_non_pf_array[pkt_hook_flow_start_non_pf_array_size].sid = s->iid;
921  pkt_hook_flow_start_non_pf_array[pkt_hook_flow_start_non_pf_array_size].value = value;
922  pkt_hook_flow_start_non_pf_array[pkt_hook_flow_start_non_pf_array_size].type = type;
923  pkt_hook_flow_start_non_pf_array[pkt_hook_flow_start_non_pf_array_size].pkt.sig_mask =
924  s->mask;
925  pkt_hook_flow_start_non_pf_array_size++;
926 
927  if (pkt_hook_flow_start_mask_init) {
928  pkt_hook_flow_start_mask &= s->mask;
929  } else {
930  pkt_hook_flow_start_mask = s->mask;
931  pkt_hook_flow_start_mask_init = true;
932  }
933 
934  SCLogDebug("flow_start hook");
935  continue; // done for this sig
936  }
937 
938  /* special case: insert sigs at hook before Signature::app_progress_hook for the HOOK_LTE
939  * case: we need a addition per hook to make sure that the sig is called when needed. For
940  * hook 0 it could have a preceding rule that makes sure this sig isn't triggered, but then
941  * for hook 1 we would need to be called. */
942  if (s->flags & SIG_FLAG_FW_HOOK_LTE) {
943  for (uint8_t state = 0; state < s->app_progress_hook; state++) {
944  SCLogDebug("handle HOOK %u LTE", state);
945  const int dir = (s->flags & SIG_FLAG_TOSERVER) ? 0 : 1;
946  const char *pname = DetectEngineAppHookToName(
947  s->alproto, state, dir == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT);
948  if (pname == NULL) {
949  goto error;
950  }
951  const int sm_list = DetectEngineAppHookToSmlist(
952  s->alproto, state, dir == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT);
953  if (TxNonPFAddSig(de_ctx, tx_engines_hash, s->alproto, dir, state, sm_list, pname,
954  s) != 0) {
955  goto error;
956  }
957  tx_non_pf = true;
958  }
959  }
960 
961  for (uint32_t x = 0; x < s->init_data->buffer_index; x++) {
962  const int list_id = s->init_data->buffers[x].id;
964  if (buf == NULL)
965  continue;
966  /* for now, exclude app-layer-events, as they are not tied to a specific
967  * progress value like other keywords. */
968  SCLogDebug("list_id %d buf %p", list_id, buf);
969  if (list_id == app_events_list_id)
970  continue;
971  if (buf->packet) {
972  SCLogDebug("packet buf");
973  /* packet is handled below */
974  pkt_non_pf = true;
975  } else if (buf->frame) {
977  f != NULL; f = f->next) {
978  if (!((((s->flags & SIG_FLAG_TOSERVER) != 0 && f->dir == 0) ||
979  ((s->flags & SIG_FLAG_TOCLIENT) != 0 && f->dir == 1)) &&
980  list_id == (int)f->sm_list &&
981  AppProtoEquals(s->alproto, f->alproto)))
982  continue;
983 
984  SCLogDebug("frame '%s' type %u", buf->name, f->type);
985  frame_type = f->type;
986  frame_non_pf = true;
987 
988  frame_non_pf_array[frame_non_pf_array_size].sid = s->iid;
989  frame_non_pf_array[frame_non_pf_array_size].value = s->alproto;
990  frame_non_pf_array[frame_non_pf_array_size].frame.type = frame_type;
991  frame_non_pf_array_size++;
992  break;
993  }
994 
995  } else {
996  SCLogDebug("x %u list_id %d", x, list_id);
998  app != NULL; app = app->next) {
999  SCLogDebug("app %p proto %s list_d %d sig dir %0x", app,
1000  AppProtoToString(app->alproto), app->sm_list,
1002 
1003  /* skip if:
1004  * - not in our dir
1005  * - not our list
1006  * - app proto mismatch. Both sig and app can have proto or unknown */
1007  if (!((((s->flags & SIG_FLAG_TOSERVER) != 0 && app->dir == 0) ||
1008  ((s->flags & SIG_FLAG_TOCLIENT) != 0 && app->dir == 1)) &&
1009  list_id == (int)app->sm_list &&
1010  (s->alproto == ALPROTO_UNKNOWN || app->alproto == ALPROTO_UNKNOWN ||
1011  AppProtoEquals(s->alproto, app->alproto))))
1012  continue;
1013 
1014  int sig_list = 0;
1015  if (list_id == app_state_list_id)
1016  sig_list = app_state_list_id;
1017  if (TxNonPFAddSig(de_ctx, tx_engines_hash, app->alproto, app->dir,
1018  app->progress, sig_list, buf->name, s) != 0) {
1019  goto error;
1020  }
1021  tx_non_pf = true;
1022  }
1023  }
1024  }
1025  /* handle hook only rules */
1026  if (!tx_non_pf && s->init_data->hook.type == SIGNATURE_HOOK_TYPE_APP) {
1027  const int dir = (s->flags & SIG_FLAG_TOSERVER) ? 0 : 1;
1028  const char *pname = AppLayerParserGetStateNameById(IPPROTO_TCP, // TODO
1029  s->alproto, s->init_data->hook.t.app.app_progress,
1030  dir == 0 ? STREAM_TOSERVER : STREAM_TOCLIENT);
1031 
1032  if (TxNonPFAddSig(de_ctx, tx_engines_hash, s->alproto, dir,
1033  s->init_data->hook.t.app.app_progress, s->init_data->hook.sm_list, pname,
1034  s) != 0) {
1035  goto error;
1036  }
1037  tx_non_pf = true;
1038  }
1039  /* mark as prefiltered as the sig is now part of a engine */
1040  // s->flags |= SIG_FLAG_PREFILTER;
1041  // TODO doesn't work for sigs that are in multiple sgh's
1042 
1043  /* default to pkt if there was no tx or frame match */
1044  if (!(tx_non_pf || frame_non_pf)) {
1045  if (!pkt_non_pf) {
1046  SCLogDebug("not frame, not tx, so pkt");
1047  }
1048  pkt_non_pf = true;
1049  }
1050 
1051  SCLogDebug("setting up sid %u for non-prefilter: %s", s->id,
1052  tx_non_pf ? "tx engine" : (frame_non_pf ? "frame engine" : "pkt engine"));
1053 
1054  if (pkt_non_pf) {
1055  /* for pkt non prefilter, we have some space in the structure,
1056  * so we can squeeze another filter */
1057  uint8_t type;
1058  uint16_t value;
1059  if ((s->flags & SIG_FLAG_DSIZE) && s->dsize_mode == DETECT_UINT_EQ) {
1060  SCLogDebug("dsize extra match");
1061  type = 2;
1062  value = s->dsize_low;
1063 #ifdef NONPF_PKT_STATS
1064  nonpf_pkt_dsize++;
1065 #endif
1066  } else if (s->dp != NULL && s->dp->next == NULL && s->dp->port == s->dp->port2) {
1067  type = 1;
1068  value = s->dp->port;
1069 #ifdef NONPF_PKT_STATS
1070  nonpf_pkt_dport++;
1071 #endif
1072  } else {
1073  type = 0;
1074  value = s->alproto;
1075 #ifdef NONPF_PKT_STATS
1076  nonpf_pkt_alproto++;
1077 #endif
1078  }
1079 
1080  pkt_non_pf_array[pkt_non_pf_array_size].sid = s->iid;
1081  pkt_non_pf_array[pkt_non_pf_array_size].value = value;
1082  pkt_non_pf_array[pkt_non_pf_array_size].type = type;
1083  pkt_non_pf_array[pkt_non_pf_array_size].pkt.sig_mask = s->mask;
1084  pkt_non_pf_array_size++;
1085 
1086  if (pkt_mask_init) {
1087  pkt_mask &= s->mask;
1088  } else {
1089  pkt_mask = s->mask;
1090  pkt_mask_init = true;
1091  }
1092  SCLogDebug("s->id %u added", s->id);
1093  }
1094  }
1095 
1096  /* for each unique sig set, add an engine */
1097  for (HashListTableBucket *b = HashListTableGetListHead(tx_engines_hash); b != NULL;
1098  b = HashListTableGetListNext(b)) {
1099  struct TxNonPFData *t = HashListTableGetListData(b);
1100  SCLogDebug("%s engine for %s hook %d has %u non-pf sigs",
1101  t->dir == 0 ? "toserver" : "toclient", AppProtoToString(t->alproto), t->progress,
1102  t->sigs_cnt);
1103 
1104  if (((sgh->init->direction & SIG_FLAG_TOSERVER) && t->dir == 1) ||
1105  ((sgh->init->direction & SIG_FLAG_TOCLIENT) && t->dir == 0)) {
1106  SCLogDebug("skipped");
1107  continue;
1108  }
1109 
1110  /* register special progress value to indicate we need to run it all the time */
1111  DEBUG_VALIDATE_BUG_ON(t->progress > INT8_MAX);
1112  int8_t engine_progress = (int8_t)t->progress;
1113  if (t->sig_list == app_state_list_id) {
1114  SCLogDebug("engine %s for state list", t->engine_name);
1115  engine_progress = -1;
1116  }
1117 
1118  struct PrefilterNonPFDataTx *data =
1119  SCCalloc(1, sizeof(*data) + t->sigs_cnt * sizeof(data->array[0]));
1120  if (data == NULL)
1121  goto error;
1122  data->size = t->sigs_cnt;
1123  for (uint32_t i = 0; i < t->sigs_cnt; i++) {
1124  data->array[i] = t->sigs[i].sid;
1125  }
1126  if (PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxNonPF, t->alproto, engine_progress,
1127  (void *)data, PrefilterNonPFDataFree, t->engine_name) < 0) {
1128  SCFree(data);
1129  goto error;
1130  }
1131  }
1132  HashListTableFree(tx_engines_hash);
1133  tx_engines_hash = NULL;
1134 
1135  if (pkt_non_pf_array_size) {
1136  SCLogDebug("pkt_non_pf_array_size %u", pkt_non_pf_array_size);
1137  struct PrefilterNonPFData *data =
1138  SCCalloc(1, sizeof(*data) + pkt_non_pf_array_size * sizeof(data->array[0]));
1139  if (data == NULL)
1140  goto error;
1141  data->size = pkt_non_pf_array_size;
1142  memcpy((uint8_t *)&data->array, pkt_non_pf_array,
1143  pkt_non_pf_array_size * sizeof(data->array[0]));
1144  enum SignatureHookPkt hook = SIGNATURE_HOOK_PKT_NOT_SET; // TODO review
1145  if (PrefilterAppendEngine(de_ctx, sgh, PrefilterPktNonPF, pkt_mask, hook, (void *)data,
1146  PrefilterNonPFDataFree, "packet:non_pf") < 0) {
1147  SCFree(data);
1148  goto error;
1149  }
1150  }
1151  if (pkt_hook_flow_start_non_pf_array_size) {
1152  struct PrefilterNonPFData *data = SCCalloc(
1153  1, sizeof(*data) + pkt_hook_flow_start_non_pf_array_size * sizeof(data->array[0]));
1154  if (data == NULL)
1155  goto error;
1156  data->size = pkt_hook_flow_start_non_pf_array_size;
1157  memcpy((uint8_t *)&data->array, pkt_hook_flow_start_non_pf_array,
1158  pkt_hook_flow_start_non_pf_array_size * sizeof(data->array[0]));
1159  SCLogDebug("packet:flow_start:non_pf added with %u rules", data->size);
1161  if (PrefilterAppendEngine(de_ctx, sgh,
1162  PrefilterPktNonPFHookFlowStart, // TODO no longer needed to have a dedicated
1163  // callback
1164  pkt_hook_flow_start_mask, hook, (void *)data, PrefilterNonPFDataFree,
1165  "packet:flow_start:non_pf") < 0) {
1166  SCFree(data);
1167  goto error;
1168  }
1169  }
1170  if (frame_non_pf_array_size) {
1171  SCLogDebug("%u frame non-pf sigs", frame_non_pf_array_size);
1172  struct PrefilterNonPFData *data =
1173  SCCalloc(1, sizeof(*data) + frame_non_pf_array_size * sizeof(data->array[0]));
1174  if (data == NULL)
1175  goto error;
1176  data->size = frame_non_pf_array_size;
1177  memcpy((uint8_t *)&data->array, frame_non_pf_array,
1178  frame_non_pf_array_size * sizeof(data->array[0]));
1179  if (PrefilterAppendFrameEngine(de_ctx, sgh, PrefilterFrameNonPF, ALPROTO_UNKNOWN,
1180  FRAME_ANY_TYPE, (void *)data, PrefilterNonPFDataFree, "frame:non_pf") < 0) {
1181  SCFree(data);
1182  goto error;
1183  }
1184  }
1185 
1186  SCFree(pkt_hook_flow_start_non_pf_array);
1187  pkt_hook_flow_start_non_pf_array = NULL;
1188  SCFree(pkt_non_pf_array);
1189  pkt_non_pf_array = NULL;
1190  SCFree(frame_non_pf_array);
1191  frame_non_pf_array = NULL;
1192  return 0;
1193 
1194 error:
1195  if (tx_engines_hash) {
1196  HashListTableFree(tx_engines_hash);
1197  }
1198  SCFree(pkt_hook_flow_start_non_pf_array);
1199  SCFree(pkt_non_pf_array);
1200  SCFree(frame_non_pf_array);
1201  return -1;
1202 }
1203 
1205 {
1206  int r = PatternMatchPrepareGroup(de_ctx, sgh);
1207  if (r != 0) {
1208  FatalError("failed to set up pattern matching");
1209  }
1210 
1211  /* set up engines if needed - when prefilter is set to auto we run
1212  * all engines, otherwise only those that have been forced by the
1213  * prefilter keyword. */
1215  for (int i = 0; i < DETECT_TBLSIZE; i++) {
1216  if (sigmatch_table[i].SetupPrefilter != NULL &&
1217  (setting == DETECT_PREFILTER_AUTO || de_ctx->sm_types_prefilter[i])) {
1219  }
1220  }
1221 
1222  if (SetupNonPrefilter(de_ctx, sgh) != 0) {
1223  return -1;
1224  }
1225 
1226  /* we have lists of engines in sgh->init now. Lets setup the
1227  * match arrays */
1228  PrefilterEngineList *el;
1229  if (sgh->init->pkt_engines != NULL) {
1230  SCLogDebug("for %p we have %p", sgh, sgh->init->pkt_engines);
1231  uint32_t cnt = 0;
1232  for (el = sgh->init->pkt_engines ; el != NULL; el = el->next) {
1233  cnt++;
1234  }
1235  SCLogDebug("cnt %u", cnt);
1236  sgh->pkt_engines = SCMallocAligned(cnt * sizeof(PrefilterEngine), CLS);
1237  if (sgh->pkt_engines == NULL) {
1238  return -1;
1239  }
1240  memset(sgh->pkt_engines, 0x00, (cnt * sizeof(PrefilterEngine)));
1241 
1242  PrefilterEngine *e = sgh->pkt_engines;
1243  for (el = sgh->init->pkt_engines ; el != NULL; el = el->next) {
1244  e->local_id = el->id;
1245  e->cb.Prefilter = el->Prefilter;
1246  e->ctx.pkt.mask = el->pkt_mask;
1247  // TODO right now we represent the hook in a u8 in the prefilter engine for space
1248  // reasons.
1249  BUG_ON(el->pkt_hook >= 8);
1250  e->ctx.pkt.hook = (uint8_t)el->pkt_hook;
1251  e->pectx = el->pectx;
1252  el->pectx = NULL; // e now owns the ctx
1253  e->gid = el->gid;
1254  if (el->next == NULL) {
1255  e->is_last = true;
1256  }
1257  e++;
1258  }
1259  }
1260  if (sgh->init->payload_engines != NULL) {
1261  uint32_t cnt = 0;
1262  for (el = sgh->init->payload_engines ; el != NULL; el = el->next) {
1263  cnt++;
1264  }
1266  if (sgh->payload_engines == NULL) {
1267  return -1;
1268  }
1269  memset(sgh->payload_engines, 0x00, (cnt * sizeof(PrefilterEngine)));
1270 
1271  PrefilterEngine *e = sgh->payload_engines;
1272  for (el = sgh->init->payload_engines ; el != NULL; el = el->next) {
1273  e->local_id = el->id;
1274  e->cb.Prefilter = el->Prefilter;
1275  e->ctx.pkt.mask = el->pkt_mask;
1276  // TODO right now we represent the hook in a u8 in the prefilter engine for space
1277  // reasons.
1278  BUG_ON(el->pkt_hook >= 8);
1279  e->ctx.pkt.hook = (uint8_t)el->pkt_hook;
1280  e->pectx = el->pectx;
1281  el->pectx = NULL; // e now owns the ctx
1282  e->gid = el->gid;
1283  if (el->next == NULL) {
1284  e->is_last = true;
1285  }
1286  e++;
1287  }
1288  }
1289  if (sgh->init->tx_engines != NULL) {
1290  uint32_t cnt = 0;
1291  for (el = sgh->init->tx_engines ; el != NULL; el = el->next) {
1292  cnt++;
1293  }
1294  sgh->tx_engines = SCMallocAligned(cnt * sizeof(PrefilterEngine), CLS);
1295  if (sgh->tx_engines == NULL) {
1296  return -1;
1297  }
1298  memset(sgh->tx_engines, 0x00, (cnt * sizeof(PrefilterEngine)));
1299 
1300  uint16_t local_id = 0;
1301  PrefilterEngine *e = sgh->tx_engines;
1302  for (el = sgh->init->tx_engines ; el != NULL; el = el->next) {
1303  e->local_id = local_id++;
1304  e->alproto = el->alproto;
1306  e->cb.PrefilterTx = el->PrefilterTx;
1307  e->pectx = el->pectx;
1308  el->pectx = NULL; // e now owns the ctx
1309  e->gid = el->gid;
1310  e++;
1311  }
1312 
1313  /* sort by tx_min_progress, then alproto, then local_id */
1314  qsort(sgh->tx_engines, local_id, sizeof(PrefilterEngine),
1315  PrefilterSetupRuleGroupSortHelper);
1316  sgh->tx_engines[local_id - 1].is_last = true;
1317  sgh->tx_engines[local_id - 1].is_last_for_progress = true;
1318 
1319  PrefilterEngine *engine;
1320 
1321  /* per alproto to set is_last_for_progress per alproto because the inspect
1322  * loop skips over engines that are not the correct alproto */
1323  for (AppProto a = ALPROTO_FAILED + 1; a < g_alproto_max; a++) {
1324  int last_tx_progress = 0;
1325  bool last_tx_progress_set = false;
1326  PrefilterEngine *prev_engine = NULL;
1327  engine = sgh->tx_engines;
1328  do {
1329  if (engine->ctx.tx_min_progress != -1)
1330  BUG_ON(engine->ctx.tx_min_progress < last_tx_progress);
1331  if (engine->alproto == a) {
1332  if (last_tx_progress_set && engine->ctx.tx_min_progress > last_tx_progress) {
1333  if (prev_engine) {
1334  prev_engine->is_last_for_progress = true;
1335  }
1336  }
1337 
1338  last_tx_progress_set = true;
1339  prev_engine = engine;
1340  } else {
1341  if (prev_engine) {
1342  prev_engine->is_last_for_progress = true;
1343  }
1344  }
1345  last_tx_progress = engine->ctx.tx_min_progress;
1346  if (engine->is_last)
1347  break;
1348  engine++;
1349  } while (1);
1350  }
1351 #ifdef DEBUG
1352  SCLogDebug("sgh %p", sgh);
1353  engine = sgh->tx_engines;
1354  do {
1355  SCLogDebug("engine: gid %u alproto %s tx_min_progress %d is_last %s "
1356  "is_last_for_progress %s",
1357  engine->gid, AppProtoToString(engine->alproto), engine->ctx.tx_min_progress,
1358  engine->is_last ? "true" : "false",
1359  engine->is_last_for_progress ? "true" : "false");
1360  if (engine->is_last)
1361  break;
1362  engine++;
1363  } while (1);
1364 #endif
1365  }
1366  if (sgh->init->frame_engines != NULL) {
1367  uint32_t cnt = 0;
1368  for (el = sgh->init->frame_engines; el != NULL; el = el->next) {
1369  cnt++;
1370  }
1372  if (sgh->frame_engines == NULL) {
1373  return -1;
1374  }
1375  memset(sgh->frame_engines, 0x00, (cnt * sizeof(PrefilterEngine)));
1376 
1377  PrefilterEngine *e = sgh->frame_engines;
1378  for (el = sgh->init->frame_engines; el != NULL; el = el->next) {
1379  e->local_id = el->id;
1380  e->ctx.frame_type = el->frame_type;
1381  e->cb.PrefilterFrame = el->PrefilterFrame;
1382  e->alproto = el->alproto;
1383  e->pectx = el->pectx;
1384  el->pectx = NULL; // e now owns the ctx
1385  e->gid = el->gid;
1386  if (el->next == NULL) {
1387  e->is_last = true;
1388  }
1389  e++;
1390  }
1391  }
1392 
1393  if (sgh->init->post_rule_match_engines != NULL) {
1394  uint32_t cnt = 0;
1395  for (el = sgh->init->post_rule_match_engines; el != NULL; el = el->next) {
1396  cnt++;
1397  }
1399  if (sgh->post_rule_match_engines == NULL) {
1400  return -1;
1401  }
1402  memset(sgh->post_rule_match_engines, 0x00, (cnt * sizeof(PrefilterEngine)));
1403 
1404  uint16_t local_id = 0;
1406  for (el = sgh->init->post_rule_match_engines; el != NULL; el = el->next) {
1407  e->local_id = local_id++;
1409  e->pectx = el->pectx;
1410  el->pectx = NULL; // e now owns the ctx
1411  e->gid = el->gid;
1412  e->is_last = (el->next == NULL);
1413  e++;
1414  }
1415  SCLogDebug("sgh %p max local_id %u", sgh, local_id);
1416  }
1417 
1418  return 0;
1419 }
1420 
1421 /* hash table for assigning a unique id to each engine type. */
1422 
1423 static uint32_t PrefilterStoreHashFunc(HashListTable *ht, void *data, uint16_t datalen)
1424 {
1425  PrefilterStore *ctx = data;
1426 
1427  uint32_t hash = (uint32_t)strlen(ctx->name);
1428 
1429  for (size_t u = 0; u < strlen(ctx->name); u++) {
1430  hash += ctx->name[u];
1431  }
1432 
1433  hash %= ht->array_size;
1434  return hash;
1435 }
1436 
1437 static char PrefilterStoreCompareFunc(void *data1, uint16_t len1,
1438  void *data2, uint16_t len2)
1439 {
1440  PrefilterStore *ctx1 = data1;
1441  PrefilterStore *ctx2 = data2;
1442  return (strcmp(ctx1->name, ctx2->name) == 0);
1443 }
1444 
1445 static void PrefilterStoreFreeFunc(void *ptr)
1446 {
1447  SCFree(ptr);
1448 }
1449 
1451 {
1452  if (de_ctx->prefilter_hash_table != NULL) {
1454  }
1455 }
1456 
1458 {
1460 
1462  PrefilterStoreHashFunc,
1463  PrefilterStoreCompareFunc,
1464  PrefilterStoreFreeFunc);
1466 }
1467 
1468 static int PrefilterStoreGetId(DetectEngineCtx *de_ctx,
1469  const char *name, void (*FreeFunc)(void *))
1470 {
1471  PrefilterStore ctx = { name, FreeFunc, 0 };
1472 
1474 
1475  SCLogDebug("looking up %s", name);
1476 
1478  if (rctx != NULL) {
1479  return rctx->id;
1480  }
1481 
1482  PrefilterStore *actx = SCCalloc(1, sizeof(*actx));
1483  if (actx == NULL) {
1484  return -1;
1485  }
1486 
1487  actx->name = name;
1488  actx->FreeFunc = FreeFunc;
1489  actx->id = de_ctx->prefilter_id++;
1490  SCLogDebug("prefilter engine %s has profile id %u", actx->name, actx->id);
1491 
1492  int ret = HashListTableAdd(de_ctx->prefilter_hash_table, actx, 0);
1493  if (ret != 0) {
1494  SCFree(actx);
1495  return -1;
1496  }
1497 
1498  int r = actx->id;
1499  return r;
1500 }
1501 
1502 /** \warning slow */
1503 static const PrefilterStore *PrefilterStoreGetStore(const DetectEngineCtx *de_ctx,
1504  const uint32_t id)
1505 {
1506 
1507  const PrefilterStore *store = NULL;
1508  if (de_ctx->prefilter_hash_table != NULL) {
1510  for ( ; hb != NULL; hb = HashListTableGetListNext(hb)) {
1512  if (ctx->id == id) {
1513  store = ctx;
1514  break;
1515  }
1516  }
1517  }
1518  return store;
1519 }
1520 
1521 #include "util-print.h"
1522 
1523 typedef struct PrefilterMpmCtx {
1524  int list_id;
1525  union {
1528  };
1529  const MpmCtx *mpm_ctx;
1532 
1533 /** \brief Generic Mpm prefilter callback for simple InspectionSingleBufferGetDataPtr
1534  *
1535  * \param det_ctx detection engine thread ctx
1536  * \param p packet to inspect
1537  * \param f flow to inspect
1538  * \param txv tx to inspect
1539  * \param pectx inspection context
1540  */
1541 static void PrefilterMpmTxSingle(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p,
1542  Flow *f, void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags)
1543 {
1544  SCEnter();
1545 
1546  const PrefilterMpmCtx *ctx = (const PrefilterMpmCtx *)pectx;
1547  const MpmCtx *mpm_ctx = ctx->mpm_ctx;
1548  SCLogDebug("running on list %d", ctx->list_id);
1549 
1551  det_ctx, ctx->transforms, f, flags, txv, ctx->list_id, ctx->GetDataSingle);
1552  if (buffer == NULL)
1553  return;
1554 
1555  const uint32_t data_len = buffer->inspect_len;
1556  const uint8_t *data = buffer->inspect;
1557 
1558  SCLogDebug("mpm'ing buffer:");
1559  // PrintRawDataFp(stdout, data, data_len);
1560 
1561  if (data != NULL && data_len >= mpm_ctx->minlen) {
1562  (void)mpm_table[mpm_ctx->mpm_type].Search(
1563  mpm_ctx, &det_ctx->mtc, &det_ctx->pmq, data, data_len);
1564  PREFILTER_PROFILING_ADD_BYTES(det_ctx, data_len);
1565  }
1566 }
1567 
1568 /** \brief Generic Mpm prefilter callback
1569  *
1570  * \param det_ctx detection engine thread ctx
1571  * \param p packet to inspect
1572  * \param f flow to inspect
1573  * \param txv tx to inspect
1574  * \param pectx inspection context
1575  */
1576 static void PrefilterMpm(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f,
1577  void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags)
1578 {
1579  SCEnter();
1580 
1581  const PrefilterMpmCtx *ctx = (const PrefilterMpmCtx *)pectx;
1582  const MpmCtx *mpm_ctx = ctx->mpm_ctx;
1583  SCLogDebug("running on list %d", ctx->list_id);
1584 
1585  InspectionBuffer *buffer = ctx->GetData(det_ctx, ctx->transforms, f, flags, txv, ctx->list_id);
1586  if (buffer == NULL)
1587  return;
1588 
1589  const uint32_t data_len = buffer->inspect_len;
1590  const uint8_t *data = buffer->inspect;
1591 
1592  SCLogDebug("mpm'ing buffer:");
1593  //PrintRawDataFp(stdout, data, data_len);
1594 
1595  if (data != NULL && data_len >= mpm_ctx->minlen) {
1596  (void)mpm_table[mpm_ctx->mpm_type].Search(
1597  mpm_ctx, &det_ctx->mtc, &det_ctx->pmq, data, data_len);
1598  PREFILTER_PROFILING_ADD_BYTES(det_ctx, data_len);
1599  }
1600 }
1601 
1602 static void PrefilterGenericMpmFree(void *ptr)
1603 {
1604  SCFree(ptr);
1605 }
1606 
1608  const DetectBufferMpmRegistry *mpm_reg, int list_id)
1609 {
1610  SCEnter();
1611  PrefilterMpmCtx *pectx = SCCalloc(1, sizeof(*pectx));
1612  if (pectx == NULL)
1613  return -1;
1614  pectx->list_id = list_id;
1615  pectx->GetData = mpm_reg->app_v2.GetData;
1616  pectx->mpm_ctx = mpm_ctx;
1617  pectx->transforms = &mpm_reg->transforms;
1618 
1620  mpm_reg->app_v2.alproto, mpm_reg->app_v2.tx_min_progress,
1621  pectx, PrefilterGenericMpmFree, mpm_reg->pname);
1622  if (r != 0) {
1623  SCFree(pectx);
1624  }
1625  return r;
1626 }
1627 
1629  const DetectBufferMpmRegistry *mpm_reg, int list_id)
1630 {
1631  SCEnter();
1632  PrefilterMpmCtx *pectx = SCCalloc(1, sizeof(*pectx));
1633  if (pectx == NULL)
1634  return -1;
1635  pectx->list_id = list_id;
1636  pectx->GetDataSingle = mpm_reg->app_v2.GetDataSingle;
1637  pectx->mpm_ctx = mpm_ctx;
1638  pectx->transforms = &mpm_reg->transforms;
1639 
1640  int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterMpmTxSingle, mpm_reg->app_v2.alproto,
1641  mpm_reg->app_v2.tx_min_progress, pectx, PrefilterGenericMpmFree, mpm_reg->pname);
1642  if (r != 0) {
1643  SCFree(pectx);
1644  }
1645  return r;
1646 }
1647 
1648 static void PrefilterMultiGenericMpmFree(void *ptr)
1649 {
1650  // PrefilterMpmListId
1651  SCFree(ptr);
1652 }
1653 
1654 static void PrefilterMultiMpm(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f,
1655  void *txv, const uint64_t idx, const AppLayerTxData *_txd, const uint8_t flags)
1656 {
1657  SCEnter();
1658 
1659  const PrefilterMpmListId *ctx = (const PrefilterMpmListId *)pectx;
1660  const MpmCtx *mpm_ctx = ctx->mpm_ctx;
1661  SCLogDebug("running on list %d", ctx->list_id);
1662  uint32_t local_id = 0;
1663 
1664  do {
1665  // loop until we get a NULL
1667  det_ctx, ctx->transforms, f, flags, txv, ctx->list_id, local_id, ctx->GetData);
1668  if (buffer == NULL)
1669  break;
1670 
1671  if (buffer->inspect_len >= mpm_ctx->minlen) {
1672  (void)mpm_table[mpm_ctx->mpm_type].Search(
1673  mpm_ctx, &det_ctx->mtc, &det_ctx->pmq, buffer->inspect, buffer->inspect_len);
1674  PREFILTER_PROFILING_ADD_BYTES(det_ctx, buffer->inspect_len);
1675  }
1676 
1677  local_id++;
1678  } while (1);
1679 }
1680 
1682  const DetectBufferMpmRegistry *mpm_reg, int list_id)
1683 {
1684  SCEnter();
1685  PrefilterMpmListId *pectx = SCCalloc(1, sizeof(*pectx));
1686  if (pectx == NULL)
1687  return -1;
1688  pectx->list_id = list_id;
1689  pectx->GetData = mpm_reg->app_v2.GetMultiData;
1690  pectx->mpm_ctx = mpm_ctx;
1691  pectx->transforms = &mpm_reg->transforms;
1692 
1693  int r = PrefilterAppendTxEngine(de_ctx, sgh, PrefilterMultiMpm, mpm_reg->app_v2.alproto,
1694  mpm_reg->app_v2.tx_min_progress, pectx, PrefilterMultiGenericMpmFree, mpm_reg->pname);
1695  if (r != 0) {
1696  SCFree(pectx);
1697  }
1698  return r;
1699 }
1700 
1701 /* generic mpm for pkt engines */
1702 
1703 typedef struct PrefilterMpmPktCtx {
1704  int list_id;
1706  const MpmCtx *mpm_ctx;
1709 
1710 /** \brief Generic Mpm prefilter callback
1711  *
1712  * \param det_ctx detection engine thread ctx
1713  * \param p packet to inspect
1714  * \param f flow to inspect
1715  * \param txv tx to inspect
1716  * \param pectx inspection context
1717  */
1718 static void PrefilterMpmPkt(DetectEngineThreadCtx *det_ctx,
1719  Packet *p, const void *pectx)
1720 {
1721  SCEnter();
1722 
1723  const PrefilterMpmPktCtx *ctx = (const PrefilterMpmPktCtx *)pectx;
1724  const MpmCtx *mpm_ctx = ctx->mpm_ctx;
1725  SCLogDebug("running on list %d", ctx->list_id);
1726 
1727  InspectionBuffer *buffer = ctx->GetData(det_ctx, ctx->transforms,
1728  p, ctx->list_id);
1729  if (buffer == NULL)
1730  return;
1731 
1732  const uint32_t data_len = buffer->inspect_len;
1733  const uint8_t *data = buffer->inspect;
1734 
1735  SCLogDebug("mpm'ing buffer:");
1736  //PrintRawDataFp(stdout, data, data_len);
1737 
1738  if (data != NULL && data_len >= mpm_ctx->minlen) {
1739  (void)mpm_table[mpm_ctx->mpm_type].Search(
1740  mpm_ctx, &det_ctx->mtc, &det_ctx->pmq, data, data_len);
1741  PREFILTER_PROFILING_ADD_BYTES(det_ctx, data_len);
1742  }
1743 }
1744 
1745 static void PrefilterMpmPktFree(void *ptr)
1746 {
1747  SCFree(ptr);
1748 }
1749 
1751  const DetectBufferMpmRegistry *mpm_reg, int list_id)
1752 {
1753  SCEnter();
1754  PrefilterMpmPktCtx *pectx = SCCalloc(1, sizeof(*pectx));
1755  if (pectx == NULL)
1756  return -1;
1757  pectx->list_id = list_id;
1758  pectx->GetData = mpm_reg->pkt_v1.GetData;
1759  pectx->mpm_ctx = mpm_ctx;
1760  pectx->transforms = &mpm_reg->transforms;
1761 
1762  enum SignatureHookPkt hook = SIGNATURE_HOOK_PKT_NOT_SET; // TODO review
1763  int r = PrefilterAppendEngine(
1764  de_ctx, sgh, PrefilterMpmPkt, 0, hook, pectx, PrefilterMpmPktFree, mpm_reg->pname);
1765  if (r != 0) {
1766  SCFree(pectx);
1767  }
1768  return r;
1769 }
1770 
1771 #define QUEUE_STEP 16
1774  DetectEngineThreadCtx *det_ctx, const Signature *s, const int type, const uint32_t value)
1775 {
1776  if (det_ctx->post_rule_work_queue.q == NULL) {
1777  det_ctx->post_rule_work_queue.q =
1779  if (det_ctx->post_rule_work_queue.q == NULL) {
1781  return;
1782  }
1784  } else if (det_ctx->post_rule_work_queue.len == det_ctx->post_rule_work_queue.size) {
1785  void *ptr = SCRealloc(
1786  det_ctx->post_rule_work_queue.q, (det_ctx->post_rule_work_queue.size + QUEUE_STEP) *
1787  sizeof(PostRuleMatchWorkQueueItem));
1788  if (ptr == NULL) {
1790  return;
1791  }
1792  det_ctx->post_rule_work_queue.q = ptr;
1793  det_ctx->post_rule_work_queue.size += QUEUE_STEP;
1794  }
1796  det_ctx->post_rule_work_queue.q[det_ctx->post_rule_work_queue.len].value = value;
1797 #ifdef DEBUG
1798  det_ctx->post_rule_work_queue.q[det_ctx->post_rule_work_queue.len].id = s->iid;
1799 #endif
1800  det_ctx->post_rule_work_queue.len++;
1801  SCLogDebug("det_ctx->post_rule_work_queue.len %u", det_ctx->post_rule_work_queue.len);
1802 }
HashListTableGetListData
#define HashListTableGetListData(hb)
Definition: util-hashlist.h:56
PrefilterGenericMpmPktRegister
int PrefilterGenericMpmPktRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
Definition: detect-engine-prefilter.c:1750
detect-engine-uint.h
PrefilterEngineList_::frame_type
uint8_t frame_type
Definition: detect.h:1588
SigGroupHead_::tx_engines
PrefilterEngine * tx_engines
Definition: detect.h:1691
DetectEngineAppInspectionEngine_
Definition: detect.h:416
DetectGetMultiData
InspectionBuffer * DetectGetMultiData(struct DetectEngineThreadCtx_ *det_ctx, const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, const int list_id, uint32_t index, InspectionMultiBufferGetDataPtr GetBuf)
Definition: detect-engine.c:2230
Packet_::proto
uint8_t proto
Definition: decode.h:537
util-hash-string.h
DetectTransaction_::tx_data_ptr
struct AppLayerTxData * tx_data_ptr
Definition: detect-engine-prefilter.h:34
PrefilterEngineList_::Prefilter
PrefilterPktFn Prefilter
Definition: detect.h:1598
MpmCtx_::mpm_type
uint8_t mpm_type
Definition: util-mpm.h:99
detect-engine.h
PrefilterNonPFDataSig::sid
uint32_t sid
Definition: detect-engine-prefilter.c:536
PrefilterEngine_::PrefilterPostRule
void(* PrefilterPostRule)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f)
Definition: detect.h:1642
SIG_FLAG_FW_HOOK_LTE
#define SIG_FLAG_FW_HOOK_LTE
Definition: detect.h:251
DetectGetSingleData
InspectionBuffer * DetectGetSingleData(struct DetectEngineThreadCtx_ *det_ctx, const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, const int list_id, InspectionSingleBufferGetDataPtr GetBuf)
Definition: detect-engine.c:2213
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
PostRuleMatchWorkQueueAppend
void PostRuleMatchWorkQueueAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, const int type, const uint32_t value)
Definition: detect-engine-prefilter.c:1773
AppLayerParserGetStateNameById
const char * AppLayerParserGetStateNameById(uint8_t ipproto, AppProto alproto, const int id, const uint8_t direction)
Definition: app-layer-parser.c:1641
SignatureHook_::sm_list
int sm_list
Definition: detect.h:577
PatternMatchPrepareGroup
int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
Prepare the pattern matcher ctx in a sig group head.
Definition: detect-engine-mpm.c:2353
PrefilterMpmPktCtx
struct PrefilterMpmPktCtx PrefilterMpmPktCtx
PrefilterStore_::FreeFunc
void(* FreeFunc)(void *)
Definition: detect-engine-prefilter.h:50
DetectEngineAppHookToSmlist
int DetectEngineAppHookToSmlist(const AppProto p, const uint8_t state, const int direction)
get the sm_list for a app hook
Definition: detect-engine.c:841
PostRuleMatchWorkQueue::len
uint32_t len
Definition: detect.h:1274
PostRuleMatchWorkQueueItem::sm_type
int sm_type
Definition: detect.h:1263
PREFILTER_PROFILING_END
#define PREFILTER_PROFILING_END(ctx, profile_id)
Definition: util-profiling.h:276
PrefilterStore_
Definition: detect-engine-prefilter.h:48
CLS
#define CLS
Definition: suricata-common.h:77
PrefilterRuleStore_::rule_id_array_cnt
uint32_t rule_id_array_cnt
Definition: util-prefilter.h:40
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1679
PostRuleMatchWorkQueueItem
Definition: detect.h:1262
PrefilterNonPFData::size
uint32_t size
Definition: detect-engine-prefilter.c:556
DetectEngineTransforms
Definition: detect.h:391
PrefilterEngineList_::id
uint16_t id
Definition: detect.h:1580
PROF_DETECT_PF_PAYLOAD
@ PROF_DETECT_PF_PAYLOAD
Definition: suricata-common.h:471
Signature_::app_progress_hook
uint8_t app_progress_hook
Definition: detect.h:712
BIT_U16
#define BIT_U16(n)
Definition: suricata-common.h:424
SignatureInitData_::prefilter_sm
SigMatch * prefilter_sm
Definition: detect.h:629
PcapPacketCntGet
uint64_t PcapPacketCntGet(const Packet *p)
Definition: decode.c:1180
Signature_::alproto
AppProto alproto
Definition: detect.h:680
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
QUEUE_STEP
#define QUEUE_STEP
Definition: detect-engine-prefilter.c:1771
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
DetectPort_::port
uint16_t port
Definition: detect.h:220
SignatureHook_::app
struct SignatureHook_::@87::@88 app
DetectBufferMpmRegistry_::app_v2
struct DetectBufferMpmRegistry_::@90::@92 app_v2
name
const char * name
Definition: detect-engine-proto.c:48
PrefilterSingleMpmRegister
int PrefilterSingleMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
Definition: detect-engine-prefilter.c:1628
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:87
PrefilterMpmCtx::GetData
InspectionBufferGetDataPtr GetData
Definition: detect-engine-prefilter.c:1526
InspectionBuffer
Definition: detect-engine-inspect-buffer.h:34
SignatureHook_::t
union SignatureHook_::@87 t
PrefilterAppendEngine
int PrefilterAppendEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, PrefilterPktFn PrefilterFunc, SignatureMask mask, enum SignatureHookPkt hook, void *pectx, void(*FreeFunc)(void *pectx), const char *name)
Definition: detect-engine-prefilter.c:285
Packet_::flags
uint32_t flags
Definition: decode.h:561
type
uint8_t type
Definition: decode-sctp.h:0
Frame
Definition: app-layer-frames.h:43
Flow_
Flow data structure.
Definition: flow.h:354
PrefilterEngine_::tx_min_progress
int8_t tx_min_progress
Definition: detect.h:1627
PREFILTER_PROFILING_START
#define PREFILTER_PROFILING_START(det_ctx)
Definition: util-profiling.h:260
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1399
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:41
ctx
struct Thresholds ctx
PrefilterEngineList_::name
const char * name
Definition: detect.h:1609
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:973
SIGNATURE_HOOK_PKT_NOT_SET
@ SIGNATURE_HOOK_PKT_NOT_SET
Definition: detect.h:540
HashListTableGetListHead
HashListTableBucket * HashListTableGetListHead(HashListTable *ht)
Definition: util-hashlist.c:287
DETECT_UINT_EQ
#define DETECT_UINT_EQ
Definition: detect-engine-uint.h:35
PrefilterNonPFData
Definition: detect-engine-prefilter.c:555
InspectionBufferGetPktDataPtr
InspectionBuffer *(* InspectionBufferGetPktDataPtr)(struct DetectEngineThreadCtx_ *det_ctx, const DetectEngineTransforms *transforms, Packet *p, const int list_id)
Definition: detect.h:479
PrefilterEngine_::cb
union PrefilterEngine_::@105 cb
PrefilterDeinit
void PrefilterDeinit(DetectEngineCtx *de_ctx)
Definition: detect-engine-prefilter.c:1450
TxNonPFData::engine_name
const char * engine_name
Definition: detect-engine-prefilter.c:710
HashTable_
Definition: util-hash.h:35
DetectEngineSetEvent
void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e)
Definition: detect-engine.c:5172
Packet_::sig_mask
SignatureMask sig_mask
Definition: decode.h:552
Frames
Definition: app-layer-frames.h:58
DetectBufferMpmRegistry_
one time registration of keywords at start up
Definition: detect.h:770
DetectPort_::next
struct DetectPort_ * next
Definition: detect.h:233
PrefilterNonPFDataTx
Definition: detect-engine-prefilter.c:560
PrefilterMpmPktCtx
Definition: detect-engine-prefilter.c:1703
detect-engine-frame.h
SigGroupHead_::payload_engines
PrefilterEngine * payload_engines
Definition: detect.h:1690
DetectEngineCtx_::prefilter_setting
enum DetectEnginePrefilterSetting prefilter_setting
Definition: detect.h:1111
DetectBufferType_
Definition: detect.h:449
p
Packet * p
Definition: fuzz_iprep.c:21
PKT_NOPAYLOAD_INSPECTION
#define PKT_NOPAYLOAD_INSPECTION
Definition: decode.h:1296
PrefilterNonPFData::array
struct PrefilterNonPFDataSig array[]
Definition: detect-engine-prefilter.c:557
PostRuleMatchWorkQueue::size
uint32_t size
Definition: detect.h:1275
PACKET_PROFILING_DETECT_END
#define PACKET_PROFILING_DETECT_END(p, id)
Definition: util-profiling.h:221
HashListTableLookup
void * HashListTableLookup(HashListTable *ht, void *data, uint16_t datalen)
Definition: util-hashlist.c:245
TxNonPFData::sig_list
int sig_list
Definition: detect-engine-prefilter.c:706
PrefilterEngine_::local_id
uint16_t local_id
Definition: detect.h:1615
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:546
PrefilterEngineList_::Free
void(* Free)(void *pectx)
Definition: detect.h:1607
StringHashCompareFunc
char StringHashCompareFunc(void *data1, uint16_t datalen1, void *data2, uint16_t datalen2)
Definition: util-hash-string.c:38
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:271
PrefilterAppendFrameEngine
int PrefilterAppendFrameEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, PrefilterFrameFn PrefilterFrameFunc, AppProto alproto, uint8_t frame_type, void *pectx, void(*FreeFunc)(void *pectx), const char *name)
Definition: detect-engine-prefilter.c:391
DetectBufferMpmRegistry_::transforms
DetectEngineTransforms transforms
Definition: detect.h:783
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:620
Signature_::dsize_low
uint16_t dsize_low
Definition: detect.h:682
DetectPort_::port2
uint16_t port2
Definition: detect.h:221
DetectEngineCtx_::non_pf_engine_names
HashTable * non_pf_engine_names
Definition: detect.h:1189
detect-engine-prefilter.h
PrefilterMultiGenericMpmRegister
int PrefilterMultiGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
Definition: detect-engine-prefilter.c:1681
PrefilterNonPFDataSig::foo
uint8_t foo
Definition: detect-engine-prefilter.c:550
PrefilterStore_::id
uint32_t id
Definition: detect-engine-prefilter.h:51
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1383
HashListTableAdd
int HashListTableAdd(HashListTable *ht, void *data, uint16_t datalen)
Definition: util-hashlist.c:114
HashTable_::array_size
uint32_t array_size
Definition: util-hash.h:37
DetectBufferMpmRegistry_::pkt_v1
struct DetectBufferMpmRegistry_::@90::@93 pkt_v1
DETECT_PREFILTER_AUTO
@ DETECT_PREFILTER_AUTO
Definition: detect.h:905
HashListTable_::array_size
uint32_t array_size
Definition: util-hashlist.h:41
PrefilterEngine_::is_last_for_progress
bool is_last_for_progress
Definition: detect.h:1632
PROF_DETECT_PF_SORT1
@ PROF_DETECT_PF_SORT1
Definition: suricata-common.h:474
DetectEngineAppHookToName
const char * DetectEngineAppHookToName(const AppProto p, const uint8_t state, const uint8_t direction)
Definition: detect-engine.c:810
DetectEngineCtx_::prefilter_id
uint32_t prefilter_id
Definition: detect.h:1142
FRAME_ANY_TYPE
#define FRAME_ANY_TYPE
Definition: app-layer-frames.h:28
PrefilterEngineList_::next
struct PrefilterEngineList_ * next
Definition: detect.h:1604
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1494
SIGNATURE_HOOK_TYPE_APP
@ SIGNATURE_HOOK_TYPE_APP
Definition: detect.h:550
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:478
HashListTableGetListNext
#define HashListTableGetListNext(hb)
Definition: util-hashlist.h:55
PrefilterMpmListId
Definition: detect-engine-mpm.h:123
DetectEngineCtx_::prefilter_hash_table
HashListTable * prefilter_hash_table
Definition: detect.h:1143
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:270
app-layer-htp.h
HashListTableInit
HashListTable * HashListTableInit(uint32_t size, uint32_t(*Hash)(struct HashListTable_ *, void *, uint16_t), char(*Compare)(void *, uint16_t, void *, uint16_t), void(*Free)(void *))
Definition: util-hashlist.c:35
DetectBufferMpmRegistry_::pname
char pname[DETECT_PROFILE_NAME_LEN]
Definition: detect.h:772
PrefilterEngineList_::pkt_hook
enum SignatureHookPkt pkt_hook
Definition: detect.h:1592
PrefilterEngineList_::alproto
AppProto alproto
Definition: detect.h:1583
TxNonPFData::progress
uint8_t progress
Definition: detect-engine-prefilter.c:705
SigGroupHeadInitData_::sig_cnt
SigIntId sig_cnt
Definition: detect.h:1672
AppLayerTxData
Definition: app-layer-parser.h:163
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
g_alproto_max
AppProto g_alproto_max
Definition: app-layer-protos.c:30
Prefilter
void Prefilter(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, Packet *p, const uint8_t flags, const SignatureMask mask)
Definition: detect-engine-prefilter.c:219
DetectEngineThreadCtx_
Definition: detect.h:1291
PrefilterEngine_
Definition: detect.h:1614
SigGroupHeadInitData_::tx_engines
PrefilterEngineList * tx_engines
Definition: detect.h:1667
DetectTransaction_::detect_progress
uint8_t detect_progress
Definition: detect-engine-prefilter.h:39
SignatureInitData_::mpm_sm
SigMatch * mpm_sm
Definition: detect.h:627
DetectEngineGetMaxSigId
#define DetectEngineGetMaxSigId(de_ctx)
Definition: detect-engine.h:93
PROF_DETECT_PF_PKT
@ PROF_DETECT_PF_PKT
Definition: suricata-common.h:470
PrefilterEngineList_::PrefilterFrame
PrefilterFrameFn PrefilterFrame
Definition: detect.h:1600
PrefilterEngine_::ctx
union PrefilterEngine_::@104 ctx
PrefilterEngineList_::pectx
void * pectx
Definition: detect.h:1596
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:284
detect-engine-mpm.h
PrefilterEngineList_::PrefilterTx
PrefilterTxFn PrefilterTx
Definition: detect.h:1599
DetectEngineCtx_::sm_types_prefilter
bool * sm_types_prefilter
Definition: detect.h:1158
TxNonPFData
Definition: detect-engine-prefilter.c:702
SignatureHookPkt
SignatureHookPkt
Definition: detect.h:539
PrefilterEngineList_::gid
uint32_t gid
Definition: detect.h:1611
PrefilterMpmPktCtx::GetData
InspectionBufferGetPktDataPtr GetData
Definition: detect-engine-prefilter.c:1705
PKT_DETECT_HAS_STREAMDATA
#define PKT_DETECT_HAS_STREAMDATA
Definition: decode.h:1349
InspectionSingleBufferGetDataPtr
bool(* InspectionSingleBufferGetDataPtr)(const void *txv, const uint8_t flow_flags, const uint8_t **buf, uint32_t *buf_len)
Definition: detect-engine-helper.h:45
FLOW_PKT_TOCLIENT_FIRST
#define FLOW_PKT_TOCLIENT_FIRST
Definition: flow.h:235
PrefilterMpmCtx
struct PrefilterMpmCtx PrefilterMpmCtx
NONPF_PKT_STATS_INCR
#define NONPF_PKT_STATS_INCR(s)
Definition: detect-engine-prefilter.c:589
DetectEngineCtx_::frame_inspect_engines
DetectEngineFrameInspectionEngine * frame_inspect_engines
Definition: detect.h:1138
PrefilterGenericMpmRegister
int PrefilterGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistry *mpm_reg, int list_id)
Definition: detect-engine-prefilter.c:1607
PrefilterFrameFn
void(* PrefilterFrameFn)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, const struct Frames *frames, const struct Frame *frame)
Definition: detect.h:1572
HashTableAdd
int HashTableAdd(HashTable *ht, void *data, uint16_t datalen)
Definition: util-hash.c:132
PrefilterNonPFDataTx::array
uint32_t array[]
Definition: detect-engine-prefilter.c:562
SigGroupHead_::init
SigGroupHeadInitData * init
Definition: detect.h:1696
SignatureHook_::pkt
struct SignatureHook_::@87::@89 pkt
PrefilterMpmListId::transforms
const DetectEngineTransforms * transforms
Definition: detect-engine-mpm.h:127
app-layer-parser.h
MpmCtx_::minlen
uint16_t minlen
Definition: util-mpm.h:108
Packet_::pkt_hooks
uint16_t pkt_hooks
Definition: decode.h:555
PrefilterNonPFDataSig::type
uint8_t type
Definition: detect-engine-prefilter.c:547
SignatureInitData_::hook
SignatureHook hook
Definition: detect.h:594
SigGroupHeadInitData_::direction
uint32_t direction
Definition: detect.h:1657
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:325
PrefilterEngine_::pkt
struct PrefilterEngine_::@104::@106 pkt
util-profiling.h
DetectTransaction_::tx_id
const uint64_t tx_id
Definition: detect-engine-prefilter.h:33
SigIntId
#define SigIntId
Definition: detect-engine-state.h:38
SCReturn
#define SCReturn
Definition: util-debug.h:286
PrefilterEngine_::alproto
AppProto alproto
Definition: detect.h:1618
Signature_::flags
uint32_t flags
Definition: detect.h:676
PrefilterMpmListId::mpm_ctx
const MpmCtx * mpm_ctx
Definition: detect-engine-mpm.h:125
Packet_
Definition: decode.h:515
SCFreeAligned
#define SCFreeAligned(p)
Definition: util-mem.h:77
Flow_::type
uint8_t type
Definition: flow.h:361
DetectBufferType_::packet
bool packet
Definition: detect.h:455
DetectEngineFrameInspectionEngine
Definition: detect.h:509
DetectEngineBufferTypeGetById
const DetectBufferType * DetectEngineBufferTypeGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1403
PrefilterEngine_::PrefilterFrame
PrefilterFrameFn PrefilterFrame
Definition: detect.h:1641
PrefilterEngine_::frame_type
uint8_t frame_type
Definition: detect.h:1628
DetectBufferType_::name
char name[64]
Definition: detect.h:450
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:754
HashListTable_
Definition: util-hashlist.h:37
PrefilterTxFn
void(* PrefilterTxFn)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f, void *tx, const uint64_t tx_id, const AppLayerTxData *tx_data, const uint8_t flags)
Definition: detect.h:1576
MpmTableElmt_::Search
uint32_t(* Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
Definition: util-mpm.h:186
SigGroupHead_::frame_engines
PrefilterEngine * frame_engines
Definition: detect.h:1692
PrefilterMpmCtx::list_id
int list_id
Definition: detect-engine-prefilter.c:1524
DetectEngineThreadCtx_::mtc
MpmThreadCtx mtc
Definition: detect.h:1395
Flow_::next
struct Flow_ * next
Definition: flow.h:401
PrefilterMpmPktCtx::list_id
int list_id
Definition: detect-engine-prefilter.c:1704
PrefilterAppendPayloadEngine
int PrefilterAppendPayloadEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, PrefilterPktFn PrefilterFunc, void *pectx, void(*FreeFunc)(void *pectx), const char *name)
Definition: detect-engine-prefilter.c:324
PrefilterEngineList_::tx_min_progress
int8_t tx_min_progress
Definition: detect.h:1586
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
SIG_FLAG_MPM_NEG
#define SIG_FLAG_MPM_NEG
Definition: detect.h:256
SigGroupHeadInitData_::pkt_engines
PrefilterEngineList * pkt_engines
Definition: detect.h:1665
SigGroupHead_::post_rule_match_engines
PrefilterEngine * post_rule_match_engines
Definition: detect.h:1693
DetectBufferType_::frame
bool frame
Definition: detect.h:456
cnt
uint32_t cnt
Definition: tmqh-packetpool.h:7
PREFILTER_PROFILING_ADD_BYTES
#define PREFILTER_PROFILING_ADD_BYTES(det_ctx, bytes)
Definition: util-profiling.h:286
Packet_::flow
struct Flow_ * flow
Definition: decode.h:563
PrefilterNonPFDataSig::type
uint32_t type
Definition: detect-engine-prefilter.c:537
flags
uint8_t flags
Definition: decode-gre.h:0
PrefilterNonPFDataTx::size
uint32_t size
Definition: detect-engine-prefilter.c:561
suricata-common.h
SigGroupHeadInitData_::frame_engines
PrefilterEngineList * frame_engines
Definition: detect.h:1668
SigGroupHeadInitData_::payload_engines
PrefilterEngineList * payload_engines
Definition: detect.h:1666
PrefilterNonPFDataSig::sig_mask
SignatureMask sig_mask
Definition: detect-engine-prefilter.c:543
HashListTableFree
void HashListTableFree(HashListTable *ht)
Definition: util-hashlist.c:88
SigGroupHeadInitData_::match_array
Signature ** match_array
Definition: detect.h:1675
PROF_DETECT_PF_RECORD
@ PROF_DETECT_PF_RECORD
Definition: suricata-common.h:473
SCMallocAligned
#define SCMallocAligned(size, align)
Definition: util-mem.h:68
DetectEnginePrefilterSetting
DetectEnginePrefilterSetting
Definition: detect.h:903
SignatureHook_::type
enum SignatureHookType type
Definition: detect.h:576
DetectTransaction_
Definition: detect-engine-prefilter.h:31
PrefilterEngineList_::PrefilterPostRule
void(* PrefilterPostRule)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f)
Definition: detect.h:1601
PrefilterEngineList_
Definition: detect.h:1579
PrefilterCleanupRuleGroup
void PrefilterCleanupRuleGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sgh)
Definition: detect-engine-prefilter.c:495
PostRuleMatchWorkQueue::q
PostRuleMatchWorkQueueItem * q
Definition: detect.h:1273
PrefilterEngine_::gid
uint32_t gid
Definition: detect.h:1647
PrefilterNonPFDataSig::app
struct PrefilterNonPFDataSig::@53::@57 app
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(...)
Definition: util-debug.h:517
SIGNATURE_HOOK_TYPE_PKT
@ SIGNATURE_HOOK_TYPE_PKT
Definition: detect.h:549
PrefilterMpmPktCtx::transforms
const DetectEngineTransforms * transforms
Definition: detect-engine-prefilter.c:1707
PrefilterPktFn
void(* PrefilterPktFn)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
Definition: detect.h:1571
PrefilterMpmCtx
Definition: detect-engine-prefilter.c:1523
PrefilterMpmListId::GetData
InspectionMultiBufferGetDataPtr GetData
Definition: detect-engine-mpm.h:126
util-validate.h
DetectTransaction_::tx_ptr
void * tx_ptr
Definition: detect-engine-prefilter.h:32
InspectionBuffer::inspect_len
uint32_t inspect_len
Definition: detect-engine-inspect-buffer.h:37
SignatureInitData_::buffers
SignatureInitDataBuffer * buffers
Definition: detect.h:654
DetectEngineCtx_::app_inspect_engines
DetectEngineAppInspectionEngine * app_inspect_engines
Definition: detect.h:1134
PrefilterEngine_::pectx
void * pectx
Definition: detect.h:1636
PrefilterAppendPostRuleEngine
int PrefilterAppendPostRuleEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, void(*PrefilterPostRuleFunc)(DetectEngineThreadCtx *det_ctx, const void *pectx, Packet *p, Flow *f), void *pectx, void(*FreeFunc)(void *pectx), const char *name)
Definition: detect-engine-prefilter.c:426
Signature_::dp
DetectPort * dp
Definition: detect.h:726
PrefilterInit
void PrefilterInit(DetectEngineCtx *de_ctx)
Definition: detect-engine-prefilter.c:1457
InspectionBuffer::inspect
const uint8_t * inspect
Definition: detect-engine-inspect-buffer.h:35
PACKET_PROFILING_DETECT_START
#define PACKET_PROFILING_DETECT_START(p, id)
Definition: util-profiling.h:214
str
#define str(s)
Definition: suricata-common.h:316
PrefilterMpmCtx::transforms
const DetectEngineTransforms * transforms
Definition: detect-engine-prefilter.c:1530
DETECT_TBLSIZE
int DETECT_TBLSIZE
Definition: detect-engine-register.c:264
TxNonPFData::dir
int dir
Definition: detect-engine-prefilter.c:704
Signature_::iid
SigIntId iid
Definition: detect.h:687
TxNonPFData::sigs_cnt
uint32_t sigs_cnt
Definition: detect-engine-prefilter.c:708
PrefilterStore_::name
const char * name
Definition: detect-engine-prefilter.h:49
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SigGroupHeadInitData_::post_rule_match_engines
PrefilterEngineList * post_rule_match_engines
Definition: detect.h:1669
PrefilterAppendTxEngine
int PrefilterAppendTxEngine(DetectEngineCtx *de_ctx, SigGroupHead *sgh, PrefilterTxFn PrefilterTxFunc, AppProto alproto, int8_t tx_min_progress, void *pectx, void(*FreeFunc)(void *pectx), const char *name)
Definition: detect-engine-prefilter.c:356
Signature_::id
uint32_t id
Definition: detect.h:720
HashListTableBucket_
Definition: util-hashlist.h:28
PrefilterMpmPktCtx::mpm_ctx
const MpmCtx * mpm_ctx
Definition: detect-engine-prefilter.c:1706
PrefilterNonPFDataSig
Definition: detect-engine-prefilter.c:535
SignatureInitDataBuffer_::id
uint32_t id
Definition: detect.h:526
Signature_
Signature container.
Definition: detect.h:675
PrefilterEngineList_::pkt_mask
SignatureMask pkt_mask
Definition: detect.h:1590
PrefilterMpmListId::list_id
int list_id
Definition: detect-engine-mpm.h:124
TxNonPFData::alproto
AppProto alproto
Definition: detect-engine-prefilter.c:703
HashTableInit
HashTable * HashTableInit(uint32_t size, uint32_t(*Hash)(struct HashTable_ *, void *, uint16_t), char(*Compare)(void *, uint16_t, void *, uint16_t), void(*Free)(void *))
Definition: util-hash.c:35
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
ALPROTO_FAILED
@ ALPROTO_FAILED
Definition: app-layer-protos.h:33
PostRuleMatchWorkQueueItem::value
uint32_t value
Definition: detect.h:1264
Signature_::dsize_mode
uint8_t dsize_mode
Definition: detect.h:684
mpm_table
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
Definition: util-mpm.c:47
PrefilterSetupRuleGroup
int PrefilterSetupRuleGroup(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
Definition: detect-engine-prefilter.c:1204
SIGNATURE_HOOK_PKT_FLOW_START
@ SIGNATURE_HOOK_PKT_FLOW_START
Definition: detect.h:541
PrefilterEngine_::is_last
bool is_last
Definition: detect.h:1631
suricata.h
InspectionBufferGetDataPtr
InspectionBuffer *(* InspectionBufferGetDataPtr)(struct DetectEngineThreadCtx_ *det_ctx, const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, const int list_id)
Definition: detect-engine-helper.h:39
PrefilterPostRuleMatch
void PrefilterPostRuleMatch(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, Packet *p, Flow *f)
invoke post-rule match "prefilter" engines
Definition: detect-engine-prefilter.c:196
DetectGetInnerTx
void * DetectGetInnerTx(void *tx_ptr, AppProto alproto, AppProto engine_alproto, uint8_t flow_flags)
Definition: detect.c:1249
PrefilterNonPFDataSig::pkt
struct PrefilterNonPFDataSig::@53::@55 pkt
likely
#define likely(expr)
Definition: util-optimize.h:32
PrefilterMpmCtx::GetDataSingle
InspectionSingleBufferGetDataPtr GetDataSingle
Definition: detect-engine-prefilter.c:1527
PrefilterNonPFDataSig::value
uint16_t value
Definition: detect-engine-prefilter.c:538
PrefilterMpm
struct PrefilterMpm PrefilterMpm
SigGroupHead_::pkt_engines
PrefilterEngine * pkt_engines
Definition: detect.h:1689
PrefilterEngine_::Prefilter
PrefilterPktFn Prefilter
Definition: detect.h:1639
DetectTransaction_::tx_progress
const uint8_t tx_progress
Definition: detect-engine-prefilter.h:43
PrefilterEngine_::PrefilterTx
PrefilterTxFn PrefilterTx
Definition: detect.h:1640
MpmCtx_
Definition: util-mpm.h:97
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:450
Packet_::dp
Port dp
Definition: decode.h:530
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
PrefilterNonPFDataSig::frame
struct PrefilterNonPFDataSig::@53::@56 frame
PrefilterMpm
Definition: detect-dns-response.c:40
SignatureInitData_::buffer_index
uint32_t buffer_index
Definition: detect.h:655
PrefilterFreeEnginesList
void PrefilterFreeEnginesList(PrefilterEngineList *list)
Definition: detect-engine-prefilter.c:467
FLOW_PKT_TOSERVER_FIRST
#define FLOW_PKT_TOSERVER_FIRST
Definition: flow.h:234
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
SIG_FLAG_PREFILTER
#define SIG_FLAG_PREFILTER
Definition: detect.h:277
PrefilterMpmCtx::mpm_ctx
const MpmCtx * mpm_ctx
Definition: detect-engine-prefilter.c:1529
DetectRunPrefilterTx
void DetectRunPrefilterTx(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, Packet *p, const uint8_t ipproto, const uint8_t flow_flags, const AppProto alproto, void *alstate, DetectTransaction *tx)
run prefilter engines on a transaction
Definition: detect-engine-prefilter.c:95
DetectEngineThreadCtx_::post_rule_work_queue
PostRuleMatchWorkQueue post_rule_work_queue
Definition: detect.h:1397
SIG_FLAG_DSIZE
#define SIG_FLAG_DSIZE
Definition: detect.h:247
StringHashDjb2
uint32_t StringHashDjb2(const uint8_t *data, uint32_t datalen)
Definition: util-hash-string.c:22
SignatureMask
#define SignatureMask
Definition: decode.h:100
Signature_::mask
SignatureMask mask
Definition: detect.h:686
DETECT_EVENT_POST_MATCH_QUEUE_FAILED
@ DETECT_EVENT_POST_MATCH_QUEUE_FAILED
Definition: detect.h:1535
PrefilterRuleStore_::rule_id_array
SigIntId * rule_id_array
Definition: util-prefilter.h:38
PrefilterPktNonPFStatsDump
void PrefilterPktNonPFStatsDump(void)
Definition: detect-engine-prefilter.c:592
TxNonPFData::sigs
struct PrefilterNonPFDataSig * sigs
Definition: detect-engine-prefilter.c:709