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 {
146  if (!ctx || !PacketIsIPv4(p))
147  return 0;
148 
149  uint8_t fragbits = 0;
150  const DetectFragBitsData *de = (const DetectFragBitsData *)ctx;
151  const IPV4Hdr *ip4h = PacketGetIPv4(p);
152  if (IPV4_GET_RAW_FLAG_MF(ip4h))
153  fragbits |= FRAGBITS_HAVE_MF;
154  if (IPV4_GET_RAW_FLAG_DF(ip4h))
155  fragbits |= FRAGBITS_HAVE_DF;
156  if (IPV4_GET_RAW_FLAG_RF(ip4h))
157  fragbits |= FRAGBITS_HAVE_RF;
158 
159  return FragBitsMatch(fragbits, de->modifier, de->fragbits);
160 }
161 
162 /**
163  * \internal
164  * \brief This function is used to parse fragbits options passed via fragbits: keyword
165  *
166  * \param rawstr Pointer to the user provided fragbits options
167  *
168  * \retval de pointer to DetectFragBitsData on success
169  * \retval NULL on failure
170  */
171 static DetectFragBitsData *DetectFragBitsParse (const char *rawstr)
172 {
173  DetectFragBitsData *de = NULL;
174  int found = 0, res = 0;
175  size_t pcre2_len;
176  const char *str_ptr = NULL;
177  char *args[2] = { NULL, NULL};
178  char *ptr;
179  int i;
180  pcre2_match_data *match = NULL;
181 
182  int ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0);
183  if (ret < 1) {
184  SCLogError("pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
185  goto error;
186  }
187 
188  for (i = 0; i < (ret - 1); i++) {
189  res = SC_Pcre2SubstringGet(match, i + 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
190  if (res < 0) {
191  SCLogError("pcre2_substring_get_bynumber failed %d", res);
192  goto error;
193  }
194 
195  args[i] = (char *)str_ptr;
196  }
197 
198  if (args[1] == NULL) {
199  SCLogError("invalid value");
200  goto error;
201  }
202 
203  de = SCCalloc(1, sizeof(DetectFragBitsData));
204  if (unlikely(de == NULL))
205  goto error;
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 
291  de = DetectFragBitsParse(rawstr);
292  if (de == NULL)
293  return -1;
294 
297  goto error;
298  }
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 {
325  const PrefilterPacketHeaderCtx *ctx = pectx;
326 
327  if (!PacketIsIPv4(p))
328  return;
329 
330  uint8_t fragbits = 0;
331  const IPV4Hdr *ip4h = PacketGetIPv4(p);
332  if (IPV4_GET_RAW_FLAG_MF(ip4h))
333  fragbits |= FRAGBITS_HAVE_MF;
334  if (IPV4_GET_RAW_FLAG_DF(ip4h))
335  fragbits |= FRAGBITS_HAVE_DF;
336  if (IPV4_GET_RAW_FLAG_RF(ip4h))
337  fragbits |= FRAGBITS_HAVE_RF;
338 
339  if (FragBitsMatch(fragbits, ctx->v1.u8[0], ctx->v1.u8[1]))
340  {
341  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
342  }
343 }
344 
345 static void
346 PrefilterPacketFragBitsSet(PrefilterPacketHeaderValue *v, void *smctx)
347 {
348  const DetectFragBitsData *fb = smctx;
349  v->u8[0] = fb->modifier;
350  v->u8[1] = fb->fragbits;
351 }
352 
353 static bool
354 PrefilterPacketFragBitsCompare(PrefilterPacketHeaderValue v, void *smctx)
355 {
356  const DetectFragBitsData *fb = smctx;
357  if (v.u8[0] == fb->modifier &&
358  v.u8[1] == fb->fragbits)
359  {
360  return true;
361  }
362  return false;
363 }
364 
365 static int PrefilterSetupFragBits(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
366 {
368  PrefilterPacketFragBitsSet, PrefilterPacketFragBitsCompare,
369  PrefilterPacketFragBitsMatch);
370 }
371 
372 static bool PrefilterFragBitsIsPrefilterable(const Signature *s)
373 {
374  const SigMatch *sm;
375  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
376  switch (sm->type) {
377  case DETECT_FRAGBITS:
378  return true;
379  }
380  }
381  return false;
382 }
383 
384 /*
385  * ONLY TESTS BELOW THIS COMMENT
386  */
387 
388 #ifdef UNITTESTS
389 #include "util-unittest-helper.h"
390 #include "packet.h"
391 
392 /**
393  * \test FragBitsTestParse01 is a test for a valid fragbits value
394  *
395  * \retval 1 on success
396  * \retval 0 on failure
397  */
398 static int FragBitsTestParse01 (void)
399 {
400  DetectFragBitsData *de = NULL;
401  de = DetectFragBitsParse("M");
402  if (de && (de->fragbits == FRAGBITS_HAVE_MF) ) {
403  DetectFragBitsFree(NULL, de);
404  return 1;
405  }
406 
407  return 0;
408 }
409 
410 /**
411  * \test FragBitsTestParse02 is a test for an invalid fragbits value
412  *
413  * \retval 1 on success
414  * \retval 0 on failure
415  */
416 static int FragBitsTestParse02 (void)
417 {
418  DetectFragBitsData *de = NULL;
419  de = DetectFragBitsParse("G");
420  if (de) {
421  DetectFragBitsFree(NULL, de);
422  return 0;
423  }
424 
425  return 1;
426 }
427 
428 /**
429  * \test FragBitsTestParse03 test if DONT FRAG is set. Must return success
430  *
431  * \retval 1 on success
432  * \retval 0 on failure
433  */
434 static int FragBitsTestParse03 (void)
435 {
436  uint8_t raw_eth[] = {
437  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
438  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
439  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
440  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
441  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
442  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
443  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
444  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
445  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
446  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
447  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
448  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
449  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
450  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
451  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
452  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
453  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
454  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
455  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
456  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
457  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
458  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
459  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
460  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
461  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
462  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
463  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
464  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
465  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
466  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
467  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
468  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
469  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
470  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
471  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
472  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
473  0x51};
474  Packet *p = PacketGetFromAlloc();
475  FAIL_IF(unlikely(p == NULL));
476  ThreadVars tv;
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));
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  int ret = 0;
561  DetectFragBitsData *de = NULL;
562  SigMatch *sm = NULL;
563 
564  memset(&tv, 0, sizeof(ThreadVars));
565  memset(&dtv, 0, sizeof(DecodeThreadVars));
567 
569 
570  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
571 
572  de = DetectFragBitsParse("!D");
573 
574  FAIL_IF(de == NULL);
575  FAIL_IF(de->fragbits != FRAGBITS_HAVE_DF);
576  FAIL_IF(de->modifier != MODIFIER_NOT);
577 
578  sm = SigMatchAlloc();
579  FAIL_IF(sm == NULL);
580 
581  sm->type = DETECT_FRAGBITS;
582  sm->ctx = (SigMatchCtx *)de;
583 
584  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
585  FAIL_IF(ret);
586  SCFree(de);
587  SCFree(sm);
588  PacketRecycle(p);
589  FlowShutdown();
590  SCFree(p);
591  PASS;
592 }
593 
594 /**
595  * \brief this function registers unit tests for FragBits
596  */
597 static void FragBitsRegisterTests(void)
598 {
599  UtRegisterTest("FragBitsTestParse01", FragBitsTestParse01);
600  UtRegisterTest("FragBitsTestParse02", FragBitsTestParse02);
601  UtRegisterTest("FragBitsTestParse03", FragBitsTestParse03);
602  UtRegisterTest("FragBitsTestParse04", FragBitsTestParse04);
603 }
604 #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:1307
SIG_MASK_REQUIRE_REAL_PKT
#define SIG_MASK_REQUIRE_REAL_PKT
Definition: detect.h:306
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:586
SigTableElmt_::desc
const char * desc
Definition: detect.h:1306
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:127
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1294
MODIFIER_NOT
#define MODIFIER_NOT
Definition: detect-fragbits.c:60
DetectParseRegex
Definition: detect-parse.h:62
SigTableElmt_::name
const char * name
Definition: detect.h:1304
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1317
IPV4_GET_RAW_FLAG_DF
#define IPV4_GET_RAW_FLAG_DF(ip4h)
Definition: decode-ipv4.h:113
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1460
IPV4_GET_RAW_FLAG_MF
#define IPV4_GET_RAW_FLAG_MF(ip4h)
Definition: decode-ipv4.h:112
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
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:143
FRAGBITS_HAVE_DF
#define FRAGBITS_HAVE_DF
Definition: detect-fragbits.c:65
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1200
ctx
struct Thresholds ctx
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:841
PrefilterPacketHeaderValue::u8
uint8_t u8[16]
Definition: detect-engine-prefilter-common.h:24
DetectFragBitsData_
Definition: detect-fragbits.h:37
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:2641
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1289
MODIFIER_PLUS
#define MODIFIER_PLUS
Definition: detect-fragbits.c:61
detect-engine-prefilter.h
util-unittest.h
util-unittest-helper.h
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1292
DETECT_FRAGBITS
@ DETECT_FRAGBITS
Definition: detect-engine-register.h:43
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:533
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:1093
detect-fragbits.h
de
uint8_t de
Definition: app-layer-htp.c:554
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2767
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
pkt-var.h
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:353
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:114
SC_Pcre2SubstringGet
int SC_Pcre2SubstringGet(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR **bufferptr, PCRE2_SIZE *bufflen)
Definition: detect-parse.c:2755
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:352
util-profiling.h
Signature_::flags
uint32_t flags
Definition: detect.h:602
Packet_
Definition: decode.h:473
DetectFragBitsData_::fragbits
uint8_t fragbits
Definition: detect-fragbits.h:38
DecodeThreadVars_::app_tctx
AppLayerThreadCtx * app_tctx
Definition: decode.h:931
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:670
PrefilterSetupPacketHeader
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, SignatureMask mask, 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:404
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(void)
Creates a new app layer thread context.
Definition: app-layer.c:1059
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1272
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:322
decode-events.h
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:344
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:350
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:680
packet.h
IPV4_GET_RAW_FLAG_RF
#define IPV4_GET_RAW_FLAG_RF(ip4h)
Definition: decode-ipv4.h:114
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:232
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:929
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1291
detect-parse.h
Signature_
Signature container.
Definition: detect.h:601
SigMatch_
a single match condition for a signature
Definition: detect.h:349
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:23
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:436
detect-engine-prefilter-common.h
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
flow-var.h
MODIFIER_ANY
#define MODIFIER_ANY
Definition: detect-fragbits.c:62
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
DecodeEthernet
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ethernet.c:42
DetectFragBitsData_::modifier
uint8_t modifier
Definition: detect-fragbits.h:39
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1296
app-layer.h
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:250