suricata
detect.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2017 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  * Basic detection engine
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 #include "conf.h"
29 
30 #include "decode.h"
31 #include "flow.h"
32 #include "stream-tcp.h"
33 #include "app-layer.h"
34 #include "app-layer-parser.h"
35 
36 #include "detect.h"
37 #include "detect-engine.h"
38 #include "detect-engine-profile.h"
39 
40 #include "detect-engine-alert.h"
41 #include "detect-engine-siggroup.h"
42 #include "detect-engine-address.h"
43 #include "detect-engine-proto.h"
44 #include "detect-engine-port.h"
45 #include "detect-engine-mpm.h"
46 #include "detect-engine-iponly.h"
49 #include "detect-engine-state.h"
50 #include "detect-engine-analyzer.h"
51 
52 #include "detect-engine-payload.h"
53 #include "detect-engine-event.h"
54 
55 #include "detect-filestore.h"
56 #include "detect-flowvar.h"
57 #include "detect-replace.h"
58 
59 #include "util-validate.h"
60 #include "util-detect.h"
61 
62 typedef struct DetectRunScratchpad {
64  const uint8_t flow_flags; /* flow/state flags: STREAM_* */
65  const bool app_decoder_events;
66  const SigGroupHead *sgh;
69 
70 /* prototypes */
71 static DetectRunScratchpad DetectRunSetup(const DetectEngineCtx *de_ctx,
72  DetectEngineThreadCtx *det_ctx, Packet * const p, Flow * const pflow);
73 static void DetectRunInspectIPOnly(ThreadVars *tv, const DetectEngineCtx *de_ctx,
74  DetectEngineThreadCtx *det_ctx, Flow * const pflow, Packet * const p);
75 static inline void DetectRunGetRuleGroup(const DetectEngineCtx *de_ctx,
76  Packet * const p, Flow * const pflow, DetectRunScratchpad *scratch);
77 static inline void DetectRunPrefilterPkt(ThreadVars *tv,
79  DetectRunScratchpad *scratch);
80 static inline void DetectRulePacketRules(ThreadVars * const tv,
81  DetectEngineCtx * const de_ctx, DetectEngineThreadCtx * const det_ctx,
82  Packet * const p, Flow * const pflow, const DetectRunScratchpad *scratch);
83 static void DetectRunTx(ThreadVars *tv, DetectEngineCtx *de_ctx,
84  DetectEngineThreadCtx *det_ctx, Packet *p,
85  Flow *f, DetectRunScratchpad *scratch);
86 static inline void DetectRunPostRules(ThreadVars *tv, DetectEngineCtx *de_ctx,
87  DetectEngineThreadCtx *det_ctx, Packet * const p, Flow * const pflow,
88  DetectRunScratchpad *scratch);
89 static void DetectRunCleanup(DetectEngineThreadCtx *det_ctx,
90  Packet *p, Flow * const pflow);
91 
92 /** \internal
93  */
94 static void DetectRun(ThreadVars *th_v,
96  Packet *p)
97 {
98  SCEnter();
99  SCLogDebug("pcap_cnt %"PRIu64, p->pcap_cnt);
100 
101  /* bail early if packet should not be inspected */
102  if (p->flags & PKT_NOPACKET_INSPECTION) {
103  /* nothing to do */
104  SCReturn;
105  }
106 
107  /* Load the Packet's flow early, even though it might not be needed.
108  * Mark as a constant pointer, although the flow itself can change. */
109  Flow * const pflow = p->flow;
110 
111  DetectRunScratchpad scratch = DetectRunSetup(de_ctx, det_ctx, p, pflow);
112 
113  /* run the IPonly engine */
114  DetectRunInspectIPOnly(th_v, de_ctx, det_ctx, pflow, p);
115 
116  /* get our rule group */
117  DetectRunGetRuleGroup(de_ctx, p, pflow, &scratch);
118  /* if we didn't get a sig group head, we
119  * have nothing to do.... */
120  if (scratch.sgh == NULL) {
121  SCLogDebug("no sgh for this packet, nothing to match against");
122  goto end;
123  }
124 
125  /* run the prefilters for packets */
126  DetectRunPrefilterPkt(th_v, de_ctx, det_ctx, p, &scratch);
127 
129  /* inspect the rules against the packet */
130  DetectRulePacketRules(th_v, de_ctx, det_ctx, p, pflow, &scratch);
132 
133  /* run tx/state inspection. Don't call for ICMP error msgs. */
134  if (pflow && pflow->alstate && likely(pflow->proto == p->proto)) {
136  DetectRunTx(th_v, de_ctx, det_ctx, p, pflow, &scratch);
138  }
139 
140 end:
141  DetectRunPostRules(th_v, de_ctx, det_ctx, p, pflow, &scratch);
142 
143  DetectRunCleanup(det_ctx, p, pflow);
144  SCReturn;
145 }
146 
147 static void DetectRunPostMatch(ThreadVars *tv,
148  DetectEngineThreadCtx *det_ctx, Packet *p,
149  const Signature *s)
150 {
151  /* run the packet match functions */
153  if (smd != NULL) {
155 
156  SCLogDebug("running match functions, sm %p", smd);
157 
158  while (1) {
160  (void)sigmatch_table[smd->type].Match(det_ctx, p, s, smd->ctx);
161  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
162  if (smd->is_last)
163  break;
164  smd++;
165  }
166  }
167 }
168 
169 /**
170  * \brief Get the SigGroupHead for a packet.
171  *
172  * \param de_ctx detection engine context
173  * \param p packet
174  *
175  * \retval sgh the SigGroupHead or NULL if non applies to the packet
176  */
178  const Packet *p)
179 {
180  SCEnter();
181 
182  int f;
183  SigGroupHead *sgh = NULL;
184 
185  /* if the packet proto is 0 (not set), we're inspecting it against
186  * the decoder events sgh we have. */
187  if (p->proto == 0 && p->events.cnt > 0) {
188  SCReturnPtr(de_ctx->decoder_event_sgh, "SigGroupHead");
189  } else if (p->proto == 0) {
190  if (!(PKT_IS_IPV4(p) || PKT_IS_IPV6(p))) {
191  /* not IP, so nothing to do */
192  SCReturnPtr(NULL, "SigGroupHead");
193  }
194  }
195 
196  /* select the flow_gh */
197  if (p->flowflags & FLOW_PKT_TOCLIENT)
198  f = 0;
199  else
200  f = 1;
201 
202  int proto = IP_GET_IPPROTO(p);
203  if (proto == IPPROTO_TCP) {
204  DetectPort *list = de_ctx->flow_gh[f].tcp;
205  SCLogDebug("tcp toserver %p, tcp toclient %p: going to use %p",
207  uint16_t port = f ? p->dp : p->sp;
208  SCLogDebug("tcp port %u -> %u:%u", port, p->sp, p->dp);
209  DetectPort *sghport = DetectPortLookupGroup(list, port);
210  if (sghport != NULL)
211  sgh = sghport->sh;
212  SCLogDebug("TCP list %p, port %u, direction %s, sghport %p, sgh %p",
213  list, port, f ? "toserver" : "toclient", sghport, sgh);
214  } else if (proto == IPPROTO_UDP) {
215  DetectPort *list = de_ctx->flow_gh[f].udp;
216  uint16_t port = f ? p->dp : p->sp;
217  DetectPort *sghport = DetectPortLookupGroup(list, port);
218  if (sghport != NULL)
219  sgh = sghport->sh;
220  SCLogDebug("UDP list %p, port %u, direction %s, sghport %p, sgh %p",
221  list, port, f ? "toserver" : "toclient", sghport, sgh);
222  } else {
223  sgh = de_ctx->flow_gh[f].sgh[proto];
224  }
225 
226  SCReturnPtr(sgh, "SigGroupHead");
227 }
228 
229 static inline void DetectPrefilterMergeSort(DetectEngineCtx *de_ctx,
230  DetectEngineThreadCtx *det_ctx)
231 {
232  SigIntId mpm, nonmpm;
233  SigIntId *mpm_ptr = det_ctx->pmq.rule_id_array;
234  SigIntId *nonmpm_ptr = det_ctx->non_pf_id_array;
235  uint32_t m_cnt = det_ctx->pmq.rule_id_array_cnt;
236  uint32_t n_cnt = det_ctx->non_pf_id_cnt;
237  SigIntId *final_ptr;
238  uint32_t final_cnt;
239  SigIntId id;
240  SigIntId previous_id = (SigIntId)-1;
241  Signature **sig_array = de_ctx->sig_array;
242  Signature **match_array = det_ctx->match_array;
243  Signature *s;
244 
245  SCLogDebug("PMQ rule id array count %d", det_ctx->pmq.rule_id_array_cnt);
246 
247  /* Load first values. */
248  if (likely(m_cnt)) {
249  mpm = *mpm_ptr;
250  } else {
251  /* mpm list is empty */
252  final_ptr = nonmpm_ptr;
253  final_cnt = n_cnt;
254  goto final;
255  }
256  if (likely(n_cnt)) {
257  nonmpm = *nonmpm_ptr;
258  } else {
259  /* non-mpm list is empty. */
260  final_ptr = mpm_ptr;
261  final_cnt = m_cnt;
262  goto final;
263  }
264  while (1) {
265  if (mpm < nonmpm) {
266  /* Take from mpm list */
267  id = mpm;
268 
269  s = sig_array[id];
270  /* As the mpm list can contain duplicates, check for that here. */
271  if (likely(id != previous_id)) {
272  *match_array++ = s;
273  previous_id = id;
274  }
275  if (unlikely(--m_cnt == 0)) {
276  /* mpm list is now empty */
277  final_ptr = nonmpm_ptr;
278  final_cnt = n_cnt;
279  goto final;
280  }
281  mpm_ptr++;
282  mpm = *mpm_ptr;
283  } else if (mpm > nonmpm) {
284  id = nonmpm;
285 
286  s = sig_array[id];
287  /* As the mpm list can contain duplicates, check for that here. */
288  if (likely(id != previous_id)) {
289  *match_array++ = s;
290  previous_id = id;
291  }
292  if (unlikely(--n_cnt == 0)) {
293  final_ptr = mpm_ptr;
294  final_cnt = m_cnt;
295  goto final;
296  }
297  nonmpm_ptr++;
298  nonmpm = *nonmpm_ptr;
299 
300  } else { /* implied mpm == nonmpm */
301  /* special case: if on both lists, it's a negated mpm pattern */
302 
303  /* mpm list may have dups, so skip past them here */
304  while (--m_cnt != 0) {
305  mpm_ptr++;
306  mpm = *mpm_ptr;
307  if (mpm != nonmpm)
308  break;
309  }
310  /* if mpm is done, update nonmpm_ptrs and jump to final */
311  if (unlikely(m_cnt == 0)) {
312  n_cnt--;
313 
314  /* mpm list is now empty */
315  final_ptr = ++nonmpm_ptr;
316  final_cnt = n_cnt;
317  goto final;
318  }
319  /* otherwise, if nonmpm is done jump to final for mpm
320  * mpm ptrs alrady updated */
321  if (unlikely(--n_cnt == 0)) {
322  final_ptr = mpm_ptr;
323  final_cnt = m_cnt;
324  goto final;
325  }
326 
327  /* not at end of the lists, update nonmpm. Mpm already
328  * updated in while loop above. */
329  nonmpm_ptr++;
330  nonmpm = *nonmpm_ptr;
331  }
332  }
333 
334  final: /* Only one list remaining. Just walk that list. */
335 
336  while (final_cnt-- > 0) {
337  id = *final_ptr++;
338  s = sig_array[id];
339 
340  /* As the mpm list can contain duplicates, check for that here. */
341  if (likely(id != previous_id)) {
342  *match_array++ = s;
343  previous_id = id;
344  }
345  }
346 
347  det_ctx->match_array_cnt = match_array - det_ctx->match_array;
348 
349  DEBUG_VALIDATE_BUG_ON((det_ctx->pmq.rule_id_array_cnt + det_ctx->non_pf_id_cnt) < det_ctx->match_array_cnt);
350 }
351 
352 static inline void
353 DetectPrefilterBuildNonPrefilterList(DetectEngineThreadCtx *det_ctx, SignatureMask mask, uint8_t alproto)
354 {
355  uint32_t x = 0;
356  for (x = 0; x < det_ctx->non_pf_store_cnt; x++) {
357  /* only if the mask matches this rule can possibly match,
358  * so build the non_mpm array only for match candidates */
359  const SignatureMask rule_mask = det_ctx->non_pf_store_ptr[x].mask;
360  const uint8_t rule_alproto = det_ctx->non_pf_store_ptr[x].alproto;
361  if ((rule_mask & mask) == rule_mask && (rule_alproto == 0 || rule_alproto == alproto)) {
362  det_ctx->non_pf_id_array[det_ctx->non_pf_id_cnt++] = det_ctx->non_pf_store_ptr[x].id;
363  }
364  }
365 }
366 
367 /** \internal
368  * \brief select non-mpm list
369  * Based on the packet properties, select the non-mpm list to use
370  * \todo move non_pf_store* into scratchpad */
371 static inline void
372 DetectPrefilterSetNonPrefilterList(const Packet *p, DetectEngineThreadCtx *det_ctx, DetectRunScratchpad *scratch)
373 {
374  if ((p->proto == IPPROTO_TCP) && (p->tcph != NULL) && (p->tcph->th_flags & TH_SYN)) {
375  det_ctx->non_pf_store_ptr = scratch->sgh->non_pf_syn_store_array;
376  det_ctx->non_pf_store_cnt = scratch->sgh->non_pf_syn_store_cnt;
377  } else {
378  det_ctx->non_pf_store_ptr = scratch->sgh->non_pf_other_store_array;
379  det_ctx->non_pf_store_cnt = scratch->sgh->non_pf_other_store_cnt;
380  }
381  SCLogDebug("sgh non_pf ptr %p cnt %u (syn %p/%u, other %p/%u)",
382  det_ctx->non_pf_store_ptr, det_ctx->non_pf_store_cnt,
383  scratch->sgh->non_pf_syn_store_array, scratch->sgh->non_pf_syn_store_cnt,
385 }
386 
387 /** \internal
388  * \brief update flow's file tracking flags based on the detection engine
389  * A set of flags is prepared that is sent to the File API. The
390  File API may reject one or more based on the global force settings.
391  */
392 static inline void
393 DetectPostInspectFileFlagsUpdate(Flow *f, const SigGroupHead *sgh, uint8_t direction)
394 {
395  uint16_t flow_file_flags = FLOWFILE_INIT;
396 
397  if (sgh == NULL) {
398  SCLogDebug("requesting disabling all file features for flow");
399  flow_file_flags = FLOWFILE_NONE;
400  } else {
401  if (sgh->filestore_cnt == 0) {
402  SCLogDebug("requesting disabling filestore for flow");
403  flow_file_flags |= (FLOWFILE_NO_STORE_TS|FLOWFILE_NO_STORE_TC);
404  }
405 #ifdef HAVE_MAGIC
406  if (!(sgh->flags & SIG_GROUP_HEAD_HAVEFILEMAGIC)) {
407  SCLogDebug("requesting disabling magic for flow");
408  flow_file_flags |= (FLOWFILE_NO_MAGIC_TS|FLOWFILE_NO_MAGIC_TC);
409  }
410 #endif
411 #ifdef HAVE_NSS
412  if (!(sgh->flags & SIG_GROUP_HEAD_HAVEFILEMD5)) {
413  SCLogDebug("requesting disabling md5 for flow");
414  flow_file_flags |= (FLOWFILE_NO_MD5_TS|FLOWFILE_NO_MD5_TC);
415  }
416  if (!(sgh->flags & SIG_GROUP_HEAD_HAVEFILESHA1)) {
417  SCLogDebug("requesting disabling sha1 for flow");
418  flow_file_flags |= (FLOWFILE_NO_SHA1_TS|FLOWFILE_NO_SHA1_TC);
419  }
420  if (!(sgh->flags & SIG_GROUP_HEAD_HAVEFILESHA256)) {
421  SCLogDebug("requesting disabling sha256 for flow");
422  flow_file_flags |= (FLOWFILE_NO_SHA256_TS|FLOWFILE_NO_SHA256_TC);
423  }
424 #endif
425  if (!(sgh->flags & SIG_GROUP_HEAD_HAVEFILESIZE)) {
426  SCLogDebug("requesting disabling filesize for flow");
427  flow_file_flags |= (FLOWFILE_NO_SIZE_TS|FLOWFILE_NO_SIZE_TC);
428  }
429  }
430  if (flow_file_flags != 0) {
431  FileUpdateFlowFileFlags(f, flow_file_flags, direction);
432  }
433 }
434 
435 static inline void
436 DetectRunPostGetFirstRuleGroup(const Packet *p, Flow *pflow, const SigGroupHead *sgh)
437 {
438  if ((p->flowflags & FLOW_PKT_TOSERVER) && !(pflow->flags & FLOW_SGH_TOSERVER)) {
439  /* first time we see this toserver sgh, store it */
440  pflow->sgh_toserver = sgh;
441  pflow->flags |= FLOW_SGH_TOSERVER;
442 
443  if (p->proto == IPPROTO_TCP && (sgh == NULL || !(sgh->flags & SIG_GROUP_HEAD_HAVERAWSTREAM))) {
444  if (pflow->protoctx != NULL) {
445  TcpSession *ssn = pflow->protoctx;
446  SCLogDebug("STREAMTCP_STREAM_FLAG_DISABLE_RAW ssn.client");
448  }
449  }
450 
451  DetectPostInspectFileFlagsUpdate(pflow,
452  pflow->sgh_toserver, STREAM_TOSERVER);
453 
454  } else if ((p->flowflags & FLOW_PKT_TOCLIENT) && !(pflow->flags & FLOW_SGH_TOCLIENT)) {
455  pflow->sgh_toclient = sgh;
456  pflow->flags |= FLOW_SGH_TOCLIENT;
457 
458  if (p->proto == IPPROTO_TCP && (sgh == NULL || !(sgh->flags & SIG_GROUP_HEAD_HAVERAWSTREAM))) {
459  if (pflow->protoctx != NULL) {
460  TcpSession *ssn = pflow->protoctx;
461  SCLogDebug("STREAMTCP_STREAM_FLAG_DISABLE_RAW ssn.server");
463  }
464  }
465 
466  DetectPostInspectFileFlagsUpdate(pflow,
467  pflow->sgh_toclient, STREAM_TOCLIENT);
468  }
469 }
470 
471 static inline void DetectRunGetRuleGroup(
472  const DetectEngineCtx *de_ctx,
473  Packet * const p, Flow * const pflow,
474  DetectRunScratchpad *scratch)
475 {
476  const SigGroupHead *sgh = NULL;
477 
478  if (pflow) {
479  bool use_flow_sgh = false;
480  /* Get the stored sgh from the flow (if any). Make sure we're not using
481  * the sgh for icmp error packets part of the same stream. */
482  if (IP_GET_IPPROTO(p) == pflow->proto) { /* filter out icmp */
484  if ((p->flowflags & FLOW_PKT_TOSERVER) && (pflow->flags & FLOW_SGH_TOSERVER)) {
485  sgh = pflow->sgh_toserver;
486  SCLogDebug("sgh = pflow->sgh_toserver; => %p", sgh);
487  use_flow_sgh = true;
488  } else if ((p->flowflags & FLOW_PKT_TOCLIENT) && (pflow->flags & FLOW_SGH_TOCLIENT)) {
489  sgh = pflow->sgh_toclient;
490  SCLogDebug("sgh = pflow->sgh_toclient; => %p", sgh);
491  use_flow_sgh = true;
492  }
494  }
495 
496  if (!(use_flow_sgh)) {
500 
501  /* HACK: prevent the wrong sgh (or NULL) from being stored in the
502  * flow's sgh pointers */
504  ; /* no-op */
505  } else {
506  /* store the found sgh (or NULL) in the flow to save us
507  * from looking it up again for the next packet.
508  * Also run other tasks */
509  DetectRunPostGetFirstRuleGroup(p, pflow, sgh);
510  }
511  }
512  } else { /* p->flags & PKT_HAS_FLOW */
513  /* no flow */
514 
518  }
519 
520  scratch->sgh = sgh;
521 }
522 
523 static void DetectRunInspectIPOnly(ThreadVars *tv, const DetectEngineCtx *de_ctx,
524  DetectEngineThreadCtx *det_ctx,
525  Flow * const pflow, Packet * const p)
526 {
527  if (pflow) {
528  /* set the iponly stuff */
529  if (pflow->flags & FLOW_TOCLIENT_IPONLY_SET)
531  if (pflow->flags & FLOW_TOSERVER_IPONLY_SET)
533 
536  {
537  SCLogDebug("testing against \"ip-only\" signatures");
538 
540  IPOnlyMatchPacket(tv, de_ctx, det_ctx, &de_ctx->io_ctx, &det_ctx->io_ctx, p);
542 
543  /* save in the flow that we scanned this direction... */
544  FlowSetIPOnlyFlag(pflow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0);
545 
546  } else if (((p->flowflags & FLOW_PKT_TOSERVER) &&
547  (pflow->flags & FLOW_TOSERVER_IPONLY_SET)) ||
548  ((p->flowflags & FLOW_PKT_TOCLIENT) &&
549  (pflow->flags & FLOW_TOCLIENT_IPONLY_SET)))
550  {
551  /* If we have a drop from IP only module,
552  * we will drop the rest of the flow packets
553  * This will apply only to inline/IPS */
554  if (pflow->flags & FLOW_ACTION_DROP) {
555  PACKET_DROP(p);
556  }
557  }
558  } else { /* p->flags & PKT_HAS_FLOW */
559  /* no flow */
560 
561  /* Even without flow we should match the packet src/dst */
563  IPOnlyMatchPacket(tv, de_ctx, det_ctx, &de_ctx->io_ctx,
564  &det_ctx->io_ctx, p);
566  }
567 }
568 
569 /* returns 0 if no match, 1 if match */
570 static inline int DetectRunInspectRuleHeader(
571  const Packet *p,
572  const Flow *f,
573  const Signature *s,
574  const uint32_t sflags,
575  const uint8_t s_proto_flags)
576 {
577  /* check if this signature has a requirement for flowvars of some type
578  * and if so, if we actually have any in the flow. If not, the sig
579  * can't match and we skip it. */
580  if ((p->flags & PKT_HAS_FLOW) && (sflags & SIG_FLAG_REQUIRE_FLOWVAR)) {
581  DEBUG_VALIDATE_BUG_ON(f == NULL);
582 
583  int m = f->flowvar ? 1 : 0;
584 
585  /* no flowvars? skip this sig */
586  if (m == 0) {
587  SCLogDebug("skipping sig as the flow has no flowvars and sig "
588  "has SIG_FLAG_REQUIRE_FLOWVAR flag set.");
589  return 0;
590  }
591  }
592 
593  if ((s_proto_flags & DETECT_PROTO_IPV4) && !PKT_IS_IPV4(p)) {
594  SCLogDebug("ip version didn't match");
595  return 0;
596  }
597  if ((s_proto_flags & DETECT_PROTO_IPV6) && !PKT_IS_IPV6(p)) {
598  SCLogDebug("ip version didn't match");
599  return 0;
600  }
601 
602  if (DetectProtoContainsProto(&s->proto, IP_GET_IPPROTO(p)) == 0) {
603  SCLogDebug("proto didn't match");
604  return 0;
605  }
606 
607  /* check the source & dst port in the sig */
608  if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP || p->proto == IPPROTO_SCTP) {
609  if (!(sflags & SIG_FLAG_DP_ANY)) {
610  if (p->flags & PKT_IS_FRAGMENT)
611  return 0;
612  DetectPort *dport = DetectPortLookupGroup(s->dp,p->dp);
613  if (dport == NULL) {
614  SCLogDebug("dport didn't match.");
615  return 0;
616  }
617  }
618  if (!(sflags & SIG_FLAG_SP_ANY)) {
619  if (p->flags & PKT_IS_FRAGMENT)
620  return 0;
621  DetectPort *sport = DetectPortLookupGroup(s->sp,p->sp);
622  if (sport == NULL) {
623  SCLogDebug("sport didn't match.");
624  return 0;
625  }
626  }
627  } else if ((sflags & (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) != (SIG_FLAG_DP_ANY|SIG_FLAG_SP_ANY)) {
628  SCLogDebug("port-less protocol and sig needs ports");
629  return 0;
630  }
631 
632  /* check the destination address */
633  if (!(sflags & SIG_FLAG_DST_ANY)) {
634  if (PKT_IS_IPV4(p)) {
636  return 0;
637  } else if (PKT_IS_IPV6(p)) {
639  return 0;
640  }
641  }
642  /* check the source address */
643  if (!(sflags & SIG_FLAG_SRC_ANY)) {
644  if (PKT_IS_IPV4(p)) {
646  return 0;
647  } else if (PKT_IS_IPV6(p)) {
649  return 0;
650  }
651  }
652 
653  return 1;
654 }
655 
656 /** \internal
657  * \brief run packet/stream prefilter engines
658  */
659 static inline void DetectRunPrefilterPkt(
660  ThreadVars *tv,
662  DetectEngineThreadCtx *det_ctx,
663  Packet *p,
664  DetectRunScratchpad *scratch
665 )
666 {
667  DetectPrefilterSetNonPrefilterList(p, det_ctx, scratch);
668 
669  /* create our prefilter mask */
670  PacketCreateMask(p, &scratch->pkt_mask, scratch->alproto, scratch->app_decoder_events);
671 
672  /* build and prefilter non_pf list against the mask of the packet */
674  det_ctx->non_pf_id_cnt = 0;
675  if (likely(det_ctx->non_pf_store_cnt > 0)) {
676  DetectPrefilterBuildNonPrefilterList(det_ctx, scratch->pkt_mask, scratch->alproto);
677  }
679 
680  /* run the prefilter engines */
681  Prefilter(det_ctx, scratch->sgh, p, scratch->flow_flags);
682  /* create match list if we have non-pf and/or pf */
683  if (det_ctx->non_pf_store_cnt || det_ctx->pmq.rule_id_array_cnt) {
685  DetectPrefilterMergeSort(de_ctx, det_ctx);
687  }
688 
689 #ifdef PROFILING
690  if (tv) {
691  StatsAddUI64(tv, det_ctx->counter_mpm_list,
692  (uint64_t)det_ctx->pmq.rule_id_array_cnt);
694  (uint64_t)det_ctx->non_pf_store_cnt);
695  /* non mpm sigs after mask prefilter */
697  (uint64_t)det_ctx->non_pf_id_cnt);
698  }
699 #endif
700 }
701 
702 static inline void DetectRulePacketRules(
703  ThreadVars * const tv,
704  DetectEngineCtx * const de_ctx,
705  DetectEngineThreadCtx * const det_ctx,
706  Packet * const p,
707  Flow * const pflow,
708  const DetectRunScratchpad *scratch
709 )
710 {
711  const Signature *s = NULL;
712  const Signature *next_s = NULL;
713 
714  /* inspect the sigs against the packet */
715  /* Prefetch the next signature. */
716  SigIntId match_cnt = det_ctx->match_array_cnt;
717 #ifdef PROFILING
718  if (tv) {
720  (uint64_t)match_cnt);
721  }
722 #endif
723  Signature **match_array = det_ctx->match_array;
724 
725  SGH_PROFILING_RECORD(det_ctx, scratch->sgh);
726 #ifdef PROFILING
727  if (match_cnt >= de_ctx->profile_match_logging_threshold)
728  RulesDumpMatchArray(det_ctx, scratch->sgh, p);
729 #endif
730 
731  uint32_t sflags, next_sflags = 0;
732  if (match_cnt) {
733  next_s = *match_array++;
734  next_sflags = next_s->flags;
735  }
736  while (match_cnt--) {
738  uint8_t alert_flags = 0;
739  bool state_alert = false;
740 #ifdef PROFILING
741  bool smatch = false; /* signature match */
742 #endif
743  s = next_s;
744  sflags = next_sflags;
745  if (match_cnt) {
746  next_s = *match_array++;
747  next_sflags = next_s->flags;
748  }
749  const uint8_t s_proto_flags = s->proto.flags;
750 
751  SCLogDebug("inspecting signature id %"PRIu32"", s->id);
752 
753  if (s->app_inspect != NULL) {
754  goto next; // handle sig in DetectRunTx
755  }
756 
757  /* don't run mask check for stateful rules.
758  * There we depend on prefilter */
759  if ((s->mask & scratch->pkt_mask) != s->mask) {
760  SCLogDebug("mask mismatch %x & %x != %x", s->mask, scratch->pkt_mask, s->mask);
761  goto next;
762  }
763 
764  if (unlikely(sflags & SIG_FLAG_DSIZE)) {
765  if (likely(p->payload_len < s->dsize_low || p->payload_len > s->dsize_high)) {
766  SCLogDebug("kicked out as p->payload_len %u, dsize low %u, hi %u",
767  p->payload_len, s->dsize_low, s->dsize_high);
768  goto next;
769  }
770  }
771 
772  /* if the sig has alproto and the session as well they should match */
773  if (likely(sflags & SIG_FLAG_APPLAYER)) {
774  if (s->alproto != ALPROTO_UNKNOWN && s->alproto != scratch->alproto) {
775  if (s->alproto == ALPROTO_DCERPC) {
776  if (scratch->alproto != ALPROTO_SMB) {
777  SCLogDebug("DCERPC sig, alproto not SMB");
778  goto next;
779  }
780  } else {
781  SCLogDebug("alproto mismatch");
782  goto next;
783  }
784  }
785  }
786 
787  if (DetectRunInspectRuleHeader(p, pflow, s, sflags, s_proto_flags) == 0) {
788  goto next;
789  }
790 
791  if (DetectEnginePktInspectionRun(tv, det_ctx, s, pflow, p, &alert_flags) == false) {
792  goto next;
793  }
794 
795 #ifdef PROFILING
796  smatch = true;
797 #endif
798  DetectRunPostMatch(tv, det_ctx, p, s);
799 
800  if (!(sflags & SIG_FLAG_NOALERT)) {
801  /* stateful sigs call PacketAlertAppend from DeStateDetectStartDetection */
802  if (!state_alert)
803  PacketAlertAppend(det_ctx, s, p, 0, alert_flags);
804  } else {
805  /* apply actions even if not alerting */
806  DetectSignatureApplyActions(p, s, alert_flags);
807  }
808 next:
809  DetectVarProcessList(det_ctx, pflow, p);
810  DetectReplaceFree(det_ctx);
811  RULE_PROFILING_END(det_ctx, s, smatch, p);
812 
813  det_ctx->flags = 0;
814  continue;
815  }
816 }
817 
818 static DetectRunScratchpad DetectRunSetup(
819  const DetectEngineCtx *de_ctx,
820  DetectEngineThreadCtx *det_ctx,
821  Packet * const p, Flow * const pflow)
822 {
823  AppProto alproto = ALPROTO_UNKNOWN;
824  uint8_t flow_flags = 0; /* flow/state flags */
825  bool app_decoder_events = false;
826 
828 
829 #ifdef UNITTESTS
830  p->alerts.cnt = 0;
831 #endif
832  det_ctx->ticker++;
833  det_ctx->filestore_cnt = 0;
834  det_ctx->base64_decoded_len = 0;
835  det_ctx->raw_stream_progress = 0;
836  det_ctx->match_array_cnt = 0;
837 
838 #ifdef DEBUG
839  if (p->flags & PKT_STREAM_ADD) {
840  det_ctx->pkt_stream_add_cnt++;
841  }
842 #endif
843 
844  /* grab the protocol state we will detect on */
845  if (p->flags & PKT_HAS_FLOW) {
846  DEBUG_VALIDATE_BUG_ON(pflow == NULL);
847 
848  if (p->flowflags & FLOW_PKT_TOSERVER) {
849  flow_flags = STREAM_TOSERVER;
850  SCLogDebug("flag STREAM_TOSERVER set");
851  } else if (p->flowflags & FLOW_PKT_TOCLIENT) {
852  flow_flags = STREAM_TOCLIENT;
853  SCLogDebug("flag STREAM_TOCLIENT set");
854  }
855  SCLogDebug("p->flowflags 0x%02x", p->flowflags);
856 
857  if (p->flags & PKT_STREAM_EOF) {
858  flow_flags |= STREAM_EOF;
859  SCLogDebug("STREAM_EOF set");
860  }
861 
862  /* store tenant_id in the flow so that we can use it
863  * for creating pseudo packets */
864  if (p->tenant_id > 0 && pflow->tenant_id == 0) {
865  pflow->tenant_id = p->tenant_id;
866  }
867 
868  /* live ruleswap check for flow updates */
869  if (pflow->de_ctx_version == 0) {
870  /* first time this flow is inspected, set id */
871  pflow->de_ctx_version = de_ctx->version;
872  } else if (pflow->de_ctx_version != de_ctx->version) {
873  /* first time we inspect flow with this de_ctx, reset */
874  pflow->flags &= ~FLOW_SGH_TOSERVER;
875  pflow->flags &= ~FLOW_SGH_TOCLIENT;
876  pflow->sgh_toserver = NULL;
877  pflow->sgh_toclient = NULL;
878 
879  pflow->de_ctx_version = de_ctx->version;
880  GenericVarFree(pflow->flowvar);
881  pflow->flowvar = NULL;
882 
884  }
885 
886  /* Retrieve the app layer state and protocol and the tcp reassembled
887  * stream chunks. */
888  if ((p->proto == IPPROTO_TCP && (p->flags & PKT_STREAM_EST)) ||
889  (p->proto == IPPROTO_UDP) ||
890  (p->proto == IPPROTO_SCTP && (p->flowflags & FLOW_PKT_ESTABLISHED)))
891  {
892  /* update flow flags with knowledge on disruptions */
893  flow_flags = FlowGetDisruptionFlags(pflow, flow_flags);
894  alproto = FlowGetAppProtocol(pflow);
895  if (p->proto == IPPROTO_TCP && pflow->protoctx &&
898  flow_flags |= STREAM_FLUSH;
899  }
900  SCLogDebug("alproto %u", alproto);
901  } else {
902  SCLogDebug("packet doesn't have established flag set (proto %d)", p->proto);
903  }
904 
905  app_decoder_events = AppLayerParserHasDecoderEvents(pflow->alparser);
906  }
907 
908  DetectRunScratchpad pad = { alproto, flow_flags, app_decoder_events, NULL, 0 };
910  return pad;
911 }
912 
913 static inline void DetectRunPostRules(
914  ThreadVars *tv,
916  DetectEngineThreadCtx *det_ctx,
917  Packet * const p,
918  Flow * const pflow,
919  DetectRunScratchpad *scratch)
920 {
921  /* see if we need to increment the inspect_id and reset the de_state */
922  if (pflow && pflow->alstate) {
924  DeStateUpdateInspectTransactionId(pflow, scratch->flow_flags, (scratch->sgh == NULL));
926  }
927 
928  /* so now let's iterate the alerts and remove the ones after a pass rule
929  * matched (if any). This is done inside PacketAlertFinalize() */
930  /* PR: installed "tag" keywords are handled after the threshold inspection */
931 
933  PacketAlertFinalize(de_ctx, det_ctx, p);
934  if (p->alerts.cnt > 0) {
935  StatsAddUI64(tv, det_ctx->counter_alerts, (uint64_t)p->alerts.cnt);
936  }
938 }
939 
940 static void DetectRunCleanup(DetectEngineThreadCtx *det_ctx,
941  Packet *p, Flow * const pflow)
942 {
944  /* cleanup pkt specific part of the patternmatcher */
945  PacketPatternCleanup(det_ctx);
946  InspectionBufferClean(det_ctx);
947 
948  if (pflow != NULL) {
949  /* update inspected tracker for raw reassembly */
950  if (p->proto == IPPROTO_TCP && pflow->protoctx != NULL &&
951  (p->flags & PKT_STREAM_EST))
952  {
954  det_ctx->raw_stream_progress);
955  }
956  }
958  SCReturn;
959 }
960 
962 {
964  det_ctx->tx_candidates = SCCalloc(size, sizeof(RuleMatchCandidateTx));
965  if (det_ctx->tx_candidates == NULL) {
966  FatalError(SC_ERR_MEM_ALLOC, "failed to allocate %"PRIu64" bytes",
967  (uint64_t)(size * sizeof(RuleMatchCandidateTx)));
968  }
969  det_ctx->tx_candidates_size = size;
970  SCLogDebug("array initialized to %u elements (%"PRIu64" bytes)",
971  size, (uint64_t)(size * sizeof(RuleMatchCandidateTx)));
972 }
973 
975 {
976  SCFree(det_ctx->tx_candidates);
977  det_ctx->tx_candidates_size = 0;
978 }
979 
980 /* if size >= cur_space */
981 static inline bool RuleMatchCandidateTxArrayHasSpace(const DetectEngineThreadCtx *det_ctx,
982  const uint32_t need)
983 {
984  if (det_ctx->tx_candidates_size >= need)
985  return 1;
986  return 0;
987 }
988 
989 /* realloc */
990 static int RuleMatchCandidateTxArrayExpand(DetectEngineThreadCtx *det_ctx, const uint32_t needed)
991 {
992  const uint32_t old_size = det_ctx->tx_candidates_size;
993  uint32_t new_size = needed;
994  void *ptmp = SCRealloc(det_ctx->tx_candidates, (new_size * sizeof(RuleMatchCandidateTx)));
995  if (ptmp == NULL) {
996  FatalError(SC_ERR_MEM_ALLOC, "failed to expand to %"PRIu64" bytes",
997  (uint64_t)(new_size * sizeof(RuleMatchCandidateTx)));
998  // TODO can this be handled more gracefully?
999  }
1000  det_ctx->tx_candidates = ptmp;
1001  det_ctx->tx_candidates_size = new_size;
1002  SCLogDebug("array expanded from %u to %u elements (%"PRIu64" bytes -> %"PRIu64" bytes)",
1003  old_size, new_size, (uint64_t)(old_size * sizeof(RuleMatchCandidateTx)),
1004  (uint64_t)(new_size * sizeof(RuleMatchCandidateTx))); (void)old_size;
1005  return 1;
1006 }
1007 
1008 
1009 /* TODO maybe let one with flags win if equal? */
1010 static int
1011 DetectRunTxSortHelper(const void *a, const void *b)
1012 {
1013  const RuleMatchCandidateTx *s0 = a;
1014  const RuleMatchCandidateTx *s1 = b;
1015  if (s1->id == s0->id)
1016  return 0;
1017  else
1018  return s0->id > s1->id ? -1 : 1;
1019 }
1020 
1021 #if 0
1022 #define TRACE_SID_TXS(sid,txs,...) \
1023  do { \
1024  char _trace_buf[2048]; \
1025  snprintf(_trace_buf, sizeof(_trace_buf), __VA_ARGS__); \
1026  SCLogNotice("%p/%"PRIu64"/%u: %s", txs->tx_ptr, txs->tx_id, sid, _trace_buf); \
1027  } while(0)
1028 #else
1029 #define TRACE_SID_TXS(sid,txs,...)
1030 #endif
1031 
1032 /** \internal
1033  * \brief inspect a rule against a transaction
1034  *
1035  * Inspect a rule. New detection or continued stateful
1036  * detection.
1037  *
1038  * \param stored_flags pointer to stored flags or NULL.
1039  * If stored_flags is set it means we're continueing
1040  * inspection from an earlier run.
1041  *
1042  * \retval bool true sig matched, false didn't match
1043  */
1044 static bool DetectRunTxInspectRule(ThreadVars *tv,
1046  DetectEngineThreadCtx *det_ctx,
1047  Packet *p,
1048  Flow *f,
1049  const uint8_t in_flow_flags, // direction, EOF, etc
1050  void *alstate,
1051  DetectTransaction *tx,
1052  const Signature *s,
1053  uint32_t *stored_flags,
1054  RuleMatchCandidateTx *can,
1055  DetectRunScratchpad *scratch)
1056 {
1057  uint8_t flow_flags = in_flow_flags;
1058  const int direction = (flow_flags & STREAM_TOSERVER) ? 0 : 1;
1059  uint32_t inspect_flags = stored_flags ? *stored_flags : 0;
1060  int total_matches = 0;
1061  int file_no_match = 0;
1062  bool retval = false;
1063  bool mpm_before_progress = false; // is mpm engine before progress?
1064  bool mpm_in_progress = false; // is mpm engine in a buffer we will revisit?
1065 
1066  /* see if we want to pass on the FLUSH flag */
1067  if ((s->flags & SIG_FLAG_FLUSH) == 0)
1068  flow_flags &=~ STREAM_FLUSH;
1069 
1070  TRACE_SID_TXS(s->id, tx, "starting %s", direction ? "toclient" : "toserver");
1071  TRACE_SID_TXS(s->id, tx, "FLUSH? %s", (flow_flags & STREAM_FLUSH)?"true":"false");
1072 
1073  /* for a new inspection we inspect pkt header and packet matches */
1074  if (likely(stored_flags == NULL)) {
1075  TRACE_SID_TXS(s->id, tx, "first inspect, run packet matches");
1076  if (DetectRunInspectRuleHeader(p, f, s, s->flags, s->proto.flags) == 0) {
1077  TRACE_SID_TXS(s->id, tx, "DetectRunInspectRuleHeader() no match");
1078  return false;
1079  }
1080  if (DetectEnginePktInspectionRun(tv, det_ctx, s, f, p, NULL) == false) {
1081  TRACE_SID_TXS(s->id, tx, "DetectEnginePktInspectionRun no match");
1082  return false;
1083  }
1084  /* stream mpm and negated mpm sigs can end up here with wrong proto */
1085  if (!(f->alproto == s->alproto || s->alproto == ALPROTO_UNKNOWN)) {
1086  TRACE_SID_TXS(s->id, tx, "alproto mismatch");
1087  return false;
1088  }
1089  }
1090 
1091  const DetectEngineAppInspectionEngine *engine = s->app_inspect;
1092  while (engine != NULL) { // TODO could be do {} while as s->app_inspect cannot be null
1093  TRACE_SID_TXS(s->id, tx, "engine %p inspect_flags %x", engine, inspect_flags);
1094  if (!(inspect_flags & BIT_U32(engine->id)) &&
1095  direction == engine->dir)
1096  {
1097  const bool skip_engine = (engine->alproto != 0 && engine->alproto != f->alproto);
1098  /* special case: file_data on 'alert tcp' will have engines
1099  * in the list that are not for us. */
1100  if (unlikely(skip_engine)) {
1101  engine = engine->next;
1102  continue;
1103  }
1104 
1105  /* engines are sorted per progress, except that the one with
1106  * mpm/prefilter enabled is first */
1107  if (tx->tx_progress < engine->progress) {
1108  SCLogDebug("tx progress %d < engine progress %d",
1109  tx->tx_progress, engine->progress);
1110  break;
1111  }
1112  if (engine->mpm) {
1113  if (tx->tx_progress > engine->progress) {
1114  mpm_before_progress = true;
1115  } else if (tx->tx_progress == engine->progress) {
1116  mpm_in_progress = true;
1117  }
1118  }
1119 
1120  /* run callback: but bypass stream callback if we can */
1121  int match;
1122  if (unlikely(engine->stream && can->stream_stored)) {
1123  match = can->stream_result;
1124  TRACE_SID_TXS(s->id, tx, "stream skipped, stored result %d used instead", match);
1125  } else {
1126  KEYWORD_PROFILING_SET_LIST(det_ctx, engine->sm_list);
1127  if (engine->Callback) {
1128  match = engine->Callback(tv, de_ctx, det_ctx,
1129  s, engine->smd, f, flow_flags, alstate, tx->tx_ptr, tx->tx_id);
1130  } else {
1131  BUG_ON(engine->v2.Callback == NULL);
1132  match = engine->v2.Callback(de_ctx, det_ctx, engine,
1133  s, f, flow_flags, alstate, tx->tx_ptr, tx->tx_id);
1134  }
1135  TRACE_SID_TXS(s->id, tx, "engine %p match %d", engine, match);
1136  if (engine->stream) {
1137  can->stream_stored = true;
1138  can->stream_result = match;
1139  TRACE_SID_TXS(s->id, tx, "stream ran, store result %d for next tx (if any)", match);
1140  }
1141  }
1142  if (match == DETECT_ENGINE_INSPECT_SIG_MATCH) {
1143  inspect_flags |= BIT_U32(engine->id);
1144  engine = engine->next;
1145  total_matches++;
1146  continue;
1147  } else if (match == DETECT_ENGINE_INSPECT_SIG_MATCH_MORE_FILES) {
1148  /* if the file engine matched, but indicated more
1149  * files are still in progress, we don't set inspect
1150  * flags as these would end inspection for this tx */
1151  engine = engine->next;
1152  total_matches++;
1153  continue;
1154  } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH) {
1155  inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
1156  inspect_flags |= BIT_U32(engine->id);
1157  } else if (match == DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILES) {
1158  inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
1159  inspect_flags |= BIT_U32(engine->id);
1160  file_no_match = 1;
1161  }
1162  /* implied DETECT_ENGINE_INSPECT_SIG_NO_MATCH */
1163  if (engine->mpm && mpm_before_progress) {
1164  inspect_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
1165  inspect_flags |= BIT_U32(engine->id);
1166  }
1167  break;
1168  }
1169  engine = engine->next;
1170  }
1171  TRACE_SID_TXS(s->id, tx, "inspect_flags %x, total_matches %u, engine %p",
1172  inspect_flags, total_matches, engine);
1173 
1174  if (engine == NULL && total_matches) {
1175  inspect_flags |= DE_STATE_FLAG_FULL_INSPECT;
1176  TRACE_SID_TXS(s->id, tx, "MATCH");
1177  retval = true;
1178  }
1179 
1180  if (stored_flags) {
1181  *stored_flags = inspect_flags;
1182  TRACE_SID_TXS(s->id, tx, "continue inspect flags %08x", inspect_flags);
1183  } else {
1184  // store... or? If tx is done we might not want to come back to this tx
1185 
1186  // also... if mpmid tracking is enabled, we won't do a sig again for this tx...
1187  TRACE_SID_TXS(s->id, tx, "start inspect flags %08x", inspect_flags);
1188  if (inspect_flags & DE_STATE_FLAG_SIG_CANT_MATCH) {
1189  if (file_no_match) {
1190  /* if we have a mismatch on a file sig, we need to keep state.
1191  * We may get another file on the same tx (for http and smtp
1192  * at least), so for a new file we need to re-eval the sig.
1193  * Thoughts / TODO:
1194  * - not for some protos that have 1 file per tx (e.g. nfs)
1195  * - maybe we only need this for file sigs that mix with
1196  * other matches? E.g. 'POST + filename', is different than
1197  * just 'filename'.
1198  */
1199  DetectRunStoreStateTx(scratch->sgh, f, tx->tx_ptr, tx->tx_id, s,
1200  inspect_flags, flow_flags, file_no_match);
1201  }
1202  } else if ((inspect_flags & DE_STATE_FLAG_FULL_INSPECT) && mpm_before_progress) {
1203  TRACE_SID_TXS(s->id, tx, "no need to store match sig, "
1204  "mpm won't trigger for it anymore");
1205 
1206  if (inspect_flags & DE_STATE_FLAG_FILE_INSPECT) {
1207  TRACE_SID_TXS(s->id, tx, "except that for new files, "
1208  "we may have to revisit anyway");
1209  DetectRunStoreStateTx(scratch->sgh, f, tx->tx_ptr, tx->tx_id, s,
1210  inspect_flags, flow_flags, file_no_match);
1211  }
1212  } else if ((inspect_flags & DE_STATE_FLAG_FULL_INSPECT) == 0 && mpm_in_progress) {
1213  TRACE_SID_TXS(s->id, tx, "no need to store no-match sig, "
1214  "mpm will revisit it");
1215  } else {
1216  TRACE_SID_TXS(s->id, tx, "storing state: flags %08x", inspect_flags);
1217  DetectRunStoreStateTx(scratch->sgh, f, tx->tx_ptr, tx->tx_id, s,
1218  inspect_flags, flow_flags, file_no_match);
1219  }
1220  }
1221 
1222  return retval;
1223 }
1224 
1225 /** \internal
1226  * \brief get a DetectTransaction object
1227  * \retval struct filled with relevant info or all nulls/0s
1228  */
1229 static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alproto,
1230  void *alstate, const uint64_t tx_id, void *tx_ptr, const int tx_end_state,
1231  const uint8_t flow_flags)
1232 {
1233  const uint64_t detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx_ptr, flow_flags);
1234  if (detect_flags & APP_LAYER_TX_INSPECTED_FLAG) {
1235  SCLogDebug("%"PRIu64" tx already fully inspected for %s. Flags %016"PRIx64,
1236  tx_id, flow_flags & STREAM_TOSERVER ? "toserver" : "toclient",
1237  detect_flags);
1238  DetectTransaction no_tx = { NULL, 0, NULL, 0, 0, 0, 0, 0, };
1239  return no_tx;
1240  }
1241 
1242  const int tx_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx_ptr, flow_flags);
1243  const int dir_int = (flow_flags & STREAM_TOSERVER) ? 0 : 1;
1244  DetectEngineState *tx_de_state = AppLayerParserGetTxDetectState(ipproto, alproto, tx_ptr);
1245  DetectEngineStateDirection *tx_dir_state = tx_de_state ? &tx_de_state->dir_state[dir_int] : NULL;
1246  uint64_t prefilter_flags = detect_flags & APP_LAYER_TX_PREFILTER_MASK;
1247 
1248  DetectTransaction tx = {
1249  .tx_ptr = tx_ptr,
1250  .tx_id = tx_id,
1251  .de_state = tx_dir_state,
1252  .detect_flags = detect_flags,
1253  .prefilter_flags = prefilter_flags,
1254  .prefilter_flags_orig = prefilter_flags,
1255  .tx_progress = tx_progress,
1256  .tx_end_state = tx_end_state,
1257  };
1258  return tx;
1259 }
1260 
1261 static void DetectRunTx(ThreadVars *tv,
1263  DetectEngineThreadCtx *det_ctx,
1264  Packet *p,
1265  Flow *f,
1266  DetectRunScratchpad *scratch)
1267 {
1268  const uint8_t flow_flags = scratch->flow_flags;
1269  const SigGroupHead * const sgh = scratch->sgh;
1270  void * const alstate = f->alstate;
1271  const uint8_t ipproto = f->proto;
1272  const AppProto alproto = f->alproto;
1273 
1274  const uint64_t total_txs = AppLayerParserGetTxCnt(f, alstate);
1275  uint64_t tx_id_min = AppLayerParserGetTransactionInspectId(f->alparser, flow_flags);
1276  const int tx_end_state = AppLayerParserGetStateProgressCompletionStatus(alproto, flow_flags);
1277 
1278  AppLayerGetTxIteratorFunc IterFunc = AppLayerGetTxIterator(ipproto, alproto);
1279  AppLayerGetTxIterState state;
1280  memset(&state, 0, sizeof(state));
1281 
1282  while (1) {
1283  AppLayerGetTxIterTuple ires = IterFunc(ipproto, alproto, alstate, tx_id_min, total_txs, &state);
1284  if (ires.tx_ptr == NULL)
1285  break;
1286 
1287  DetectTransaction tx = GetDetectTx(ipproto, alproto,
1288  alstate, ires.tx_id, ires.tx_ptr, tx_end_state, flow_flags);
1289  if (tx.tx_ptr == NULL) {
1290  SCLogDebug("%p/%"PRIu64" no transaction to inspect",
1291  tx.tx_ptr, tx_id_min);
1292 
1293  tx_id_min++; // next (if any) run look for +1
1294  goto next;
1295  }
1296  tx_id_min = tx.tx_id + 1; // next look for cur + 1
1297 
1298  uint32_t array_idx = 0;
1299  uint32_t total_rules = det_ctx->match_array_cnt;
1300  total_rules += (tx.de_state ? tx.de_state->cnt : 0);
1301 
1302  /* run prefilter engines and merge results into a candidates array */
1303  if (sgh->tx_engines) {
1305  DetectRunPrefilterTx(det_ctx, sgh, p, ipproto, flow_flags, alproto,
1306  alstate, &tx);
1308  SCLogDebug("%p/%"PRIu64" rules added from prefilter: %u candidates",
1309  tx.tx_ptr, tx.tx_id, det_ctx->pmq.rule_id_array_cnt);
1310 
1311  total_rules += det_ctx->pmq.rule_id_array_cnt;
1312  if (!(RuleMatchCandidateTxArrayHasSpace(det_ctx, total_rules))) {
1313  RuleMatchCandidateTxArrayExpand(det_ctx, total_rules);
1314  }
1315 
1316  for (uint32_t i = 0; i < det_ctx->pmq.rule_id_array_cnt; i++) {
1317  const Signature *s = de_ctx->sig_array[det_ctx->pmq.rule_id_array[i]];
1318  const SigIntId id = s->num;
1319  det_ctx->tx_candidates[array_idx].s = s;
1320  det_ctx->tx_candidates[array_idx].id = id;
1321  det_ctx->tx_candidates[array_idx].flags = NULL;
1322  det_ctx->tx_candidates[array_idx].stream_reset = 0;
1323  array_idx++;
1324  }
1325  } else {
1326  if (!(RuleMatchCandidateTxArrayHasSpace(det_ctx, total_rules))) {
1327  RuleMatchCandidateTxArrayExpand(det_ctx, total_rules);
1328  }
1329  }
1330 
1331  /* merge 'state' rules from the regular prefilter */
1332  uint32_t x = array_idx;
1333  for (uint32_t i = 0; i < det_ctx->match_array_cnt; i++) {
1334  const Signature *s = det_ctx->match_array[i];
1335  if (s->app_inspect != NULL) {
1336  const SigIntId id = s->num;
1337  det_ctx->tx_candidates[array_idx].s = s;
1338  det_ctx->tx_candidates[array_idx].id = id;
1339  det_ctx->tx_candidates[array_idx].flags = NULL;
1340  det_ctx->tx_candidates[array_idx].stream_reset = 0;
1341  array_idx++;
1342 
1343  SCLogDebug("%p/%"PRIu64" rule %u (%u) added from 'match' list",
1344  tx.tx_ptr, tx.tx_id, s->id, id);
1345  }
1346  }
1347  SCLogDebug("%p/%"PRIu64" rules added from 'match' list: %u",
1348  tx.tx_ptr, tx.tx_id, array_idx - x); (void)x;
1349 
1350  /* merge stored state into results */
1351  if (tx.de_state != NULL) {
1352  const uint32_t old = array_idx;
1353 
1354  /* if tx.de_state->flags has 'new file' set and sig below has
1355  * 'file inspected' flag, reset the file part of the state */
1356  const bool have_new_file = (tx.de_state->flags & DETECT_ENGINE_STATE_FLAG_FILE_NEW);
1357  if (have_new_file) {
1358  SCLogDebug("%p/%"PRIu64" destate: need to consider new file",
1359  tx.tx_ptr, tx.tx_id);
1361  }
1362 
1363  SigIntId state_cnt = 0;
1364  DeStateStore *tx_store = tx.de_state->head;
1365  for (; tx_store != NULL; tx_store = tx_store->next) {
1366  SCLogDebug("tx_store %p", tx_store);
1367 
1368  SigIntId store_cnt = 0;
1369  for (store_cnt = 0;
1370  store_cnt < DE_STATE_CHUNK_SIZE && state_cnt < tx.de_state->cnt;
1371  store_cnt++, state_cnt++)
1372  {
1373  DeStateStoreItem *item = &tx_store->store[store_cnt];
1374  SCLogDebug("rule id %u, inspect_flags %u", item->sid, item->flags);
1375  if (have_new_file && (item->flags & DE_STATE_FLAG_FILE_INSPECT)) {
1376  /* remove part of the state. File inspect engine will now
1377  * be able to run again */
1379  SCLogDebug("rule id %u, post file reset inspect_flags %u", item->sid, item->flags);
1380  }
1381  det_ctx->tx_candidates[array_idx].s = de_ctx->sig_array[item->sid];
1382  det_ctx->tx_candidates[array_idx].id = item->sid;
1383  det_ctx->tx_candidates[array_idx].flags = &item->flags;
1384  det_ctx->tx_candidates[array_idx].stream_reset = 0;
1385  array_idx++;
1386  }
1387  }
1388  if (old && old != array_idx) {
1389  qsort(det_ctx->tx_candidates, array_idx, sizeof(RuleMatchCandidateTx),
1390  DetectRunTxSortHelper);
1391 
1392  SCLogDebug("%p/%"PRIu64" rules added from 'continue' list: %u",
1393  tx.tx_ptr, tx.tx_id, array_idx - old);
1394  }
1395  }
1396 
1397  det_ctx->tx_id = tx.tx_id;
1398  det_ctx->tx_id_set = 1;
1399  det_ctx->p = p;
1400 
1401  /* run rules: inspect the match candidates */
1402  for (uint32_t i = 0; i < array_idx; i++) {
1403  RuleMatchCandidateTx *can = &det_ctx->tx_candidates[i];
1404  const Signature *s = det_ctx->tx_candidates[i].s;
1405  uint32_t *inspect_flags = det_ctx->tx_candidates[i].flags;
1406 
1407  /* deduplicate: rules_array is sorted, but not deduplicated:
1408  * both mpm and stored state could give us the same sid.
1409  * As they are back to back in that case we can check for it
1410  * here. We select the stored state one. */
1411  if ((i + 1) < array_idx) {
1412  if (det_ctx->tx_candidates[i].s == det_ctx->tx_candidates[i+1].s) {
1413  if (det_ctx->tx_candidates[i].flags != NULL) {
1414  i++;
1415  SCLogDebug("%p/%"PRIu64" inspecting SKIP NEXT: sid %u (%u), flags %08x",
1416  tx.tx_ptr, tx.tx_id, s->id, s->num, inspect_flags ? *inspect_flags : 0);
1417  } else if (det_ctx->tx_candidates[i+1].flags != NULL) {
1418  SCLogDebug("%p/%"PRIu64" inspecting SKIP CURRENT: sid %u (%u), flags %08x",
1419  tx.tx_ptr, tx.tx_id, s->id, s->num, inspect_flags ? *inspect_flags : 0);
1420  continue;
1421  } else {
1422  // if it's all the same, inspect the current one and skip next.
1423  i++;
1424  SCLogDebug("%p/%"PRIu64" inspecting SKIP NEXT: sid %u (%u), flags %08x",
1425  tx.tx_ptr, tx.tx_id, s->id, s->num, inspect_flags ? *inspect_flags : 0);
1426  }
1427  }
1428  }
1429 
1430  SCLogDebug("%p/%"PRIu64" inspecting: sid %u (%u), flags %08x",
1431  tx.tx_ptr, tx.tx_id, s->id, s->num, inspect_flags ? *inspect_flags : 0);
1432 
1433  if (inspect_flags) {
1435  SCLogDebug("%p/%"PRIu64" inspecting: sid %u (%u), flags %08x ALREADY COMPLETE",
1436  tx.tx_ptr, tx.tx_id, s->id, s->num, *inspect_flags);
1437  continue;
1438  }
1439  }
1440 
1441  if (inspect_flags) {
1442  /* continue previous inspection */
1443  SCLogDebug("%p/%"PRIu64" Continueing sid %u", tx.tx_ptr, tx.tx_id, s->id);
1444  } else {
1445  /* start new inspection */
1446  SCLogDebug("%p/%"PRIu64" Start sid %u", tx.tx_ptr, tx.tx_id, s->id);
1447  }
1448 
1449  /* call individual rule inspection */
1451  const int r = DetectRunTxInspectRule(tv, de_ctx, det_ctx, p, f, flow_flags,
1452  alstate, &tx, s, inspect_flags, can, scratch);
1453  if (r == 1) {
1454  /* match */
1455  DetectRunPostMatch(tv, det_ctx, p, s);
1456 
1457  uint8_t alert_flags = (PACKET_ALERT_FLAG_STATE_MATCH|PACKET_ALERT_FLAG_TX);
1458  if (s->action & ACTION_DROP)
1459  alert_flags |= PACKET_ALERT_FLAG_DROP_FLOW;
1460 
1461  SCLogDebug("%p/%"PRIu64" sig %u (%u) matched", tx.tx_ptr, tx.tx_id, s->id, s->num);
1462  if (!(s->flags & SIG_FLAG_NOALERT)) {
1463  PacketAlertAppend(det_ctx, s, p, tx.tx_id, alert_flags);
1464  } else {
1465  DetectSignatureApplyActions(p, s, alert_flags);
1466  }
1467  }
1468  DetectVarProcessList(det_ctx, p->flow, p);
1469  RULE_PROFILING_END(det_ctx, s, r, p);
1470  }
1471 
1472  det_ctx->tx_id = 0;
1473  det_ctx->tx_id_set = 0;
1474  det_ctx->p = NULL;
1475 
1476  /* see if we have any updated state to store in the tx */
1477 
1478  uint64_t new_detect_flags = 0;
1479  /* this side of the tx is done */
1480  if (tx.tx_progress >= tx.tx_end_state) {
1481  new_detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
1482  SCLogDebug("%p/%"PRIu64" tx is done for direction %s. Flag %016"PRIx64,
1483  tx.tx_ptr, tx.tx_id,
1484  flow_flags & STREAM_TOSERVER ? "toserver" : "toclient",
1485  new_detect_flags);
1486  }
1487  if (tx.prefilter_flags != tx.prefilter_flags_orig) {
1488  new_detect_flags |= tx.prefilter_flags;
1489  SCLogDebug("%p/%"PRIu64" updated prefilter flags %016"PRIx64" "
1490  "(was: %016"PRIx64") for direction %s. Flag %016"PRIx64,
1492  flow_flags & STREAM_TOSERVER ? "toserver" : "toclient",
1493  new_detect_flags);
1494  }
1495  if (new_detect_flags != 0 &&
1496  (new_detect_flags | tx.detect_flags) != tx.detect_flags)
1497  {
1498  new_detect_flags |= tx.detect_flags;
1499  SCLogDebug("%p/%"PRIu64" Storing new flags %016"PRIx64" (was %016"PRIx64")",
1500  tx.tx_ptr, tx.tx_id, new_detect_flags, tx.detect_flags);
1501  AppLayerParserSetTxDetectFlags(ipproto, alproto, tx.tx_ptr,
1502  flow_flags, new_detect_flags);
1503  }
1504 next:
1505  InspectionBufferClean(det_ctx);
1506 
1507  if (!ires.has_next)
1508  break;
1509  }
1510 }
1511 
1512 /** \brief Apply action(s) and Set 'drop' sig info,
1513  * if applicable */
1515  const Signature *s, const uint8_t alert_flags)
1516 {
1518 
1519  if (s->action & ACTION_DROP) {
1520  if (p->alerts.drop.action == 0) {
1521  p->alerts.drop.num = s->num;
1522  p->alerts.drop.action = s->action;
1523  p->alerts.drop.s = (Signature *)s;
1524  }
1525  } else if (s->action & ACTION_PASS) {
1526  /* if an stream/app-layer match we enforce the pass for the flow */
1527  if ((p->flow != NULL) &&
1529  {
1530  FlowSetNoPacketInspectionFlag(p->flow);
1531  }
1532 
1533  }
1534 }
1535 
1536 static DetectEngineThreadCtx *GetTenantById(HashTable *h, uint32_t id)
1537 {
1538  /* technically we need to pass a DetectEngineThreadCtx struct with the
1539  * tentant_id member. But as that member is the first in the struct, we
1540  * can use the id directly. */
1541  return HashTableLookup(h, &id, 0);
1542 }
1543 
1544 static void DetectFlow(ThreadVars *tv,
1546  Packet *p)
1547 {
1548  if (p->flags & PKT_NOPACKET_INSPECTION) {
1549  /* hack: if we are in pass the entire flow mode, we need to still
1550  * update the inspect_id forward. So test for the condition here,
1551  * and call the update code if necessary. */
1552  const int pass = ((p->flow->flags & FLOW_NOPACKET_INSPECTION));
1553  if (pass) {
1554  uint8_t flags;
1555  if (p->flowflags & FLOW_PKT_TOSERVER) {
1557  } else {
1559  }
1562  }
1563  SCLogDebug("p->pcap %"PRIu64": no detection on packet, "
1564  "PKT_NOPACKET_INSPECTION is set", p->pcap_cnt);
1565  return;
1566  }
1567 
1568  /* see if the packet matches one or more of the sigs */
1569  (void)DetectRun(tv, de_ctx, det_ctx, p);
1570 }
1571 
1572 
1573 static void DetectNoFlow(ThreadVars *tv,
1575  Packet *p)
1576 {
1577  /* No need to perform any detection on this packet, if the the given flag is set.*/
1578  if ((p->flags & PKT_NOPACKET_INSPECTION) ||
1580  {
1581  return;
1582  }
1583 
1584  /* see if the packet matches one or more of the sigs */
1585  DetectRun(tv, de_ctx, det_ctx, p);
1586  return;
1587 }
1588 
1589 /** \brief Detection engine thread wrapper.
1590  * \param tv thread vars
1591  * \param p packet to inspect
1592  * \param data thread specific data
1593  * \param pq packet queue
1594  * \retval TM_ECODE_FAILED error
1595  * \retval TM_ECODE_OK ok
1596  */
1597 TmEcode Detect(ThreadVars *tv, Packet *p, void *data)
1598 {
1600 
1601  DetectEngineCtx *de_ctx = NULL;
1602  DetectEngineThreadCtx *det_ctx = (DetectEngineThreadCtx *)data;
1603  if (det_ctx == NULL) {
1604  printf("ERROR: Detect has no thread ctx\n");
1605  goto error;
1606  }
1607 
1608  if (unlikely(SC_ATOMIC_GET(det_ctx->so_far_used_by_detect) == 0)) {
1609  (void)SC_ATOMIC_SET(det_ctx->so_far_used_by_detect, 1);
1610  SCLogDebug("Detect Engine using new det_ctx - %p",
1611  det_ctx);
1612  }
1613 
1614  /* if in MT mode _and_ we have tenants registered, use
1615  * MT logic. */
1616  if (det_ctx->mt_det_ctxs_cnt > 0 && det_ctx->TenantGetId != NULL)
1617  {
1618  uint32_t tenant_id = p->tenant_id;
1619  if (tenant_id == 0)
1620  tenant_id = det_ctx->TenantGetId(det_ctx, p);
1621  if (tenant_id > 0 && tenant_id < det_ctx->mt_det_ctxs_cnt) {
1622  p->tenant_id = tenant_id;
1623  det_ctx = GetTenantById(det_ctx->mt_det_ctxs_hash, tenant_id);
1624  if (det_ctx == NULL)
1625  return TM_ECODE_OK;
1626  de_ctx = det_ctx->de_ctx;
1627  if (de_ctx == NULL)
1628  return TM_ECODE_OK;
1629 
1630  if (unlikely(SC_ATOMIC_GET(det_ctx->so_far_used_by_detect) == 0)) {
1631  (void)SC_ATOMIC_SET(det_ctx->so_far_used_by_detect, 1);
1632  SCLogDebug("MT de_ctx %p det_ctx %p (tenant %u)", de_ctx, det_ctx, tenant_id);
1633  }
1634  } else {
1635  /* use default if no tenants are registered for this packet */
1636  de_ctx = det_ctx->de_ctx;
1637  }
1638  } else {
1639  de_ctx = det_ctx->de_ctx;
1640  }
1641 
1642  if (p->flow) {
1643  DetectFlow(tv, de_ctx, det_ctx, p);
1644  } else {
1645  DetectNoFlow(tv, de_ctx, det_ctx, p);
1646  }
1647  return TM_ECODE_OK;
1648 error:
1649  return TM_ECODE_FAILED;
1650 }
1651 
1652 /** \brief disable file features we don't need
1653  * Called if we have no detection engine.
1654  */
1656 {
1657  DetectPostInspectFileFlagsUpdate(f, NULL /* no sgh */, STREAM_TOSERVER);
1658  DetectPostInspectFileFlagsUpdate(f, NULL /* no sgh */, STREAM_TOCLIENT);
1659 }
1660 
1661 #ifdef UNITTESTS
1662 /**
1663  * \brief wrapper for old tests
1664  */
1667  Packet *p)
1668 {
1669  DetectRun(th_v, de_ctx, det_ctx, p);
1670 }
1671 #endif
1672 
1673 /*
1674  * TESTS
1675  */
1676 
1677 #ifdef UNITTESTS
1678 #include "tests/detect.c"
1679 #endif
1680 
SigGroupHead_::non_pf_syn_store_cnt
uint32_t non_pf_syn_store_cnt
Definition: detect.h:1346
FLOWFILE_NO_MD5_TS
#define FLOWFILE_NO_MD5_TS
Definition: flow.h:122
DetectEngineThreadCtx_::non_pf_store_ptr
SignatureNonPrefilterStore * non_pf_store_ptr
Definition: detect.h:1094
SIG_GROUP_HEAD_HAVEFILEMD5
#define SIG_GROUP_HEAD_HAVEFILEMD5
Definition: detect.h:1233
FLOWFILE_NO_MD5_TC
#define FLOWFILE_NO_MD5_TC
Definition: flow.h:123
SigGroupHead_::tx_engines
PrefilterEngine * tx_engines
Definition: detect.h:1359
DetectEngineAppInspectionEngine_
Definition: detect.h:395
Packet_::proto
uint8_t proto
Definition: decode.h:431
RULE_PROFILING_END
#define RULE_PROFILING_END(ctx, r, m, p)
Definition: util-profiling.h:54
DE_STATE_CHUNK_SIZE
#define DE_STATE_CHUNK_SIZE
Definition: detect-engine-state.h:53
RuleMatchCandidateTx::stream_stored
bool stream_stored
Definition: detect.h:992
FLOWFILE_NO_SIZE_TS
#define FLOWFILE_NO_SIZE_TS
Definition: flow.h:134
PROF_DETECT_GETSGH
@ PROF_DETECT_GETSGH
Definition: suricata-common.h:398
FLOWFILE_NO_SIZE_TC
#define FLOWFILE_NO_SIZE_TC
Definition: flow.h:135
detect-engine.h
PACKET_ALERT_FLAG_STREAM_MATCH
#define PACKET_ALERT_FLAG_STREAM_MATCH
Definition: decode.h:285
PacketAlert_::s
const struct Signature_ * s
Definition: decode.h:274
detect-engine-proto.h
DetectEngineThreadCtx_::match_array_cnt
SigIntId match_array_cnt
Definition: detect.h:1089
DetectEngineStateDirection_::flags
uint8_t flags
Definition: detect-engine-state.h:88
Signature_::addr_src_match6
DetectMatchAddressIPv6 * addr_src_match6
Definition: detect.h:553
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1077
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
PACKET_ALERT_FLAG_TX
#define PACKET_ALERT_FLAG_TX
Definition: decode.h:287
DetectEngineCtx_::decoder_event_sgh
struct SigGroupHead_ * decoder_event_sgh
Definition: detect.h:859
DetectEngineCtx_::flow_gh
DetectEngineLookupFlow flow_gh[FLOW_STATES]
Definition: detect.h:795
DE_STATE_FLAG_SIG_CANT_MATCH
#define DE_STATE_FLAG_SIG_CANT_MATCH
Definition: detect-engine-state.h:57
DetectEngineThreadCtx_::counter_match_list
uint16_t counter_match_list
Definition: detect.h:1046
DetectEngineAppInspectionEngine_::next
struct DetectEngineAppInspectionEngine_ * next
Definition: detect.h:421
DETECT_PROTO_IPV6
#define DETECT_PROTO_IPV6
Definition: detect-engine-proto.h:34
detect-engine-siggroup.h
IPOnlyMatchPacket
void IPOnlyMatchPacket(ThreadVars *tv, const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectEngineIPOnlyCtx *io_ctx, DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p)
Match a packet against the IP Only detection engine contexts.
Definition: detect-engine-iponly.c:977
PKT_IS_IPV6
#define PKT_IS_IPV6(p)
Definition: decode.h:253
DetectEngineState_
Definition: detect-engine-state.h:92
Signature_::num
SigIntId num
Definition: detect.h:532
stream-tcp.h
Prefilter
void Prefilter(DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, Packet *p, const uint8_t flags)
Definition: detect-engine-prefilter.c:139
PrefilterRuleStore_::rule_id_array_cnt
uint32_t rule_id_array_cnt
Definition: util-prefilter.h:38
detect-engine-event.h
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1337
SIG_GROUP_HEAD_HAVEFILESIZE
#define SIG_GROUP_HEAD_HAVEFILESIZE
Definition: detect.h:1234
SCFree
#define SCFree(a)
Definition: util-mem.h:322
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
detect.c
SC_ATOMIC_SET
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
Definition: util-atomic.h:207
DetectEngineThreadCtx_::tx_id_set
uint16_t tx_id_set
Definition: detect.h:1072
ACTION_PASS
#define ACTION_PASS
Definition: action-globals.h:34
KEYWORD_PROFILING_SET_LIST
#define KEYWORD_PROFILING_SET_LIST(ctx, list)
Definition: util-profiling.h:65
DetectAddressMatchIPv4
int DetectAddressMatchIPv4(const DetectMatchAddressIPv4 *addrs, uint16_t addrs_cnt, const Address *a)
Match a packets address against a signatures addrs array.
Definition: detect-engine-address.c:1595
AppLayerParserSetTxDetectFlags
void AppLayerParserSetTxDetectFlags(uint8_t ipproto, AppProto alproto, void *tx, uint8_t dir, uint64_t flags)
Definition: app-layer-parser.c:1167
DetectEngineAppInspectionEngine_::Callback
InspectEngineFuncPtr Callback
Definition: detect.h:410
PacketPatternCleanup
void PacketPatternCleanup(DetectEngineThreadCtx *det_ctx)
cleans up the mpm instance after a match
Definition: detect-engine-mpm.c:656
Signature_::alproto
AppProto alproto
Definition: detect.h:526
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:335
SignatureNonPrefilterStore_::id
SigIntId id
Definition: detect.h:981
FLOW_SGH_TOCLIENT
#define FLOW_SGH_TOCLIENT
Definition: flow.h:69
Packet_::pcap_cnt
uint64_t pcap_cnt
Definition: decode.h:562
DetectEngineStateDirection_::cnt
SigIntId cnt
Definition: detect-engine-state.h:86
AppLayerGetTxIterator
AppLayerGetTxIteratorFunc AppLayerGetTxIterator(const uint8_t ipproto, const AppProto alproto)
Definition: app-layer-parser.c:688
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:2
Flow_::proto
uint8_t proto
Definition: flow.h:361
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:71
PacketAlerts_::cnt
uint16_t cnt
Definition: decode.h:294
AppLayerParserGetStateProgress
int AppLayerParserGetStateProgress(uint8_t ipproto, AppProto alproto, void *alstate, uint8_t flags)
get the progress value for a tx/protocol
Definition: app-layer-parser.c:1023
DetectEngineThreadCtx_::tx_id
uint64_t tx_id
Definition: detect.h:1074
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:330
FLOWFILE_NO_MAGIC_TS
#define FLOWFILE_NO_MAGIC_TS
Definition: flow.h:115
Packet_::flags
uint32_t flags
Definition: decode.h:444
ICMPV4_DEST_UNREACH_IS_VALID
#define ICMPV4_DEST_UNREACH_IS_VALID(p)
Definition: decode-icmpv4.h:247
Flow_
Flow data structure.
Definition: flow.h:342
DetectTransaction_::tx_end_state
const int tx_end_state
Definition: detect-engine-state.h:105
PROF_DETECT_ALERT
@ PROF_DETECT_ALERT
Definition: suricata-common.h:408
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1103
SIG_GROUP_HEAD_HAVEFILESHA1
#define SIG_GROUP_HEAD_HAVEFILESHA1
Definition: detect.h:1235
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:761
AppLayerParserGetStateProgressCompletionStatus
int AppLayerParserGetStateProgressCompletionStatus(AppProto alproto, uint8_t direction)
Definition: app-layer-parser.c:1056
DetectRunScratchpad
struct DetectRunScratchpad DetectRunScratchpad
PROF_DETECT_PF_TX
@ PROF_DETECT_PF_TX
Definition: suricata-common.h:404
DetectEngineThreadCtx_::p
Packet * p
Definition: detect.h:1075
DetectEngineState_::dir_state
DetectEngineStateDirection dir_state[2]
Definition: detect-engine-state.h:93
StreamReassembleRawUpdateProgress
void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, uint64_t progress)
update stream engine after detection
Definition: stream-tcp-reassemble.c:1275
RuleMatchCandidateTx::id
SigIntId id
Definition: detect.h:988
PROF_DETECT_CLEANUP
@ PROF_DETECT_CLEANUP
Definition: suricata-common.h:410
SIG_FLAG_DST_ANY
#define SIG_FLAG_DST_ANY
Definition: detect.h:212
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:218
HashTable_
Definition: util-hash.h:35
DetectEngineThreadCtx_::flags
uint16_t flags
Definition: detect.h:1069
PacketAlerts_::drop
PacketAlert drop
Definition: decode.h:298
APP_LAYER_TX_INSPECTED_FLAG
#define APP_LAYER_TX_INSPECTED_FLAG
Definition: app-layer-parser.h:49
DetectRunScratchpad
Definition: detect.c:62
SIG_GROUP_HEAD_HAVERAWSTREAM
#define SIG_GROUP_HEAD_HAVERAWSTREAM
Definition: detect.h:1229
FLOW_ACTION_DROP
#define FLOW_ACTION_DROP
Definition: flow.h:64
TcpStream_::flags
uint16_t flags
Definition: stream-tcp-private.h:95
FLOWFILE_NONE
#define FLOWFILE_NONE
Definition: flow.h:149
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:575
proto
uint8_t proto
Definition: decode-template.h:2
m
SCMutex m
Definition: flow-hash.h:5
DetectPort_::sh
struct SigGroupHead_ * sh
Definition: detect.h:202
PACKET_PROFILING_DETECT_END
#define PACKET_PROFILING_DETECT_END(p, id)
Definition: util-profiling.h:241
Detect
TmEcode Detect(ThreadVars *tv, Packet *p, void *data)
Detection engine thread wrapper.
Definition: detect.c:1597
FLOW_PKT_TOCLIENT_IPONLY_SET
#define FLOW_PKT_TOCLIENT_IPONLY_SET
Definition: flow.h:222
detect-engine-payload.h
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:440
SIG_FLAG_SRC_ANY
#define SIG_FLAG_SRC_ANY
Definition: detect.h:211
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:79
Flow_::protoctx
void * protoctx
Definition: flow.h:416
SigMatchData_
Data needed for Match()
Definition: detect.h:327
DeStateStoreItem_::sid
SigIntId sid
Definition: detect-engine-state.h:75
RuleMatchCandidateTx::s
const Signature * s
Definition: detect.h:998
KEYWORD_PROFILING_START
#define KEYWORD_PROFILING_START
Definition: util-profiling.h:69
DetectEngineThreadCtx_::counter_fnonmpm_list
uint16_t counter_fnonmpm_list
Definition: detect.h:1045
DetectEngineCtx_::version
uint32_t version
Definition: detect.h:855
Packet_::payload_len
uint16_t payload_len
Definition: decode.h:542
DisableDetectFlowFileFlags
void DisableDetectFlowFileFlags(Flow *f)
disable file features we don't need Called if we have no detection engine.
Definition: detect.c:1655
AppLayerParserGetTransactionInspectId
uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint8_t direction)
Definition: app-layer-parser.c:741
Signature_::dsize_low
uint16_t dsize_low
Definition: detect.h:528
Packet_::alerts
PacketAlerts alerts
Definition: decode.h:556
DetectTransaction_::tx_progress
const int tx_progress
Definition: detect-engine-state.h:104
DetectEngineThreadCtx_::counter_nonmpm_list
uint16_t counter_nonmpm_list
Definition: detect.h:1044
detect-engine-prefilter.h
Packet_::events
PacketEngineEvents events
Definition: decode.h:566
DetectTransaction_::prefilter_flags_orig
const uint64_t prefilter_flags_orig
Definition: detect-engine-state.h:103
PROF_DETECT_PF_SORT2
@ PROF_DETECT_PF_SORT2
Definition: suricata-common.h:406
pad
uint16_t pad
Definition: source-erf-file.c:8
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:78
PacketCreateMask
void PacketCreateMask(Packet *p, SignatureMask *mask, AppProto alproto, bool app_decoder_events)
Definition: detect-engine-build.c:395
SIG_FLAG_APPLAYER
#define SIG_FLAG_APPLAYER
Definition: detect.h:218
KEYWORD_PROFILING_END
#define KEYWORD_PROFILING_END(ctx, type, m)
Definition: util-profiling.h:83
detect-flowvar.h
DetectEngineThreadCtx_::mt_det_ctxs_hash
HashTable * mt_det_ctxs_hash
Definition: detect.h:1020
PacketAlert_::action
uint8_t action
Definition: decode.h:272
DetectEnginePktInspectionRun
bool DetectEnginePktInspectionRun(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, const Signature *s, Flow *f, Packet *p, uint8_t *alert_flags)
Definition: detect-engine.c:1394
DetectEngineThreadCtx_::ticker
uint64_t ticker
Definition: detect.h:1010
Flow_::sgh_toserver
const struct SigGroupHead_ * sgh_toserver
Definition: flow.h:461
PROF_DETECT_TX_UPDATE
@ PROF_DETECT_TX_UPDATE
Definition: suricata-common.h:409
DetectEngineAppInspectionEngine_::id
uint8_t id
Definition: detect.h:398
DetectRunStoreStateTx
void DetectRunStoreStateTx(const SigGroupHead *sgh, Flow *f, void *tx, uint64_t tx_id, const Signature *s, uint32_t inspect_flags, uint8_t flow_flags, const uint16_t file_no_match)
Definition: detect-engine-state.c:220
DetectEngineAppInspectionEngine_::sm_list
uint16_t sm_list
Definition: detect.h:401
FLOWFILE_INIT
#define FLOWFILE_INIT
Definition: flow.h:112
Flow_::alparser
AppLayerParserState * alparser
Definition: flow.h:453
DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILES
#define DETECT_ENGINE_INSPECT_SIG_CANT_MATCH_FILES
Definition: detect-engine-state.h:44
FLOWFILE_NO_SHA1_TC
#define FLOWFILE_NO_SHA1_TC
Definition: flow.h:127
DETECT_SM_LIST_POSTMATCH
@ DETECT_SM_LIST_POSTMATCH
Definition: detect.h:98
DetectEngineThreadCtx_::tx_candidates
RuleMatchCandidateTx * tx_candidates
Definition: detect.h:1091
Signature_::addr_src_match4
DetectMatchAddressIPv4 * addr_src_match4
Definition: detect.h:550
decode.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:16
DetectEngineThreadCtx_
Definition: detect.h:1004
DEBUG_VALIDATE_PACKET
#define DEBUG_VALIDATE_PACKET(p)
Definition: util-validate.h:110
DeStateStoreItem_::flags
uint32_t flags
Definition: detect-engine-state.h:74
PacketAlert_::num
SigIntId num
Definition: decode.h:271
PKT_STREAM_ADD
#define PKT_STREAM_ADD
Definition: decode.h:1074
DeStateUpdateInspectTransactionId
void DeStateUpdateInspectTransactionId(Flow *f, const uint8_t flags, const bool tag_txs_as_inspected)
update flow's inspection id's
Definition: detect-engine-state.c:252
FLOWFILE_NO_STORE_TS
#define FLOWFILE_NO_STORE_TS
Definition: flow.h:119
BIT_U32
#define BIT_U32(n)
Definition: suricata-common.h:369
DetectEngineThreadCtx_::tx_candidates_size
uint32_t tx_candidates_size
Definition: detect.h:1092
FLOW_PKT_TOSERVER_IPONLY_SET
#define FLOW_PKT_TOSERVER_IPONLY_SET
Definition: flow.h:221
SIG_FLAG_FLUSH
#define SIG_FLAG_FLUSH
Definition: detect.h:228
PKT_IS_FRAGMENT
#define PKT_IS_FRAGMENT
Definition: decode.h:1092
STREAM_TOSERVER
#define STREAM_TOSERVER
Definition: stream.h:31
SCEnter
#define SCEnter(...)
Definition: util-debug.h:337
detect-engine-mpm.h
DetectEngineLookupFlow_::sgh
struct SigGroupHead_ * sgh[256]
Definition: detect.h:700
HashTableLookup
void * HashTableLookup(HashTable *ht, void *data, uint16_t datalen)
Definition: util-hash.c:193
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
DeStateStore_::next
struct DeStateStore_ * next
Definition: detect-engine-state.h:80
SCRealloc
#define SCRealloc(x, a)
Definition: util-mem.h:238
DetectEngineAppInspectionEngine_::mpm
uint16_t mpm
Definition: detect.h:399
Packet_::sp
Port sp
Definition: decode.h:416
FLOWFILE_NO_SHA256_TS
#define FLOWFILE_NO_SHA256_TS
Definition: flow.h:130
DETECT_ENGINE_INSPECT_SIG_MATCH
#define DETECT_ENGINE_INSPECT_SIG_MATCH
Definition: detect-engine-state.h:39
PKT_DETECT_HAS_STREAMDATA
#define PKT_DETECT_HAS_STREAMDATA
Definition: decode.h:1106
SigMatchData_::type
uint8_t type
Definition: detect.h:328
StreamReassembleRawHasDataReady
bool StreamReassembleRawHasDataReady(TcpSession *ssn, Packet *p)
does the stream engine have data to inspect?
Definition: stream-tcp-reassemble.c:1231
detect-engine-port.h
DetectEngineThreadCtx_::non_pf_id_cnt
uint32_t non_pf_id_cnt
Definition: detect.h:1016
DetectPort_
Port structure for detection engine.
Definition: detect.h:191
app-layer-parser.h
Signature_::app_inspect
DetectEngineAppInspectionEngine * app_inspect
Definition: detect.h:570
util-detect.h
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:265
detect-engine-profile.h
Flow_::sgh_toclient
const struct SigGroupHead_ * sgh_toclient
Definition: flow.h:458
SigMatchSignatures
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1665
DetectEngineThreadCtx_::base64_decoded_len
int base64_decoded_len
Definition: detect.h:1137
SIG_FLAG_REQUIRE_FLOWVAR
#define SIG_FLAG_REQUIRE_FLOWVAR
Definition: detect.h:232
RuleMatchCandidateTx::stream_result
uint8_t stream_result
Definition: detect.h:993
Signature_::action
uint8_t action
Definition: detect.h:535
DetectTransaction_::tx_id
const uint64_t tx_id
Definition: detect-engine-state.h:99
DetectEngineLookupFlow_::udp
DetectPort * udp
Definition: detect.h:699
DetectEngineThreadCtx_::raw_stream_progress
uint64_t raw_stream_progress
Definition: detect.h:1029
FileUpdateFlowFileFlags
void FileUpdateFlowFileFlags(Flow *f, uint16_t set_file_flags, uint8_t direction)
set a flow's file flags
Definition: util-file.c:1053
SCReturn
#define SCReturn
Definition: util-debug.h:339
Signature_::flags
uint32_t flags
Definition: detect.h:523
PACKET_ALERT_FLAG_DROP_FLOW
#define PACKET_ALERT_FLAG_DROP_FLOW
Definition: decode.h:281
RuleMatchCandidateTxArrayFree
void RuleMatchCandidateTxArrayFree(DetectEngineThreadCtx *det_ctx)
Definition: detect.c:974
AppLayerGetTxIterState
Definition: app-layer-parser.h:114
DetectTransaction_::prefilter_flags
uint64_t prefilter_flags
Definition: detect-engine-state.h:102
Packet_
Definition: decode.h:408
SCCalloc
#define SCCalloc(nm, a)
Definition: util-mem.h:253
APP_LAYER_TX_PREFILTER_MASK
#define APP_LAYER_TX_PREFILTER_MASK
Definition: app-layer-parser.h:52
detect-engine-alert.h
conf.h
DetectRunScratchpad::pkt_mask
SignatureMask pkt_mask
Definition: detect.c:67
FlowSetIPOnlyFlag
void FlowSetIPOnlyFlag(Flow *f, int direction)
Set the IPOnly scanned flag for 'direction'.
Definition: flow.c:201
FLOW_TOSERVER_IPONLY_SET
#define FLOW_TOSERVER_IPONLY_SET
Definition: flow.h:54
DetectEngineThreadCtx_::filestore_cnt
uint16_t filestore_cnt
Definition: detect.h:1038
PROF_DETECT_IPONLY
@ PROF_DETECT_IPONLY
Definition: suricata-common.h:399
TmEcode
TmEcode
Definition: tm-threads-common.h:77
RULE_PROFILING_START
#define RULE_PROFILING_START(p)
Definition: util-profiling.h:42
PKT_STREAM_EOF
#define PKT_STREAM_EOF
Definition: decode.h:1076
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:353
DetectTransaction_::de_state
DetectEngineStateDirection * de_state
Definition: detect-engine-state.h:100
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
detect-filestore.h
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1171
detect-replace.h
RulesDumpMatchArray
void RulesDumpMatchArray(const DetectEngineThreadCtx *det_ctx, const SigGroupHead *sgh, const Packet *p)
Definition: detect-engine-profile.c:59
DetectSignatureApplyActions
void DetectSignatureApplyActions(Packet *p, const Signature *s, const uint8_t alert_flags)
Apply action(s) and Set 'drop' sig info, if applicable.
Definition: detect.c:1514
Signature_::addr_dst_match6_cnt
uint16_t addr_dst_match6_cnt
Definition: detect.h:547
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:219
Signature_::sp
DetectPort * sp
Definition: detect.h:561
DetectRunScratchpad::sgh
const SigGroupHead * sgh
Definition: detect.c:66
DETECT_ENGINE_INSPECT_SIG_CANT_MATCH
#define DETECT_ENGINE_INSPECT_SIG_CANT_MATCH
Definition: detect-engine-state.h:40
DETECT_ENGINE_STATE_FLAG_FILE_NEW
#define DETECT_ENGINE_STATE_FLAG_FILE_NEW
Definition: detect-engine-state.h:71
Flow_::flowvar
GenericVar * flowvar
Definition: flow.h:464
RuleMatchCandidateTx::flags
uint32_t * flags
Definition: detect.h:989
DetectEngineAppInspectionEngine_::alproto
AppProto alproto
Definition: detect.h:396
detect-engine-analyzer.h
FLOWFILE_NO_SHA256_TC
#define FLOWFILE_NO_SHA256_TC
Definition: flow.h:131
PACKET_UPDATE_ACTION
#define PACKET_UPDATE_ACTION(p, a)
Definition: decode.h:852
DetectEngineAppInspectionEngine_::smd
SigMatchData * smd
Definition: detect.h:419
DetectEngineStateDirection_::head
DeStateStore * head
Definition: detect-engine-state.h:84
DETECT_ENGINE_INSPECT_SIG_MATCH_MORE_FILES
#define DETECT_ENGINE_INSPECT_SIG_MATCH_MORE_FILES
Definition: detect-engine-state.h:50
DetectProto_::flags
uint8_t flags
Definition: detect-engine-proto.h:38
DETECT_PROTO_IPV4
#define DETECT_PROTO_IPV4
Definition: detect-engine-proto.h:33
DetectAddressMatchIPv6
int DetectAddressMatchIPv6(const DetectMatchAddressIPv6 *addrs, uint16_t addrs_cnt, const Address *a)
Match a packets address against a signatures addrs array.
Definition: detect-engine-address.c:1629
Packet_::tenant_id
uint32_t tenant_id
Definition: decode.h:595
Packet_::flow
struct Flow_ * flow
Definition: decode.h:446
DetectEngineStateResetTxs
void DetectEngineStateResetTxs(Flow *f)
Reset de state for active tx' To be used on detect engine reload.
Definition: detect-engine-state.c:267
FLOWFILE_NO_MAGIC_TC
#define FLOWFILE_NO_MAGIC_TC
Definition: flow.h:116
TH_SYN
#define TH_SYN
Definition: decode-tcp.h:35
flags
uint8_t flags
Definition: decode-gre.h:2
Signature_::proto
DetectProto proto
Definition: detect.h:539
SigGroupHead_::non_pf_other_store_array
SignatureNonPrefilterStore * non_pf_other_store_array
Definition: detect.h:1347
FLOW_TOCLIENT_IPONLY_SET
#define FLOW_TOCLIENT_IPONLY_SET
Definition: flow.h:56
SigMatchData_::is_last
uint8_t is_last
Definition: detect.h:329
suricata-common.h
SIG_FLAG_SP_ANY
#define SIG_FLAG_SP_ANY
Definition: detect.h:213
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:523
Signature_::dsize_high
uint16_t dsize_high
Definition: detect.h:529
SigGroupHead_::non_pf_other_store_cnt
uint32_t non_pf_other_store_cnt
Definition: detect.h:1345
DeStateStore_
Definition: detect-engine-state.h:78
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
ACTION_DROP
#define ACTION_DROP
Definition: action-globals.h:30
DetectTransaction_
Definition: detect-engine-state.h:97
STREAM_TOCLIENT
#define STREAM_TOCLIENT
Definition: stream.h:32
PROF_DETECT_SETUP
@ PROF_DETECT_SETUP
Definition: suricata-common.h:397
DetectEngineStateDirection_
Definition: detect-engine-state.h:83
DetectEngineCtx_::profile_match_logging_threshold
uint32_t profile_match_logging_threshold
Definition: detect.h:888
FatalError
#define FatalError(x,...)
Definition: util-debug.h:569
STREAM_FLUSH
#define STREAM_FLUSH
Definition: stream.h:36
TcpSession_::client
TcpStream client
Definition: stream-tcp-private.h:272
SIG_FLAG_NOALERT
#define SIG_FLAG_NOALERT
Definition: detect.h:216
FLOWFILE_NO_STORE_TC
#define FLOWFILE_NO_STORE_TC
Definition: flow.h:120
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
DetectEngineThreadCtx_::non_pf_id_array
SigIntId * non_pf_id_array
Definition: detect.h:1015
DetectEngineAppInspectionEngine_::progress
int16_t progress
Definition: detect.h:402
PKT_IS_ICMPV4
#define PKT_IS_ICMPV4(p)
Definition: decode.h:256
util-validate.h
FlowGetAppProtocol
AppProto FlowGetAppProtocol(const Flow *f)
Definition: flow.c:1082
DetectTransaction_::tx_ptr
void * tx_ptr
Definition: detect-engine-state.h:98
Signature_::addr_src_match6_cnt
uint16_t addr_src_match6_cnt
Definition: detect.h:548
StatsAddUI64
void StatsAddUI64(ThreadVars *tv, uint16_t id, uint64_t x)
Adds a value of type uint64_t to the local counter.
Definition: counters.c:147
FLOWFILE_NO_SHA1_TS
#define FLOWFILE_NO_SHA1_TS
Definition: flow.h:126
PROF_DETECT_RULES
@ PROF_DETECT_RULES
Definition: suricata-common.h:400
DetectRunScratchpad::app_decoder_events
const bool app_decoder_events
Definition: detect.c:65
TcpSession_::server
TcpStream server
Definition: stream-tcp-private.h:271
PROF_DETECT_NONMPMLIST
@ PROF_DETECT_NONMPMLIST
Definition: suricata-common.h:407
Signature_::dp
DetectPort * dp
Definition: detect.h:561
PACKET_PROFILING_DETECT_START
#define PACKET_PROFILING_DETECT_START(p, id)
Definition: util-profiling.h:234
DetectEngineThreadCtx_::non_pf_store_cnt
uint32_t non_pf_store_cnt
Definition: detect.h:1095
FLOW_SGH_TOSERVER
#define FLOW_SGH_TOSERVER
Definition: flow.h:67
DetectEngineThreadCtx_::counter_alerts
uint16_t counter_alerts
Definition: detect.h:1041
SigGroupHead_::flags
uint32_t flags
Definition: detect.h:1338
PACKET_DROP
#define PACKET_DROP(p)
Definition: decode.h:837
SGH_PROFILING_RECORD
#define SGH_PROFILING_RECORD(det_ctx, sgh)
Definition: util-profiling.h:272
PacketAlertFinalize
void PacketAlertFinalize(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
Check the threshold of the sigs that match, set actions, break on pass action This function iterate t...
Definition: detect-engine-alert.c:238
Signature_::addr_dst_match6
DetectMatchAddressIPv6 * addr_dst_match6
Definition: detect.h:552
Flow_::alstate
void * alstate
Definition: flow.h:454
Signature_::id
uint32_t id
Definition: detect.h:555
DeStateStore_::store
DeStateStoreItem store[DE_STATE_CHUNK_SIZE]
Definition: detect-engine-state.h:79
Flow_::flags
uint32_t flags
Definition: flow.h:396
RuleMatchCandidateTx::stream_reset
uint32_t stream_reset
Definition: detect.h:995
detect-engine-iponly.h
Signature_
Signature container.
Definition: detect.h:522
IP_GET_IPPROTO
#define IP_GET_IPPROTO(p)
Definition: decode.h:264
InspectionBufferClean
void InspectionBufferClean(DetectEngineThreadCtx *det_ctx)
Definition: detect-engine.c:1015
SignatureMask
#define SignatureMask
Definition: detect.h:278
AppLayerParserGetTxDetectState
DetectEngineState * AppLayerParserGetTxDetectState(uint8_t ipproto, AppProto alproto, void *tx)
Definition: app-layer-parser.c:1127
ALPROTO_UNKNOWN
@ ALPROTO_UNKNOWN
Definition: app-layer-protos.h:29
TRACE_SID_TXS
#define TRACE_SID_TXS(sid, txs,...)
Definition: detect.c:1029
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:220
STREAM_EOF
#define STREAM_EOF
Definition: stream.h:30
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
DetectRunScratchpad::flow_flags
const uint8_t flow_flags
Definition: detect.c:64
DetectEngineThreadCtx_::de_ctx
DetectEngineCtx * de_ctx
Definition: detect.h:1128
suricata.h
DetectEngineCtx_::sig_array
Signature ** sig_array
Definition: detect.h:776
Packet_::dst
Address dst
Definition: decode.h:414
SigGroupHead_::non_pf_syn_store_array
SignatureNonPrefilterStore * non_pf_syn_store_array
Definition: detect.h:1349
DetectEngineAppInspectionEngine_::stream
uint16_t stream
Definition: detect.h:400
PROF_DETECT_TX
@ PROF_DETECT_TX
Definition: suricata-common.h:401
DetectEngineAppInspectionEngine_::dir
uint8_t dir
Definition: detect.h:397
PKT_NOPACKET_INSPECTION
#define PKT_NOPACKET_INSPECTION
Definition: decode.h:1070
SignatureNonPrefilterStore_::mask
SignatureMask mask
Definition: detect.h:982
PacketAlertAppend
int PacketAlertAppend(DetectEngineThreadCtx *det_ctx, const Signature *s, Packet *p, uint64_t tx_id, uint8_t flags)
append a signature match to a packet
Definition: detect-engine-alert.c:188
DetectRunScratchpad::alproto
const AppProto alproto
Definition: detect.c:63
DE_STATE_FLAG_FULL_INSPECT
#define DE_STATE_FLAG_FULL_INSPECT
Definition: detect-engine-state.h:56
STREAMTCP_STREAM_FLAG_DISABLE_RAW
#define STREAMTCP_STREAM_FLAG_DISABLE_RAW
Definition: stream-tcp-private.h:219
ALPROTO_SMB
@ ALPROTO_SMB
Definition: app-layer-protos.h:37
DetectEngineThreadCtx_::mt_det_ctxs_cnt
uint32_t mt_det_ctxs_cnt
Definition: detect.h:1018
AppLayerGetTxIteratorFunc
AppLayerGetTxIterTuple(* AppLayerGetTxIteratorFunc)(const uint8_t ipproto, const AppProto alproto, void *alstate, uint64_t min_tx_id, uint64_t max_tx_id, AppLayerGetTxIterState *state)
tx iterator prototype
Definition: app-layer-parser.h:123
likely
#define likely(expr)
Definition: util-optimize.h:32
DE_STATE_FLAG_FILE_INSPECT
#define DE_STATE_FLAG_FILE_INSPECT
Definition: detect-engine-state.h:61
FLOW_NOPACKET_INSPECTION
#define FLOW_NOPACKET_INSPECTION
Definition: flow.h:59
DetectEngineCtx_::io_ctx
DetectEngineIPOnlyCtx io_ctx
Definition: detect.h:807
SC_ATOMIC_GET
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
Definition: util-atomic.h:192
Signature_::addr_dst_match4
DetectMatchAddressIPv4 * addr_dst_match4
Definition: detect.h:549
FlowGetDisruptionFlags
uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags)
get 'disruption' flags: GAP/DEPTH/PASS
Definition: flow.c:1099
TcpSession_
Definition: stream-tcp-private.h:260
flow.h
Signature_::addr_src_match4_cnt
uint16_t addr_src_match4_cnt
Definition: detect.h:546
SigIntId
#define SigIntId
Definition: suricata-common.h:280
DeStateStoreItem_
Definition: detect-engine-state.h:73
GenericVarFree
void GenericVarFree(GenericVar *gv)
Definition: util-var.c:47
Signature_::addr_dst_match4_cnt
uint16_t addr_dst_match4_cnt
Definition: detect.h:545
Flow_::alproto
AppProto alproto
application level protocol
Definition: flow.h:425
Packet_::dp
Port dp
Definition: decode.h:424
SIG_GROUP_HEAD_HAVEFILESHA256
#define SIG_GROUP_HEAD_HAVEFILESHA256
Definition: detect.h:1236
SignatureNonPrefilterStore_::alproto
uint8_t alproto
Definition: detect.h:983
SigGroupHead_::filestore_cnt
uint16_t filestore_cnt
Definition: detect.h:1353
AppLayerParserGetTxCnt
uint64_t AppLayerParserGetTxCnt(const Flow *f, void *alstate)
Definition: app-layer-parser.c:1038
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:252
PACKET_ALERT_FLAG_STATE_MATCH
#define PACKET_ALERT_FLAG_STATE_MATCH
Definition: decode.h:283
AppLayerParserHasDecoderEvents
bool AppLayerParserHasDecoderEvents(AppLayerParserState *pstate)
Definition: app-layer-parser.c:1360
DetectEngineLookupFlow_::tcp
DetectPort * tcp
Definition: detect.h:698
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
DetectTransaction_::detect_flags
const uint64_t detect_flags
Definition: detect-engine-state.h:101
detect-engine-address.h
Flow_::tenant_id
uint32_t tenant_id
Definition: flow.h:391
Packet_::src
Address src
Definition: decode.h:413
AppLayerParserGetTxDetectFlags
uint64_t AppLayerParserGetTxDetectFlags(uint8_t ipproto, AppProto alproto, void *tx, uint8_t dir)
Definition: app-layer-parser.c:1157
DetectEngineThreadCtx_::counter_mpm_list
uint16_t counter_mpm_list
Definition: detect.h:1043
SigMatchSignaturesGetSgh
const SigGroupHead * SigMatchSignaturesGetSgh(const DetectEngineCtx *de_ctx, const Packet *p)
Get the SigGroupHead for a packet.
Definition: detect.c:177
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:90
RuleMatchCandidateTxArrayInit
void RuleMatchCandidateTxArrayInit(DetectEngineThreadCtx *det_ctx, uint32_t size)
Definition: detect.c:961
SIG_FLAG_DP_ANY
#define SIG_FLAG_DP_ANY
Definition: detect.h:214
DetectEngineAppInspectionEngine_::v2
struct DetectEngineAppInspectionEngine_::@94 v2
DetectPortLookupGroup
DetectPort * DetectPortLookupGroup(DetectPort *dp, uint16_t port)
Function that find the group matching address in a group head.
Definition: detect-engine-port.c:669
PKT_STREAM_EST
#define PKT_STREAM_EST
Definition: decode.h:1075
detect-engine-threshold.h
PACKET_TEST_ACTION
#define PACKET_TEST_ACTION(p, a)
Definition: decode.h:847
SIG_FLAG_DSIZE
#define SIG_FLAG_DSIZE
Definition: detect.h:217
DetectEngineThreadCtx_::io_ctx
DetectEngineIPOnlyThreadCtx io_ctx
Definition: detect.h:1110
Signature_::mask
SignatureMask mask
Definition: detect.h:531
app-layer.h
RuleMatchCandidateTx
Definition: detect.h:987
DetectEngineThreadCtx_::TenantGetId
uint32_t(* TenantGetId)(const void *, const Packet *p)
Definition: detect.h:1025
PrefilterRuleStore_::rule_id_array
SigIntId * rule_id_array
Definition: util-prefilter.h:36
PacketEngineEvents_::cnt
uint8_t cnt
Definition: decode.h:307
Flow_::de_ctx_version
uint32_t de_ctx_version
Definition: flow.h:439
DetectProtoContainsProto
int DetectProtoContainsProto(const DetectProto *dp, int proto)
see if a DetectProto contains a certain proto
Definition: detect-engine-proto.c:135
DetectEngineThreadCtx_::match_array
Signature ** match_array
Definition: detect.h:1084