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(void *);
74 
75 static int PrefilterSetupFragBits(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
76 static bool PrefilterFragBitsIsPrefilterable(const Signature *s);
77 
78 /**
79  * \brief Registration function for fragbits: keyword
80  */
81 
83 {
84  sigmatch_table[DETECT_FRAGBITS].name = "fragbits";
85  sigmatch_table[DETECT_FRAGBITS].desc = "check if the fragmentation and reserved bits are set in the IP header";
86  sigmatch_table[DETECT_FRAGBITS].url = DOC_URL DOC_VERSION "/rules/header-keywords.html#fragbits-ip-fragmentation";
87  sigmatch_table[DETECT_FRAGBITS].Match = DetectFragBitsMatch;
88  sigmatch_table[DETECT_FRAGBITS].Setup = DetectFragBitsSetup;
89  sigmatch_table[DETECT_FRAGBITS].Free = DetectFragBitsFree;
91 
92  sigmatch_table[DETECT_FRAGBITS].SetupPrefilter = PrefilterSetupFragBits;
93  sigmatch_table[DETECT_FRAGBITS].SupportsPrefilter = PrefilterFragBitsIsPrefilterable;
94 
95  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
96 }
97 
98 static inline int
99 FragBitsMatch(const uint8_t pbits, const uint8_t modifier,
100  const uint8_t dbits)
101 {
102  switch (modifier) {
103  case MODIFIER_ANY:
104  if ((pbits & dbits) > 0)
105  return 1;
106  return 0;
107 
108  case MODIFIER_PLUS:
109  if (((pbits & dbits) == dbits) && (((pbits - dbits) > 0)))
110  return 1;
111  return 0;
112 
113  case MODIFIER_NOT:
114  if ((pbits & dbits) != dbits)
115  return 1;
116  return 0;
117 
118  default:
119  if (pbits == dbits)
120  return 1;
121  }
122  return 0;
123 }
124 
125 /**
126  * \internal
127  * \brief This function is used to match fragbits on a packet with those passed via fragbits:
128  *
129  * \param t pointer to thread vars
130  * \param det_ctx pointer to the pattern matcher thread
131  * \param p pointer to the current packet
132  * \param s pointer to the Signature
133  * \param m pointer to the sigmatch
134  *
135  * \retval 0 no match
136  * \retval 1 match
137  */
138 static int DetectFragBitsMatch (DetectEngineThreadCtx *det_ctx,
139  Packet *p, const Signature *s, const SigMatchCtx *ctx)
140 {
141  if (!ctx || !PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p))
142  return 0;
143 
144  uint8_t fragbits = 0;
145  const DetectFragBitsData *de = (const DetectFragBitsData *)ctx;
146  if(IPV4_GET_MF(p))
147  fragbits |= FRAGBITS_HAVE_MF;
148  if(IPV4_GET_DF(p))
149  fragbits |= FRAGBITS_HAVE_DF;
150  if(IPV4_GET_RF(p))
151  fragbits |= FRAGBITS_HAVE_RF;
152 
153  return FragBitsMatch(fragbits, de->modifier, de->fragbits);
154 }
155 
156 /**
157  * \internal
158  * \brief This function is used to parse fragbits options passed via fragbits: keyword
159  *
160  * \param rawstr Pointer to the user provided fragbits options
161  *
162  * \retval de pointer to DetectFragBitsData on success
163  * \retval NULL on failure
164  */
165 static DetectFragBitsData *DetectFragBitsParse (const char *rawstr)
166 {
167  DetectFragBitsData *de = NULL;
168  int ret = 0, found = 0, res = 0;
169  int ov[MAX_SUBSTRINGS];
170  const char *str_ptr = NULL;
171  char *args[2] = { NULL, NULL};
172  char *ptr;
173  int i;
174 
175  ret = DetectParsePcreExec(&parse_regex, rawstr, 0, 0, ov, MAX_SUBSTRINGS);
176  if (ret < 1) {
177  SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, rawstr);
178  goto error;
179  }
180 
181  for (i = 0; i < (ret - 1); i++) {
182  res = pcre_get_substring((char *)rawstr, ov, MAX_SUBSTRINGS, i + 1, &str_ptr);
183  if (res < 0) {
184  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
185  goto error;
186  }
187 
188  args[i] = (char *)str_ptr;
189  }
190 
191  if (args[1] == NULL) {
192  SCLogError(SC_ERR_INVALID_VALUE, "invalid value");
193  goto error;
194  }
195 
196  de = SCMalloc(sizeof(DetectFragBitsData));
197  if (unlikely(de == NULL))
198  goto error;
199 
200  memset(de,0,sizeof(DetectFragBitsData));
201 
202  /** First parse args[0] */
203 
204  if (args[0] && strlen(args[0])) {
205  ptr = args[0];
206  switch (*ptr) {
207  case '!':
208  de->modifier = MODIFIER_NOT;
209  break;
210  case '+':
211  de->modifier = MODIFIER_PLUS;
212  break;
213  case '*':
214  de->modifier = MODIFIER_ANY;
215  break;
216  }
217  }
218 
219  /** Second parse first set of fragbits */
220 
221  ptr = args[1];
222 
223  while (*ptr != '\0') {
224  switch (*ptr) {
225  case 'M':
226  case 'm':
227  de->fragbits |= FRAGBITS_HAVE_MF;
228  found++;
229  break;
230  case 'D':
231  case 'd':
232  de->fragbits |= FRAGBITS_HAVE_DF;
233  found++;
234  break;
235  case 'R':
236  case 'r':
237  de->fragbits |= FRAGBITS_HAVE_RF;
238  found++;
239  break;
240  default:
241  found = 0;
242  break;
243  }
244  ptr++;
245  }
246 
247  if(found == 0)
248  goto error;
249 
250  for (i = 0; i < 2; i++) {
251  if (args[i] != NULL)
252  SCFree(args[i]);
253  }
254  return de;
255 
256 error:
257  for (i = 0; i < 2; i++) {
258  if (args[i] != NULL)
259  SCFree(args[i]);
260  }
261  if (de != NULL)
262  SCFree(de);
263  return NULL;
264 }
265 
266 /**
267  * \internal
268  * \brief this function is used to add the parsed fragbits into the current signature
269  *
270  * \param de_ctx pointer to the Detection Engine Context
271  * \param s pointer to the Current Signature
272  * \param m pointer to the Current SigMatch
273  * \param rawstr pointer to the user provided fragbits options
274  *
275  * \retval 0 on Success
276  * \retval -1 on Failure
277  */
278 static int DetectFragBitsSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
279 {
280  DetectFragBitsData *de = NULL;
281  SigMatch *sm = NULL;
282 
283  de = DetectFragBitsParse(rawstr);
284  if (de == NULL)
285  return -1;
286 
287  sm = SigMatchAlloc();
288  if (sm == NULL)
289  goto error;
290 
291  sm->type = DETECT_FRAGBITS;
292  sm->ctx = (SigMatchCtx *)de;
293 
296 
297  return 0;
298 
299 error:
300  if (de)
301  SCFree(de);
302  return -1;
303 }
304 
305 /**
306  * \internal
307  * \brief this function will free memory associated with DetectFragBitsData
308  *
309  * \param de pointer to DetectFragBitsData
310  */
311 static void DetectFragBitsFree(void *de_ptr)
312 {
314  if(de) SCFree(de);
315 }
316 
317 static void
318 PrefilterPacketFragBitsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
319 {
320  const PrefilterPacketHeaderCtx *ctx = pectx;
321 
322  if (!PKT_IS_IPV4(p) || PKT_IS_PSEUDOPKT(p))
323  return;
324 
325  uint8_t fragbits = 0;
326  if (IPV4_GET_MF(p))
327  fragbits |= FRAGBITS_HAVE_MF;
328  if (IPV4_GET_DF(p))
329  fragbits |= FRAGBITS_HAVE_DF;
330  if (IPV4_GET_RF(p))
331  fragbits |= FRAGBITS_HAVE_RF;
332 
333  if (FragBitsMatch(fragbits, ctx->v1.u8[0], ctx->v1.u8[1]))
334  {
335  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
336  }
337 }
338 
339 static void
340 PrefilterPacketFragBitsSet(PrefilterPacketHeaderValue *v, void *smctx)
341 {
342  const DetectFragBitsData *fb = smctx;
343  v->u8[0] = fb->modifier;
344  v->u8[1] = fb->fragbits;
345 }
346 
347 static bool
348 PrefilterPacketFragBitsCompare(PrefilterPacketHeaderValue v, void *smctx)
349 {
350  const DetectFragBitsData *fb = smctx;
351  if (v.u8[0] == fb->modifier &&
352  v.u8[1] == fb->fragbits)
353  {
354  return TRUE;
355  }
356  return FALSE;
357 }
358 
359 static int PrefilterSetupFragBits(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
360 {
362  PrefilterPacketFragBitsSet,
363  PrefilterPacketFragBitsCompare,
364  PrefilterPacketFragBitsMatch);
365 }
366 
367 static bool PrefilterFragBitsIsPrefilterable(const Signature *s)
368 {
369  const SigMatch *sm;
370  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
371  switch (sm->type) {
372  case DETECT_FRAGBITS:
373  return TRUE;
374  }
375  }
376  return FALSE;
377 }
378 
379 /*
380  * ONLY TESTS BELOW THIS COMMENT
381  */
382 
383 #ifdef UNITTESTS
384 /**
385  * \test FragBitsTestParse01 is a test for a valid fragbits value
386  *
387  * \retval 1 on succces
388  * \retval 0 on failure
389  */
390 static int FragBitsTestParse01 (void)
391 {
392  DetectFragBitsData *de = NULL;
393  de = DetectFragBitsParse("M");
394  if (de && (de->fragbits == FRAGBITS_HAVE_MF) ) {
395  DetectFragBitsFree(de);
396  return 1;
397  }
398 
399  return 0;
400 }
401 
402 /**
403  * \test FragBitsTestParse02 is a test for an invalid fragbits value
404  *
405  * \retval 1 on succces
406  * \retval 0 on failure
407  */
408 static int FragBitsTestParse02 (void)
409 {
410  DetectFragBitsData *de = NULL;
411  de = DetectFragBitsParse("G");
412  if (de) {
413  DetectFragBitsFree(de);
414  return 0;
415  }
416 
417  return 1;
418 }
419 
420 /**
421  * \test FragBitsTestParse03 test if DONT FRAG is set. Must return success
422  *
423  * \retval 1 on success
424  * \retval 0 on failure
425  */
426 static int FragBitsTestParse03 (void)
427 {
428  uint8_t raw_eth[] = {
429  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
430  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
431  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
432  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
433  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
434  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
435  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
436  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
437  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
438  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
439  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
440  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
441  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
442  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
443  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
444  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
445  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
446  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
447  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
448  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
449  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
450  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
451  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
452  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
453  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
454  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
455  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
456  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
457  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
458  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
459  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
460  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
461  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
462  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
463  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
464  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
465  0x51};
467  FAIL_IF(unlikely(p == NULL));
468  ThreadVars tv;
470  IPV4Hdr ipv4h;
471  int ret = 0;
472  DetectFragBitsData *de = NULL;
473  SigMatch *sm = NULL;
474 
475  memset(&tv, 0, sizeof(ThreadVars));
476  memset(p, 0, SIZE_OF_PACKET);
477  memset(&dtv, 0, sizeof(DecodeThreadVars));
478  memset(&ipv4h, 0, sizeof(IPV4Hdr));
480 
481  p->ip4h = &ipv4h;
482 
484 
485  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
486 
487  de = DetectFragBitsParse("D");
488 
489  FAIL_IF(de == NULL || (de->fragbits != FRAGBITS_HAVE_DF));
490 
491  sm = SigMatchAlloc();
492  FAIL_IF(sm == NULL);
493 
494  sm->type = DETECT_FRAGBITS;
495  sm->ctx = (SigMatchCtx *)de;
496 
497  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
498  FAIL_IF(ret == 0);
499 
500  FlowShutdown();
501  SCFree(de);
502  SCFree(sm);
503  SCFree(p);
504  PASS;
505 }
506 
507 /**
508  * \test FragBitsTestParse04 test if DONT FRAG is not set. Must fails.
509  *
510  * \retval 1 on success
511  * \retval 0 on failure
512  */
513 static int FragBitsTestParse04 (void)
514 {
515  uint8_t raw_eth[] = {
516  0x00 ,0x40 ,0x33 ,0xd9 ,0x7c ,0xfd ,0x00 ,0x00,
517  0x39 ,0xcf ,0xd9 ,0xcd ,0x08 ,0x00 ,0x45 ,0x00,
518  0x01 ,0x13 ,0x9c ,0x5d ,0x40 ,0x00 ,0xf6 ,0x11,
519  0x44 ,0xca ,0x97 ,0xa4 ,0x01 ,0x08 ,0x0a ,0x00,
520  0x00 ,0x06 ,0x00 ,0x35 ,0x04 ,0x0b ,0x00 ,0xff,
521  0x3c ,0x87 ,0x7d ,0x9e ,0x85 ,0x80 ,0x00 ,0x01,
522  0x00 ,0x01 ,0x00 ,0x05 ,0x00 ,0x05 ,0x06 ,0x70,
523  0x69 ,0x63 ,0x61 ,0x72 ,0x64 ,0x07 ,0x75 ,0x74,
524  0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65 ,0x64,
525  0x75 ,0x00 ,0x00 ,0x01 ,0x00 ,0x01 ,0xc0 ,0x0c,
526  0x00 ,0x01 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
527  0x00 ,0x04 ,0x81 ,0x6f ,0x1e ,0x1b ,0x07 ,0x75,
528  0x74 ,0x68 ,0x73 ,0x63 ,0x73 ,0x61 ,0x03 ,0x65,
529  0x64 ,0x75 ,0x00 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
530  0x00 ,0x0e ,0x10 ,0x00 ,0x09 ,0x06 ,0x6b ,0x65,
531  0x6e ,0x6f ,0x62 ,0x69 ,0xc0 ,0x34 ,0xc0 ,0x34,
532  0x00 ,0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10,
533  0x00 ,0x07 ,0x04 ,0x6a ,0x69 ,0x6e ,0x6e ,0xc0,
534  0x34 ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
535  0x00 ,0x0e ,0x10 ,0x00 ,0x0c ,0x04 ,0x64 ,0x6e,
536  0x73 ,0x31 ,0x04 ,0x6e ,0x6a ,0x69 ,0x74 ,0xc0,
537  0x3c ,0xc0 ,0x34 ,0x00 ,0x02 ,0x00 ,0x01 ,0x00,
538  0x00 ,0x0e ,0x10 ,0x00 ,0x08 ,0x05 ,0x65 ,0x6c,
539  0x7a ,0x69 ,0x70 ,0xc0 ,0x34 ,0xc0 ,0x34 ,0x00,
540  0x02 ,0x00 ,0x01 ,0x00 ,0x00 ,0x0e ,0x10 ,0x00,
541  0x08 ,0x05 ,0x61 ,0x72 ,0x77 ,0x65 ,0x6e ,0xc0,
542  0x34 ,0xc0 ,0x4b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
543  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
544  0x06 ,0xc0 ,0x60 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
545  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x1a,
546  0x07 ,0xc0 ,0x73 ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
547  0x01 ,0x03 ,0x82 ,0x00 ,0x04 ,0x80 ,0xeb ,0xfb,
548  0x0a ,0xc0 ,0x8b ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
549  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x01,
550  0x0b ,0xc0 ,0x9f ,0x00 ,0x01 ,0x00 ,0x01 ,0x00,
551  0x00 ,0x0e ,0x10 ,0x00 ,0x04 ,0x81 ,0x6f ,0x0b,
552  0x51};
554  FAIL_IF(unlikely(p == NULL));
555  ThreadVars tv;
557  IPV4Hdr ipv4h;
558  int ret = 0;
559  DetectFragBitsData *de = NULL;
560  SigMatch *sm = NULL;
561 
562  memset(&tv, 0, sizeof(ThreadVars));
563  memset(p, 0, SIZE_OF_PACKET);
564  memset(&dtv, 0, sizeof(DecodeThreadVars));
565  memset(&ipv4h, 0, sizeof(IPV4Hdr));
567 
568  p->ip4h = &ipv4h;
569 
571 
572  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
573 
574 
575  de = DetectFragBitsParse("!D");
576 
577  FAIL_IF(de == NULL);
578  FAIL_IF(de->fragbits != FRAGBITS_HAVE_DF);
579  FAIL_IF(de->modifier != MODIFIER_NOT);
580 
581  sm = SigMatchAlloc();
582  FAIL_IF(sm == NULL);
583 
584  sm->type = DETECT_FRAGBITS;
585  sm->ctx = (SigMatchCtx *)de;
586 
587  ret = DetectFragBitsMatch(NULL, p, NULL, sm->ctx);
588  FAIL_IF(ret);
589  SCFree(de);
590  SCFree(sm);
591  PACKET_RECYCLE(p);
592  FlowShutdown();
593  SCFree(p);
594  PASS;
595 }
596 #endif /* UNITTESTS */
597 
598 /**
599  * \brief this function registers unit tests for FragBits
600  */
602 {
603 #ifdef UNITTESTS
604  UtRegisterTest("FragBitsTestParse01", FragBitsTestParse01);
605  UtRegisterTest("FragBitsTestParse02", FragBitsTestParse02);
606  UtRegisterTest("FragBitsTestParse03", FragBitsTestParse03);
607  UtRegisterTest("FragBitsTestParse04", FragBitsTestParse04);
608 #endif /* UNITTESTS */
609 }
DetectFragBitsRegister
void DetectFragBitsRegister(void)
Registration function for fragbits: keyword.
Definition: detect-fragbits.c:82
host.h
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-fragbits.c:53
SigTableElmt_::url
const char * url
Definition: detect.h:1204
SigTableElmt_::desc
const char * desc
Definition: detect.h:1203
SC_ERR_INVALID_VALUE
@ SC_ERR_INVALID_VALUE
Definition: util-error.h:160
MODIFIER_NOT
#define MODIFIER_NOT
Definition: detect-fragbits.c:60
SigTableElmt_::name
const char * name
Definition: detect.h:1201
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1115
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1337
MAX_SUBSTRINGS
#define MAX_SUBSTRINGS
SCFree
#define SCFree(a)
Definition: util-mem.h:322
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
IPV4_GET_DF
#define IPV4_GET_DF(p)
Definition: decode-ipv4.h:141
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
FRAGBITS_HAVE_RF
#define FRAGBITS_HAVE_RF
Definition: detect-fragbits.c:66
FRAGBITS_HAVE_DF
#define FRAGBITS_HAVE_DF
Definition: detect-fragbits.c:65
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1103
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:761
FlowInitConfig
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:529
PrefilterPacketHeaderCtx_::sigs_array
SigIntId * sigs_array
Definition: detect-engine-prefilter-common.h:41
PrefilterPacketHeaderValue::u8
uint8_t u8[16]
Definition: detect-engine-prefilter-common.h:22
DetectFragBitsData_
Definition: detect-fragbits.h:41
SigTableElmt_::Free
void(* Free)(void *)
Definition: detect.h:1192
PrefilterPacketHeaderCtx_::sigs_cnt
uint32_t sigs_cnt
Definition: detect-engine-prefilter-common.h:40
SC_ERR_PCRE_GET_SUBSTRING
@ SC_ERR_PCRE_GET_SUBSTRING
Definition: util-error.h:34
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1187
MODIFIER_PLUS
#define MODIFIER_PLUS
Definition: detect-fragbits.c:61
detect-engine-prefilter.h
util-unittest.h
IPV4_GET_RF
#define IPV4_GET_RF(p)
Definition: decode-ipv4.h:138
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1190
DETECT_FRAGBITS
@ DETECT_FRAGBITS
Definition: detect-engine-register.h:41
app-layer-detect-proto.h
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:33
decode.h
util-debug.h
SC_ERR_PCRE_MATCH
@ SC_ERR_PCRE_MATCH
Definition: util-error.h:32
FRAGBITS_HAVE_MF
#define FRAGBITS_HAVE_MF
Definition: detect-fragbits.c:64
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:16
DetectEngineThreadCtx_
Definition: detect.h:1004
detect-fragbits.h
res
PoolThreadReserved res
Definition: stream-tcp-private.h:60
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2440
AppLayerGetCtxThread
AppLayerThreadCtx * AppLayerGetCtxThread(ThreadVars *tv)
Creates a new app layer thread context.
Definition: app-layer.c:825
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
de
int de
Definition: app-layer-htp.c:565
pkt-var.h
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:322
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:89
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:619
TRUE
#define TRUE
Definition: suricata-common.h:33
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:321
SCMalloc
#define SCMalloc(a)
Definition: util-mem.h:222
util-profiling.h
FALSE
#define FALSE
Definition: suricata-common.h:34
FragBitsRegisterTests
void FragBitsRegisterTests(void)
this function registers unit tests for FragBits
Definition: detect-fragbits.c:601
Signature_::flags
uint32_t flags
Definition: detect.h:523
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options, int *ovector, int ovector_size)
Definition: detect-parse.c:2372
Packet_
Definition: decode.h:408
DetectFragBitsData_::fragbits
uint8_t fragbits
Definition: detect-fragbits.h:42
DecodeThreadVars_::app_tctx
AppLayerThreadCtx * app_tctx
Definition: decode.h:625
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:501
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:591
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1171
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:516
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
decode-events.h
SigMatch_::type
uint8_t type
Definition: detect.h:319
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
PrefilterPacketHeaderCtx_::v1
PrefilterPacketHeaderValue v1
Definition: detect-engine-prefilter-common.h:34
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:313
IPV4Hdr_
Definition: decode-ipv4.h:70
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:684
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
DetectParseRegex_
Definition: detect-parse.h:42
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
DOC_URL
#define DOC_URL
Definition: suricata.h:86
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:407
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:622
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1189
IPV4_GET_MF
#define IPV4_GET_MF(p)
Definition: decode-ipv4.h:144
detect-parse.h
Signature_
Signature container.
Definition: detect.h:522
SigMatch_
a single match condition for a signature
Definition: detect.h:318
suricata.h
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:38
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:21
detect-engine-prefilter-common.h
flow-var.h
PKT_IS_IPV4
#define PKT_IS_IPV4(p)
Definition: decode.h:252
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:41
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
DOC_VERSION
#define DOC_VERSION
Definition: suricata.h:91
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:804
DetectFragBitsData_::modifier
uint8_t modifier
Definition: detect-fragbits.h:43
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1193
app-layer.h
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:223