suricata
detect-bytetest.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 Brian Rectanus <brectanu@gmail.com>
22  *
23  * Implements byte_test keyword.
24  */
25 
26 #include "suricata-common.h"
27 #include "debug.h"
28 #include "decode.h"
29 #include "detect.h"
30 #include "detect-engine.h"
31 #include "detect-parse.h"
32 
33 #include "detect-content.h"
34 #include "detect-uricontent.h"
35 #include "detect-bytetest.h"
36 #include "detect-bytejump.h"
37 #include "detect-byte-extract.h"
38 #include "app-layer.h"
39 
40 #include "util-byte.h"
41 #include "util-unittest.h"
42 #include "util-debug.h"
43 #include "detect-pcre.h"
44 
45 
46 /**
47  * \brief Regex for parsing our options
48  */
49 /** \todo We probably just need a simple tokenizer here */
50 #define PARSE_REGEX "^\\s*" \
51  "([^\\s,]+)" \
52  "\\s*,\\s*(\\!?)\\s*([^\\s,]*)" \
53  "\\s*,\\s*([^\\s,]+)" \
54  "\\s*,\\s*([^\\s,]+)" \
55  "(?:\\s*,\\s*([^\\s,]+))?" \
56  "(?:\\s*,\\s*([^\\s,]+))?" \
57  "(?:\\s*,\\s*([^\\s,]+))?" \
58  "(?:\\s*,\\s*([^\\s,]+))?" \
59  "(?:\\s*,\\s*([^\\s,]+))?" \
60  "\\s*$"
61 
62 static pcre *parse_regex;
63 static pcre_extra *parse_regex_study;
64 
65 static int DetectBytetestMatch(DetectEngineThreadCtx *det_ctx,
66  Packet *p, const Signature *s, const SigMatchCtx *ctx);
67 static int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr);
68 static void DetectBytetestFree(void *ptr);
69 static void DetectBytetestRegisterTests(void);
70 
72 {
73  sigmatch_table[DETECT_BYTETEST].name = "byte_test";
74  sigmatch_table[DETECT_BYTETEST].desc = "extract <num of bytes> and perform an operation selected with <operator> against the value in <test value> at a particular <offset>";
75  sigmatch_table[DETECT_BYTETEST].url = DOC_URL DOC_VERSION "/rules/payload-keywords.html#byte-test";
76  sigmatch_table[DETECT_BYTETEST].Match = DetectBytetestMatch;
77  sigmatch_table[DETECT_BYTETEST].Setup = DetectBytetestSetup;
78  sigmatch_table[DETECT_BYTETEST].Free = DetectBytetestFree;
79  sigmatch_table[DETECT_BYTETEST].RegisterTests = DetectBytetestRegisterTests;
80 
81  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
82 }
83 
84 /** \brief Bytetest detection code
85  *
86  * Byte test works on the packet payload.
87  *
88  * \param det_ctx thread de ctx
89  * \param s signature
90  * \param m sigmatch for this bytettest
91  * \param payload ptr to the start of the buffer to inspect
92  * \param payload_len length of the payload
93  * \retval 1 match
94  * \retval 0 no match
95  */
97  const Signature *s, const SigMatchCtx *ctx,
98  const uint8_t *payload, uint32_t payload_len,
99  uint8_t flags, int32_t offset, uint64_t value)
100 {
101  SCEnter();
102 
103  const DetectBytetestData *data = (const DetectBytetestData *)ctx;
104  const uint8_t *ptr = NULL;
105  int32_t len = 0;
106  uint64_t val = 0;
107  int extbytes;
108  int neg;
109  int match;
110 
111  if (payload_len == 0) {
112  SCReturnInt(0);
113  }
114 
115  /* Calculate the ptr value for the bytetest and length remaining in
116  * the packet from that point.
117  */
118  if (flags & DETECT_BYTETEST_RELATIVE) {
119  SCLogDebug("relative, working with det_ctx->buffer_offset %"PRIu32", "
120  "data->offset %"PRIi32"", det_ctx->buffer_offset, data->offset);
121 
122  ptr = payload + det_ctx->buffer_offset;
123  len = payload_len - det_ctx->buffer_offset;
124 
125  ptr += offset;
126  len -= offset;
127 
128  /* No match if there is no relative base */
129  if (ptr == NULL || len <= 0) {
130  SCReturnInt(0);
131  }
132  //PrintRawDataFp(stdout,ptr,len);
133  }
134  else {
135  SCLogDebug("absolute, data->offset %"PRIi32"", data->offset);
136 
137  ptr = payload + offset;
138  len = payload_len - offset;
139  }
140 
141  /* Validate that the to-be-extracted is within the packet
142  * \todo Should this validate it is in the *payload*?
143  */
144  if (ptr < payload || data->nbytes > len) {
145  SCLogDebug("Data not within payload pkt=%p, ptr=%p, len=%"PRIu32", nbytes=%d",
146  payload, ptr, len, data->nbytes);
147  SCReturnInt(0);
148  }
149 
150  neg = flags & DETECT_BYTETEST_NEGOP;
151 
152  /* Extract the byte data */
153  if (flags & DETECT_BYTETEST_STRING) {
154  extbytes = ByteExtractStringUint64(&val, data->base,
155  data->nbytes, (const char *)ptr);
156  if (extbytes <= 0) {
157  /* strtoull() return 0 if there is no numeric value in data string */
158  if (val == 0) {
159  SCLogDebug("No Numeric value");
160  SCReturnInt(0);
161  } else {
162  SCLogDebug("error extracting %d "
163  "bytes of string data: %d", data->nbytes, extbytes);
164  SCReturnInt(-1);
165  }
166  }
167 
168  SCLogDebug("comparing base %d string 0x%" PRIx64 " %s%u 0x%" PRIx64,
169  data->base, val, (neg ? "!" : ""), data->op, data->value);
170  }
171  else {
172  int endianness = (flags & DETECT_BYTETEST_LITTLE) ?
174  extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
175  if (extbytes != data->nbytes) {
176  SCLogDebug("error extracting %d bytes "
177  "of numeric data: %d", data->nbytes, extbytes);
178  SCReturnInt(-1);
179  }
180 
181  SCLogDebug("comparing numeric 0x%" PRIx64 " %s%u 0x%" PRIx64,
182  val, (neg ? "!" : ""), data->op, data->value);
183  }
184 
185  /* Compare using the configured operator */
186  match = 0;
187  switch (data->op) {
189  if (val == value) {
190  match = 1;
191  }
192  break;
194  if (val < value) {
195  match = 1;
196  }
197  break;
199  if (val > value) {
200  match = 1;
201  }
202  break;
204  if (val & value) {
205  match = 1;
206  }
207  break;
209  if (val ^ value) {
210  match = 1;
211  }
212  break;
214  if (val >= value) {
215  match = 1;
216  }
217  break;
219  if (val <= value) {
220  match = 1;
221  }
222  break;
223  default:
224  /* Should never get here as we handle this in parsing. */
225  SCReturnInt(-1);
226  }
227 
228  /* A successful match depends on negation */
229  if ((!neg && match) || (neg && !match)) {
230  SCLogDebug("MATCH");
231  SCReturnInt(1);
232  }
233 
234  SCLogDebug("NO MATCH");
235  SCReturnInt(0);
236 
237 }
238 
239 static int DetectBytetestMatch(DetectEngineThreadCtx *det_ctx,
240  Packet *p, const Signature *s, const SigMatchCtx *ctx)
241 {
242  return DetectBytetestDoMatch(det_ctx, s, ctx, p->payload, p->payload_len,
243  ((DetectBytetestData *)ctx)->flags, 0, 0);
244 }
245 
246 static DetectBytetestData *DetectBytetestParse(const char *optstr, char **value, char **offset)
247 {
248  DetectBytetestData *data = NULL;
249  char *args[9] = {
250  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
251  NULL
252  };
253 #define MAX_SUBSTRINGS 30
254  int ret = 0, res = 0;
255  int ov[MAX_SUBSTRINGS];
256  int i;
257  uint32_t nbytes;
258  const char *str_ptr = NULL;
259 
260  /* Execute the regex and populate args with captures. */
261  ret = pcre_exec(parse_regex, parse_regex_study, optstr,
262  strlen(optstr), 0, 0, ov, MAX_SUBSTRINGS);
263  if (ret < 6 || ret > 10) {
264  SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32
265  ", string %s", ret, optstr);
266  goto error;
267  }
268  for (i = 0; i < (ret - 1); i++) {
269  res = pcre_get_substring((char *)optstr, ov, MAX_SUBSTRINGS,
270  i + 1, &str_ptr);
271  if (res < 0) {
272  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed "
273  "for arg %d", i + 1);
274  goto error;
275  }
276  args[i] = (char *)str_ptr;
277  }
278 
279  /* Initialize the data */
280  data = SCMalloc(sizeof(DetectBytetestData));
281  if (unlikely(data == NULL))
282  goto error;
284  data->flags = 0;
285 
286 
287  /*
288  * The first four options are required and positional. The
289  * remaining arguments are flags and are not positional.
290  */
291 
292  /* Number of bytes */
293  if (ByteExtractStringUint32(&nbytes, 10, 0, args[0]) <= 0) {
294  SCLogError(SC_ERR_INVALID_VALUE, "Malformed number of bytes: %s", str_ptr);
295  goto error;
296  }
297 
298  /* Operator is next two args: neg + op */
299  data->op = 0;
300  if (args[1] != NULL && *args[1] == '!') {
301  data->flags |= DETECT_BYTETEST_NEGOP;
302  }
303 
304  if (args[2] != NULL) {
305  if ((strcmp("=", args[2]) == 0) || ((data->flags & DETECT_BYTETEST_NEGOP)
306  && strcmp("", args[2]) == 0)) {
307  data->op |= DETECT_BYTETEST_OP_EQ;
308  } else if (strcmp("<", args[2]) == 0) {
309  data->op |= DETECT_BYTETEST_OP_LT;
310  } else if (strcmp(">", args[2]) == 0) {
311  data->op |= DETECT_BYTETEST_OP_GT;
312  } else if (strcmp("&", args[2]) == 0) {
313  data->op |= DETECT_BYTETEST_OP_AND;
314  } else if (strcmp("^", args[2]) == 0) {
315  data->op |= DETECT_BYTETEST_OP_OR;
316  } else if (strcmp(">=", args[2]) == 0) {
317  data->op |= DETECT_BYTETEST_OP_GE;
318  } else if (strcmp("<=", args[2]) == 0) {
319  data->op |= DETECT_BYTETEST_OP_LE;
320  } else {
321  SCLogError(SC_ERR_INVALID_OPERATOR, "Invalid operator");
322  goto error;
323  }
324  }
325 
326  /* Value */
327  if (args[3][0] != '-' && isalpha((unsigned char)args[3][0])) {
328  if (value == NULL) {
329  SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with "
330  "var name for value. \"value\" argument supplied to "
331  "this function has to be non-NULL");
332  goto error;
333  }
334  *value = SCStrdup(args[3]);
335  if (*value == NULL)
336  goto error;
337  } else {
338  if (ByteExtractStringUint64(&data->value, 0, 0, args[3]) <= 0) {
339  SCLogError(SC_ERR_INVALID_VALUE, "Malformed value: %s", str_ptr);
340  goto error;
341  }
342  }
343 
344  /* Offset */
345  if (args[4][0] != '-' && isalpha((unsigned char)args[4][0])) {
346  if (offset == NULL) {
347  SCLogError(SC_ERR_INVALID_ARGUMENT, "byte_test supplied with "
348  "var name for offset. \"offset\" argument supplied to "
349  "this function has to be non-NULL");
350  goto error;
351  }
352  *offset = SCStrdup(args[4]);
353  if (*offset == NULL)
354  goto error;
355  } else {
356  if (ByteExtractStringInt32(&data->offset, 0, 0, args[4]) <= 0) {
357  SCLogError(SC_ERR_INVALID_VALUE, " Malformed offset: %s", str_ptr);
358  goto error;
359  }
360  }
361 
362  /* The remaining options are flags. */
363  /** \todo Error on dups? */
364  for (i = 5; i < (ret - 1); i++) {
365  if (args[i] != NULL) {
366  if (strcmp("relative", args[i]) == 0) {
368  } else if (strcasecmp("string", args[i]) == 0) {
369  data->flags |= DETECT_BYTETEST_STRING;
370  } else if (strcasecmp("dec", args[i]) == 0) {
372  } else if (strcasecmp("hex", args[i]) == 0) {
374  } else if (strcasecmp("oct", args[i]) == 0) {
376  } else if (strcasecmp("big", args[i]) == 0) {
377  if (data->flags & DETECT_BYTETEST_LITTLE) {
378  data->flags ^= DETECT_BYTETEST_LITTLE;
379  }
380  data->flags |= DETECT_BYTETEST_BIG;
381  } else if (strcasecmp("little", args[i]) == 0) {
382  data->flags |= DETECT_BYTETEST_LITTLE;
383  } else if (strcasecmp("dce", args[i]) == 0) {
384  data->flags |= DETECT_BYTETEST_DCE;
385  } else {
386  SCLogError(SC_ERR_UNKNOWN_VALUE, "Unknown value: \"%s\"",
387  args[i]);
388  goto error;
389  }
390  }
391  }
392 
393  if (data->flags & DETECT_BYTETEST_STRING) {
394  /* 23 - This is the largest string (octal, with a zero prefix) that
395  * will not overflow uint64_t. The only way this length
396  * could be over 23 and still not overflow is if it were zero
397  * prefixed and we only support 1 byte of zero prefix for octal.
398  *
399  * "01777777777777777777777" = 0xffffffffffffffff
400  */
401  if (nbytes > 23) {
402  SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 23 bytes with \"string\": %s",
403  optstr);
404  goto error;
405  }
406  } else {
407  if (nbytes > 8) {
408  SCLogError(SC_ERR_INVALID_VALUE, "Cannot test more than 8 bytes without \"string\": %s",
409  optstr);
410  goto error;
411  }
412  if (data->base != DETECT_BYTETEST_BASE_UNSET) {
413  SCLogError(SC_ERR_INVALID_VALUE, "Cannot use a base without \"string\": %s", optstr);
414  goto error;
415  }
416  }
417 
418  /* This is max 23 so it will fit in a byte (see above) */
419  data->nbytes = (uint8_t)nbytes;
420 
421  for (i = 0; i < (ret - 1); i++){
422  if (args[i] != NULL) SCFree(args[i]);
423  }
424  return data;
425 
426 error:
427  for (i = 0; i < (ret - 1); i++){
428  if (args[i] != NULL) SCFree(args[i]);
429  }
430  if (data != NULL) DetectBytetestFree(data);
431  return NULL;
432 }
433 
434 static int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr)
435 {
436  SigMatch *sm = NULL;
437  SigMatch *prev_pm = NULL;
438  char *value = NULL;
439  char *offset = NULL;
440  int ret = -1;
441 
442  DetectBytetestData *data = DetectBytetestParse(optstr, &value, &offset);
443  if (data == NULL)
444  goto error;
445 
446  int sm_list;
447  if (s->init_data->list != DETECT_SM_LIST_NOTSET) {
448  if (DetectBufferGetActiveList(de_ctx, s) == -1)
449  goto error;
450 
451  sm_list = s->init_data->list;
452 
453  if (data->flags & DETECT_BYTETEST_RELATIVE) {
455  }
456 
457  } else if (data->flags & DETECT_BYTETEST_DCE) {
458  if (data->flags & DETECT_BYTETEST_RELATIVE) {
459  prev_pm = DetectGetLastSMFromLists(s,
462  DETECT_ISDATAAT, -1);
463  if (prev_pm == NULL) {
464  sm_list = DETECT_SM_LIST_PMATCH;
465  } else {
466  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
467  if (sm_list < 0)
468  goto error;
469  }
470  } else {
471  sm_list = DETECT_SM_LIST_PMATCH;
472  }
473 
475  goto error;
476 
477  } else if (data->flags & DETECT_BYTETEST_RELATIVE) {
478  prev_pm = DetectGetLastSMFromLists(s,
481  DETECT_ISDATAAT, -1);
482  if (prev_pm == NULL) {
483  sm_list = DETECT_SM_LIST_PMATCH;
484  } else {
485  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
486  if (sm_list < 0)
487  goto error;
488  }
489 
490  } else {
491  sm_list = DETECT_SM_LIST_PMATCH;
492  }
493 
494  if (data->flags & DETECT_BYTETEST_DCE) {
495  if ((data->flags & DETECT_BYTETEST_STRING) ||
496  (data->flags & DETECT_BYTETEST_LITTLE) ||
497  (data->flags & DETECT_BYTETEST_BIG) ||
498  (data->base == DETECT_BYTETEST_BASE_DEC) ||
499  (data->base == DETECT_BYTETEST_BASE_HEX) ||
500  (data->base == DETECT_BYTETEST_BASE_OCT) ) {
501  SCLogError(SC_ERR_CONFLICTING_RULE_KEYWORDS, "Invalid option. "
502  "A byte_test keyword with dce holds other invalid modifiers.");
503  goto error;
504  }
505  }
506 
507  if (value != NULL) {
508  SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(value, s);
509  if (bed_sm == NULL) {
510  SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
511  "seen in byte_test - %s\n", value);
512  goto error;
513  }
514  data->value = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
516  SCFree(value);
517  value = NULL;
518  }
519 
520  if (offset != NULL) {
521  SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(offset, s);
522  if (bed_sm == NULL) {
523  SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown byte_extract var "
524  "seen in byte_test - %s\n", offset);
525  goto error;
526  }
527  data->offset = ((DetectByteExtractData *)bed_sm->ctx)->local_id;
529  SCFree(offset);
530  offset = NULL;
531  }
532 
533  sm = SigMatchAlloc();
534  if (sm == NULL)
535  goto error;
536  sm->type = DETECT_BYTETEST;
537  sm->ctx = (SigMatchCtx *)data;
538  SigMatchAppendSMToList(s, sm, sm_list);
539 
540  if (!(data->flags & DETECT_BYTETEST_RELATIVE))
541  goto okay;
542 
543  if (prev_pm == NULL)
544  goto okay;
545  if (prev_pm->type == DETECT_CONTENT) {
546  DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
548  } else if (prev_pm->type == DETECT_PCRE) {
549  DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
551  }
552 
553  okay:
554  ret = 0;
555  return ret;
556  error:
557  if (offset)
558  SCFree(offset);
559  if (value)
560  SCFree(value);
561  DetectBytetestFree(data);
562  return ret;
563 }
564 
565 /**
566  * \brief this function will free memory associated with DetectBytetestData
567  *
568  * \param data pointer to DetectBytetestData
569  */
570 static void DetectBytetestFree(void *ptr)
571 {
572  if (ptr == NULL)
573  return;
574 
575  DetectBytetestData *data = (DetectBytetestData *)ptr;
576  SCFree(data);
577 }
578 
579 
580 /* UNITTESTS */
581 #ifdef UNITTESTS
582 #include "util-unittest-helper.h"
583 static int g_file_data_buffer_id = 0;
584 static int g_dce_stub_data_buffer_id = 0;
585 
586 /**
587  * \test DetectBytetestTestParse01 is a test to make sure that we return "something"
588  * when given valid bytetest opt
589  */
590 static int DetectBytetestTestParse01(void)
591 {
592  int result = 0;
593  DetectBytetestData *data = NULL;
594  data = DetectBytetestParse("4, =, 1 , 0", NULL, NULL);
595  if (data != NULL) {
596  DetectBytetestFree(data);
597  result = 1;
598  }
599 
600  return result;
601 }
602 
603 /**
604  * \test DetectBytetestTestParse02 is a test for setting the required opts
605  */
606 static int DetectBytetestTestParse02(void)
607 {
608  int result = 0;
609  DetectBytetestData *data = NULL;
610  data = DetectBytetestParse("4, !=, 1, 0", NULL, NULL);
611  if (data != NULL) {
612  if ( (data->op == DETECT_BYTETEST_OP_EQ)
613  && (data->nbytes == 4)
614  && (data->value == 1)
615  && (data->offset == 0)
616  && (data->flags == DETECT_BYTETEST_NEGOP)
617  && (data->base == DETECT_BYTETEST_BASE_UNSET))
618  {
619  result = 1;
620  }
621  DetectBytetestFree(data);
622  }
623 
624  return result;
625 }
626 
627 /**
628  * \test DetectBytetestTestParse03 is a test for setting the relative flag
629  */
630 static int DetectBytetestTestParse03(void)
631 {
632  int result = 0;
633  DetectBytetestData *data = NULL;
634  data = DetectBytetestParse("4, !=, 1, 0, relative", NULL, NULL);
635  if (data != NULL) {
636  if ( (data->op == DETECT_BYTETEST_OP_EQ)
637  && (data->nbytes == 4)
638  && (data->value == 1)
639  && (data->offset == 0)
640  && (data->flags == ( DETECT_BYTETEST_NEGOP
642  && (data->base == DETECT_BYTETEST_BASE_UNSET))
643  {
644  result = 1;
645  }
646  DetectBytetestFree(data);
647  }
648 
649  return result;
650 }
651 
652 /**
653  * \test DetectBytetestTestParse04 is a test for setting the string/oct flags
654  */
655 static int DetectBytetestTestParse04(void)
656 {
657  int result = 0;
658  DetectBytetestData *data = NULL;
659  data = DetectBytetestParse("4, !=, 1, 0, string, oct", NULL, NULL);
660  if (data != NULL) {
661  if ( (data->op == DETECT_BYTETEST_OP_EQ)
662  && (data->nbytes == 4)
663  && (data->value == 1)
664  && (data->offset == 0)
665  && (data->flags == ( DETECT_BYTETEST_NEGOP
667  && (data->base == DETECT_BYTETEST_BASE_OCT))
668  {
669  result = 1;
670  }
671  DetectBytetestFree(data);
672  }
673 
674  return result;
675 }
676 
677 /**
678  * \test DetectBytetestTestParse05 is a test for setting the string/dec flags
679  */
680 static int DetectBytetestTestParse05(void)
681 {
682  int result = 0;
683  DetectBytetestData *data = NULL;
684  data = DetectBytetestParse("4, =, 1, 0, string, dec", NULL, NULL);
685  if (data != NULL) {
686  if ( (data->op == DETECT_BYTETEST_OP_EQ)
687  && (data->nbytes == 4)
688  && (data->value == 1)
689  && (data->offset == 0)
690  && (data->flags == DETECT_BYTETEST_STRING)
691  && (data->base == DETECT_BYTETEST_BASE_DEC))
692  {
693  result = 1;
694  }
695  DetectBytetestFree(data);
696  }
697 
698  return result;
699 }
700 
701 /**
702  * \test DetectBytetestTestParse06 is a test for setting the string/hex flags
703  */
704 static int DetectBytetestTestParse06(void)
705 {
706  int result = 0;
707  DetectBytetestData *data = NULL;
708  data = DetectBytetestParse("4, >, 1, 0, string, hex", NULL, NULL);
709  if (data != NULL) {
710  if ( (data->op == DETECT_BYTETEST_OP_GT)
711  && (data->nbytes == 4)
712  && (data->value == 1)
713  && (data->offset == 0)
714  && (data->flags == DETECT_BYTETEST_STRING)
715  && (data->base == DETECT_BYTETEST_BASE_HEX))
716  {
717  result = 1;
718  }
719  DetectBytetestFree(data);
720  }
721 
722  return result;
723 }
724 
725 /**
726  * \test DetectBytetestTestParse07 is a test for setting the big flag
727  */
728 static int DetectBytetestTestParse07(void)
729 {
730  int result = 0;
731  DetectBytetestData *data = NULL;
732  data = DetectBytetestParse("4, <, 5, 0, big", NULL, NULL);
733  if (data != NULL) {
734  if ( (data->op == DETECT_BYTETEST_OP_LT)
735  && (data->nbytes == 4)
736  && (data->value == 5)
737  && (data->offset == 0)
738  && (data->flags == 4)
739  && (data->base == DETECT_BYTETEST_BASE_UNSET))
740  {
741  result = 1;
742  }
743  DetectBytetestFree(data);
744  }
745 
746  return result;
747 }
748 
749 /**
750  * \test DetectBytetestTestParse08 is a test for setting the little flag
751  */
752 static int DetectBytetestTestParse08(void)
753 {
754  int result = 0;
755  DetectBytetestData *data = NULL;
756  data = DetectBytetestParse("4, <, 5, 0, little", NULL, NULL);
757  if (data != NULL) {
758  if ( (data->op == DETECT_BYTETEST_OP_LT)
759  && (data->nbytes == 4)
760  && (data->value == 5)
761  && (data->offset == 0)
762  && (data->flags == DETECT_BYTETEST_LITTLE)
763  && (data->base == DETECT_BYTETEST_BASE_UNSET))
764  {
765  result = 1;
766  }
767  DetectBytetestFree(data);
768  }
769 
770  return result;
771 }
772 
773 /**
774  * \test DetectBytetestTestParse09 is a test for neg operator only
775  */
776 static int DetectBytetestTestParse09(void)
777 {
778  int result = 0;
779  DetectBytetestData *data = NULL;
780  data = DetectBytetestParse("4, !, 5, 0", NULL, NULL);
781  if (data != NULL) {
782  if ( (data->op == DETECT_BYTETEST_OP_EQ)
783  && (data->nbytes == 4)
784  && (data->value == 5)
785  && (data->offset == 0)
786  && (data->flags == DETECT_BYTETEST_NEGOP)
787  && (data->base == DETECT_BYTETEST_BASE_UNSET))
788  {
789  result = 1;
790  }
791  DetectBytetestFree(data);
792  }
793 
794  return result;
795 }
796 
797 /**
798  * \test DetectBytetestTestParse10 is a test for whitespace
799  */
800 static int DetectBytetestTestParse10(void)
801 {
802  int result = 0;
803  DetectBytetestData *data = NULL;
804  data = DetectBytetestParse(" 4 , ! &, 5 , 0 , little ", NULL, NULL);
805  if (data != NULL) {
806  if ( (data->op == DETECT_BYTETEST_OP_AND)
807  && (data->nbytes == 4)
808  && (data->value == 5)
809  && (data->offset == 0)
811  && (data->base == DETECT_BYTETEST_BASE_UNSET))
812  {
813  result = 1;
814  }
815  DetectBytetestFree(data);
816  }
817 
818  return result;
819 }
820 
821 /**
822  * \test DetectBytetestTestParse11 is a test for whitespace
823  */
824 static int DetectBytetestTestParse11(void)
825 {
826  int result = 0;
827  DetectBytetestData *data = NULL;
828  data = DetectBytetestParse("4,!^,5,0,little,string,relative,hex", NULL, NULL);
829  if (data != NULL) {
830  if ( (data->op == DETECT_BYTETEST_OP_OR)
831  && (data->nbytes == 4)
832  && (data->value == 5)
833  && (data->offset == 0)
834  && (data->flags == ( DETECT_BYTETEST_NEGOP
838  && (data->base == DETECT_BYTETEST_BASE_HEX))
839  {
840  result = 1;
841  }
842  DetectBytetestFree(data);
843  }
844 
845  return result;
846 }
847 
848 /**
849  * \test DetectBytetestTestParse12 is a test for hex w/o string
850  */
851 static int DetectBytetestTestParse12(void)
852 {
853  int result = 0;
854  DetectBytetestData *data = NULL;
855  data = DetectBytetestParse("4, =, 1, 0, hex", NULL, NULL);
856  if (data == NULL) {
857  result = 1;
858  }
859 
860  return result;
861 }
862 
863 /**
864  * \test DetectBytetestTestParse13 is a test for too many bytes to extract
865  */
866 static int DetectBytetestTestParse13(void)
867 {
868  int result = 0;
869  DetectBytetestData *data = NULL;
870  data = DetectBytetestParse("9, =, 1, 0", NULL, NULL);
871  if (data == NULL) {
872  result = 1;
873  }
874 
875  return result;
876 }
877 
878 /**
879  * \test DetectBytetestTestParse14 is a test for large string extraction
880  */
881 static int DetectBytetestTestParse14(void)
882 {
883  int result = 0;
884  DetectBytetestData *data = NULL;
885  data = DetectBytetestParse("23,=,0xffffffffffffffffULL,0,string,oct", NULL, NULL);
886  if (data != NULL) {
887  if ( (data->op == DETECT_BYTETEST_OP_EQ)
888  && (data->nbytes == 23)
889  && (data->value == 0xffffffffffffffffULL)
890  && (data->offset == 0)
891  && (data->flags == DETECT_BYTETEST_STRING)
892  && (data->base == DETECT_BYTETEST_BASE_OCT))
893  {
894  result = 1;
895  }
896  DetectBytetestFree(data);
897  }
898 
899  return result;
900 }
901 
902 /**
903  * \test DetectBytetestTestParse15 is a test for too many bytes to extract (string)
904  */
905 static int DetectBytetestTestParse15(void)
906 {
907  int result = 0;
908  DetectBytetestData *data = NULL;
909  data = DetectBytetestParse("24, =, 0xffffffffffffffffULL, 0, string", NULL, NULL);
910  if (data == NULL) {
911  result = 1;
912  }
913 
914  return result;
915 }
916 
917 /**
918  * \test DetectBytetestTestParse16 is a test for offset too big
919  */
920 static int DetectBytetestTestParse16(void)
921 {
922  int result = 0;
923  DetectBytetestData *data = NULL;
924  data = DetectBytetestParse("4,=,0,0xffffffffffffffffULL", NULL, NULL);
925  if (data == NULL) {
926  result = 1;
927  }
928 
929  return result;
930 }
931 
932 /**
933  * \test Test dce option.
934  */
935 static int DetectBytetestTestParse17(void)
936 {
937  int result = 0;
938  DetectBytetestData *data = NULL;
939  data = DetectBytetestParse("4, <, 5, 0, dce", NULL, NULL);
940  if (data != NULL) {
941  if ( (data->op == DETECT_BYTETEST_OP_LT) &&
942  (data->nbytes == 4) &&
943  (data->value == 5) &&
944  (data->offset == 0) &&
945  (data->flags & DETECT_BYTETEST_DCE) ) {
946  result = 1;
947  }
948  DetectBytetestFree(data);
949  }
950 
951  return result;
952 }
953 
954 /**
955  * \test Test dce option.
956  */
957 static int DetectBytetestTestParse18(void)
958 {
959  int result = 0;
960  DetectBytetestData *data = NULL;
961  data = DetectBytetestParse("4, <, 5, 0", NULL, NULL);
962  if (data != NULL) {
963  if ( (data->op == DETECT_BYTETEST_OP_LT) &&
964  (data->nbytes == 4) &&
965  (data->value == 5) &&
966  (data->offset == 0) &&
967  !(data->flags & DETECT_BYTETEST_DCE) ) {
968  result = 1;
969  }
970  DetectBytetestFree(data);
971  }
972 
973  return result;
974 }
975 
976 /**
977  * \test Test dce option.
978  */
979 static int DetectBytetestTestParse19(void)
980 {
981  Signature *s = SigAlloc();
982  if (s == NULL)
983  return 0;
984 
985  int result = 1;
986 
988  SigFree(s);
989  return 0;
990  }
991 
992  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,dce") == 0);
993  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,string,dce") == -1);
994  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,big,dce") == -1);
995  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,little,dce") == -1);
996  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,hex,dce") == -1);
997  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,oct,dce") == -1);
998  result &= (DetectBytetestSetup(NULL, s, "1,=,1,6,dec,dce") == -1);
999 
1000  SigFree(s);
1001  return result;
1002 }
1003 
1004 /**
1005  * \test Test dce option.
1006  */
1007 static int DetectBytetestTestParse20(void)
1008 {
1009  DetectEngineCtx *de_ctx = NULL;
1010  int result = 1;
1011  Signature *s = NULL;
1012  DetectBytetestData *bd = NULL;
1013 
1014  de_ctx = DetectEngineCtxInit();
1015  if (de_ctx == NULL)
1016  goto end;
1017 
1018  de_ctx->flags |= DE_QUIET;
1019  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1020  "(msg:\"Testing bytetest_body\"; "
1021  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1022  "dce_stub_data; "
1023  "content:\"one\"; distance:0; "
1024  "byte_test:1,=,1,6,relative,dce; sid:1;)");
1025  if (de_ctx->sig_list == NULL) {
1026  result = 0;
1027  goto end;
1028  }
1029  s = de_ctx->sig_list;
1030  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1031  result = 0;
1032  goto end;
1033  }
1034  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST);
1035  bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1036  if (!(bd->flags & DETECT_BYTETEST_DCE) &&
1037  !(bd->flags & DETECT_BYTETEST_RELATIVE) &&
1038  (bd->flags & DETECT_BYTETEST_STRING) &&
1039  (bd->flags & DETECT_BYTETEST_BIG) &&
1040  (bd->flags & DETECT_BYTETEST_LITTLE) &&
1041  (bd->flags & DETECT_BYTETEST_NEGOP) ) {
1042  result = 0;
1043  goto end;
1044  }
1045 
1046  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1047  "(msg:\"Testing bytetest_body\"; "
1048  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1049  "dce_stub_data; "
1050  "content:\"one\"; distance:0; "
1051  "byte_test:1,=,1,6,relative,dce; sid:1;)");
1052  if (s->next == NULL) {
1053  result = 0;
1054  goto end;
1055  }
1056  s = s->next;
1057  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1058  result = 0;
1059  goto end;
1060  }
1061  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST);
1062  bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1063  if (!(bd->flags & DETECT_BYTETEST_DCE) &&
1064  !(bd->flags & DETECT_BYTETEST_RELATIVE) &&
1065  (bd->flags & DETECT_BYTETEST_STRING) &&
1066  (bd->flags & DETECT_BYTETEST_BIG) &&
1067  (bd->flags & DETECT_BYTETEST_LITTLE) &&
1068  (bd->flags & DETECT_BYTETEST_NEGOP) ) {
1069  result = 0;
1070  goto end;
1071  }
1072 
1073  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1074  "(msg:\"Testing bytetest_body\"; "
1075  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1076  "dce_stub_data; "
1077  "content:\"one\"; distance:0; "
1078  "byte_test:1,=,1,6,relative; sid:1;)");
1079  if (s->next == NULL) {
1080  result = 0;
1081  goto end;
1082  }
1083  s = s->next;
1084  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1085  result = 0;
1086  goto end;
1087  }
1088  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_BYTETEST);
1089  bd = (DetectBytetestData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1090  if ((bd->flags & DETECT_BYTETEST_DCE) &&
1091  !(bd->flags & DETECT_BYTETEST_RELATIVE) &&
1092  (bd->flags & DETECT_BYTETEST_STRING) &&
1093  (bd->flags & DETECT_BYTETEST_BIG) &&
1094  (bd->flags & DETECT_BYTETEST_LITTLE) &&
1095  (bd->flags & DETECT_BYTETEST_NEGOP) ) {
1096  result = 0;
1097  goto end;
1098  }
1099 
1100  end:
1101  SigGroupCleanup(de_ctx);
1102  SigCleanSignatures(de_ctx);
1103  DetectEngineCtxFree(de_ctx);
1104 
1105  return result;
1106 }
1107 
1108 /**
1109  * \test Test dce option.
1110  */
1111 static int DetectBytetestTestParse21(void)
1112 {
1113  DetectEngineCtx *de_ctx = NULL;
1114  int result = 1;
1115  Signature *s = NULL;
1116 
1117  de_ctx = DetectEngineCtxInit();
1118  if (de_ctx == NULL)
1119  goto end;
1120 
1121  de_ctx->flags |= DE_QUIET;
1122  s = SigInit(de_ctx, "alert tcp any any -> any any "
1123  "(msg:\"Testing bytetest_body\"; "
1124  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1125  "content:\"one\"; byte_test:1,=,1,6,string,dce; sid:1;)");
1126  if (s != NULL) {
1127  result = 0;
1128  goto end;
1129  }
1130 
1131  s = SigInit(de_ctx, "alert tcp any any -> any any "
1132  "(msg:\"Testing bytetest_body\"; "
1133  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1134  "content:\"one\"; byte_test:1,=,1,6,big,dce; sid:1;)");
1135  if (s != NULL) {
1136  result = 0;
1137  goto end;
1138  }
1139 
1140  s = SigInit(de_ctx, "alert tcp any any -> any any "
1141  "(msg:\"Testing bytetest_body\"; "
1142  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1143  "content:\"one\"; byte_test:1,=,1,6,little,dce; sid:1;)");
1144  if (s != NULL) {
1145  result = 0;
1146  goto end;
1147  }
1148 
1149  s = SigInit(de_ctx, "alert tcp any any -> any any "
1150  "(msg:\"Testing bytetest_body\"; "
1151  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1152  "content:\"one\"; byte_test:1,=,1,6,hex,dce; sid:1;)");
1153  if (s != NULL) {
1154  result = 0;
1155  goto end;
1156  }
1157 
1158  s = SigInit(de_ctx, "alert tcp any any -> any any "
1159  "(msg:\"Testing bytetest_body\"; "
1160  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1161  "content:\"one\"; byte_test:1,=,1,6,dec,dce; sid:1;)");
1162  if (s != NULL) {
1163  result = 0;
1164  goto end;
1165  }
1166 
1167  s = SigInit(de_ctx, "alert tcp any any -> any any "
1168  "(msg:\"Testing bytetest_body\"; "
1169  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1170  "content:\"one\"; byte_test:1,=,1,6,oct,dce; sid:1;)");
1171  if (s != NULL) {
1172  result = 0;
1173  goto end;
1174  }
1175 
1176  s = SigInit(de_ctx, "alert tcp any any -> any any "
1177  "(msg:\"Testing bytetest_body\"; "
1178  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1179  "content:\"one\"; byte_test:1,=,1,6,string,hex,dce; sid:1;)");
1180  if (s != NULL) {
1181  result = 0;
1182  goto end;
1183  }
1184 
1185  s = SigInit(de_ctx, "alert tcp any any -> any any "
1186  "(msg:\"Testing bytetest_body\"; "
1187  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1188  "content:\"one\"; byte_test:1,=,1,6,big,string,hex,dce; sid:1;)");
1189  if (s != NULL) {
1190  result = 0;
1191  goto end;
1192  }
1193 
1194  s = SigInit(de_ctx, "alert tcp any any -> any any "
1195  "(msg:\"Testing bytetest_body\"; "
1196  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1197  "content:\"one\"; byte_test:1,=,1,6,big,string,oct,dce; sid:1;)");
1198  if (s != NULL) {
1199  result = 0;
1200  goto end;
1201  }
1202 
1203  s = SigInit(de_ctx, "alert tcp any any -> any any "
1204  "(msg:\"Testing bytetest_body\"; "
1205  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1206  "content:\"one\"; byte_test:1,=,1,6,little,string,hex,dce; sid:1;)");
1207  if (s != NULL) {
1208  result = 0;
1209  goto end;
1210  }
1211 
1212  s = SigInit(de_ctx, "alert tcp any any -> any any "
1213  "(msg:\"Testing bytetest_body\"; "
1214  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1215  "content:\"one\"; byte_test:1,=,1,6,big,string,dec,dce; sid:1;)");
1216  if (s != NULL) {
1217  result = 0;
1218  goto end;
1219  }
1220 
1221  end:
1222  SigGroupCleanup(de_ctx);
1223  SigCleanSignatures(de_ctx);
1224  DetectEngineCtxFree(de_ctx);
1225 
1226  return result;
1227 }
1228 
1229 /**
1230  * \test Test file_data
1231  */
1232 static int DetectBytetestTestParse22(void)
1233 {
1234  DetectEngineCtx *de_ctx = NULL;
1235  int result = 0;
1236  Signature *s = NULL;
1237  DetectBytetestData *bd = NULL;
1238 
1239  de_ctx = DetectEngineCtxInit();
1240  if (de_ctx == NULL)
1241  goto end;
1242 
1243  de_ctx->flags |= DE_QUIET;
1244  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1245  "(file_data; byte_test:1,=,1,6,relative; sid:1;)");
1246  if (de_ctx->sig_list == NULL) {
1247  printf("sig parse failed: ");
1248  goto end;
1249  }
1250 
1251  s = de_ctx->sig_list;
1252  if (s->sm_lists_tail[g_file_data_buffer_id] == NULL) {
1253  printf("empty server body list: ");
1254  goto end;
1255  }
1256 
1257  if (s->sm_lists_tail[g_file_data_buffer_id]->type != DETECT_BYTETEST) {
1258  printf("bytetest not last sm in server body list: ");
1259  goto end;
1260  }
1261 
1262  bd = (DetectBytetestData *)s->sm_lists_tail[g_file_data_buffer_id]->ctx;
1263  if (bd->flags & DETECT_BYTETEST_DCE &&
1265  (bd->flags & DETECT_BYTETEST_STRING) &&
1266  (bd->flags & DETECT_BYTETEST_BIG) &&
1267  (bd->flags & DETECT_BYTETEST_LITTLE) &&
1268  (bd->flags & DETECT_BYTETEST_NEGOP) ) {
1269  printf("wrong flags: ");
1270  goto end;
1271  }
1272 
1273  result = 1;
1274  end:
1275  SigGroupCleanup(de_ctx);
1276  SigCleanSignatures(de_ctx);
1277  DetectEngineCtxFree(de_ctx);
1278 
1279  return result;
1280 }
1281 
1282 /**
1283  * \test DetectByteTestTestPacket01 is a test to check matches of
1284  * byte_test and byte_test relative works if the previous keyword is pcre
1285  * (bug 142)
1286  */
1287 static int DetectByteTestTestPacket01 (void)
1288 {
1289  int result = 0;
1290  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1291  "User-Agent: Wget/1.11.4"
1292  "Accept: */*"
1293  "Host: www.google.com"
1294  "Connection: Keep-Alive"
1295  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1296  uint16_t buflen = strlen((char *)buf);
1297  Packet *p;
1298  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1299 
1300  if (p == NULL)
1301  goto end;
1302 
1303  char sig[] = "alert tcp any any -> any any (msg:\"pcre + byte_test + "
1304  "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_test:1,=,1"
1305  ",6,relative,string,dec; sid:126; rev:1;)";
1306 
1307  result = UTHPacketMatchSig(p, sig);
1308 
1309  UTHFreePacket(p);
1310 end:
1311  return result;
1312 }
1313 
1314 /**
1315  * \test DetectByteTestTestPacket02 is a test to check matches of
1316  * byte_test and byte_test relative works if the previous keyword is byte_jump
1317  * (bug 158)
1318  */
1319 static int DetectByteTestTestPacket02 (void)
1320 {
1321  int result = 0;
1322  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1323  "User-Agent: Wget/1.11.4"
1324  "Accept: */*"
1325  "Host: www.google.com"
1326  "Connection: Keep-Alive"
1327  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1328  uint16_t buflen = strlen((char *)buf);
1329  Packet *p;
1330  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1331 
1332  if (p == NULL)
1333  goto end;
1334 
1335  char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test + "
1336  "relative\"; byte_jump:1,44,string,dec; byte_test:1,=,0,0,relative,string,"
1337  "dec; sid:777; rev:1;)";
1338 
1339  result = UTHPacketMatchSig(p, sig);
1340 
1341  UTHFreePacket(p);
1342 end:
1343  return result;
1344 }
1345 
1346 static int DetectByteTestTestPacket03(void)
1347 {
1348  int result = 0;
1349  uint8_t *buf = NULL;
1350  uint16_t buflen = 0;
1351  buf = SCMalloc(4);
1352  if (unlikely(buf == NULL)) {
1353  printf("malloc failed\n");
1354  exit(EXIT_FAILURE);
1355  }
1356  memcpy(buf, "boom", 4);
1357  buflen = 4;
1358 
1359  Packet *p;
1360  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1361 
1362  if (p == NULL)
1363  goto end;
1364 
1365  char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test\"; "
1366  "byte_test:1,=,65,214748364; sid:1; rev:1;)";
1367 
1368  result = !UTHPacketMatchSig(p, sig);
1369 
1370  UTHFreePacket(p);
1371 
1372 end:
1373  return result;
1374 }
1375 
1376 /** \test Test the byte_test signature matching with operator <= */
1377 static int DetectByteTestTestPacket04(void)
1378 {
1379  int result = 0;
1380  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1381  "User-Agent: Wget/1.11.4"
1382  "Accept: */*"
1383  "Host: www.google.com"
1384  "Connection: Keep-Alive"
1385  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1386  uint16_t buflen = strlen((char *)buf);
1387 
1388  Packet *p;
1389  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1390 
1391  if (p == NULL)
1392  goto end;
1393 
1394  char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test +"
1395  "relative\"; content:\"GET \"; depth:4; content:\"HTTP/1.\"; "
1396  "byte_test:1,<=,0,0,relative,string,dec; sid:124; rev:1;)";
1397 
1398  result = UTHPacketMatchSig(p, sig);
1399 
1400  UTHFreePacket(p);
1401 
1402 end:
1403  return result;
1404 }
1405 
1406 /** \test Test the byte_test signature matching with operator >= */
1407 static int DetectByteTestTestPacket05(void)
1408 {
1409  int result = 0;
1410  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1411  "User-Agent: Wget/1.11.4"
1412  "Accept: */*"
1413  "Host: www.google.com"
1414  "Connection: Keep-Alive"
1415  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1416  uint16_t buflen = strlen((char *)buf);
1417 
1418  Packet *p;
1419  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1420 
1421  if (p == NULL)
1422  goto end;
1423 
1424  char sig[] = "alert tcp any any -> any any (msg:\"content + byte_test +"
1425  "relative\"; content:\"GET \"; depth:4; content:\"HTTP/1.\"; "
1426  "byte_test:1,>=,0,0,relative,string,dec; sid:125; rev:1;)";
1427 
1428  result = UTHPacketMatchSig(p, sig);
1429 
1430  UTHFreePacket(p);
1431 
1432 end:
1433  return result;
1434 }
1435 
1436 #endif /* UNITTESTS */
1437 
1438 
1439 /**
1440  * \brief this function registers unit tests for DetectBytetest
1441  */
1442 static void DetectBytetestRegisterTests(void)
1443 {
1444 #ifdef UNITTESTS
1445  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
1446  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
1447 
1448  UtRegisterTest("DetectBytetestTestParse01", DetectBytetestTestParse01);
1449  UtRegisterTest("DetectBytetestTestParse02", DetectBytetestTestParse02);
1450  UtRegisterTest("DetectBytetestTestParse03", DetectBytetestTestParse03);
1451  UtRegisterTest("DetectBytetestTestParse04", DetectBytetestTestParse04);
1452  UtRegisterTest("DetectBytetestTestParse05", DetectBytetestTestParse05);
1453  UtRegisterTest("DetectBytetestTestParse06", DetectBytetestTestParse06);
1454  UtRegisterTest("DetectBytetestTestParse07", DetectBytetestTestParse07);
1455  UtRegisterTest("DetectBytetestTestParse08", DetectBytetestTestParse08);
1456  UtRegisterTest("DetectBytetestTestParse09", DetectBytetestTestParse09);
1457  UtRegisterTest("DetectBytetestTestParse10", DetectBytetestTestParse10);
1458  UtRegisterTest("DetectBytetestTestParse11", DetectBytetestTestParse11);
1459  UtRegisterTest("DetectBytetestTestParse12", DetectBytetestTestParse12);
1460  UtRegisterTest("DetectBytetestTestParse13", DetectBytetestTestParse13);
1461  UtRegisterTest("DetectBytetestTestParse14", DetectBytetestTestParse14);
1462  UtRegisterTest("DetectBytetestTestParse15", DetectBytetestTestParse15);
1463  UtRegisterTest("DetectBytetestTestParse16", DetectBytetestTestParse16);
1464  UtRegisterTest("DetectBytetestTestParse17", DetectBytetestTestParse17);
1465  UtRegisterTest("DetectBytetestTestParse18", DetectBytetestTestParse18);
1466  UtRegisterTest("DetectBytetestTestParse19", DetectBytetestTestParse19);
1467  UtRegisterTest("DetectBytetestTestParse20", DetectBytetestTestParse20);
1468  UtRegisterTest("DetectBytetestTestParse21", DetectBytetestTestParse21);
1469  UtRegisterTest("DetectBytetestTestParse22", DetectBytetestTestParse22);
1470 
1471  UtRegisterTest("DetectByteTestTestPacket01", DetectByteTestTestPacket01);
1472  UtRegisterTest("DetectByteTestTestPacket02", DetectByteTestTestPacket02);
1473  UtRegisterTest("DetectByteTestTestPacket03", DetectByteTestTestPacket03);
1474  UtRegisterTest("DetectByteTestTestPacket04", DetectByteTestTestPacket04);
1475  UtRegisterTest("DetectByteTestTestPacket05", DetectByteTestTestPacket05);
1476 #endif /* UNITTESTS */
1477 }
1478 
#define MAX_SUBSTRINGS
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
SignatureInitData * init_data
Definition: detect.h:591
uint16_t flags
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
#define SCLogDebug(...)
Definition: util-debug.h:335
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
#define DETECT_BYTETEST_LITTLE
#define DETECT_BYTETEST_BASE_DEC
void DetectBytetestRegister(void)
int ByteExtractStringInt32(int32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:360
#define DETECT_BYTETEST_BASE_UNSET
#define DETECT_BYTETEST_OP_LT
#define unlikely(expr)
Definition: util-optimize.h:35
#define DETECT_BYTETEST_OP_EQ
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Signature * sig_list
Definition: detect.h:767
uint64_t offset
#define PARSE_REGEX
Regex for parsing our options.
void SigCleanSignatures(DetectEngineCtx *de_ctx)
#define DETECT_BYTETEST_BASE_OCT
int ByteExtractStringUint32(uint32_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:244
uint32_t buffer_offset
Definition: detect.h:1032
#define DETECT_BYTETEST_BIG
const char * name
Definition: detect.h:1200
Signature container.
Definition: detect.h:522
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:313
int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint8_t flags, int32_t offset, uint64_t value)
Bytetest detection code.
uint16_t flags
Definition: detect-pcre.h:42
main detection engine ctx
Definition: detect.h:761
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
int ByteExtractStringUint64(uint64_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:239
#define DE_QUIET
Definition: detect.h:292
#define DETECT_BYTETEST_BASE_HEX
int DetectBufferTypeGetByName(const char *name)
#define DETECT_BYTETEST_STRING
uint8_t flags
Definition: detect.h:762
#define DETECT_BYTETEST_OP_OR
void(* Free)(void *)
Definition: detect.h:1191
int UTHPacketMatchSig(Packet *p, const char *sig)
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void SigFree(Signature *)
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
#define DETECT_BYTETEST_OP_GE
#define SCEnter(...)
Definition: util-debug.h:337
#define DETECT_BYTETEST_VALUE_BE
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:115
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1170
#define BYTE_BIG_ENDIAN
Definition: util-byte.h:29
int SigGroupCleanup(DetectEngineCtx *de_ctx)
struct Signature_ * next
Definition: detect.h:594
uint8_t type
Definition: detect.h:319
#define SCReturnInt(x)
Definition: util-debug.h:341
#define DETECT_BYTETEST_OP_AND
#define BYTE_LITTLE_ENDIAN
Definition: util-byte.h:30
const char * desc
Definition: detect.h:1202
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:346
Signature * SigAlloc(void)
#define DETECT_BYTETEST_NEGOP
SigMatch * DetectByteExtractRetrieveSMVar(const char *arg, const Signature *s)
Lookup the SigMatch for a named byte_extract variable.
SigMatchCtx * ctx
Definition: detect.h:321
#define SCMalloc(a)
Definition: util-mem.h:222
uint16_t payload_len
#define SCFree(a)
Definition: util-mem.h:322
PoolThreadReserved res
#define DETECT_BYTETEST_RELATIVE
#define DETECT_BYTETEST_OP_GT
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us. ...
Definition: detect-parse.c:465
int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:122
const char * url
Definition: detect.h:1203
#define DETECT_BYTETEST_DCE
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself...
#define DETECT_BYTETEST_OFFSET_BE
#define SCStrdup(a)
Definition: util-mem.h:268
#define DOC_URL
Definition: suricata.h:86
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:32
#define DETECT_CONTENT_RELATIVE_NEXT
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
uint8_t len
Holds data related to byte_extract keyword.
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
Definition: detect-parse.c:619
uint16_t payload_len
Definition: decode.h:542
#define DOC_VERSION
Definition: suricata.h:91
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
uint8_t * payload
Definition: decode.h:541
void(* RegisterTests)(void)
Definition: detect.h:1192
a single match condition for a signature
Definition: detect.h:318
#define DETECT_BYTETEST_OP_LE
DetectEngineCtx * DetectEngineCtxInit(void)