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