]>
Commit | Line | Data |
---|---|---|
7f6af10f | 1 | /* Copyright (C) 2007-2020 Open Information Security Foundation |
ce019275 WM |
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 | */ | |
8b302269 VJ |
17 | |
18 | /** | |
19 | * \file | |
ce019275 | 20 | * |
ac53ca5b GS |
21 | * \author Gurvinder Singh <gurvindersinghdahiya@gmail.com> |
22 | * | |
23 | * Stream size for the engine. | |
24 | */ | |
25 | ||
ecf86f9c | 26 | #include "suricata-common.h" |
ac53ca5b GS |
27 | #include "stream-tcp.h" |
28 | #include "util-unittest.h" | |
b259e362 | 29 | |
ac53ca5b | 30 | #include "detect.h" |
b259e362 VJ |
31 | #include "detect-parse.h" |
32 | ||
ac53ca5b GS |
33 | #include "flow.h" |
34 | #include "detect-stream_size.h" | |
aa87f704 | 35 | #include "stream-tcp-private.h" |
cacbf31a | 36 | #include "util-debug.h" |
4ed72add | 37 | #include "util-byte.h" |
ac53ca5b | 38 | |
df74597a | 39 | /** |
ac53ca5b GS |
40 | * \brief Regex for parsing our flow options |
41 | */ | |
d82d83eb | 42 | #define PARSE_REGEX "^\\s*([A-z_]+)\\s*,\\s*([<=>!]+)\\s*,\\s*([0-9]+)\\s*$" |
ac53ca5b | 43 | |
4b0085b0 | 44 | static DetectParseRegex parse_regex; |
ac53ca5b | 45 | |
df74597a | 46 | /*prototypes*/ |
14896365 | 47 | static int DetectStreamSizeMatch (DetectEngineThreadCtx *, Packet *, |
bfd4bc82 | 48 | const Signature *, const SigMatchCtx *); |
ab1200fb | 49 | static int DetectStreamSizeSetup (DetectEngineCtx *, Signature *, const char *); |
d3a65fe1 | 50 | void DetectStreamSizeFree(DetectEngineCtx *de_ctx, void *); |
6ab323d3 VJ |
51 | #ifdef UNITTESTS |
52 | static void DetectStreamSizeRegisterTests(void); | |
53 | #endif | |
ac53ca5b | 54 | |
df74597a GS |
55 | /** |
56 | * \brief Registration function for stream_size: keyword | |
57 | */ | |
58 | ||
8f1d7503 KS |
59 | void DetectStreamSizeRegister(void) |
60 | { | |
ac53ca5b | 61 | sigmatch_table[DETECT_STREAM_SIZE].name = "stream_size"; |
68425453 | 62 | sigmatch_table[DETECT_STREAM_SIZE].desc = "match on amount of bytes of a stream"; |
26bcc975 | 63 | sigmatch_table[DETECT_STREAM_SIZE].url = "/rules/flow-keywords.html#stream-size"; |
ac53ca5b GS |
64 | sigmatch_table[DETECT_STREAM_SIZE].Match = DetectStreamSizeMatch; |
65 | sigmatch_table[DETECT_STREAM_SIZE].Setup = DetectStreamSizeSetup; | |
66 | sigmatch_table[DETECT_STREAM_SIZE].Free = DetectStreamSizeFree; | |
6ab323d3 | 67 | #ifdef UNITTESTS |
ac53ca5b | 68 | sigmatch_table[DETECT_STREAM_SIZE].RegisterTests = DetectStreamSizeRegisterTests; |
6ab323d3 | 69 | #endif |
4b0085b0 | 70 | DetectSetupParseRegexes(PARSE_REGEX, &parse_regex); |
ac53ca5b GS |
71 | } |
72 | ||
df74597a GS |
73 | /** |
74 | * \brief Function to comapre the stream size against defined size in the user | |
75 | * options. | |
76 | * | |
77 | * \param diff The stream size of server or client stream. | |
78 | * \param stream_size User defined stream size | |
79 | * \param mode The mode defined by user. | |
80 | * | |
81 | * \retval 1 on success and 0 on failure. | |
82 | */ | |
aa87f704 | 83 | |
e6a009ae VJ |
84 | static int DetectStreamSizeCompare (uint32_t diff, uint32_t stream_size, uint8_t mode) |
85 | { | |
86 | SCLogDebug("diff %u stream_size %u mode %u", diff, stream_size, mode); | |
aa87f704 GS |
87 | |
88 | int ret = 0; | |
d883a993 VJ |
89 | switch (mode) { |
90 | case DETECTSSIZE_LT: | |
91 | if (diff < stream_size) | |
92 | ret = 1; | |
93 | break; | |
94 | case DETECTSSIZE_LEQ: | |
95 | if (diff <= stream_size) | |
96 | ret = 1; | |
97 | break; | |
98 | case DETECTSSIZE_EQ: | |
99 | if (diff == stream_size) | |
100 | ret = 1; | |
101 | break; | |
102 | case DETECTSSIZE_NEQ: | |
103 | if (diff != stream_size) | |
104 | ret = 1; | |
105 | break; | |
106 | case DETECTSSIZE_GEQ: | |
107 | if (diff >= stream_size) | |
108 | ret = 1; | |
109 | break; | |
110 | case DETECTSSIZE_GT: | |
d883a993 VJ |
111 | if (diff > stream_size) |
112 | ret = 1; | |
113 | break; | |
aa87f704 GS |
114 | } |
115 | ||
e6a009ae | 116 | SCReturnInt(ret); |
aa87f704 GS |
117 | } |
118 | ||
ac53ca5b GS |
119 | /** |
120 | * \brief This function is used to match Stream size rule option on a packet with those passed via stream_size: | |
121 | * | |
122 | * \param t pointer to thread vars | |
123 | * \param det_ctx pointer to the pattern matcher thread | |
124 | * \param p pointer to the current packet | |
125 | * \param m pointer to the sigmatch that we will cast into DetectStreamSizeData | |
126 | * | |
127 | * \retval 0 no match | |
128 | * \retval 1 match | |
129 | */ | |
14896365 | 130 | static int DetectStreamSizeMatch (DetectEngineThreadCtx *det_ctx, Packet *p, |
bfd4bc82 | 131 | const Signature *s, const SigMatchCtx *ctx) |
8f1d7503 | 132 | { |
ac53ca5b | 133 | |
923a77e9 | 134 | const DetectStreamSizeData *sd = (const DetectStreamSizeData *)ctx; |
ac53ca5b | 135 | |
d883a993 | 136 | if (!(PKT_IS_TCP(p))) |
e6a009ae VJ |
137 | return 0; |
138 | if (p->flow == NULL || p->flow->protoctx == NULL) | |
139 | return 0; | |
df74597a | 140 | |
e6a009ae VJ |
141 | const TcpSession *ssn = (TcpSession *)p->flow->protoctx; |
142 | int ret = 0; | |
aa87f704 GS |
143 | uint32_t csdiff = 0; |
144 | uint32_t ssdiff = 0; | |
df74597a | 145 | |
aa87f704 | 146 | if (sd->flags & STREAM_SIZE_SERVER) { |
d883a993 | 147 | /* get the server stream size */ |
df74597a | 148 | ssdiff = ssn->server.next_seq - ssn->server.isn; |
aa87f704 | 149 | ret = DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode); |
df74597a | 150 | |
aa87f704 | 151 | } else if (sd->flags & STREAM_SIZE_CLIENT) { |
d883a993 | 152 | /* get the client stream size */ |
df74597a | 153 | csdiff = ssn->client.next_seq - ssn->client.isn; |
aa87f704 | 154 | ret = DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode); |
df74597a | 155 | |
aa87f704 | 156 | } else if (sd->flags & STREAM_SIZE_BOTH) { |
df74597a GS |
157 | ssdiff = ssn->server.next_seq - ssn->server.isn; |
158 | csdiff = ssn->client.next_seq - ssn->client.isn; | |
e6a009ae VJ |
159 | |
160 | if (DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode) && | |
161 | DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode)) | |
aa87f704 | 162 | ret = 1; |
df74597a | 163 | |
aa87f704 | 164 | } else if (sd->flags & STREAM_SIZE_EITHER) { |
df74597a GS |
165 | ssdiff = ssn->server.next_seq - ssn->server.isn; |
166 | csdiff = ssn->client.next_seq - ssn->client.isn; | |
e6a009ae VJ |
167 | |
168 | if (DetectStreamSizeCompare(ssdiff, sd->ssize, sd->mode) || | |
169 | DetectStreamSizeCompare(csdiff, sd->ssize, sd->mode)) | |
aa87f704 | 170 | ret = 1; |
ac53ca5b GS |
171 | } |
172 | ||
e6a009ae | 173 | SCReturnInt(ret); |
ac53ca5b GS |
174 | } |
175 | ||
df74597a GS |
176 | /** |
177 | * \brief This function is used to parse stream options passed via stream_size: keyword | |
178 | * | |
d3a65fe1 | 179 | * \param de_ctx Pointer to the detection engine context |
df74597a GS |
180 | * \param streamstr Pointer to the user provided stream_size options |
181 | * | |
182 | * \retval sd pointer to DetectStreamSizeData on success | |
183 | * \retval NULL on failure | |
184 | */ | |
d3a65fe1 | 185 | static DetectStreamSizeData *DetectStreamSizeParse (DetectEngineCtx *de_ctx, const char *streamstr) |
8f1d7503 | 186 | { |
ac53ca5b GS |
187 | DetectStreamSizeData *sd = NULL; |
188 | char *arg = NULL; | |
189 | char *value = NULL; | |
190 | char *mode = NULL; | |
fa2b46cd | 191 | int res = 0; |
3de99a21 | 192 | size_t pcre2_len; |
ac53ca5b | 193 | |
3de99a21 | 194 | int ret = DetectParsePcreExec(&parse_regex, streamstr, 0, 0); |
7e5f5e68 | 195 | if (ret != 4) { |
ba6d807a | 196 | SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, streamstr); |
ac53ca5b GS |
197 | goto error; |
198 | } | |
199 | ||
200 | const char *str_ptr; | |
3de99a21 | 201 | res = pcre2_substring_get_bynumber(parse_regex.match, 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len); |
ac53ca5b | 202 | if (res < 0) { |
3de99a21 | 203 | SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed"); |
ac53ca5b GS |
204 | goto error; |
205 | } | |
206 | arg = (char *)str_ptr; | |
207 | ||
3de99a21 | 208 | res = pcre2_substring_get_bynumber(parse_regex.match, 2, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len); |
ac53ca5b | 209 | if (res < 0) { |
3de99a21 | 210 | SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed"); |
ac53ca5b GS |
211 | goto error; |
212 | } | |
213 | mode = (char *)str_ptr; | |
214 | ||
3de99a21 | 215 | res = pcre2_substring_get_bynumber(parse_regex.match, 3, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len); |
ac53ca5b | 216 | if (res < 0) { |
3de99a21 | 217 | SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed"); |
ac53ca5b GS |
218 | goto error; |
219 | } | |
220 | value = (char *)str_ptr; | |
221 | ||
25a3a5c6 | 222 | sd = SCMalloc(sizeof(DetectStreamSizeData)); |
e176be6f | 223 | if (unlikely(sd == NULL)) |
fa2b46cd | 224 | goto error; |
ac53ca5b GS |
225 | sd->ssize = 0; |
226 | sd->flags = 0; | |
227 | ||
d883a993 VJ |
228 | if (strlen(mode) == 0) |
229 | goto error; | |
230 | ||
cd038419 Z |
231 | if (mode[0] == '=') { |
232 | sd->mode = DETECTSSIZE_EQ; | |
233 | } else if (mode[0] == '<') { | |
014f6224 | 234 | sd->mode = DETECTSSIZE_LT; |
cd038419 Z |
235 | if (strcmp("<=", mode) == 0) |
236 | sd->mode = DETECTSSIZE_LEQ; | |
237 | } else if (mode[0] == '>') { | |
014f6224 | 238 | sd->mode = DETECTSSIZE_GT; |
cd038419 Z |
239 | if (strcmp(">=", mode) == 0) |
240 | sd->mode = DETECTSSIZE_GEQ; | |
241 | } else if (strcmp("!=", mode) == 0) { | |
014f6224 | 242 | sd->mode = DETECTSSIZE_NEQ; |
cd038419 | 243 | } else { |
ba6d807a | 244 | SCLogError(SC_ERR_INVALID_OPERATOR, "Invalid operator"); |
d883a993 VJ |
245 | goto error; |
246 | } | |
ac53ca5b GS |
247 | |
248 | /* set the value */ | |
4ed72add SB |
249 | if (StringParseUint32(&sd->ssize, 10, 0, (const char *)value) < 0) { |
250 | SCLogError(SC_ERR_INVALID_VALUE, "Invalid value for stream size: %s", value); | |
251 | goto error; | |
252 | } | |
df74597a | 253 | /* inspect our options and set the flags */ |
ac53ca5b | 254 | if (strcmp(arg, "server") == 0) { |
aa87f704 | 255 | sd->flags |= STREAM_SIZE_SERVER; |
ac53ca5b | 256 | } else if (strcmp(arg, "client") == 0) { |
aa87f704 | 257 | sd->flags |= STREAM_SIZE_CLIENT; |
aa87f704 | 258 | } else if ((strcmp(arg, "both") == 0)) { |
aa87f704 GS |
259 | sd->flags |= STREAM_SIZE_BOTH; |
260 | } else if (strcmp(arg, "either") == 0) { | |
aa87f704 | 261 | sd->flags |= STREAM_SIZE_EITHER; |
7e5f5e68 GS |
262 | } else { |
263 | goto error; | |
ac53ca5b GS |
264 | } |
265 | ||
3de99a21 PA |
266 | pcre2_substring_free((PCRE2_UCHAR8 *)mode); |
267 | pcre2_substring_free((PCRE2_UCHAR8 *)arg); | |
268 | pcre2_substring_free((PCRE2_UCHAR8 *)value); | |
ac53ca5b GS |
269 | return sd; |
270 | ||
271 | error: | |
014f6224 | 272 | if (mode != NULL) |
3de99a21 | 273 | pcre2_substring_free((PCRE2_UCHAR8 *)mode); |
014f6224 | 274 | if (arg != NULL) |
3de99a21 | 275 | pcre2_substring_free((PCRE2_UCHAR8 *)arg); |
014f6224 | 276 | if (value != NULL) |
3de99a21 | 277 | pcre2_substring_free((PCRE2_UCHAR8 *)value); |
014f6224 | 278 | if (sd != NULL) |
d3a65fe1 | 279 | DetectStreamSizeFree(de_ctx, sd); |
ac53ca5b GS |
280 | return NULL; |
281 | } | |
282 | ||
283 | /** | |
284 | * \brief this function is used to add the parsed stream size data into the current signature | |
285 | * | |
286 | * \param de_ctx pointer to the Detection Engine Context | |
287 | * \param s pointer to the Current Signature | |
ac53ca5b GS |
288 | * \param streamstr pointer to the user provided stream size options |
289 | * | |
290 | * \retval 0 on Success | |
291 | * \retval -1 on Failure | |
292 | */ | |
ab1200fb | 293 | static int DetectStreamSizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *streamstr) |
8f1d7503 | 294 | { |
fa2b46cd | 295 | DetectStreamSizeData *sd = DetectStreamSizeParse(de_ctx, streamstr); |
ac53ca5b | 296 | if (sd == NULL) |
fa2b46cd | 297 | return -1; |
ac53ca5b | 298 | |
fa2b46cd VJ |
299 | SigMatch *sm = SigMatchAlloc(); |
300 | if (sm == NULL) { | |
301 | DetectStreamSizeFree(de_ctx, sd); | |
302 | return -1; | |
303 | } | |
ac53ca5b GS |
304 | |
305 | sm->type = DETECT_STREAM_SIZE; | |
923a77e9 | 306 | sm->ctx = (SigMatchCtx *)sd; |
ac53ca5b | 307 | |
a4638fb0 | 308 | SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH); |
ac53ca5b | 309 | return 0; |
ac53ca5b GS |
310 | } |
311 | ||
312 | /** | |
313 | * \brief this function will free memory associated with DetectStreamSizeData | |
314 | * | |
315 | * \param ptr pointer to DetectStreamSizeData | |
316 | */ | |
d3a65fe1 | 317 | void DetectStreamSizeFree(DetectEngineCtx *de_ctx, void *ptr) |
8f1d7503 | 318 | { |
ac53ca5b | 319 | DetectStreamSizeData *sd = (DetectStreamSizeData *)ptr; |
25a3a5c6 | 320 | SCFree(sd); |
ac53ca5b GS |
321 | } |
322 | ||
c43319c3 | 323 | #ifdef UNITTESTS |
df74597a GS |
324 | /** |
325 | * \test DetectStreamSizeParseTest01 is a test to make sure that we parse the | |
326 | * user options correctly, when given valid stream_size options. | |
327 | */ | |
328 | ||
8f1d7503 KS |
329 | static int DetectStreamSizeParseTest01 (void) |
330 | { | |
ac53ca5b GS |
331 | int result = 0; |
332 | DetectStreamSizeData *sd = NULL; | |
d3a65fe1 | 333 | sd = DetectStreamSizeParse(NULL, "server,<,6"); |
ac53ca5b | 334 | if (sd != NULL) { |
aa87f704 | 335 | if (sd->flags & STREAM_SIZE_SERVER && sd->mode == DETECTSSIZE_LT && sd->ssize == 6) |
ac53ca5b | 336 | result = 1; |
d3a65fe1 | 337 | DetectStreamSizeFree(NULL, sd); |
ac53ca5b GS |
338 | } |
339 | ||
340 | return result; | |
341 | } | |
342 | ||
df74597a GS |
343 | /** |
344 | * \test DetectStreamSizeParseTest02 is a test to make sure that we detect the | |
345 | * invalid stream_size options. | |
346 | */ | |
347 | ||
8f1d7503 KS |
348 | static int DetectStreamSizeParseTest02 (void) |
349 | { | |
ac53ca5b GS |
350 | int result = 1; |
351 | DetectStreamSizeData *sd = NULL; | |
d3a65fe1 | 352 | sd = DetectStreamSizeParse(NULL, "invalidoption,<,6"); |
ac53ca5b | 353 | if (sd != NULL) { |
4aceaf9f | 354 | printf("expected: NULL got 0x%02X %" PRIu32 ": ",sd->flags, sd->ssize); |
ac53ca5b | 355 | result = 0; |
d3a65fe1 | 356 | DetectStreamSizeFree(NULL, sd); |
ac53ca5b GS |
357 | } |
358 | ||
359 | return result; | |
360 | } | |
aa87f704 | 361 | |
df74597a GS |
362 | /** |
363 | * \test DetectStreamSizeParseTest03 is a test to make sure that we match the | |
364 | * packet correctly provided valid stream size. | |
365 | */ | |
366 | ||
8f1d7503 KS |
367 | static int DetectStreamSizeParseTest03 (void) |
368 | { | |
aa87f704 GS |
369 | |
370 | int result = 0; | |
371 | DetectStreamSizeData *sd = NULL; | |
372 | TcpSession ssn; | |
373 | ThreadVars tv; | |
374 | DetectEngineThreadCtx dtx; | |
9c7b411a | 375 | Packet *p = PacketGetFromAlloc(); |
e176be6f | 376 | if (unlikely(p == NULL)) |
9c7b411a | 377 | return 0; |
aa87f704 GS |
378 | Signature s; |
379 | SigMatch sm; | |
380 | TcpStream client; | |
381 | Flow f; | |
d883a993 | 382 | TCPHdr tcph; |
aa87f704 GS |
383 | |
384 | memset(&ssn, 0, sizeof(TcpSession)); | |
385 | memset(&tv, 0, sizeof(ThreadVars)); | |
386 | memset(&dtx, 0, sizeof(DetectEngineThreadCtx)); | |
aa87f704 GS |
387 | memset(&s, 0, sizeof(Signature)); |
388 | memset(&sm, 0, sizeof(SigMatch)); | |
389 | memset(&client, 0, sizeof(TcpStream)); | |
390 | memset(&f, 0, sizeof(Flow)); | |
d883a993 | 391 | memset(&tcph, 0, sizeof(TCPHdr)); |
aa87f704 | 392 | |
d3a65fe1 | 393 | sd = DetectStreamSizeParse(NULL, "client,>,8"); |
aa87f704 | 394 | if (sd != NULL) { |
d883a993 VJ |
395 | if (!(sd->flags & STREAM_SIZE_CLIENT)) { |
396 | printf("sd->flags not STREAM_SIZE_CLIENT: "); | |
d3a65fe1 | 397 | DetectStreamSizeFree(NULL, sd); |
1db4aadd | 398 | SCFree(p); |
aa87f704 | 399 | return 0; |
d883a993 VJ |
400 | } |
401 | ||
402 | if (sd->mode != DETECTSSIZE_GT) { | |
403 | printf("sd->mode not DETECTSSIZE_GT: "); | |
d3a65fe1 | 404 | DetectStreamSizeFree(NULL, sd); |
1db4aadd | 405 | SCFree(p); |
d883a993 VJ |
406 | return 0; |
407 | } | |
408 | ||
409 | if (sd->ssize != 8) { | |
410 | printf("sd->ssize is %"PRIu32", not 8: ", sd->ssize); | |
d3a65fe1 | 411 | DetectStreamSizeFree(NULL, sd); |
1db4aadd | 412 | SCFree(p); |
d883a993 VJ |
413 | return 0; |
414 | } | |
415 | } else { | |
416 | printf("sd == NULL: "); | |
1db4aadd | 417 | SCFree(p); |
7e5f5e68 | 418 | return 0; |
d883a993 | 419 | } |
aa87f704 | 420 | |
df74597a GS |
421 | client.next_seq = 20; |
422 | client.isn = 10; | |
aa87f704 | 423 | ssn.client = client; |
0675b7d7 | 424 | f.protoctx = &ssn; |
1db4aadd EL |
425 | p->flow = &f; |
426 | p->tcph = &tcph; | |
923a77e9 | 427 | sm.ctx = (SigMatchCtx*)sd; |
aa87f704 | 428 | |
14896365 | 429 | result = DetectStreamSizeMatch(&dtx, p, &s, sm.ctx); |
d883a993 VJ |
430 | if (result == 0) { |
431 | printf("result 0 != 1: "); | |
432 | } | |
d3a65fe1 | 433 | DetectStreamSizeFree(NULL, sd); |
1db4aadd | 434 | SCFree(p); |
aa87f704 GS |
435 | return result; |
436 | } | |
437 | ||
df74597a GS |
438 | /** |
439 | * \test DetectStreamSizeParseTest04 is a test to make sure that we match the | |
440 | * stream_size against invalid packet parameters. | |
441 | */ | |
442 | ||
8f1d7503 KS |
443 | static int DetectStreamSizeParseTest04 (void) |
444 | { | |
aa87f704 GS |
445 | |
446 | int result = 0; | |
447 | DetectStreamSizeData *sd = NULL; | |
448 | TcpSession ssn; | |
449 | ThreadVars tv; | |
450 | DetectEngineThreadCtx dtx; | |
9c7b411a | 451 | Packet *p = PacketGetFromAlloc(); |
e176be6f | 452 | if (unlikely(p == NULL)) |
9c7b411a | 453 | return 0; |
aa87f704 GS |
454 | Signature s; |
455 | SigMatch sm; | |
456 | TcpStream client; | |
457 | Flow f; | |
458 | IPV4Hdr ip4h; | |
459 | ||
460 | memset(&ssn, 0, sizeof(TcpSession)); | |
461 | memset(&tv, 0, sizeof(ThreadVars)); | |
462 | memset(&dtx, 0, sizeof(DetectEngineThreadCtx)); | |
aa87f704 GS |
463 | memset(&s, 0, sizeof(Signature)); |
464 | memset(&sm, 0, sizeof(SigMatch)); | |
465 | memset(&client, 0, sizeof(TcpStream)); | |
466 | memset(&f, 0, sizeof(Flow)); | |
467 | memset(&ip4h, 0, sizeof(IPV4Hdr)); | |
468 | ||
d3a65fe1 | 469 | sd = DetectStreamSizeParse(NULL, " client , > , 8 "); |
aa87f704 | 470 | if (sd != NULL) { |
1db4aadd EL |
471 | if (!(sd->flags & STREAM_SIZE_CLIENT) && sd->mode != DETECTSSIZE_GT && sd->ssize != 8) { |
472 | SCFree(p); | |
473 | return 0; | |
474 | } | |
7e5f5e68 | 475 | } else |
1db4aadd EL |
476 | { |
477 | SCFree(p); | |
7e5f5e68 | 478 | return 0; |
1db4aadd | 479 | } |
aa87f704 | 480 | |
df74597a GS |
481 | client.next_seq = 20; |
482 | client.isn = 12; | |
aa87f704 | 483 | ssn.client = client; |
0675b7d7 | 484 | f.protoctx = &ssn; |
1db4aadd EL |
485 | p->flow = &f; |
486 | p->ip4h = &ip4h; | |
923a77e9 | 487 | sm.ctx = (SigMatchCtx*)sd; |
aa87f704 | 488 | |
14896365 | 489 | if (!DetectStreamSizeMatch(&dtx, p, &s, sm.ctx)) |
aa87f704 GS |
490 | result = 1; |
491 | ||
1db4aadd | 492 | SCFree(p); |
aa87f704 GS |
493 | return result; |
494 | } | |
495 | ||
df74597a GS |
496 | /** |
497 | * \brief this function registers unit tests for DetectStreamSize | |
498 | */ | |
8f1d7503 KS |
499 | void DetectStreamSizeRegisterTests(void) |
500 | { | |
796dd522 JI |
501 | UtRegisterTest("DetectStreamSizeParseTest01", DetectStreamSizeParseTest01); |
502 | UtRegisterTest("DetectStreamSizeParseTest02", DetectStreamSizeParseTest02); | |
503 | UtRegisterTest("DetectStreamSizeParseTest03", DetectStreamSizeParseTest03); | |
504 | UtRegisterTest("DetectStreamSizeParseTest04", DetectStreamSizeParseTest04); | |
d883a993 | 505 | } |
3de99a21 | 506 | #endif /* UNITTESTS */ |