suricata
detect-fragbits.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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 Breno Silva <breno.silva@gmail.com>
22  * \author Victor Julien <victor@inliniac.net>
23  *
24  * Implements fragbits keyword
25  */
26 
27 #include "suricata-common.h"
28 #include "suricata.h"
29 #include "decode.h"
30 
31 #include "detect.h"
32 #include "detect-parse.h"
35 
36 #include "flow-var.h"
37 #include "decode-events.h"
38 #include "app-layer.h"
39 #include "app-layer-detect-proto.h"
40 
41 #include "detect-fragbits.h"
42 #include "util-unittest.h"
43 #include "util-debug.h"
44 
45 #include "pkt-var.h"
46 #include "host.h"
47 #include "util-profiling.h"
48 
49 /**
50  * Regex
51  * fragbits: [!+*](MDR)
52  */
53 #define PARSE_REGEX "^(?:([\\+\\*!]))?\\s*([MDR]+)"
54 
55 /**
56  * FragBits args[0] *(3) +(2) !(1)
57  *
58  */
59 
60 #define MODIFIER_NOT 1
61 #define MODIFIER_PLUS 2
62 #define MODIFIER_ANY 3
63 
64 #define FRAGBITS_HAVE_MF 0x01
65 #define FRAGBITS_HAVE_DF 0x02
66 #define FRAGBITS_HAVE_RF 0x04
67 
68 static DetectParseRegex parse_regex;
69 
70 static int DetectFragBitsMatch (DetectEngineThreadCtx *, Packet *,
71  const Signature *, const SigMatchCtx *);
72 static int DetectFragBitsSetup (DetectEngineCtx *, Signature *, const char *);
73 static void DetectFragBitsFree(DetectEngineCtx *, void *);
74 
75 static int PrefilterSetupFragBits(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
76 static bool PrefilterFragBitsIsPrefilterable(const Signature *s);
77 #ifdef UNITTESTS
78 static void FragBitsRegisterTests(void);
79 #endif
80 
81 /**
82  * \brief Registration function for fragbits: keyword
83  */
84 
86 {
87  sigmatch_table[DETECT_FRAGBITS].name = "fragbits";
88  sigmatch_table[DETECT_FRAGBITS].desc = "check if the fragmentation and reserved bits are set in the IP header";
89  sigmatch_table[DETECT_FRAGBITS].url = "/rules/header-keywords.html#fragbits-ip-fragmentation";
90  sigmatch_table[DETECT_FRAGBITS].Match = DetectFragBitsMatch;
91  sigmatch_table[DETECT_FRAGBITS].Setup = DetectFragBitsSetup;
92  sigmatch_table[DETECT_FRAGBITS].Free = DetectFragBitsFree;
93 #ifdef UNITTESTS
94  sigmatch_table[DETECT_FRAGBITS].RegisterTests = FragBitsRegisterTests;
95 #endif
96  sigmatch_table[DETECT_FRAGBITS].SetupPrefilter = PrefilterSetupFragBits;
97  sigmatch_table[DETECT_FRAGBITS].SupportsPrefilter = PrefilterFragBitsIsPrefilterable;
98 
99  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
100 }
101 
102 static inline int
103 FragBitsMatch(const uint8_t pbits, const uint8_t modifier,
104  const uint8_t dbits)
105 {
106  switch (modifier) {
107  case MODIFIER_ANY:
108  if ((pbits & dbits) > 0)
109  return 1;
110  return 0;
111 
112  case MODIFIER_PLUS:
113  if (((pbits & dbits) == dbits) && (((pbits - dbits) > 0)))
114  return 1;
115  return 0;
116 
117  case MODIFIER_NOT:
118  if ((pbits & dbits) != dbits)
119  return 1;
120  return 0;
121 
122  default:
123  if (pbits == dbits)
124  return 1;
125  }
126  return 0;
127 }
128 
129 /**
130  * \internal
131  * \brief This function is used to match fragbits on a packet with those passed via fragbits:
132  *
133  * \param t pointer to thread vars
134  * \param det_ctx pointer to the pattern matcher thread
135  * \param p pointer to the current packet
136  * \param s pointer to the Signature
137  * \param m pointer to the sigmatch
138  *
139  * \retval 0 no match
140  * \retval 1 match
141  */
142 static int DetectFragBitsMatch (DetectEngineThreadCtx *det_ctx,
143  Packet *p, const Signature *s, const SigMatchCtx *ctx)
144 {
145  if (!ctx || !PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p))
146  return 0;
147 
148  uint8_t fragbits = 0;
149  const DetectFragBitsData *de = (const DetectFragBitsData *)ctx;
150  if(IPV4_GET_MF(p))
151  fragbits |= FRAGBITS_HAVE_MF;
152  if(IPV4_GET_DF(p))
153  fragbits |= FRAGBITS_HAVE_DF;
154  if(IPV4_GET_RF(p))
155  fragbits |= FRAGBITS_HAVE_RF;
156 
157  return FragBitsMatch(fragbits, de->modifier, de->fragbits);
158 }
159 
160 /**
161  * \internal
162  * \brief This function is used to parse fragbits options passed via fragbits: keyword
163  *
164  * \param rawstr Pointer to the user provided fragbits options
165  *
166  * \retval de pointer to DetectFragBitsData on success
167  * \retval NULL on failure
168  */
169 static DetectFragBitsData *DetectFragBitsParse (const char *rawstr)
170 {
171  DetectFragBitsData *de = NULL;
172  int found = 0, res = 0;
173  size_t pcre2_len;
174  const char *str_ptr = NULL;
175  char *args[2] = { NULL, NULL};
176  char *ptr;
177  int i;
178  pcre2_match_data *match = NULL;
179 
180  int ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0);
181  if (ret < 1) {
182  SCLogError("pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
183  goto error;
184  }
185 
186  for (i = 0; i < (ret - 1); i++) {
187  res = SC_Pcre2SubstringGet(match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
188  if (res < 0) {
189  SCLogError("pcre2_substring_get_bynumber failed %d", res);
190  goto error;
191  }
192 
193  args[i] = (char *)str_ptr;
194  }
195 
196  if (args[1] == NULL) {
197  SCLogError("invalid value");
198  goto error;
199  }
200 
201  de = SCCalloc(1, sizeof(DetectFragBitsData));
202  if (unlikely(de == NULL))
203  goto error;
204 
205  /** First parse args[0] */
206 
207  if (args[0] && strlen(args[0])) {
208  ptr = args[0];
209  switch (*ptr) {
210  case '!':
211  de->modifier = MODIFIER_NOT;
212  break;
213  case '+':
214  de->modifier = MODIFIER_PLUS;
215  break;
216  case '*':
217  de->modifier = MODIFIER_ANY;
218  break;
219  }
220  }
221 
222  /** Second parse first set of fragbits */
223 
224  ptr = args[1];
225 
226  while (*ptr != '\0') {
227  switch (*ptr) {
228  case 'M':
229  case 'm':
230  de->fragbits |= FRAGBITS_HAVE_MF;
231  found++;
232  break;
233  case 'D':
234  case 'd':
235  de->fragbits |= FRAGBITS_HAVE_DF;
236  found++;
237  break;
238  case 'R':
239  case 'r':
240  de->fragbits |= FRAGBITS_HAVE_RF;
241  found++;
242  break;
243  default:
244  found = 0;
245  break;
246  }
247  ptr++;
248  }
249 
250  if(found == 0)
251  goto error;
252 
253  for (i = 0; i < 2; i++) {
254  if (args[i] != NULL)
255  pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
256  }
257  pcre2_match_data_free(match);
258  return de;
259 
260 error:
261  if (match) {
262  pcre2_match_data_free(match);
263  }
264  for (i = 0; i < 2; i++) {
265  if (args[i] != NULL)
266  pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
267  }
268  if (de != NULL)
269  SCFree(de);
270  return NULL;
271 }
272 
273 /**
274  * \internal
275  * \brief this function is used to add the parsed fragbits into the current signature
276  *
277  * \param de_ctx pointer to the Detection Engine Context
278  * \param s pointer to the Current Signature
279  * \param m pointer to the Current SigMatch
280  * \param rawstr pointer to the user provided fragbits options
281  *
282  * \retval 0 on Success
283  * \retval -1 on Failure
284  */
285 static int DetectFragBitsSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
286 {
287  DetectFragBitsData *de = NULL;
288 
289  de = DetectFragBitsParse(rawstr);
290  if (de == NULL)
291  return -1;
292 
295  goto error;
296  }
298 
299  return 0;
300 
301 error:
302  if (de)
303  SCFree(de);
304  return -1;
305 }
306 
307 /**
308  * \internal
309  * \brief this function will free memory associated with DetectFragBitsData
310  *
311  * \param de pointer to DetectFragBitsData
312  */
313 static void DetectFragBitsFree(DetectEngineCtx *de_ctx, void *de_ptr)
314 {
316  if(de) SCFree(de);
317 }
318 
319 static void
320 PrefilterPacketFragBitsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
321 {
322  const PrefilterPacketHeaderCtx *ctx = pectx;
323 
324  if (!PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p))
325  return;
326 
327  uint8_t fragbits = 0;
328  if (IPV4_GET_MF(p))
329  fragbits |= FRAGBITS_HAVE_MF;
330  if (IPV4_GET_DF(p))
331  fragbits |= FRAGBITS_HAVE_DF;
332  if (IPV4_GET_RF(p))
333  fragbits |= FRAGBITS_HAVE_RF;
334 
335  if (FragBitsMatch(fragbits, ctx->v1.u8[0], ctx->v1.u8[1]))
336  {
337  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
338  }
339 }
340 
341 static void
342 PrefilterPacketFragBitsSet(PrefilterPacketHeaderValue *v, void *smctx)
343 {
344  const DetectFragBitsData *fb = smctx;
345  v->u8[0] = fb->modifier;
346  v->u8[1] = fb->fragbits;
347 }
348 
349 static bool
350 PrefilterPacketFragBitsCompare(PrefilterPacketHeaderValue v, void *smctx)
351 {
352  const DetectFragBitsData *fb = smctx;
353  if (v.u8[0] == fb->modifier &&
354  v.u8[1] == fb->fragbits)
355  {
356  return true;
357  }
358  return false;
359 }
360 
361 static int PrefilterSetupFragBits(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
362 {
364  PrefilterPacketFragBitsSet,
365  PrefilterPacketFragBitsCompare,
366  PrefilterPacketFragBitsMatch);
367 }
368 
369 static bool PrefilterFragBitsIsPrefilterable(const Signature *s)
370 {
371  const SigMatch *sm;
372  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
373  switch (sm->type) {
374  case DETECT_FRAGBITS:
375  return true;
376  }
377  }
378  return false;
379 }
380 
381 /*
382  * ONLY TESTS BELOW THIS COMMENT
383  */
384 
385 #ifdef UNITTESTS
386 #include "util-unittest-helper.h"
387 #include "packet.h"
388 
389 /**
390  * \test FragBitsTestParse01 is a test for a valid fragbits value
391  *
392  * \retval 1 on success
393  * \retval 0 on failure
394  */
395 static int FragBitsTestParse01 (void)
396 {
397  DetectFragBitsData *de = NULL;
398  de = DetectFragBitsParse("M");
399  if (de && (de->fragbits == FRAGBITS_HAVE_MF) ) {
400  DetectFragBitsFree(NULL, de);
401  return 1;
402  }
403 
404  return 0;
405 }
406 
407 /**
408  * \test FragBitsTestParse02 is a test for an invalid fragbits value
409  *
410  * \retval 1 on success
411  * \retval 0 on failure
412  */
413 static int FragBitsTestParse02 (void)
414 {
415  DetectFragBitsData *de = NULL;
416  de = DetectFragBitsParse("G");
417  if (de) {
418  DetectFragBitsFree(NULL, de);
419  return 0;
420  }
421 
422  return 1;
423 }
424 
425 /**
426  * \test FragBitsTestParse03 test if DONT FRAG is set. Must return success
427  *
428  * \retval 1 on success
429  * \retval 0 on failure
430  */
431 static int FragBitsTestParse03 (void)
432 {
433  uint8_t raw_eth[] = {
434  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
435  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
436  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
437  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
438  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
439  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
440  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
441  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
442  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
443  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
444  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
445  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
446  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
447  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
448  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
449  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
450  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
451  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
452  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
453  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
454  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
455  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
456  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
457  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
458  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
459  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
460  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
461  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
462  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
463  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
464  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
465  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
466  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
467  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
468  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
469  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
470  0x51};
471  Packet *p = PacketGetFromAlloc();
472  FAIL_IF(unlikely(p == NULL));
473  ThreadVars tv;
475  int ret = 0;
476  DetectFragBitsData *de = NULL;
477  SigMatch *sm = NULL;
478 
479  memset(&tv, 0, sizeof(ThreadVars));
480  memset(&dtv, 0, sizeof(DecodeThreadVars));
482 
484 
485  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
486 
487  de = DetectFragBitsParse("D");
488 
489  FAIL_IF(de == NULL || (de->fragbits != FRAGBITS_HAVE_DF));
490 
491  sm = SigMatchAlloc();
492  FAIL_IF(sm == NULL);
493 
494  sm->type = DETECT_FRAGBITS;
495  sm->ctx = (SigMatchCtx *)de;
496 
497  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
498  FAIL_IF(ret == 0);
499 
500  FlowShutdown();
501  SCFree(de);
502  SCFree(sm);
503  SCFree(p);
504  PASS;
505 }
506 
507 /**
508  * \test FragBitsTestParse04 test if DONT FRAG is not set. Must fails.
509  *
510  * \retval 1 on success
511  * \retval 0 on failure
512  */
513 static int FragBitsTestParse04 (void)
514 {
515  uint8_t raw_eth[] = {
516  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
517  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
518  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
519  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
520  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
521  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
522  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
523  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
524  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
525  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
526  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
527  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
528  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
529  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
530  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
531  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
532  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
533  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
534  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
535  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
536  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
537  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
538  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
539  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
540  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
541  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
542  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
543  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
544  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
545  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
546  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
547  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
548  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
549  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
550  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
551  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
552  0x51};
553  Packet *p = PacketGetFromAlloc();
554  FAIL_IF(unlikely(p == NULL));
555  ThreadVars tv;
557  int ret = 0;
558  DetectFragBitsData *de = NULL;
559  SigMatch *sm = NULL;
560 
561  memset(&tv, 0, sizeof(ThreadVars));
562  memset(&dtv, 0, sizeof(DecodeThreadVars));
564 
566 
567  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
568 
569  de = DetectFragBitsParse("!D");
570 
571  FAIL_IF(de == NULL);
572  FAIL_IF(de->fragbits != FRAGBITS_HAVE_DF);
573  FAIL_IF(de->modifier != MODIFIER_NOT);
574 
575  sm = SigMatchAlloc();
576  FAIL_IF(sm == NULL);
577 
578  sm->type = DETECT_FRAGBITS;
579  sm->ctx = (SigMatchCtx *)de;
580 
581  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
582  FAIL_IF(ret);
583  SCFree(de);
584  SCFree(sm);
585  PacketRecycle(p);
586  FlowShutdown();
587  SCFree(p);
588  PASS;
589 }
590 
591 /**
592  * \brief this function registers unit tests for FragBits
593  */
594 static void FragBitsRegisterTests(void)
595 {
596  UtRegisterTest("FragBitsTestParse01", FragBitsTestParse01);
597  UtRegisterTest("FragBitsTestParse02", FragBitsTestParse02);
598  UtRegisterTest("FragBitsTestParse03", FragBitsTestParse03);
599  UtRegisterTest("FragBitsTestParse04", FragBitsTestParse04);
600 }
601 #endif /* UNITTESTS */
DetectFragBitsRegister
void DetectFragBitsRegister(void)
Registration function for fragbits: keyword.
Definition: detect-fragbits.c:85
host.h
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-fragbits.c:53
SigTableElmt_::url
const char * url
Definition: detect.h:1299
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:581
SigTableElmt_::desc
const char * desc
Definition: detect.h:1298
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1286
MODIFIER_NOT
#define MODIFIER_NOT
Definition: detect-fragbits.c:60
DetectParseRegex
Definition: detect-parse.h:62
SigTableElmt_::name
const char * name
Definition: detect.h:1296
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1075
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1448
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
IPV4_GET_DF
#define IPV4_GET_DF(p)
Definition: decode-ipv4.h:141
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
FRAGBITS_HAVE_RF
#define FRAGBITS_HAVE_RF
Definition: detect-fragbits.c:66
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:169
FRAGBITS_HAVE_DF
#define FRAGBITS_HAVE_DF
Definition: detect-fragbits.c:65
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1204
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:839
PrefilterPacketHeaderCtx_::sigs_array
SigIntId * sigs_array
Definition: detect-engine-prefilter-common.h:43
PrefilterPacketHeaderValue::u8
uint8_t u8[16]
Definition: detect-engine-prefilter-common.h:24
DetectFragBitsData_
Definition: detect-fragbits.h:37
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:2674
PrefilterPacketHeaderCtx_::sigs_cnt
uint32_t sigs_cnt
Definition: detect-engine-prefilter-common.h:42
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1281
MODIFIER_PLUS
#define MODIFIER_PLUS
Definition: detect-fragbits.c:61
detect-engine-prefilter.h
util-unittest.h
IPV4_GET_RF
#define IPV4_GET_RF(p)
Definition: decode-ipv4.h:138
util-unittest-helper.h
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1284
DETECT_FRAGBITS
@ DETECT_FRAGBITS
Definition: detect-engine-register.h:43
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:537
app-layer-detect-proto.h
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:35
decode.h
util-debug.h
FRAGBITS_HAVE_MF
#define FRAGBITS_HAVE_MF
Definition: detect-fragbits.c:64
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1095
detect-fragbits.h
de
uint8_t de
Definition: app-layer-htp.c:581
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2791
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(ThreadVars *tv)
Creates a new app layer thread context.
Definition: app-layer.c:1059
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
pkt-var.h
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:354
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:114
SC_Pcre2SubstringGet
int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
Definition: detect-parse.c:2779
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:353
util-profiling.h
Signature_::flags
uint32_t flags
Definition: detect.h:597
Packet_
Definition: decode.h:437
DetectFragBitsData_::fragbits
uint8_t fragbits
Definition: detect-fragbits.h:38
DecodeThreadVars_::app_tctx
AppLayerThreadCtx * app_tctx
Definition: decode.h:687
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:665
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1264
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:333
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
PrefilterPacketHeaderCtx_::v1
PrefilterPacketHeaderValue v1
Definition: detect-engine-prefilter-common.h:36
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:345
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:351
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:685
packet.h
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:127
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
PrefilterSetupPacketHeader
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, 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:417
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:229
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:685
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1283
IPV4_GET_MF
#define IPV4_GET_MF(p)
Definition: decode-ipv4.h:144
detect-parse.h
Signature_
Signature container.
Definition: detect.h:596
SigMatch_
a single match condition for a signature
Definition: detect.h:350
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:42
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:23
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:447
detect-engine-prefilter-common.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
flow-var.h
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:246
MODIFIER_ANY
#define MODIFIER_ANY
Definition: detect-fragbits.c:62
DecodeEthernet
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ethernet.c:42
DetectFragBitsData_::modifier
uint8_t modifier
Definition: detect-fragbits.h:39
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1288
app-layer.h
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:249