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