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