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