suricata
detect-flow-elephant.c
Go to the documentation of this file.
1 /* Copyright (C) 2025 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Shivani Bhardwaj <shivani@oisf.net>
22  *
23  * Elephant flow detection.
24  */
25 
26 #include "suricata-common.h"
27 #include "rust.h"
28 #include "flow.h"
29 #include "detect-flow-elephant.h"
30 #include "detect-engine.h"
33 #include "detect-parse.h"
34 
35 static int DetectFlowElephantMatchAux(Packet *p, const DetectFlowDir *fdir)
36 {
37  switch (*fdir) {
38  case DETECT_FLOW_TOSERVER:
39  return (p->flow->flags & FLOW_IS_ELEPHANT_TOSERVER);
40  case DETECT_FLOW_TOCLIENT:
41  return (p->flow->flags & FLOW_IS_ELEPHANT_TOCLIENT);
42  case DETECT_FLOW_TOEITHER:
43  return ((p->flow->flags & FLOW_IS_ELEPHANT_TOSERVER) ||
45  case DETECT_FLOW_TOBOTH:
48  }
49 
51  return -1;
52 }
53 
54 static int DetectFlowElephantMatch(
55  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
56 {
57  if (p->flow == NULL) {
58  return 0;
59  }
60 
61  DetectFlowDir *fdir = (DetectFlowDir *)ctx;
62 
63  return DetectFlowElephantMatchAux(p, fdir);
64 }
65 
66 static int DetectFlowElephantSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
67 {
68  DetectFlowDir *fdir = SCDetectFlowDir(rawstr);
69  if (fdir == NULL)
70  return -1;
71 
73  DETECT_SM_LIST_MATCH) == NULL) {
74  return -1;
75  }
77 
78  return 0;
79 }
80 
81 static void DetectFlowElephantFree(DetectEngineCtx *de_ctx, void *dfd)
82 {
83  SCDetectFlowDirFree(dfd);
84 }
85 
86 /* prefilter code */
87 
88 static void PrefilterPacketFlowElephantMatch(
89  DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
90 {
91  if (p->flow == NULL)
92  return;
93 
94  /* during setup Suricata will automatically see if there is another
95  * check that can be added: alproto, sport or dport */
96  const PrefilterPacketHeaderCtx *ctx = pectx;
97  if (!PrefilterPacketHeaderExtraMatch(ctx, p))
98  return;
99 
100  DetectFlowDir dfd = ctx->v1.u8[0];
101  /* if we match, add all the sigs that use this prefilter. This means
102  * that these will be inspected further */
103  if (DetectFlowElephantMatchAux(p, &dfd) > 0) {
104  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
105  }
106 }
107 
108 static void PrefilterPacketFlowElephantSet(PrefilterPacketHeaderValue *v, void *smctx)
109 {
110  const DetectFlowDir *a = smctx;
111  v->u8[0] = *a;
112 }
113 
114 static bool PrefilterPacketFlowElephantCompare(PrefilterPacketHeaderValue v, void *smctx)
115 {
116  const DetectFlowDir *a = smctx;
117  if (v.u8[0] == *a)
118  return true;
119  return false;
120 }
121 
122 static int PrefilterSetupFlowElephant(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
123 {
125  PrefilterPacketFlowElephantSet, PrefilterPacketFlowElephantCompare,
126  PrefilterPacketFlowElephantMatch);
127 }
128 
129 static bool PrefilterFlowElephantIsPrefilterable(const Signature *s)
130 {
131  return PrefilterIsPrefilterableById(s, DETECT_FLOW_ELEPHANT);
132 }
133 
135 {
136  sigmatch_table[DETECT_FLOW_ELEPHANT].name = "flow.elephant";
137  sigmatch_table[DETECT_FLOW_ELEPHANT].desc = "match elephant flow";
138  sigmatch_table[DETECT_FLOW_ELEPHANT].url = "/rules/flow-keywords.html#flow-elephant";
139  sigmatch_table[DETECT_FLOW_ELEPHANT].Match = DetectFlowElephantMatch;
140  sigmatch_table[DETECT_FLOW_ELEPHANT].Setup = DetectFlowElephantSetup;
141  sigmatch_table[DETECT_FLOW_ELEPHANT].Free = DetectFlowElephantFree;
142  sigmatch_table[DETECT_FLOW_ELEPHANT].SupportsPrefilter = PrefilterFlowElephantIsPrefilterable;
143  sigmatch_table[DETECT_FLOW_ELEPHANT].SetupPrefilter = PrefilterSetupFlowElephant;
144 }
SigTableElmt_::url
const char * url
Definition: detect.h:1461
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1460
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1445
SigTableElmt_::name
const char * name
Definition: detect.h:1458
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1628
FLOW_IS_ELEPHANT_TOCLIENT
#define FLOW_IS_ELEPHANT_TOCLIENT
Definition: flow.h:60
DetectFlowElephantRegister
void DetectFlowElephantRegister(void)
Definition: detect-flow-elephant.c:134
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1348
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:933
PrefilterPacketHeaderValue::u8
uint8_t u8[16]
Definition: detect-engine-prefilter-common.h:24
rust.h
detect-flow-elephant.h
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1440
detect-engine-prefilter.h
DETECT_FLOW_ELEPHANT
@ DETECT_FLOW_ELEPHANT
Definition: detect-engine-register.h:135
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1443
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:35
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:19
DetectEngineThreadCtx_
Definition: detect.h:1245
SIG_MASK_REQUIRE_FLOW
#define SIG_MASK_REQUIRE_FLOW
Definition: detect.h:312
SCSigMatchAppendSMToList
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:388
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:117
Signature_::flags
uint32_t flags
Definition: detect.h:669
Packet_
Definition: decode.h:501
PrefilterSetupPacketHeader
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, SignatureMask mask, void(*Set)(PrefilterPacketHeaderValue *v, void *), bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
Definition: detect-engine-prefilter-common.c:470
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1420
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
Packet_::flow
struct Flow_ * flow
Definition: decode.h:546
suricata-common.h
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1442
Flow_::flags
uint32_t flags
Definition: flow.h:412
detect-parse.h
Signature_
Signature container.
Definition: detect.h:668
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:23
detect-engine-prefilter-common.h
flow.h
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
FLOW_IS_ELEPHANT_TOSERVER
#define FLOW_IS_ELEPHANT_TOSERVER
Definition: flow.h:59
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:254