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