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