suricata
detect-engine-content-inspection.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2017 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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Performs content inspection on any buffer supplied.
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 
29 #include "decode.h"
30 
31 #include "detect.h"
32 #include "detect-engine.h"
33 #include "detect-parse.h"
34 #include "detect-content.h"
35 #include "detect-pcre.h"
36 #include "detect-isdataat.h"
37 #include "detect-bytetest.h"
38 #include "detect-bytejump.h"
39 #include "detect-byte-extract.h"
40 #include "detect-replace.h"
42 #include "detect-uricontent.h"
43 #include "detect-urilen.h"
44 #include "detect-bsize.h"
45 #include "detect-lua.h"
46 #include "detect-base64-decode.h"
47 #include "detect-base64-data.h"
48 #include "detect-dataset.h"
49 #include "detect-datarep.h"
50 
51 #include "app-layer-dcerpc.h"
52 
53 #include "util-spm.h"
54 #include "util-debug.h"
55 #include "util-print.h"
56 
57 #include "util-unittest.h"
58 #include "util-unittest-helper.h"
59 #include "util-profiling.h"
60 
61 #ifdef HAVE_LUA
62 #include "util-lua.h"
63 #endif
64 
65 /**
66  * \brief Run the actual payload match functions
67  *
68  * The following keywords are inspected:
69  * - content, including all the http and dce modified contents
70  * - isdaatat
71  * - pcre
72  * - bytejump
73  * - bytetest
74  * - byte_extract
75  * - urilen
76  * -
77  *
78  * All keywords are evaluated against the buffer with buffer_len.
79  *
80  * For accounting the last match in relative matching the
81  * det_ctx->buffer_offset int is used.
82  *
83  * \param de_ctx Detection engine context
84  * \param det_ctx Detection engine thread context
85  * \param s Signature to inspect
86  * \param sm SigMatch to inspect
87  * \param p Packet. Can be NULL.
88  * \param f Flow (for pcre flowvar storage)
89  * \param buffer Ptr to the buffer to inspect
90  * \param buffer_len Length of the payload
91  * \param stream_start_offset Indicates the start of the current buffer in
92  * the whole buffer stream inspected. This
93  * applies if the current buffer is inspected
94  * in chunks.
95  * \param inspection_mode Refers to the engine inspection mode we are currently
96  * inspecting. Can be payload, stream, one of the http
97  * buffer inspection modes or dce inspection mode.
98  * \param flags DETECT_CI_FLAG_*
99  *
100  * \retval 0 no match
101  * \retval 1 match
102  */
104  const Signature *s, const SigMatchData *smd,
105  Packet *p, Flow *f,
106  const uint8_t *buffer, uint32_t buffer_len,
107  uint32_t stream_start_offset, uint8_t flags,
108  uint8_t inspection_mode)
109 {
110  SCEnter();
112 
113  det_ctx->inspection_recursion_counter++;
114 
116  det_ctx->discontinue_matching = 1;
117  KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
118  SCReturnInt(0);
119  }
120 
121  if (smd == NULL || buffer_len == 0) {
122  KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
123  SCReturnInt(0);
124  }
125 
126  /* \todo unify this which is phase 2 of payload inspection unification */
127  if (smd->type == DETECT_CONTENT) {
128 
130  SCLogDebug("inspecting content %"PRIu32" buffer_len %"PRIu32, cd->id, buffer_len);
131 
132  /* we might have already have this content matched by the mpm.
133  * (if there is any other reason why we'd want to avoid checking
134  * it here, please fill it in) */
135  //if (cd->flags & DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED) {
136  // goto match;
137  //}
138 
139  /* rule parsers should take care of this */
140 #ifdef DEBUG
141  BUG_ON(cd->depth != 0 && cd->depth <= cd->offset);
142 #endif
143 
144  /* search for our pattern, checking the matches recursively.
145  * if we match we look for the next SigMatch as well */
146  const uint8_t *found = NULL;
147  uint32_t offset = 0;
148  uint32_t depth = buffer_len;
149  uint32_t prev_offset = 0; /**< used in recursive searching */
150  uint32_t prev_buffer_offset = det_ctx->buffer_offset;
151 
152  do {
153  if ((cd->flags & DETECT_CONTENT_DISTANCE) ||
154  (cd->flags & DETECT_CONTENT_WITHIN)) {
155  SCLogDebug("det_ctx->buffer_offset %"PRIu32, det_ctx->buffer_offset);
156 
157  offset = prev_buffer_offset;
158  depth = buffer_len;
159 
160  int distance = cd->distance;
161  if (cd->flags & DETECT_CONTENT_DISTANCE) {
162  if (cd->flags & DETECT_CONTENT_DISTANCE_BE) {
163  distance = det_ctx->bj_values[cd->distance];
164  }
165  if (distance < 0 && (uint32_t)(abs(distance)) > offset)
166  offset = 0;
167  else
168  offset += distance;
169 
170  SCLogDebug("cd->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32,
171  distance, offset, depth);
172  }
173 
174  if (cd->flags & DETECT_CONTENT_WITHIN) {
175  if (cd->flags & DETECT_CONTENT_WITHIN_BE) {
176  if ((int32_t)depth > (int32_t)(prev_buffer_offset + det_ctx->bj_values[cd->within] + distance)) {
177  depth = prev_buffer_offset + det_ctx->bj_values[cd->within] + distance;
178  }
179  } else {
180  if ((int32_t)depth > (int32_t)(prev_buffer_offset + cd->within + distance)) {
181  depth = prev_buffer_offset + cd->within + distance;
182  }
183 
184  SCLogDebug("cd->within %"PRIi32", det_ctx->buffer_offset %"PRIu32", depth %"PRIu32,
185  cd->within, prev_buffer_offset, depth);
186  }
187 
188  if (stream_start_offset != 0 && prev_buffer_offset == 0) {
189  if (depth <= stream_start_offset) {
190  goto no_match;
191  } else if (depth >= (stream_start_offset + buffer_len)) {
192  ;
193  } else {
194  depth = depth - stream_start_offset;
195  }
196  }
197  }
198 
199  if (cd->flags & DETECT_CONTENT_DEPTH_BE) {
200  if ((det_ctx->bj_values[cd->depth] + prev_buffer_offset) < depth) {
201  depth = prev_buffer_offset + det_ctx->bj_values[cd->depth];
202  }
203  } else {
204  if (cd->depth != 0) {
205  if ((cd->depth + prev_buffer_offset) < depth) {
206  depth = prev_buffer_offset + cd->depth;
207  }
208 
209  SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32, cd->depth, depth);
210  }
211  }
212 
213  if (cd->flags & DETECT_CONTENT_OFFSET_BE) {
214  if (det_ctx->bj_values[cd->offset] > offset)
215  offset = det_ctx->bj_values[cd->offset];
216  } else {
217  if (cd->offset > offset) {
218  offset = cd->offset;
219  SCLogDebug("setting offset %"PRIu32, offset);
220  }
221  }
222  } else { /* implied no relative matches */
223  /* set depth */
224  if (cd->flags & DETECT_CONTENT_DEPTH_BE) {
225  depth = det_ctx->bj_values[cd->depth];
226  } else {
227  if (cd->depth != 0) {
228  depth = cd->depth;
229  }
230  }
231 
232  if (stream_start_offset != 0 && cd->flags & DETECT_CONTENT_DEPTH) {
233  if (depth <= stream_start_offset) {
234  goto no_match;
235  } else if (depth >= (stream_start_offset + buffer_len)) {
236  ;
237  } else {
238  depth = depth - stream_start_offset;
239  }
240  }
241 
242  /* set offset */
244  offset = det_ctx->bj_values[cd->offset];
245  else
246  offset = cd->offset;
247  prev_buffer_offset = 0;
248  }
249 
250  /* update offset with prev_offset if we're searching for
251  * matches after the first occurence. */
252  SCLogDebug("offset %"PRIu32", prev_offset %"PRIu32, offset, prev_offset);
253  if (prev_offset != 0)
254  offset = prev_offset;
255 
256  SCLogDebug("offset %"PRIu32", depth %"PRIu32, offset, depth);
257 
258  if (depth > buffer_len)
259  depth = buffer_len;
260 
261  /* if offset is bigger than depth we can never match on a pattern.
262  * We can however, "match" on a negated pattern. */
263  if (offset > depth || depth == 0) {
264  if (cd->flags & DETECT_CONTENT_NEGATED) {
265  goto match;
266  } else {
267  goto no_match;
268  }
269  }
270 
271  const uint8_t *sbuffer = buffer + offset;
272  uint32_t sbuffer_len = depth - offset;
273  uint32_t match_offset = 0;
274  SCLogDebug("sbuffer_len %"PRIu32, sbuffer_len);
275 #ifdef DEBUG
276  BUG_ON(sbuffer_len > buffer_len);
277 #endif
278  if (cd->flags & DETECT_CONTENT_ENDS_WITH && depth < buffer_len) {
279  SCLogDebug("depth < buffer_len while DETECT_CONTENT_ENDS_WITH is set. Can't possibly match.");
280  found = NULL;
281  } else if (cd->content_len > sbuffer_len) {
282  found = NULL;
283  } else {
284  /* do the actual search */
285  found = SpmScan(cd->spm_ctx, det_ctx->spm_thread_ctx, sbuffer,
286  sbuffer_len);
287  }
288 
289  /* next we evaluate the result in combination with the
290  * negation flag. */
291  SCLogDebug("found %p cd negated %s", found, cd->flags & DETECT_CONTENT_NEGATED ? "true" : "false");
292 
293  if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) {
295  /* independent match from previous matches, so failure is fatal */
296  det_ctx->discontinue_matching = 1;
297  }
298 
299  goto no_match;
300  } else if (found == NULL && (cd->flags & DETECT_CONTENT_NEGATED)) {
301  goto match;
302  } else if (found != NULL && (cd->flags & DETECT_CONTENT_NEGATED)) {
303  SCLogDebug("content %"PRIu32" matched at offset %"PRIu32", but negated so no match", cd->id, match_offset);
304  /* don't bother carrying recursive matches now, for preceding
305  * relative keywords */
306  if (DETECT_CONTENT_IS_SINGLE(cd))
307  det_ctx->discontinue_matching = 1;
308  goto no_match;
309  } else {
310  match_offset = (uint32_t)((found - buffer) + cd->content_len);
311  SCLogDebug("content %"PRIu32" matched at offset %"PRIu32"", cd->id, match_offset);
312  det_ctx->buffer_offset = match_offset;
313 
314  if ((cd->flags & DETECT_CONTENT_ENDS_WITH) == 0 || match_offset == buffer_len) {
315  /* Match branch, add replace to the list if needed */
316  if (cd->flags & DETECT_CONTENT_REPLACE) {
317  if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD) {
318  /* we will need to replace content if match is confirmed
319  * cast to non-const as replace writes to it. */
320  det_ctx->replist = DetectReplaceAddToList(det_ctx->replist, (uint8_t *)found, cd);
321  } else {
322  SCLogWarning(SC_ERR_INVALID_VALUE, "Can't modify payload without packet");
323  }
324  }
325 
326  /* if this is the last match we're done */
327  if (smd->is_last) {
328  goto match;
329  }
330 
331  SCLogDebug("content %"PRIu32, cd->id);
332  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
333 
334  /* see if the next buffer keywords match. If not, we will
335  * search for another occurence of this content and see
336  * if the others match then until we run out of matches */
337  int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
338  p, f, buffer, buffer_len, stream_start_offset, flags,
339  inspection_mode);
340  if (r == 1) {
341  SCReturnInt(1);
342  }
343  SCLogDebug("no match for 'next sm'");
344 
345  if (det_ctx->discontinue_matching) {
346  SCLogDebug("'next sm' said to discontinue this right now");
347  goto no_match;
348  }
349 
350  /* no match and no reason to look for another instance */
351  if ((cd->flags & DETECT_CONTENT_WITHIN_NEXT) == 0) {
352  SCLogDebug("'next sm' does not depend on me, so we can give up");
353  det_ctx->discontinue_matching = 1;
354  goto no_match;
355  }
356 
357  SCLogDebug("'next sm' depends on me %p, lets see what we can do (flags %u)", cd, cd->flags);
358  }
359  /* set the previous match offset to the start of this match + 1 */
360  prev_offset = (match_offset - (cd->content_len - 1));
361  SCLogDebug("trying to see if there is another match after prev_offset %"PRIu32, prev_offset);
362  }
363 
364  } while(1);
365 
366  } else if (smd->type == DETECT_ISDATAAT) {
367  SCLogDebug("inspecting isdataat");
368 
369  const DetectIsdataatData *id = (DetectIsdataatData *)smd->ctx;
370  uint32_t dataat = id->dataat;
371  if (id->flags & ISDATAAT_OFFSET_BE) {
372  uint64_t be_value = det_ctx->bj_values[dataat];
373  if (be_value >= 100000000) {
374  if ((id->flags & ISDATAAT_NEGATED) == 0) {
375  SCLogDebug("extracted value %"PRIu64" very big: no match", be_value);
376  goto no_match;
377  }
378  SCLogDebug("extracted value way %"PRIu64" very big: match", be_value);
379  goto match;
380  }
381  dataat = (uint32_t)be_value;
382  SCLogDebug("isdataat: using value %u from byte_extract local_id %u", dataat, id->dataat);
383  }
384 
385  if (id->flags & ISDATAAT_RELATIVE) {
386  if (det_ctx->buffer_offset + dataat > buffer_len) {
387  SCLogDebug("det_ctx->buffer_offset + dataat %"PRIu32" > %"PRIu32, det_ctx->buffer_offset + dataat, buffer_len);
388  if (id->flags & ISDATAAT_NEGATED)
389  goto match;
390  goto no_match;
391  } else {
392  SCLogDebug("relative isdataat match");
393  if (id->flags & ISDATAAT_NEGATED)
394  goto no_match;
395  goto match;
396  }
397  } else {
398  if (dataat < buffer_len) {
399  SCLogDebug("absolute isdataat match");
400  if (id->flags & ISDATAAT_NEGATED)
401  goto no_match;
402  goto match;
403  } else {
404  SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", buffer_len %"PRIu32"", dataat, buffer_len);
405  if (id->flags & ISDATAAT_NEGATED)
406  goto match;
407  goto no_match;
408  }
409  }
410 
411  } else if (smd->type == DETECT_PCRE) {
412  SCLogDebug("inspecting pcre");
413  DetectPcreData *pe = (DetectPcreData *)smd->ctx;
414  uint32_t prev_buffer_offset = det_ctx->buffer_offset;
415  uint32_t prev_offset = 0;
416  int r = 0;
417 
418  det_ctx->pcre_match_start_offset = 0;
419  do {
420  r = DetectPcrePayloadMatch(det_ctx, s, smd, p, f,
421  buffer, buffer_len);
422  if (r == 0) {
423  goto no_match;
424  }
425 
426  if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) {
427  SCLogDebug("no relative match coming up, so this is a match");
428  goto match;
429  }
430  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
431 
432  /* save it, in case we need to do a pcre match once again */
433  prev_offset = det_ctx->pcre_match_start_offset;
434 
435  /* see if the next payload keywords match. If not, we will
436  * search for another occurence of this pcre and see
437  * if the others match, until we run out of matches */
438  r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
439  p, f, buffer, buffer_len, stream_start_offset, flags,
440  inspection_mode);
441  if (r == 1) {
442  SCReturnInt(1);
443  }
444 
445  if (det_ctx->discontinue_matching)
446  goto no_match;
447 
448  det_ctx->buffer_offset = prev_buffer_offset;
449  det_ctx->pcre_match_start_offset = prev_offset;
450  } while (1);
451 
452  } else if (smd->type == DETECT_BYTETEST) {
453  DetectBytetestData *btd = (DetectBytetestData *)smd->ctx;
454  uint8_t btflags = btd->flags;
455  int32_t offset = btd->offset;
456  uint64_t value = btd->value;
457  if (btflags & DETECT_BYTETEST_OFFSET_BE) {
458  offset = det_ctx->bj_values[offset];
459  }
460  if (btflags & DETECT_BYTETEST_VALUE_BE) {
461  value = det_ctx->bj_values[value];
462  }
463 
464  /* if we have dce enabled we will have to use the endianness
465  * specified by the dce header */
466  if (btflags & DETECT_BYTETEST_DCE) {
467  /* enable the endianness flag temporarily. once we are done
468  * processing we reset the flags to the original value*/
469  btflags |= ((flags & DETECT_CI_FLAGS_DCE_LE) ?
471  }
472 
473  if (DetectBytetestDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len, btflags,
474  offset, value) != 1) {
475  goto no_match;
476  }
477 
478  goto match;
479 
480  } else if (smd->type == DETECT_BYTEJUMP) {
481  DetectBytejumpData *bjd = (DetectBytejumpData *)smd->ctx;
482  uint8_t bjflags = bjd->flags;
483  int32_t offset = bjd->offset;
484 
485  if (bjflags & DETECT_BYTEJUMP_OFFSET_BE) {
486  offset = det_ctx->bj_values[offset];
487  }
488 
489  /* if we have dce enabled we will have to use the endianness
490  * specified by the dce header */
491  if (bjflags & DETECT_BYTEJUMP_DCE) {
492  /* enable the endianness flag temporarily. once we are done
493  * processing we reset the flags to the original value*/
494  bjflags |= ((flags & DETECT_CI_FLAGS_DCE_LE) ?
496  }
497 
498  if (DetectBytejumpDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len,
499  bjflags, offset) != 1) {
500  goto no_match;
501  }
502 
503  goto match;
504 
505  } else if (smd->type == DETECT_BYTE_EXTRACT) {
506 
507  DetectByteExtractData *bed = (DetectByteExtractData *)smd->ctx;
508  uint8_t endian = bed->endian;
509 
510  /* if we have dce enabled we will have to use the endianness
511  * specified by the dce header */
512  if ((bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN) &&
513  endian == DETECT_BYTE_EXTRACT_ENDIAN_DCE &&
515 
516  /* enable the endianness flag temporarily. once we are done
517  * processing we reset the flags to the original value*/
518  endian |= ((flags & DETECT_CI_FLAGS_DCE_LE) ?
520  }
521 
522  if (DetectByteExtractDoMatch(det_ctx, smd, s, buffer,
523  buffer_len,
524  &det_ctx->bj_values[bed->local_id],
525  endian) != 1) {
526  goto no_match;
527  }
528 
529  goto match;
530 
531  } else if (smd->type == DETECT_BSIZE) {
532 
533  bool eof = (flags & DETECT_CI_FLAGS_END);
534  const uint64_t data_size = buffer_len + stream_start_offset;
535  int r = DetectBsizeMatch(smd->ctx, data_size, eof);
536  if (r < 0) {
537  det_ctx->discontinue_matching = 1;
538  goto no_match;
539 
540  } else if (r == 0) {
541  goto no_match;
542  }
543  goto match;
544 
545  } else if (smd->type == DETECT_DATASET) {
546 
547  //PrintRawDataFp(stdout, buffer, buffer_len);
548  const DetectDatasetData *sd = (const DetectDatasetData *) smd->ctx;
549  int r = DetectDatasetBufferMatch(det_ctx, sd, buffer, buffer_len); //TODO buffer offset?
550  if (r == 1) {
551  goto match;
552  }
553  det_ctx->discontinue_matching = 1;
554  goto no_match;
555 
556  } else if (smd->type == DETECT_DATAREP) {
557 
558  //PrintRawDataFp(stdout, buffer, buffer_len);
559  const DetectDatarepData *sd = (const DetectDatarepData *) smd->ctx;
560  int r = DetectDatarepBufferMatch(det_ctx, sd, buffer, buffer_len); //TODO buffer offset?
561  if (r == 1) {
562  goto match;
563  }
564  det_ctx->discontinue_matching = 1;
565  goto no_match;
566 
567  } else if (smd->type == DETECT_AL_URILEN) {
568  SCLogDebug("inspecting uri len");
569 
570  int r = 0;
571  DetectUrilenData *urilend = (DetectUrilenData *) smd->ctx;
572 
573  switch (urilend->mode) {
574  case DETECT_URILEN_EQ:
575  if (buffer_len == urilend->urilen1)
576  r = 1;
577  break;
578  case DETECT_URILEN_LT:
579  if (buffer_len < urilend->urilen1)
580  r = 1;
581  break;
582  case DETECT_URILEN_GT:
583  if (buffer_len > urilend->urilen1)
584  r = 1;
585  break;
586  case DETECT_URILEN_RA:
587  if (buffer_len > urilend->urilen1 &&
588  buffer_len < urilend->urilen2) {
589  r = 1;
590  }
591  break;
592  }
593 
594  if (r == 1) {
595  goto match;
596  }
597 
598  det_ctx->discontinue_matching = 0;
599 
600  goto no_match;
601 #ifdef HAVE_LUA
602  }
603  else if (smd->type == DETECT_LUA) {
604  SCLogDebug("lua starting");
605 
606  if (DetectLuaMatchBuffer(det_ctx, s, smd, buffer, buffer_len,
607  det_ctx->buffer_offset, f) != 1)
608  {
609  SCLogDebug("lua no_match");
610  goto no_match;
611  }
612  SCLogDebug("lua match");
613  goto match;
614 #endif /* HAVE_LUA */
615  } else if (smd->type == DETECT_BASE64_DECODE) {
616  if (DetectBase64DecodeDoMatch(det_ctx, s, smd, buffer, buffer_len)) {
617  if (s->sm_arrays[DETECT_SM_LIST_BASE64_DATA] != NULL) {
618  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
619  if (DetectBase64DataDoMatch(de_ctx, det_ctx, s, f)) {
620  /* Base64 is a terminal list. */
621  goto final_match;
622  }
623  }
624  }
625  } else {
626  SCLogDebug("sm->type %u", smd->type);
627 #ifdef DEBUG
628  BUG_ON(1);
629 #endif
630  }
631 
632 no_match:
633  KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
634  SCReturnInt(0);
635 
636 match:
637  /* this sigmatch matched, inspect the next one. If it was the last,
638  * the buffer portion of the signature matched. */
639  if (!smd->is_last) {
640  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
641  int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
642  p, f, buffer, buffer_len, stream_start_offset, flags,
643  inspection_mode);
644  SCReturnInt(r);
645  }
646 final_match:
647  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
648  SCReturnInt(1);
649 }
650 
651 #ifdef UNITTESTS
653 #endif
#define ISDATAAT_OFFSET_BE
uint16_t flags
#define SCLogDebug(...)
Definition: util-debug.h:335
#define DETECT_BYTETEST_LITTLE
#define KEYWORD_PROFILING_END(ctx, type, m)
#define BUG_ON(x)
uint16_t discontinue_matching
Definition: detect.h:1067
#define DETECT_CI_FLAGS_DCE_LE
uint64_t * bj_values
Definition: detect.h:1112
uint8_t is_last
Definition: detect.h:329
int DetectBase64DecodeDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, const uint8_t *payload, uint32_t payload_len)
uint64_t offset
DetectReplaceList * replist
Definition: detect.h:1115
Data needed for Match()
Definition: detect.h:327
#define DETECT_CONTENT_DISTANCE_BE
#define ISDATAAT_RELATIVE
#define DETECT_BYTEJUMP_LITTLE
#define DETECT_CONTENT_DISTANCE
int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset, Flow *f)
uint32_t buffer_offset
Definition: detect.h:1032
Signature container.
Definition: detect.h:522
#define DETECT_CONTENT_DEPTH
#define DETECT_URILEN_EQ
Definition: detect-urilen.h:30
int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint8_t flags, int32_t offset, uint64_t value)
Bytetest detection code.
uint16_t flags
Definition: detect-pcre.h:42
#define DETECT_CONTENT_IS_SINGLE(c)
int DetectBase64DataDoMatch(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, Flow *f)
DetectReplaceList * DetectReplaceAddToList(DetectReplaceList *replist, uint8_t *found, DetectContentData *cd)
main detection engine ctx
Definition: detect.h:761
#define DETECT_CI_FLAGS_END
int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *payload, uint32_t payload_len)
Match a regex on a single payload.
Definition: detect-pcre.c:171
#define DETECT_CONTENT_WITHIN_BE
#define KEYWORD_PROFILING_START
int DetectDatarepBufferMatch(DetectEngineThreadCtx *det_ctx, const DetectDatarepData *sd, const uint8_t *data, const uint32_t data_len)
#define DETECT_URILEN_GT
Definition: detect-urilen.h:28
int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint8_t flags, int32_t offset)
Byte jump match function.
#define ISDATAAT_NEGATED
#define DETECT_URILEN_LT
Definition: detect-urilen.h:27
#define SCEnter(...)
Definition: util-debug.h:337
#define DETECT_BYTETEST_VALUE_BE
#define DETECT_CI_FLAGS_DCE_BE
#define DETECT_BYTE_EXTRACT_ENDIAN_BIG
int DetectDatasetBufferMatch(DetectEngineThreadCtx *det_ctx, const DetectDatasetData *sd, const uint8_t *data, const uint32_t data_len)
#define DETECT_CONTENT_WITHIN_NEXT
#define DETECT_URILEN_RA
Definition: detect-urilen.h:29
#define SCReturnInt(x)
Definition: util-debug.h:341
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
#define DETECT_CONTENT_ENDS_WITH
#define DETECT_BYTE_EXTRACT_ENDIAN_LITTLE
#define DETECT_CONTENT_OFFSET_BE
uint8_t type
Definition: detect.h:328
#define DETECT_CONTENT_NEGATED
#define DETECT_CONTENT_REPLACE
uint32_t pcre_match_start_offset
Definition: detect.h:1034
int DetectByteExtractDoMatch(DetectEngineThreadCtx *det_ctx, const SigMatchData *smd, const Signature *s, const uint8_t *payload, uint16_t payload_len, uint64_t *value, uint8_t endian)
int DetectBsizeMatch(const SigMatchCtx *ctx, const uint64_t buffer_size, bool eof)
bsize match function
Definition: detect-bsize.c:84
#define DETECT_BYTETEST_DCE
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode)
Run the actual payload match functions.
#define DETECT_BYTETEST_OFFSET_BE
#define DETECT_CONTENT_WITHIN
int inspection_recursion_counter
Definition: detect.h:1079
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:32
#define DETECT_BYTE_EXTRACT_FLAG_ENDIAN
Holds data related to byte_extract keyword.
#define DETECT_BYTEJUMP_OFFSET_BE
SpmThreadCtx * spm_thread_ctx
Definition: detect.h:1106
#define DETECT_CONTENT_DEPTH_BE
#define DETECT_BYTEJUMP_DCE
Flow data structure.
Definition: flow.h:325
SigMatchCtx * ctx
Definition: detect.h:330
int inspection_recursion_limit
Definition: detect.h:833
#define DETECT_BYTE_EXTRACT_ENDIAN_DCE
uint8_t * SpmScan(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, const uint8_t *haystack, uint32_t haystack_len)
Definition: util-spm.c:186