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