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 ret = 0, 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 
179  ret = DetectParsePcreExec(&parse_regex, rawstr, 0, 0);
180  if (ret < 1) {
181  SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
182  goto error;
183  }
184 
185  for (i = 0; i < (ret - 1); i++) {
186  res = SC_Pcre2SubstringGet(parse_regex.match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
187  if (res < 0) {
188  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed %d", res);
189  goto error;
190  }
191 
192  args[i] = (char *)str_ptr;
193  }
194 
195  if (args[1] == NULL) {
196  SCLogError(SC_ERR_INVALID_VALUE, "invalid value");
197  goto error;
198  }
199 
200  de = SCMalloc(sizeof(DetectFragBitsData));
201  if (unlikely(de == NULL))
202  goto error;
203 
204  memset(de,0,sizeof(DetectFragBitsData));
205 
206  /** First parse args[0] */
207 
208  if (args[0] && strlen(args[0])) {
209  ptr = args[0];
210  switch (*ptr) {
211  case '!':
212  de->modifier = MODIFIER_NOT;
213  break;
214  case '+':
215  de->modifier = MODIFIER_PLUS;
216  break;
217  case '*':
218  de->modifier = MODIFIER_ANY;
219  break;
220  }
221  }
222 
223  /** Second parse first set of fragbits */
224 
225  ptr = args[1];
226 
227  while (*ptr != '\0') {
228  switch (*ptr) {
229  case 'M':
230  case 'm':
231  de->fragbits |= FRAGBITS_HAVE_MF;
232  found++;
233  break;
234  case 'D':
235  case 'd':
236  de->fragbits |= FRAGBITS_HAVE_DF;
237  found++;
238  break;
239  case 'R':
240  case 'r':
241  de->fragbits |= FRAGBITS_HAVE_RF;
242  found++;
243  break;
244  default:
245  found = 0;
246  break;
247  }
248  ptr++;
249  }
250 
251  if(found == 0)
252  goto error;
253 
254  for (i = 0; i < 2; i++) {
255  if (args[i] != NULL)
256  pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
257  }
258  return de;
259 
260 error:
261  for (i = 0; i < 2; i++) {
262  if (args[i] != NULL)
263  pcre2_substring_free((PCRE2_UCHAR8 *)args[i]);
264  }
265  if (de != NULL)
266  SCFree(de);
267  return NULL;
268 }
269 
270 /**
271  * \internal
272  * \brief this function is used to add the parsed fragbits into the current signature
273  *
274  * \param de_ctx pointer to the Detection Engine Context
275  * \param s pointer to the Current Signature
276  * \param m pointer to the Current SigMatch
277  * \param rawstr pointer to the user provided fragbits options
278  *
279  * \retval 0 on Success
280  * \retval -1 on Failure
281  */
282 static int DetectFragBitsSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
283 {
284  DetectFragBitsData *de = NULL;
285  SigMatch *sm = NULL;
286 
287  de = DetectFragBitsParse(rawstr);
288  if (de == NULL)
289  return -1;
290 
291  sm = SigMatchAlloc();
292  if (sm == NULL)
293  goto error;
294 
295  sm->type = DETECT_FRAGBITS;
296  sm->ctx = (SigMatchCtx *)de;
297 
300 
301  return 0;
302 
303 error:
304  if (de)
305  SCFree(de);
306  return -1;
307 }
308 
309 /**
310  * \internal
311  * \brief this function will free memory associated with DetectFragBitsData
312  *
313  * \param de pointer to DetectFragBitsData
314  */
315 static void DetectFragBitsFree(DetectEngineCtx *de_ctx, void *de_ptr)
316 {
318  if(de) SCFree(de);
319 }
320 
321 static void
322 PrefilterPacketFragBitsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
323 {
324  const PrefilterPacketHeaderCtx *ctx = pectx;
325 
326  if (!PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p))
327  return;
328 
329  uint8_t fragbits = 0;
330  if (IPV4_GET_MF(p))
331  fragbits |= FRAGBITS_HAVE_MF;
332  if (IPV4_GET_DF(p))
333  fragbits |= FRAGBITS_HAVE_DF;
334  if (IPV4_GET_RF(p))
335  fragbits |= FRAGBITS_HAVE_RF;
336 
337  if (FragBitsMatch(fragbits, ctx->v1.u8[0], ctx->v1.u8[1]))
338  {
339  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
340  }
341 }
342 
343 static void
344 PrefilterPacketFragBitsSet(PrefilterPacketHeaderValue *v, void *smctx)
345 {
346  const DetectFragBitsData *fb = smctx;
347  v->u8[0] = fb->modifier;
348  v->u8[1] = fb->fragbits;
349 }
350 
351 static bool
352 PrefilterPacketFragBitsCompare(PrefilterPacketHeaderValue v, void *smctx)
353 {
354  const DetectFragBitsData *fb = smctx;
355  if (v.u8[0] == fb->modifier &&
356  v.u8[1] == fb->fragbits)
357  {
358  return true;
359  }
360  return false;
361 }
362 
363 static int PrefilterSetupFragBits(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
364 {
366  PrefilterPacketFragBitsSet,
367  PrefilterPacketFragBitsCompare,
368  PrefilterPacketFragBitsMatch);
369 }
370 
371 static bool PrefilterFragBitsIsPrefilterable(const Signature *s)
372 {
373  const SigMatch *sm;
374  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
375  switch (sm->type) {
376  case DETECT_FRAGBITS:
377  return true;
378  }
379  }
380  return false;
381 }
382 
383 /*
384  * ONLY TESTS BELOW THIS COMMENT
385  */
386 
387 #ifdef UNITTESTS
388 /**
389  * \test FragBitsTestParse01 is a test for a valid fragbits value
390  *
391  * \retval 1 on succces
392  * \retval 0 on failure
393  */
394 static int FragBitsTestParse01 (void)
395 {
396  DetectFragBitsData *de = NULL;
397  de = DetectFragBitsParse("M");
398  if (de && (de->fragbits == FRAGBITS_HAVE_MF) ) {
399  DetectFragBitsFree(NULL, de);
400  return 1;
401  }
402 
403  return 0;
404 }
405 
406 /**
407  * \test FragBitsTestParse02 is a test for an invalid fragbits value
408  *
409  * \retval 1 on succces
410  * \retval 0 on failure
411  */
412 static int FragBitsTestParse02 (void)
413 {
414  DetectFragBitsData *de = NULL;
415  de = DetectFragBitsParse("G");
416  if (de) {
417  DetectFragBitsFree(NULL, de);
418  return 0;
419  }
420 
421  return 1;
422 }
423 
424 /**
425  * \test FragBitsTestParse03 test if DONT FRAG is set. Must return success
426  *
427  * \retval 1 on success
428  * \retval 0 on failure
429  */
430 static int FragBitsTestParse03 (void)
431 {
432  uint8_t raw_eth[] = {
433  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
434  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
435  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
436  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
437  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
438  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
439  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
440  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
441  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
442  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
443  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
444  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
445  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
446  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
447  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
448  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
449  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
450  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
451  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
452  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
453  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
454  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
455  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
456  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
457  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
458  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
459  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
460  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
461  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
462  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
463  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
464  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
465  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
466  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
467  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
468  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
469  0x51};
471  FAIL_IF(unlikely(p == NULL));
472  ThreadVars tv;
474  IPV4Hdr ipv4h;
475  int ret = 0;
476  DetectFragBitsData *de = NULL;
477  SigMatch *sm = NULL;
478 
479  memset(&tv, 0, sizeof(ThreadVars));
480  memset(p, 0, SIZE_OF_PACKET);
481  memset(&dtv, 0, sizeof(DecodeThreadVars));
482  memset(&ipv4h, 0, sizeof(IPV4Hdr));
484 
485  p->ip4h = &ipv4h;
486 
488 
489  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
490 
491  de = DetectFragBitsParse("D");
492 
493  FAIL_IF(de == NULL || (de->fragbits != FRAGBITS_HAVE_DF));
494 
495  sm = SigMatchAlloc();
496  FAIL_IF(sm == NULL);
497 
498  sm->type = DETECT_FRAGBITS;
499  sm->ctx = (SigMatchCtx *)de;
500 
501  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
502  FAIL_IF(ret == 0);
503 
504  FlowShutdown();
505  SCFree(de);
506  SCFree(sm);
507  SCFree(p);
508  PASS;
509 }
510 
511 /**
512  * \test FragBitsTestParse04 test if DONT FRAG is not set. Must fails.
513  *
514  * \retval 1 on success
515  * \retval 0 on failure
516  */
517 static int FragBitsTestParse04 (void)
518 {
519  uint8_t raw_eth[] = {
520  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
521  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
522  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
523  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
524  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
525  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
526  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
527  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
528  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
529  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
530  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
531  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
532  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
533  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
534  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
535  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
536  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
537  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
538  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
539  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
540  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
541  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
542  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
543  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
544  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
545  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
546  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
547  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
548  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
549  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
550  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
551  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
552  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
553  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
554  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
555  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
556  0x51};
558  FAIL_IF(unlikely(p == NULL));
559  ThreadVars tv;
561  IPV4Hdr ipv4h;
562  int ret = 0;
563  DetectFragBitsData *de = NULL;
564  SigMatch *sm = NULL;
565 
566  memset(&tv, 0, sizeof(ThreadVars));
567  memset(p, 0, SIZE_OF_PACKET);
568  memset(&dtv, 0, sizeof(DecodeThreadVars));
569  memset(&ipv4h, 0, sizeof(IPV4Hdr));
571 
572  p->ip4h = &ipv4h;
573 
575 
576  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
577 
578 
579  de = DetectFragBitsParse("!D");
580 
581  FAIL_IF(de == NULL);
582  FAIL_IF(de->fragbits != FRAGBITS_HAVE_DF);
583  FAIL_IF(de->modifier != MODIFIER_NOT);
584 
585  sm = SigMatchAlloc();
586  FAIL_IF(sm == NULL);
587 
588  sm->type = DETECT_FRAGBITS;
589  sm->ctx = (SigMatchCtx *)de;
590 
591  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
592  FAIL_IF(ret);
593  SCFree(de);
594  SCFree(sm);
595  PACKET_RECYCLE(p);
596  FlowShutdown();
597  SCFree(p);
598  PASS;
599 }
600 
601 /**
602  * \brief this function registers unit tests for FragBits
603  */
604 static void FragBitsRegisterTests(void)
605 {
606  UtRegisterTest("FragBitsTestParse01", FragBitsTestParse01);
607  UtRegisterTest("FragBitsTestParse02", FragBitsTestParse02);
608  UtRegisterTest("FragBitsTestParse03", FragBitsTestParse03);
609  UtRegisterTest("FragBitsTestParse04", FragBitsTestParse04);
610 }
611 #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
DetectParseRegex::match
pcre2_match_data * match
Definition: detect-parse.h:45
SigTableElmt_::url
const char * url
Definition: detect.h:1204
SigTableElmt_::desc
const char * desc
Definition: detect.h:1203
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2435
SC_ERR_INVALID_VALUE
@ SC_ERR_INVALID_VALUE
Definition: util-error.h:160
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1191
MODIFIER_NOT
#define MODIFIER_NOT
Definition: detect-fragbits.c:60
DetectParseRegex
Definition: detect-parse.h:42
SigTableElmt_::name
const char * name
Definition: detect.h:1201
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1201
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1346
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
FRAGBITS_HAVE_DF
#define FRAGBITS_HAVE_DF
Definition: detect-fragbits.c:65
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1101
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:758
PrefilterPacketHeaderCtx_::sigs_array
SigIntId * sigs_array
Definition: detect-engine-prefilter-common.h:41
PrefilterPacketHeaderValue::u8
uint8_t u8[16]
Definition: detect-engine-prefilter-common.h:22
DetectFragBitsData_
Definition: detect-fragbits.h:41
PrefilterPacketHeaderCtx_::sigs_cnt
uint32_t sigs_cnt
Definition: detect-engine-prefilter-common.h:40
SC_ERR_PCRE_GET_SUBSTRING
@ SC_ERR_PCRE_GET_SUBSTRING
Definition: util-error.h:34
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
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
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1189
DETECT_FRAGBITS
@ DETECT_FRAGBITS
Definition: detect-engine-register.h:41
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:523
app-layer-detect-proto.h
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:33
decode.h
util-debug.h
SC_ERR_PCRE_MATCH
@ SC_ERR_PCRE_MATCH
Definition: util-error.h:32
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:1003
detect-fragbits.h
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2558
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(ThreadVars *tv)
Creates a new app layer thread context.
Definition: app-layer.c:869
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
de
int de
Definition: app-layer-htp.c:527
pkt-var.h
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:324
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:89
SC_Pcre2SubstringGet
int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
Definition: detect-parse.c:2546
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:634
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:323
util-profiling.h
Signature_::flags
uint32_t flags
Definition: detect.h:518
Packet_
Definition: decode.h:414
DetectFragBitsData_::fragbits
uint8_t fragbits
Definition: detect-fragbits.h:42
DecodeThreadVars_::app_tctx
AppLayerThreadCtx * app_tctx
Definition: decode.h:640
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:509
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:587
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1169
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:511
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
decode-events.h
SigMatch_::type
uint8_t type
Definition: detect.h:321
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
PrefilterPacketHeaderCtx_::v1
PrefilterPacketHeaderValue v1
Definition: detect-engine-prefilter-common.h:34
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:315
IPV4Hdr_
Definition: decode-ipv4.h:71
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:651
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
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
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:638
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1188
IPV4_GET_MF
#define IPV4_GET_MF(p)
Definition: decode-ipv4.h:144
detect-parse.h
Signature_
Signature container.
Definition: detect.h:517
SigMatch_
a single match condition for a signature
Definition: detect.h:320
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:42
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:21
detect-engine-prefilter-common.h
flow-var.h
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:259
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
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:842
DetectFragBitsData_::modifier
uint8_t modifier
Definition: detect-fragbits.h:43
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1193
app-layer.h
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:223