109 Packet *p,
Flow *f,
const uint8_t *buffer,
const uint32_t buffer_len,
110 const uint64_t stream_start_offset,
const uint8_t
flags,
116 ctx->recursion.count++;
123 if (smd == NULL || buffer == NULL) {
130 SCLogDebug(
"inspecting content %"PRIu32
" buffer_len %"PRIu32, cd->id, buffer_len);
141 BUG_ON(cd->depth != 0 && cd->depth <= cd->offset);
146 uint32_t prev_offset = 0;
150 uint32_t depth = buffer_len;
155 offset = prev_buffer_offset;
157 int distance = cd->distance;
161 distance = (uint32_t)det_ctx->
byte_values[cd->distance];
163 if (distance < 0 && (uint32_t)(abs(distance)) >
offset)
168 SCLogDebug(
"cd->distance %"PRIi32
", offset %"PRIu32
", depth %"PRIu32,
175 if ((int32_t)depth > (int32_t)(prev_buffer_offset + det_ctx->
byte_values[cd->within] + distance)) {
176 depth = prev_buffer_offset +
177 (uint32_t)det_ctx->
byte_values[cd->within] + distance;
180 if ((int32_t)depth > (int32_t)(prev_buffer_offset + cd->within + distance)) {
181 depth = prev_buffer_offset + cd->within + distance;
184 SCLogDebug(
"cd->within %"PRIi32
", det_ctx->buffer_offset %"PRIu32
", depth %"PRIu32,
185 cd->within, prev_buffer_offset, depth);
188 if (stream_start_offset != 0 && prev_buffer_offset == 0) {
189 if (depth <= stream_start_offset) {
191 }
else if (depth >= (stream_start_offset + buffer_len)) {
194 depth = depth - (uint32_t)stream_start_offset;
200 if ((det_ctx->
byte_values[cd->depth] + prev_buffer_offset) < depth) {
202 depth = prev_buffer_offset + (uint32_t)det_ctx->
byte_values[cd->depth];
205 if (cd->depth != 0) {
206 if ((cd->depth + prev_buffer_offset) < depth) {
207 depth = prev_buffer_offset + cd->depth;
210 SCLogDebug(
"cd->depth %"PRIu32
", depth %"PRIu32, cd->depth, depth);
220 if (cd->offset >
offset) {
231 if (cd->depth != 0) {
237 if (depth <= stream_start_offset) {
239 }
else if (depth >= (stream_start_offset + buffer_len)) {
242 depth = (uint32_t)(depth - stream_start_offset);
253 prev_buffer_offset = 0;
266 if (prev_offset != 0)
271 if (depth > buffer_len)
276 if (
offset > depth || depth == 0) {
284 const uint8_t *sbuffer = buffer +
offset;
285 uint32_t sbuffer_len = depth -
offset;
286 SCLogDebug(
"sbuffer_len %" PRIu32
" depth: %" PRIu32
", buffer_len: %" PRIu32,
287 sbuffer_len, depth, buffer_len);
289 BUG_ON(sbuffer_len > buffer_len);
291 const uint8_t *found;
293 SCLogDebug(
"depth < buffer_len while DETECT_CONTENT_ENDS_WITH is set. Can't possibly match.");
295 }
else if (cd->content_len > sbuffer_len) {
311 goto no_match_discontinue;
320 uint32_t match_offset = (uint32_t)((found - buffer) + cd->content_len);
322 SCLogDebug(
"content %" PRIu32
" matched at offset %" PRIu32
323 ", but negated so no match",
324 cd->id, match_offset);
330 if (sbuffer_len != match_offset) {
331 SCLogDebug(
"content \"%s\" %" PRIu32
" matched at offset %" PRIu32
332 ", but not at end of buffer so match",
333 cd->content, cd->id, match_offset);
338 goto no_match_discontinue;
343 SCLogDebug(
"content %" PRIu32
" matched at offset %" PRIu32
"", cd->id, match_offset);
370 int r = DetectEngineContentInspectionInternal(det_ctx,
ctx, s, smd + 1, p, f,
371 buffer, buffer_len, stream_start_offset,
flags, inspection_mode);
374 }
else if (r == -1) {
375 SCLogDebug(
"'next sm' said to discontinue this right now");
382 SCLogDebug(
"'next sm' does not depend on me, so we can give up");
386 SCLogDebug(
"'next sm' depends on me %p, lets see what we can do (flags %u)", cd,
390 prev_offset = (match_offset - (cd->content_len - 1));
391 SCLogDebug(
"trying to see if there is another match after prev_offset %" PRIu32,
406 uint32_t dataat =
id->dataat;
409 if (be_value >= 100000000) {
411 SCLogDebug(
"extracted value %"PRIu64
" very big: no match", be_value);
414 SCLogDebug(
"extracted value way %"PRIu64
" very big: match", be_value);
417 dataat = (uint32_t)be_value;
418 SCLogDebug(
"isdataat: using value %u from byte_extract local_id %u", dataat,
id->dataat);
423 SCLogDebug(
"det_ctx->buffer_offset + dataat %"PRIu32
" > %"PRIu32, det_ctx->
buffer_offset + dataat, buffer_len);
427 goto no_match_discontinue;
438 if (dataat < buffer_len) {
442 goto no_match_discontinue;
448 SCLogDebug(
"absolute isdataat mismatch, id->isdataat %"PRIu32
", buffer_len %"PRIu32
"", dataat, buffer_len);
452 goto no_match_discontinue;
462 uint32_t prev_offset = 0;
471 SCLogDebug(
"no relative match coming up, so this is a match");
482 r = DetectEngineContentInspectionInternal(det_ctx,
ctx, s, smd + 1, p, f, buffer,
483 buffer_len, stream_start_offset,
flags, inspection_mode);
486 }
else if (r == -1) {
490 if (prev_offset == 0) {
506 uint16_t btflags = btd->flags;
507 int32_t
offset = btd->offset;
508 uint64_t value = btd->value;
509 int32_t nbytes = btd->nbytes;
540 uint16_t bjflags = bjd->flags;
541 int32_t
offset = bjd->offset;
552 nbytes = (int32_t)det_ctx->
byte_values[bjd->nbytes];
553 SCLogDebug(
"[BJ] using nbytes value %d [index %d]", nbytes, bjd->nbytes);
555 nbytes = bjd->nbytes;
556 SCLogDebug(
"[BJ] using nbytes value %d [index n/a]", nbytes);
569 det_ctx, s, smd->
ctx, buffer, buffer_len, bjflags, nbytes,
offset)) {
577 const SCDetectByteExtractData *bed = (
const SCDetectByteExtractData *)smd->
ctx;
578 uint8_t endian = bed->endian;
582 if ((bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN) && endian == EndianDCE &&
591 &det_ctx->
byte_values[bed->local_id], endian) != 1) {
595 SCLogDebug(
"[BE] Fetched value for index %d: %"PRIu64,
596 bed->local_id, det_ctx->
byte_values[bed->local_id]);
601 const DetectByteMathData *bmd = (
const DetectByteMathData *)smd->
ctx;
602 uint8_t endian = bmd->endian;
606 if ((bmd->flags & DETECT_BYTEMATH_FLAG_ENDIAN) && endian == (
int)EndianDCE &&
613 if (bmd->flags & DETECT_BYTEMATH_FLAG_RVALUE_VAR) {
616 rvalue = bmd->rvalue;
620 if (bmd->flags & DETECT_BYTEMATH_FLAG_NBYTES_VAR) {
621 nbytes = (uint8_t)det_ctx->
byte_values[bmd->nbytes];
623 nbytes = bmd->nbytes;
627 &det_ctx->
byte_values[bmd->local_id], endian) != 1) {
631 SCLogDebug(
"[BM] Fetched value for index %d: %"PRIu64,
632 bmd->local_id, det_ctx->
byte_values[bmd->local_id]);
638 const uint64_t data_size = buffer_len + stream_start_offset;
641 goto no_match_discontinue;
655 goto no_match_discontinue;
665 goto no_match_discontinue;
671 const DetectUrilenData *urilend = (
const DetectUrilenData *)smd->
ctx;
672 if (buffer_len > UINT16_MAX) {
681 goto no_match_discontinue;
698 int r = DetectEngineContentInspectionInternal(det_ctx,
ctx, s,
736 int r = DetectEngineContentInspectionInternal(det_ctx,
ctx, s, smd + 1, p, f, buffer,
737 buffer_len, stream_start_offset,
flags, inspection_mode);
751 const uint32_t buffer_len,
const uint64_t stream_start_offset,
const uint8_t
flags,
758 int r = DetectEngineContentInspectionInternal(det_ctx, &
ctx, s, smd, p, f, buffer, buffer_len,
759 stream_start_offset,
flags, inspection_mode);
782 int r = DetectEngineContentInspectionInternal(det_ctx, &
ctx, s, smd, p, f, b->
inspect,
796 bool absent_data =
false;
bool DetectAsn1Match(const SigMatchData *smd, const uint8_t *buffer, const uint32_t buffer_len, const uint32_t offset)
int DetectBase64DecodeDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, const uint8_t *payload, uint32_t payload_len)
int DetectBsizeMatch(const SigMatchCtx *ctx, const uint64_t buffer_size, bool eof)
bsize match function
bool DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint16_t flags, int32_t nbytes, int32_t offset)
Byte jump match function.
#define DETECT_BYTEJUMP_DCE
#define DETECT_BYTEJUMP_LITTLE
#define DETECT_BYTEJUMP_OFFSET_VAR
#define DETECT_BYTEJUMP_NBYTES_VAR
int DetectByteMathDoMatch(DetectEngineThreadCtx *det_ctx, const DetectByteMathData *data, const Signature *s, const uint8_t *payload, const uint32_t payload_len, uint8_t nbytes, uint64_t rvalue, uint64_t *value, uint8_t endian)
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.
#define DETECT_BYTETEST_DCE
#define DETECT_BYTETEST_OFFSET_VAR
#define DETECT_BYTETEST_VALUE_VAR
#define DETECT_BYTETEST_LITTLE
#define DETECT_BYTETEST_NBYTES_VAR
#define DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_WITHIN_VAR
#define DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_DEPTH_VAR
#define DETECT_CONTENT_ENDS_WITH
#define DETECT_CONTENT_OFFSET_VAR
#define DETECT_CONTENT_DISTANCE
#define DETECT_CONTENT_WITHIN_NEXT
#define DETECT_CONTENT_NEGATED
#define DETECT_CONTENT_DISTANCE_VAR
#define DETECT_CONTENT_REPLACE
#define DETECT_CONTENT_IS_SINGLE(c)
int DetectDatarepBufferMatch(DetectEngineThreadCtx *det_ctx, const DetectDatarepData *sd, const uint8_t *data, const uint32_t data_len)
int DetectDatasetBufferMatch(DetectEngineThreadCtx *det_ctx, const DetectDatasetData *sd, const uint8_t *data, const uint32_t data_len)
thread_local uint32_t ut_inspection_recursion_counter
bool DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, const uint32_t buffer_len, const uint64_t stream_start_offset, const uint8_t flags, const enum DetectContentInspectionType inspection_mode)
wrapper around DetectEngineContentInspectionInternal to return true/false only
bool DetectContentInspectionMatchOnAbsentBuffer(const SigMatchData *smd)
tells if we should match on absent buffer, because there is an absent keyword being used
bool DetectEngineContentInspectionBuffer(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const InspectionBuffer *b, const enum DetectContentInspectionType inspection_mode)
wrapper around DetectEngineContentInspectionInternal to return true/false only
DetectContentInspectionType
@ DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE
@ DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD
#define DETECT_CI_FLAGS_DCE_BE
#define DETECT_CI_FLAGS_SINGLE
#define DETECT_CI_FLAGS_END
#define DETECT_CI_FLAGS_DCE_LE
int DetectU16Match(const uint16_t parg, const DetectUintData_u16 *du16)
bool DetectEntropyDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, const uint8_t *buffer, const uint32_t buffer_len)
#define ISDATAAT_RELATIVE
#define ISDATAAT_OFFSET_VAR
int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, const uint8_t *buffer, uint32_t buffer_len, uint32_t offset, Flow *f)
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.
#define DETECT_PCRE_RELATIVE_NEXT
DetectReplaceList * DetectReplaceAddToList(DetectReplaceList *replist, uint8_t *found, const DetectContentData *cd)
@ DETECT_SM_LIST_BASE64_DATA
struct DetectEngineContentInspectionCtx::@59 recursion
main detection engine ctx
int inspection_recursion_limit
SpmThreadCtx * spm_thread_ctx
uint32_t pcre_match_start_offset
DetectReplaceList * replist
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
#define SCLogWarning(...)
Macro used to log WARNING messages.
#define KEYWORD_PROFILING_END(ctx, type, m)
#define KEYWORD_PROFILING_START
uint8_t * SpmScan(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, const uint8_t *haystack, uint32_t haystack_len)