suricata
detect-flow-pkts.c
Go to the documentation of this file.
1 /* Copyright (C) 2023 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 #include "suricata-common.h"
19 #include "rust.h"
20 #include "detect-flow-pkts.h"
21 #include "detect-engine.h"
23 #include "detect-engine-uint.h"
24 #include "detect-parse.h"
25 
26 static int DetectFlowPktsToClientMatch(
27  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
28 {
29  if (p->flow == NULL) {
30  return 0;
31  }
32  uint32_t nb = p->flow->tosrcpktcnt;
33 
34  const DetectU32Data *du32 = (const DetectU32Data *)ctx;
35  return DetectU32Match(nb, du32);
36 }
37 
38 static void DetectFlowPktsToClientFree(DetectEngineCtx *de_ctx, void *ptr)
39 {
40  rs_detect_u32_free(ptr);
41 }
42 
43 static int DetectFlowPktsToClientSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
44 {
45  DetectU32Data *du32 = DetectU32Parse(rawstr);
46  if (du32 == NULL)
47  return -1;
48 
50  DETECT_SM_LIST_MATCH) == NULL) {
51  DetectFlowPktsToClientFree(de_ctx, du32);
52  return -1;
53  }
55 
56  return 0;
57 }
58 
59 static void PrefilterPacketFlowPktsToClientMatch(
60  DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
61 {
62  const PrefilterPacketHeaderCtx *ctx = pectx;
63  if (!PrefilterPacketHeaderExtraMatch(ctx, p))
64  return;
65 
66  DetectU32Data du32;
67  du32.mode = ctx->v1.u8[0];
68  du32.arg1 = ctx->v1.u32[1];
69  du32.arg2 = ctx->v1.u32[2];
70  if (DetectFlowPktsToClientMatch(det_ctx, p, NULL, (const SigMatchCtx *)&du32)) {
71  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
72  }
73 }
74 
75 static int PrefilterSetupFlowPktsToClient(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
76 {
79  PrefilterPacketFlowPktsToClientMatch);
80 }
81 
82 static bool PrefilterFlowPktsToClientIsPrefilterable(const Signature *s)
83 {
84  return PrefilterIsPrefilterableById(s, DETECT_FLOW_PKTS_TO_CLIENT);
85 }
86 
88 {
89  sigmatch_table[DETECT_FLOW_PKTS_TO_CLIENT].name = "flow.pkts_toclient";
90  sigmatch_table[DETECT_FLOW_PKTS_TO_CLIENT].desc = "match flow number of packets to client";
91  sigmatch_table[DETECT_FLOW_PKTS_TO_CLIENT].url = "/rules/flow-keywords.html#flow-pkts_toclient";
92  sigmatch_table[DETECT_FLOW_PKTS_TO_CLIENT].Match = DetectFlowPktsToClientMatch;
93  sigmatch_table[DETECT_FLOW_PKTS_TO_CLIENT].Setup = DetectFlowPktsToClientSetup;
94  sigmatch_table[DETECT_FLOW_PKTS_TO_CLIENT].Free = DetectFlowPktsToClientFree;
96  PrefilterFlowPktsToClientIsPrefilterable;
97  sigmatch_table[DETECT_FLOW_PKTS_TO_CLIENT].SetupPrefilter = PrefilterSetupFlowPktsToClient;
98 }
99 
100 static int DetectFlowPktsToServerMatch(
101  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
102 {
103  if (p->flow == NULL) {
104  return 0;
105  }
106  uint32_t nb = p->flow->todstpktcnt;
107 
108  const DetectU32Data *du32 = (const DetectU32Data *)ctx;
109  return DetectU32Match(nb, du32);
110 }
111 
112 static void DetectFlowPktsToServerFree(DetectEngineCtx *de_ctx, void *ptr)
113 {
114  rs_detect_u32_free(ptr);
115 }
116 
117 static int DetectFlowPktsToServerSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
118 {
119  DetectU32Data *du32 = DetectU32Parse(rawstr);
120  if (du32 == NULL)
121  return -1;
122 
124  DETECT_SM_LIST_MATCH) == NULL) {
125  DetectFlowPktsToServerFree(de_ctx, du32);
126  return -1;
127  }
129 
130  return 0;
131 }
132 
133 static void PrefilterPacketFlowPktsToServerMatch(
134  DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
135 {
136  const PrefilterPacketHeaderCtx *ctx = pectx;
137  if (!PrefilterPacketHeaderExtraMatch(ctx, p))
138  return;
139 
140  DetectU32Data du32;
141  du32.mode = ctx->v1.u8[0];
142  du32.arg1 = ctx->v1.u32[1];
143  du32.arg2 = ctx->v1.u32[2];
144  if (DetectFlowPktsToServerMatch(det_ctx, p, NULL, (const SigMatchCtx *)&du32)) {
145  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
146  }
147 }
148 
149 static int PrefilterSetupFlowPktsToServer(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
150 {
153  PrefilterPacketFlowPktsToServerMatch);
154 }
155 
156 static bool PrefilterFlowPktsToServerIsPrefilterable(const Signature *s)
157 {
158  return PrefilterIsPrefilterableById(s, DETECT_FLOW_PKTS_TO_SERVER);
159 }
160 
162 {
163  sigmatch_table[DETECT_FLOW_PKTS_TO_SERVER].name = "flow.pkts_toserver";
164  sigmatch_table[DETECT_FLOW_PKTS_TO_SERVER].desc = "match flow number of packets to server";
165  sigmatch_table[DETECT_FLOW_PKTS_TO_SERVER].url = "/rules/flow-keywords.html#flow-pkts_toserver";
166  sigmatch_table[DETECT_FLOW_PKTS_TO_SERVER].Match = DetectFlowPktsToServerMatch;
167  sigmatch_table[DETECT_FLOW_PKTS_TO_SERVER].Setup = DetectFlowPktsToServerSetup;
168  sigmatch_table[DETECT_FLOW_PKTS_TO_SERVER].Free = DetectFlowPktsToServerFree;
170  PrefilterFlowPktsToServerIsPrefilterable;
171  sigmatch_table[DETECT_FLOW_PKTS_TO_SERVER].SetupPrefilter = PrefilterSetupFlowPktsToServer;
172 }
173 
174 static int DetectFlowBytesToClientMatch(
175  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
176 {
177  if (p->flow == NULL) {
178  return 0;
179  }
180  uint64_t nb = p->flow->tosrcbytecnt;
181 
182  const DetectU64Data *du64 = (const DetectU64Data *)ctx;
183  return DetectU64Match(nb, du64);
184 }
185 
186 static void DetectFlowBytesToClientFree(DetectEngineCtx *de_ctx, void *ptr)
187 {
188  rs_detect_u64_free(ptr);
189 }
190 
191 static int DetectFlowBytesToClientSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
192 {
193  DetectU64Data *du64 = DetectU64Parse(rawstr);
194  if (du64 == NULL)
195  return -1;
196 
198  DETECT_SM_LIST_MATCH) == NULL) {
199  DetectFlowBytesToClientFree(de_ctx, du64);
200  return -1;
201  }
203 
204  return 0;
205 }
206 
208 {
209  sigmatch_table[DETECT_FLOW_BYTES_TO_CLIENT].name = "flow.bytes_toclient";
210  sigmatch_table[DETECT_FLOW_BYTES_TO_CLIENT].desc = "match flow number of bytes to client";
212  "/rules/flow-keywords.html#flow-bytes_toclient";
213  sigmatch_table[DETECT_FLOW_BYTES_TO_CLIENT].Match = DetectFlowBytesToClientMatch;
214  sigmatch_table[DETECT_FLOW_BYTES_TO_CLIENT].Setup = DetectFlowBytesToClientSetup;
215  sigmatch_table[DETECT_FLOW_BYTES_TO_CLIENT].Free = DetectFlowBytesToClientFree;
216 }
217 
218 static int DetectFlowBytesToServerMatch(
219  DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
220 {
221  if (p->flow == NULL) {
222  return 0;
223  }
224  uint64_t nb = p->flow->todstbytecnt;
225 
226  const DetectU64Data *du64 = (const DetectU64Data *)ctx;
227  return DetectU64Match(nb, du64);
228 }
229 
230 static void DetectFlowBytesToServerFree(DetectEngineCtx *de_ctx, void *ptr)
231 {
232  rs_detect_u64_free(ptr);
233 }
234 
235 static int DetectFlowBytesToServerSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
236 {
237  DetectU64Data *du64 = DetectU64Parse(rawstr);
238  if (du64 == NULL)
239  return -1;
240 
242  DETECT_SM_LIST_MATCH) == NULL) {
243  DetectFlowBytesToServerFree(de_ctx, du64);
244  return -1;
245  }
247 
248  return 0;
249 }
250 
252 {
253  sigmatch_table[DETECT_FLOW_BYTES_TO_SERVER].name = "flow.bytes_toserver";
254  sigmatch_table[DETECT_FLOW_BYTES_TO_SERVER].desc = "match flow number of bytes to server";
256  "/rules/flow-keywords.html#flow-bytes_toserver";
257  sigmatch_table[DETECT_FLOW_BYTES_TO_SERVER].Match = DetectFlowBytesToServerMatch;
258  sigmatch_table[DETECT_FLOW_BYTES_TO_SERVER].Setup = DetectFlowBytesToServerSetup;
259  sigmatch_table[DETECT_FLOW_BYTES_TO_SERVER].Free = DetectFlowBytesToServerFree;
260 }
detect-engine-uint.h
SigTableElmt_::url
const char * url
Definition: detect.h:1307
detect-engine.h
DetectU32Match
int DetectU32Match(const uint32_t parg, const DetectUintData_u32 *du32)
Definition: detect-engine-uint.c:31
SigTableElmt_::desc
const char * desc
Definition: detect.h:1306
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:127
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1294
SigTableElmt_::name
const char * name
Definition: detect.h:1304
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1460
DetectU32Parse
DetectUintData_u32 * DetectU32Parse(const char *u32str)
This function is used to parse u32 options passed via some u32 keyword.
Definition: detect-engine-uint.c:45
PrefilterPacketU32Set
void PrefilterPacketU32Set(PrefilterPacketHeaderValue *v, void *smctx)
Definition: detect-engine-uint.c:51
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1200
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:841
rust.h
DetectFlowBytesToClientRegister
void DetectFlowBytesToClientRegister(void)
Definition: detect-flow-pkts.c:207
DetectFlowBytesToServerRegister
void DetectFlowBytesToServerRegister(void)
Definition: detect-flow-pkts.c:251
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1289
detect-engine-prefilter.h
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1292
DETECT_FLOW_BYTES_TO_SERVER
@ DETECT_FLOW_BYTES_TO_SERVER
Definition: detect-engine-register.h:130
Flow_::tosrcbytecnt
uint64_t tosrcbytecnt
Definition: flow.h:500
DetectFlowPktsToClientRegister
void DetectFlowPktsToClientRegister(void)
Definition: detect-flow-pkts.c:87
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:35
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1093
Flow_::todstpktcnt
uint32_t todstpktcnt
Definition: flow.h:497
SIG_MASK_REQUIRE_FLOW
#define SIG_MASK_REQUIRE_FLOW
Definition: detect.h:302
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:114
DETECT_FLOW_BYTES_TO_CLIENT
@ DETECT_FLOW_BYTES_TO_CLIENT
Definition: detect-engine-register.h:129
Flow_::todstbytecnt
uint64_t todstbytecnt
Definition: flow.h:499
DetectFlowPktsToServerRegister
void DetectFlowPktsToServerRegister(void)
Definition: detect-flow-pkts.c:161
Signature_::flags
uint32_t flags
Definition: detect.h:602
Packet_
Definition: decode.h:473
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:404
PrefilterPacketU32Compare
bool PrefilterPacketU32Compare(PrefilterPacketHeaderValue v, void *smctx)
Definition: detect-engine-uint.c:60
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1272
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:344
Packet_::flow
struct Flow_ * flow
Definition: decode.h:512
suricata-common.h
DetectU32Data
DetectUintData_u32 DetectU32Data
Definition: detect-engine-uint.h:41
DETECT_FLOW_PKTS_TO_SERVER
@ DETECT_FLOW_PKTS_TO_SERVER
Definition: detect-engine-register.h:128
DetectU64Parse
DetectUintData_u64 * DetectU64Parse(const char *u64str)
Definition: detect-engine-uint.c:147
DetectU64Data
DetectUintData_u64 DetectU64Data
Definition: detect-engine-uint.h:40
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1291
detect-parse.h
Signature_
Signature container.
Definition: detect.h:601
DetectU64Match
int DetectU64Match(const uint64_t parg, const DetectUintData_u64 *du64)
Definition: detect-engine-uint.c:142
detect-flow-pkts.h
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:436
DETECT_FLOW_PKTS_TO_CLIENT
@ DETECT_FLOW_PKTS_TO_CLIENT
Definition: detect-engine-register.h:127
Flow_::tosrcpktcnt
uint32_t tosrcpktcnt
Definition: flow.h:498
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:250