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("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("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("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 #include "util-unittest-helper.h"
389 #include "packet.h"
390 
391 /**
392  * \test FragBitsTestParse01 is a test for a valid fragbits value
393  *
394  * \retval 1 on succces
395  * \retval 0 on failure
396  */
397 static int FragBitsTestParse01 (void)
398 {
399  DetectFragBitsData *de = NULL;
400  de = DetectFragBitsParse("M");
401  if (de && (de->fragbits == FRAGBITS_HAVE_MF) ) {
402  DetectFragBitsFree(NULL, de);
403  return 1;
404  }
405 
406  return 0;
407 }
408 
409 /**
410  * \test FragBitsTestParse02 is a test for an invalid fragbits value
411  *
412  * \retval 1 on succces
413  * \retval 0 on failure
414  */
415 static int FragBitsTestParse02 (void)
416 {
417  DetectFragBitsData *de = NULL;
418  de = DetectFragBitsParse("G");
419  if (de) {
420  DetectFragBitsFree(NULL, de);
421  return 0;
422  }
423 
424  return 1;
425 }
426 
427 /**
428  * \test FragBitsTestParse03 test if DONT FRAG is set. Must return success
429  *
430  * \retval 1 on success
431  * \retval 0 on failure
432  */
433 static int FragBitsTestParse03 (void)
434 {
435  uint8_t raw_eth[] = {
436  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
437  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
438  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
439  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
440  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
441  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
442  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
443  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
444  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
445  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
446  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
447  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
448  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
449  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
450  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
451  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
452  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
453  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
454  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
455  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
456  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
457  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
458  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
459  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
460  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
461  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
462  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
463  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
464  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
465  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
466  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
467  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
468  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
469  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
470  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
471  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
472  0x51};
473  Packet *p = PacketGetFromAlloc();
474  FAIL_IF(unlikely(p == NULL));
475  ThreadVars tv;
477  IPV4Hdr ipv4h;
478  int ret = 0;
479  DetectFragBitsData *de = NULL;
480  SigMatch *sm = NULL;
481 
482  memset(&tv, 0, sizeof(ThreadVars));
483  memset(&dtv, 0, sizeof(DecodeThreadVars));
484  memset(&ipv4h, 0, sizeof(IPV4Hdr));
486 
487  p->ip4h = &ipv4h;
488 
490 
491  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
492 
493  de = DetectFragBitsParse("D");
494 
495  FAIL_IF(de == NULL || (de->fragbits != FRAGBITS_HAVE_DF));
496 
497  sm = SigMatchAlloc();
498  FAIL_IF(sm == NULL);
499 
500  sm->type = DETECT_FRAGBITS;
501  sm->ctx = (SigMatchCtx *)de;
502 
503  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
504  FAIL_IF(ret == 0);
505 
506  FlowShutdown();
507  SCFree(de);
508  SCFree(sm);
509  SCFree(p);
510  PASS;
511 }
512 
513 /**
514  * \test FragBitsTestParse04 test if DONT FRAG is not set. Must fails.
515  *
516  * \retval 1 on success
517  * \retval 0 on failure
518  */
519 static int FragBitsTestParse04 (void)
520 {
521  uint8_t raw_eth[] = {
522  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
523  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
524  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
525  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
526  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
527  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
528  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
529  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
530  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
531  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
532  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
533  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
534  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
535  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
536  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
537  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
538  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
539  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
540  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
541  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
542  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
543  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
544  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
545  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
546  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
547  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
548  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
549  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
550  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
551  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
552  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
553  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
554  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
555  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
556  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
557  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
558  0x51};
559  Packet *p = PacketGetFromAlloc();
560  FAIL_IF(unlikely(p == NULL));
561  ThreadVars tv;
563  IPV4Hdr ipv4h;
564  int ret = 0;
565  DetectFragBitsData *de = NULL;
566  SigMatch *sm = NULL;
567 
568  memset(&tv, 0, sizeof(ThreadVars));
569  memset(&dtv, 0, sizeof(DecodeThreadVars));
570  memset(&ipv4h, 0, sizeof(IPV4Hdr));
572 
573  p->ip4h = &ipv4h;
574 
576 
577  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
578 
579 
580  de = DetectFragBitsParse("!D");
581 
582  FAIL_IF(de == NULL);
583  FAIL_IF(de->fragbits != FRAGBITS_HAVE_DF);
584  FAIL_IF(de->modifier != MODIFIER_NOT);
585 
586  sm = SigMatchAlloc();
587  FAIL_IF(sm == NULL);
588 
589  sm->type = DETECT_FRAGBITS;
590  sm->ctx = (SigMatchCtx *)de;
591 
592  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
593  FAIL_IF(ret);
594  SCFree(de);
595  SCFree(sm);
596  PacketRecycle(p);
597  FlowShutdown();
598  SCFree(p);
599  PASS;
600 }
601 
602 /**
603  * \brief this function registers unit tests for FragBits
604  */
605 static void FragBitsRegisterTests(void)
606 {
607  UtRegisterTest("FragBitsTestParse01", FragBitsTestParse01);
608  UtRegisterTest("FragBitsTestParse02", FragBitsTestParse02);
609  UtRegisterTest("FragBitsTestParse03", FragBitsTestParse03);
610  UtRegisterTest("FragBitsTestParse04", FragBitsTestParse04);
611 }
612 #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:47
SigTableElmt_::url
const char * url
Definition: detect.h:1241
SigTableElmt_::desc
const char * desc
Definition: detect.h:1240
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2488
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1228
MODIFIER_NOT
#define MODIFIER_NOT
Definition: detect-fragbits.c:60
DetectParseRegex
Definition: detect-parse.h:44
SigTableElmt_::name
const char * name
Definition: detect.h:1238
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1059
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1395
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:167
FRAGBITS_HAVE_DF
#define FRAGBITS_HAVE_DF
Definition: detect-fragbits.c:65
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1134
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
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1223
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:1226
DETECT_FRAGBITS
@ DETECT_FRAGBITS
Definition: detect-engine-register.h:43
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:543
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:1025
detect-fragbits.h
de
uint8_t de
Definition: app-layer-htp.c:576
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2609
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(ThreadVars *tv)
Creates a new app layer thread context.
Definition: app-layer.c:993
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
pkt-var.h
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:317
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:78
SC_Pcre2SubstringGet
int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
Definition: detect-parse.c:2597
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:316
util-profiling.h
Signature_::flags
uint32_t flags
Definition: detect.h:541
Packet_
Definition: decode.h:428
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:531
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:611
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1206
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:534
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:239
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:308
IPV4Hdr_
Definition: decode-ipv4.h:72
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:314
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:689
packet.h
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:76
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:173
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
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:664
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1225
IPV4_GET_MF
#define IPV4_GET_MF(p)
Definition: decode-ipv4.h:144
detect-parse.h
Signature_
Signature container.
Definition: detect.h:540
SigMatch_
a single match condition for a signature
Definition: detect.h:313
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:41
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:245
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:354
DetectFragBitsData_::modifier
uint8_t modifier
Definition: detect-fragbits.h:40
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1230
app-layer.h
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:215