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};
470  Packet *p = PacketGetFromAlloc();
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(&dtv, 0, sizeof(DecodeThreadVars));
481  memset(&ipv4h, 0, sizeof(IPV4Hdr));
483 
484  p->ip4h = &ipv4h;
485 
487 
488  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
489 
490  de = DetectFragBitsParse("D");
491 
492  FAIL_IF(de == NULL || (de->fragbits != FRAGBITS_HAVE_DF));
493 
494  sm = SigMatchAlloc();
495  FAIL_IF(sm == NULL);
496 
497  sm->type = DETECT_FRAGBITS;
498  sm->ctx = (SigMatchCtx *)de;
499 
500  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
501  FAIL_IF(ret == 0);
502 
503  FlowShutdown();
504  SCFree(de);
505  SCFree(sm);
506  SCFree(p);
507  PASS;
508 }
509 
510 /**
511  * \test FragBitsTestParse04 test if DONT FRAG is not set. Must fails.
512  *
513  * \retval 1 on success
514  * \retval 0 on failure
515  */
516 static int FragBitsTestParse04 (void)
517 {
518  uint8_t raw_eth[] = {
519  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
520  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
521  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
522  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
523  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
524  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
525  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
526  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
527  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
528  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
529  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
530  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
531  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
532  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
533  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
534  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
535  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
536  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
537  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
538  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
539  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
540  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
541  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
542  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
543  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
544  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
545  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
546  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
547  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
548  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
549  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
550  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
551  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
552  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
553  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
554  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
555  0x51};
556  Packet *p = PacketGetFromAlloc();
557  FAIL_IF(unlikely(p == NULL));
558  ThreadVars tv;
560  IPV4Hdr ipv4h;
561  int ret = 0;
562  DetectFragBitsData *de = NULL;
563  SigMatch *sm = NULL;
564 
565  memset(&tv, 0, sizeof(ThreadVars));
566  memset(&dtv, 0, sizeof(DecodeThreadVars));
567  memset(&ipv4h, 0, sizeof(IPV4Hdr));
569 
570  p->ip4h = &ipv4h;
571 
573 
574  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
575 
576 
577  de = DetectFragBitsParse("!D");
578 
579  FAIL_IF(de == NULL);
580  FAIL_IF(de->fragbits != FRAGBITS_HAVE_DF);
581  FAIL_IF(de->modifier != MODIFIER_NOT);
582 
583  sm = SigMatchAlloc();
584  FAIL_IF(sm == NULL);
585 
586  sm->type = DETECT_FRAGBITS;
587  sm->ctx = (SigMatchCtx *)de;
588 
589  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
590  FAIL_IF(ret);
591  SCFree(de);
592  SCFree(sm);
593  PACKET_RECYCLE(p);
594  FlowShutdown();
595  SCFree(p);
596  PASS;
597 }
598 
599 /**
600  * \brief this function registers unit tests for FragBits
601  */
602 static void FragBitsRegisterTests(void)
603 {
604  UtRegisterTest("FragBitsTestParse01", FragBitsTestParse01);
605  UtRegisterTest("FragBitsTestParse02", FragBitsTestParse02);
606  UtRegisterTest("FragBitsTestParse03", FragBitsTestParse03);
607  UtRegisterTest("FragBitsTestParse04", FragBitsTestParse04);
608 }
609 #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:1248
SigTableElmt_::desc
const char * desc
Definition: detect.h:1247
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2475
SC_ERR_INVALID_VALUE
@ SC_ERR_INVALID_VALUE
Definition: util-error.h:160
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1235
MODIFIER_NOT
#define MODIFIER_NOT
Definition: detect-fragbits.c:60
DetectParseRegex
Definition: detect-parse.h:42
SigTableElmt_::name
const char * name
Definition: detect.h:1245
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1222
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1403
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
IPV4_GET_DF
#define IPV4_GET_DF(p)
Definition: decode-ipv4.h:140
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:1141
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:785
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:38
PrefilterPacketHeaderCtx_::sigs_cnt
uint32_t sigs_cnt
Definition: detect-engine-prefilter-common.h:42
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:1230
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:137
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1233
DETECT_FRAGBITS
@ DETECT_FRAGBITS
Definition: detect-engine-register.h:41
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:524
app-layer-detect-proto.h
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:35
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:1034
detect-fragbits.h
de
uint8_t de
Definition: app-layer-htp.c:568
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2598
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(ThreadVars *tv)
Creates a new app layer thread context.
Definition: app-layer.c:982
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:56
pkt-var.h
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:318
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:80
SC_Pcre2SubstringGet
int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
Definition: detect-parse.c:2586
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:317
util-profiling.h
Signature_::flags
uint32_t flags
Definition: detect.h:541
Packet_
Definition: decode.h:434
DetectFragBitsData_::fragbits
uint8_t fragbits
Definition: detect-fragbits.h:39
DecodeThreadVars_::app_tctx
AppLayerThreadCtx * app_tctx
Definition: decode.h:666
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:532
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:611
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1213
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:534
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:32
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:309
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
SigMatch_::type
uint16_t type
Definition: detect.h:315
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:671
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:255
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:31
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:176
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:664
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1232
IPV4_GET_MF
#define IPV4_GET_MF(p)
Definition: decode-ipv4.h:143
detect-parse.h
Signature_
Signature container.
Definition: detect.h:540
SigMatch_
a single match condition for a signature
Definition: detect.h:314
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:40
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:23
detect-engine-prefilter-common.h
flow-var.h
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:253
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:876
DetectFragBitsData_::modifier
uint8_t modifier
Definition: detect-fragbits.h:40
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1237
app-layer.h
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:217