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