First stage of detect engine redesign: equal patterns share id's, search phase no longer used, new match verification phase.

remotes/origin/master-1.0.x
Victor Julien 17 years ago
parent 50e41817a7
commit bef70a04ce

@ -55,6 +55,7 @@ detect-engine-port.c detect-engine-port.h \
detect-engine-siggroup.c detect-engine-siggroup.h \
detect-engine-mpm.c detect-engine-mpm.h \
detect-engine-iponly.c detect-engine-iponly.h \
detect-engine-payload.c detect-engine-payload.h \
detect-parse.c detect-parse.h \
detect-ack.c detect-ack.h \
detect-seq.c detect-seq.h \

@ -7,6 +7,7 @@
#include "debug.h"
#include "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-bytejump.h"
@ -68,6 +69,124 @@ error:
return;
}
/** \brief Byte jump match function
* \param det_ctx thread detect engine ctx
* \param s signature
* \param m byte jump sigmatch
* \param payload ptr to the payload
* \param payload_len length of the payload
* \retval 1 match
* \retval 0 no match
*/
int DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *m, uint8_t *payload, uint32_t payload_len) {
SCEnter();
DetectBytejumpData *data = (DetectBytejumpData *)m->ctx;
uint8_t *ptr = NULL;
uint8_t *jumpptr = ptr;
uint32_t len = 0;
uint64_t val = 0;
int extbytes;
if (payload_len == 0) {
SCReturnInt(0);
}
/* Calculate the ptr value for the bytejump and length remaining in
* the packet from that point.
*/
if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
ptr = payload + det_ctx->pkt_off;
len = payload_len - det_ctx->pkt_off;
/* No match if there is no relative base */
if (ptr == NULL || len == 0) {
SCReturnInt(0);
}
ptr += data->offset;
len -= data->offset;
}
else {
ptr = payload + data->offset;
len = payload_len - data->offset;
}
/* Verify the to-be-extracted data is within the packet */
if (ptr < payload || data->nbytes > len) {
SCLogDebug("Data not within payload "
"pkt=%p, ptr=%p, len=%d, nbytes=%d",
payload, ptr, len, data->nbytes);
SCReturnInt(0);
}
/* Extract the byte data */
if (data->flags & DETECT_BYTEJUMP_STRING) {
extbytes = ByteExtractStringUint64(&val, data->base,
data->nbytes, (const char *)ptr);
if(extbytes <= 0) {
SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes "
"of string data: %d", data->nbytes, extbytes);
SCReturnInt(-1);
}
}
else {
int endianness = (data->flags & DETECT_BYTEJUMP_LITTLE) ? BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN;
extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
if (extbytes != data->nbytes) {
SCLogError(SC_ERR_BYTE_EXTRACT_FAILED,"Error extracting %d bytes "
"of numeric data: %d", data->nbytes, extbytes);
SCReturnInt(-1);
}
}
//printf("VAL: (%" PRIu64 " x %" PRIu32 ") + %d + %" PRId32 "\n", val, data->multiplier, extbytes, data->post_offset);
/* Adjust the jump value based on flags */
val *= data->multiplier;
if (data->flags & DETECT_BYTEJUMP_ALIGN) {
if ((val % 4) != 0) {
val += 4 - (val % 4);
}
}
val += extbytes + data->post_offset;
/* Calculate the jump location */
if (data->flags & DETECT_BYTEJUMP_BEGIN) {
jumpptr = payload + val;
//printf("NEWVAL: payload %p + %ld = %p\n", p->payload, val, jumpptr);
}
else {
jumpptr = ptr + val;
//printf("NEWVAL: ptr %p + %ld = %p\n", ptr, val, jumpptr);
}
/* Validate that the jump location is still in the packet
* \todo Should this validate it is still in the *payload*?
*/
if ((jumpptr < payload) || (jumpptr >= payload + payload_len)) {
SCLogDebug("Jump location (%p) is not within "
"payload (%p-%p)", jumpptr, payload, payload + payload_len - 1);
SCReturnInt(0);
}
#ifdef DEBUG
if (SCLogDebugEnabled()) {
uint8_t *sptr = (data->flags & DETECT_BYTEJUMP_BEGIN) ? payload : ptr;
SCLogDebug("jumping %" PRId64 " bytes from %p (%08x) to %p (%08x)",
val, sptr, (int)(sptr - payload),
jumpptr, (int)(jumpptr - payload));
}
#endif /* DEBUG */
/* Adjust the detection context to the jump location. */
det_ctx->pkt_ptr = jumpptr;
det_ctx->pkt_off = jumpptr - payload;
SCReturnInt(1);
}
int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m)
{
@ -365,7 +484,7 @@ error:
}
int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s,
SigMatch *m, char *optstr)
SigMatch *notused, char *optstr)
{
DetectBytejumpData *data = NULL;
SigMatch *sm = NULL;
@ -382,7 +501,7 @@ int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s,
sm->type = DETECT_BYTEJUMP;
sm->ctx = (void *)data;
SigMatchAppend(s,m,sm);
SigMatchAppendPayload(s,sm);
return 0;

@ -93,6 +93,7 @@ DetectBytejumpData *DetectBytejumpParse(char *optstr);
*/
int DetectBytejumpMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m);
int DetectBytejumpDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, uint8_t *, uint32_t);
#endif /* __DETECT_BYTEJUMP_H__ */

@ -7,7 +7,9 @@
#include "debug.h"
#include "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "detect-content.h"
#include "detect-bytetest.h"
#include "util-byte.h"
@ -69,9 +71,154 @@ error:
return;
}
/** \brief Bytetest detection code
*
* Byte test works on the packet payload.
*
* \param det_ctx thread de ctx
* \param s signature
* \param m sigmatch for this bytettest
* \param payload ptr to the start of the buffer to inspect
* \param payload_len length of the payload
* \retval 1 match
* \retval 0 no match
*/
int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *m, uint8_t *payload, uint32_t payload_len) {
SCEnter();
DetectBytetestData *data = (DetectBytetestData *)m->ctx;
uint8_t *ptr = NULL;
uint32_t len = 0;
uint64_t val = 0;
int extbytes;
int neg;
int match;
if (payload_len == 0) {
SCReturnInt(0);
}
/* Calculate the ptr value for the bytetest and length remaining in
* the packet from that point.
*/
if (data->flags & DETECT_BYTETEST_RELATIVE) {
SCLogDebug("relative, working with det_ctx->pkt_off %"PRIu32", "
"data->offset %"PRIu32"", det_ctx->pkt_off, data->offset);
ptr = payload + det_ctx->pkt_off;
len = payload_len - det_ctx->pkt_off;
/* No match if there is no relative base */
if (ptr == NULL || len == 0) {
SCReturnInt(0);
}
ptr += data->offset;
len -= data->offset;
//PrintRawDataFp(stdout,ptr,len);
}
else {
SCLogDebug("absolute, data->offset %"PRIu32"", data->offset);
ptr = payload + data->offset;
len = payload_len - data->offset;
}
/* Validate that the to-be-extracted is within the packet
* \todo Should this validate it is in the *payload*?
*/
if (ptr < payload || data->nbytes > len) {
SCLogDebug("Data not within payload pkt=%p, ptr=%p, len=%"PRIu32", nbytes=%d",
payload, ptr, len, data->nbytes);
SCReturnInt(0);
}
neg = data->flags & DETECT_BYTETEST_NEGOP;
/* Extract the byte data */
if (data->flags & DETECT_BYTETEST_STRING) {
extbytes = ByteExtractStringUint64(&val, data->base,
data->nbytes, (const char *)ptr);
if (extbytes <= 0) {
/* strtoull() return 0 if there is no numeric value in data string */
if (val == 0) {
SCLogDebug("No Numeric value");
SCReturnInt(0);
} else {
SCLogError(SC_ERR_INVALID_NUM_BYTES, "Error extracting %d "
"bytes of string data: %d", data->nbytes, extbytes);
SCReturnInt(-1);
}
}
SCLogDebug("comparing base %d string 0x%" PRIx64 " %s%c 0x%" PRIx64 "",
data->base, val, (neg ? "!" : ""), data->op, data->value);
}
else {
int endianness = (data->flags & DETECT_BYTETEST_LITTLE) ?
BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN;
extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
if (extbytes != data->nbytes) {
SCLogError(SC_ERR_INVALID_NUM_BYTES, "Error extracting %d bytes "
"of numeric data: %d\n", data->nbytes, extbytes);
SCReturnInt(-1);
}
SCLogDebug("comparing numeric 0x%" PRIx64 " %s%c 0x%" PRIx64 "",
val, (neg ? "!" : ""), data->op, data->value);
}
/* Compare using the configured operator */
match = 0;
switch (data->op) {
case DETECT_BYTETEST_OP_EQ:
if (val == data->value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_LT:
if (val < data->value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_GT:
if (val > data->value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_AND:
if (val & data->value) {
match = 1;
}
break;
case DETECT_BYTETEST_OP_OR:
if (val ^ data->value) {
match = 1;
}
break;
default:
/* Should never get here as we handle this in parsing. */
SCReturnInt(-1);
}
/* A successful match depends on negation */
if ((!neg && match) || (neg && !match)) {
SCLogDebug("MATCH");
SCReturnInt(1);
}
SCLogDebug("NO MATCH");
SCReturnInt(0);
}
int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m)
{
return DetectBytetestDoMatch(det_ctx, s, m, p->payload, p->payload_len);
#if 0
DetectBytetestData *data = (DetectBytetestData *)m->ctx;
uint8_t *ptr = NULL;
uint16_t len = 0;
@ -190,6 +337,7 @@ int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
SCLogDebug("NO MATCH");
return 0;
#endif
}
DetectBytetestData *DetectBytetestParse(char *optstr)
@ -348,7 +496,7 @@ error:
}
int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s,
SigMatch *m, char *optstr)
SigMatch *notused, char *optstr)
{
DetectBytetestData *data = NULL;
SigMatch *sm = NULL;
@ -358,6 +506,19 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s,
data = DetectBytetestParse(optstr);
if (data == NULL) goto error;
if (data->flags & DETECT_BYTETEST_RELATIVE) {
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_BYTETEST_MISSING_CONTENT, "relative bytetest match needs a previous content option");
goto error;
}
DetectContentData *cd = (DetectContentData *)pm->ctx;
cd->flags |= DETECT_CONTENT_BYTETEST_NEXT;
}
sm = SigMatchAlloc();
if (sm == NULL)
goto error;
@ -365,7 +526,7 @@ int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s,
sm->type = DETECT_BYTETEST;
sm->ctx = (void *)data;
SigMatchAppend(s,m,sm);
SigMatchAppendPayload(s,sm);
return 0;

@ -95,6 +95,7 @@ DetectBytetestData *DetectBytetestParse(char *optstr);
*/
int DetectBytetestMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Packet *p, Signature *s, SigMatch *m);
int DetectBytetestDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, uint8_t *, uint32_t);
#endif /* __DETECT_BYTETEST_H__ */

@ -793,6 +793,8 @@ void DetectContentPrint(DetectContentData *cd)
SCLogDebug("Isdataat: %u ", cd->isdataat);
SCLogDebug("flags: %u ", cd->flags);
SCLogDebug("negated %u ", cd->negated);
SCLogDebug("within next: %s ", cd->flags & DETECT_CONTENT_WITHIN_NEXT ? "true" : "false");
SCLogDebug("distance next: %s ", cd->flags & DETECT_CONTENT_DISTANCE_NEXT ? "true" : "false");
/** If it's a chunk, print the data related */
if (cd->flags & DETECT_CONTENT_IS_CHUNK) {
@ -1250,29 +1252,32 @@ int DetectContentPropagateOffset(SigMatch *first_sm)
*/
int DetectContentPropagateModifiers(SigMatch *first_sm)
{
SCEnter();
if (first_sm == NULL)
return -1;
goto error;
/** Rewind the pointer to the start of the chunk if we have a chunk group */
first_sm = DetectContentFindPrevApplicableSM(first_sm);
if (first_sm->ctx == NULL)
return -1;
goto error;
DetectContentData *first_chunk = (DetectContentData*)first_sm->ctx;
if (first_chunk == NULL)
return -1;
goto error;
if ( !(first_chunk->flags & DETECT_CONTENT_IS_CHUNK))
if ( !(first_chunk->flags & DETECT_CONTENT_IS_CHUNK)) {
/** No modifiers to update */
return 1;
SCReturnInt(1);
}
uint8_t chunk_group_id = first_chunk->chunk_group_id;
uint8_t num_chunks = DetectContentCountChunksInGroup(first_sm, chunk_group_id);
int16_t total_len = DetectContentChunksGetTotalLength(first_sm);
if (num_chunks < 1 || total_len < 1)
return -1;
goto error;
DetectContentData *cur_chunk = NULL;
DetectContentData *last_chunk = first_chunk;
@ -1291,11 +1296,13 @@ int DetectContentPropagateModifiers(SigMatch *first_sm)
int16_t remaining_len = DetectContentChunksGetRemainingLength(cur_sm);
int16_t previous_len = DetectContentChunksGetRemainingLength(cur_sm);
if (previous_len < 0 || remaining_len < 0)
return -1;
goto error;
/** If we are in the first chunk */
if (cur_chunk->chunk_id == 0) {
SCLogDebug("handling first chunk");
/** Reset the first depth removing the length of the remaining chunks
*/
SCLogDebug("CUR depth = %u remain_len %d ", cur_chunk->depth, remaining_len);
@ -1320,6 +1327,7 @@ int DetectContentPropagateModifiers(SigMatch *first_sm)
/** If it's not the first chunk we need to propagate the changes */
} else {
SCLogDebug("handling first chunk id %"PRIu8", last_chunk %p", cur_chunk->chunk_id, last_chunk);
/** Propagate the flags */
cur_chunk->flags = last_chunk->flags;
@ -1349,9 +1357,11 @@ int DetectContentPropagateModifiers(SigMatch *first_sm)
cur_chunk->within = cur_chunk->content_len;
/* set the within next flag on the previous chunk */
if (last_chunk != NULL)
if (last_chunk != NULL) {
SCLogDebug("within next flag set to prev chunk");
last_chunk->flags |= DETECT_CONTENT_WITHIN_NEXT;
}
}
/** We are iterating in the chunks after the first one, so distance
* must be 0 between the chunks, since they are consecutive
@ -1381,7 +1391,9 @@ int DetectContentPropagateModifiers(SigMatch *first_sm)
last_chunk = cur_chunk;
}
return 1;
SCReturnInt(1);
error:
SCReturnInt(-1);
}
/**
@ -1466,12 +1478,9 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
sm->type = DETECT_CONTENT;
sm->ctx = (void *)aux;
SigMatchAppend(s,m,sm);
m = sm;
SigMatchAppendPayload(s,sm);
aux->id = DetectContentGetId(de_ctx, aux);
//aux->id = de_ctx->content_max_id;
//de_ctx->content_max_id++;
/** We need to setup the modifiers for the chunks respect
* the last chunk installed inmediatelly before
@ -1500,7 +1509,7 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
sm->type = DETECT_CONTENT;
sm->ctx = (void *)cd;
SigMatchAppend(s,m,sm);
SigMatchAppendPayload(s,sm);
if (s != NULL) {
/** each group of chunks has it's own internal id in the sig,
@ -1511,8 +1520,6 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
}
cd->id = DetectContentGetId(de_ctx, cd);
//cd->id = de_ctx->content_max_id;
//de_ctx->content_max_id++;
DetectContentPrint(cd);
}
@ -1855,13 +1862,17 @@ int DetectContentChunkTestB2G01 (void) {
"32 bytes lentgh\"; content:\"12345678901234567890123456789012\"; sid:1;)";
s = de_ctx->sig_list = SigInit(de_ctx, sigstr);
if (s == NULL)
if (s == NULL) {
printf("sig parse failed: ");
goto end;
}
if (de_ctx->sig_list->match == NULL)
if (de_ctx->sig_list->pmatch == NULL) {
printf("no match in pmatch list: ");
goto end;
}
m = de_ctx->sig_list->match;
m = de_ctx->sig_list->pmatch;
if (m->type == DETECT_CONTENT && m->ctx != NULL)
cd = m->ctx;
else
@ -1898,13 +1909,17 @@ int DetectContentChunkTestB3G01 (void) {
"32 bytes lentgh\"; content:\"12345678901234567890123456789012\"; sid:1;)";
s = de_ctx->sig_list = SigInit(de_ctx, sigstr);
if (s == NULL)
if (s == NULL) {
printf("sig parse failed: ");
goto end;
}
if (de_ctx->sig_list->match == NULL)
if (de_ctx->sig_list->pmatch == NULL) {
printf("no match in pmatch list: ");
goto end;
}
m = de_ctx->sig_list->match;
m = de_ctx->sig_list->pmatch;
if (m->type == DETECT_CONTENT && m->ctx != NULL)
cd = m->ctx;
else
@ -1941,13 +1956,17 @@ int DetectContentChunkTestB2G02 (void) {
char *sigstr = "alert tcp any any -> any any (msg:\"This content is exactly 33 bytes length, so it should be splitted\"; content:\"123456789012345678901234567890123\"; sid:1;)";
s = de_ctx->sig_list = SigInit(de_ctx, sigstr);
if (s == NULL)
if (s == NULL) {
printf("sig parse failed: ");
goto end;
}
if (de_ctx->sig_list->match == NULL)
if (de_ctx->sig_list->pmatch == NULL) {
printf("no match in pmatch list: ");
goto end;
}
m = de_ctx->sig_list->match;
m = de_ctx->sig_list->pmatch;
if (m->type == DETECT_CONTENT && m->ctx != NULL)
cd = m->ctx;
else
@ -1991,13 +2010,15 @@ int DetectContentChunkTestB3G02 (void) {
char *sigstr = "alert tcp any any -> any any (msg:\"This content is exactly 33 bytes length, so it should be splitted\"; content:\"123456789012345678901234567890123\"; sid:1;)";
s = de_ctx->sig_list = SigInit(de_ctx, sigstr);
if (s == NULL)
if (s == NULL) {
goto end;
}
if (de_ctx->sig_list->match == NULL)
if (de_ctx->sig_list->pmatch == NULL) {
goto end;
}
m = de_ctx->sig_list->match;
m = de_ctx->sig_list->pmatch;
if (m->type == DETECT_CONTENT && m->ctx != NULL)
cd = m->ctx;
else
@ -2042,10 +2063,10 @@ int DetectContentChunkTestB2G03 (void) {
if (s == NULL)
goto end;
if (de_ctx->sig_list->match == NULL)
if (de_ctx->sig_list->pmatch == NULL)
goto end;
m = de_ctx->sig_list->match;
m = de_ctx->sig_list->pmatch;
uint8_t chunk_id = 0;
do {
@ -2099,10 +2120,10 @@ int DetectContentChunkTestB3G03 (void) {
if (s == NULL)
goto end;
if (de_ctx->sig_list->match == NULL)
if (de_ctx->sig_list->pmatch == NULL)
goto end;
m = de_ctx->sig_list->match;
m = de_ctx->sig_list->pmatch;
uint8_t chunk_id = 0;
do {
@ -2157,10 +2178,10 @@ int DetectContentChunkModifiersTest01 (void) {
if (s == NULL)
goto end;
if (de_ctx->sig_list->match == NULL)
if (de_ctx->sig_list->pmatch == NULL)
goto end;
m = de_ctx->sig_list->match;
m = de_ctx->sig_list->pmatch;
if (m->type == DETECT_CONTENT && m->ctx != NULL)
cd = m->ctx;
@ -2265,10 +2286,10 @@ int DetectContentChunkModifiersTest02 (void) {
if (s == NULL)
goto end;
if (de_ctx->sig_list->match == NULL)
if (de_ctx->sig_list->pmatch == NULL)
goto end;
m = de_ctx->sig_list->match;
m = de_ctx->sig_list->pmatch;
if (m->type == DETECT_CONTENT && m->ctx != NULL)
cd = m->ctx;
@ -2849,32 +2870,23 @@ static int SigTestPositiveTestContent(char *rule, uint8_t *buf)
de_ctx->sig_list = SigInit(de_ctx, rule);
if (de_ctx->sig_list == NULL) {
result = 0;
goto end;
}
SigGroupBuild(de_ctx);
//PatternMatchPrepare(mpm_ctx, MPM_B2G);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (PacketAlertCheck(&p, 1) == 1) {
result = 1;
if (PacketAlertCheck(&p, 1) != 1) {
goto end;
}
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
//PatternMatchDestroy(mpm_ctx);
DetectEngineCtxFree(de_ctx);
result = 1;
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
//PatternMatchDestroy(mpm_ctx);
DetectEngineCtxFree(de_ctx);
return result;
@ -2885,7 +2897,7 @@ static int SigTestNegativeTestContent(char *rule, uint8_t *buf)
uint16_t buflen = strlen((char *)buf);
Packet p;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
@ -2904,33 +2916,27 @@ static int SigTestNegativeTestContent(char *rule, uint8_t *buf)
de_ctx->sig_list = SigInit(de_ctx, rule);
if (de_ctx->sig_list == NULL) {
result = 0;
goto end;
}
SigGroupBuild(de_ctx);
//PatternMatchPrepare(mpm_ctx, MPM_B2G);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (PacketAlertCheck(&p, 1) == 0) {
result = 1;
if (PacketAlertCheck(&p, 1) != 0) {
goto end;
}
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
//PatternMatchDestroy(mpm_ctx);
DetectEngineCtxFree(de_ctx);
result = 1;
end:
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
}
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
//PatternMatchDestroy(mpm_ctx);
DetectEngineCtxFree(de_ctx);
}
return result;
}
@ -2955,12 +2961,13 @@ static int SigTest42TestNegatedContent(void)
/**
* \test A negative test that checks that the content string doesn't contain
* the negated content within the specified depth, and also after the
* specified offset. If it is present in the depth we get a failure
* anyways, and we don't do a check on the offset
* specified offset. Since the content is there, the match fails.
*
* Match is at offset:23, depth:34
*/
static int SigTest43TestNegatedContent(void)
{ // 12345123451234512345123
return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!twentythree; depth:15; offset:22; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
{
return SigTestNegativeTestContent("alert tcp any any -> any any (content:!twentythree; depth:34; offset:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
/**
@ -3116,12 +3123,19 @@ static int SigTest60TestNegatedContent(void)
static int SigTest61TestNegatedContent(void)
{
return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; depth:10; content:!fourty; within:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestPositiveTestContent("alert tcp any any -> any any (content:one; depth:10; content:!fourty; within:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
/** \test Test negation in combination with within and depth
*
* Match of "one" at offset:0, depth:3
* Match of "fourty" at offset:46, depth:52
*
* This signature should not match for the test to pass.
*/
static int SigTest62TestNegatedContent(void)
{
return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; depth:10; content:!fourty; within:30; depth:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestNegativeTestContent("alert tcp any any -> any any (content:one; depth:10; content:!fourty; within:49; depth:52; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
static int SigTest63TestNegatedContent(void)
@ -3131,47 +3145,55 @@ static int SigTest63TestNegatedContent(void)
static int SigTest64TestNegatedContent(void)
{
return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; depth:10; content:!fourty; within:30; depth:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestPositiveTestContent("alert tcp any any -> any any (content:one; depth:10; content:!fourty; within:30; depth:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
/** \test Test negation in combination with within and depth
*
* Match of "one" at offset:0, depth:3
* Match of "fourty" at offset:46, depth:52
*
* This signature should not match for the test to pass.
*/
static int SigTest65TestNegatedContent(void)
{
return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; depth:10; content:!fourty; within:30; offset:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestNegativeTestContent("alert tcp any any -> any any (content:one; depth:10; content:!fourty; distance:0; within:49; offset:46; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
static int SigTest66TestNegatedContent(void)
{
return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; depth:10; content:!fourty; within:30; offset:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestPositiveTestContent("alert tcp any any -> any any (content:one; depth:10; content:!fourty; within:30; offset:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
static int SigTest67TestNegatedContent(void)
{
return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; depth:10; content:!four; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestNegativeTestContent("alert tcp any any -> any any (content:one; depth:10; content:!four; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
static int SigTest68TestNegatedContent(void)
{
return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; depth:10; content:nine; offset:8; content:!fourty; within:28; content:fiftysix; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestPositiveTestContent("alert tcp any any -> any any (content:one; depth:10; content:nine; offset:8; content:!fourty; within:28; content:fiftysix; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
static int SigTest69TestNegatedContent(void)
{
return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; depth:10; content:nine; offset:8; content:!fourty; within:48; content:fiftysix; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestNegativeTestContent("alert tcp any any -> any any (content:one; depth:10; content:nine; offset:8; content:!fourty; within:48; content:fiftysix; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
static int SigTest70TestNegatedContent(void)
{
return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; content:!fourty; within:52; distance:45 sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestNegativeTestContent("alert tcp any any -> any any (content:one; content:!fourty; within:52; distance:45 sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
/** \test within and distance */
static int SigTest71TestNegatedContent(void)
{
return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; content:!fourty; within:40; distance:43; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestNegativeTestContent("alert tcp any any -> any any (content:one; content:!fourty; within:40; distance:43; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
static int SigTest72TestNegatedContent(void)
{
return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:one; content:!fourty; within:52; distance:47; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
return SigTestNegativeTestContent("alert tcp any any -> any any (content:one; content:!fourty; within:49; distance:43; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
}
static int SigTest73TestNegatedContent(void)

@ -9,11 +9,12 @@
#define DETECT_CONTENT_DISTANCE_NEXT 0x0010
#define DETECT_CONTENT_WITHIN_NEXT 0x0020
#define DETECT_CONTENT_ISDATAAT_RELATIVE 0x0040
#define DETECT_CONTENT_BYTETEST_NEXT 0x0080
#define DETECT_CONTENT_RAWBYTES 0x0080
#define DETECT_CONTENT_RAWBYTES 0x0100
/** Set if the pattern is split into multiple chunks */
#define DETECT_CONTENT_IS_CHUNK 0x0100
#define DETECT_CONTENT_IS_CHUNK 0x0200
#define DETECT_CONTENT_IS_SINGLE(c) (!((c)->flags & DETECT_CONTENT_DISTANCE || \
(c)->flags & DETECT_CONTENT_WITHIN || \

@ -20,7 +20,7 @@ void DetectDepthRegister (void) {
sigmatch_table[DETECT_DEPTH].flags |= SIGMATCH_PAYLOAD;
}
int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *depthstr)
int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused, char *depthstr)
{
char *str = depthstr;
char dubbed = 0;
@ -36,7 +36,7 @@ int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
SigMatch *pm = DetectContentFindPrevApplicableSM(m);
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_DEPTH_MISSING_CONTENT, "depth needs a preceeding content option");
if (dubbed) SCFree(str);

@ -21,13 +21,11 @@ void DetectDistanceRegister (void) {
sigmatch_table[DETECT_DISTANCE].flags |= SIGMATCH_PAYLOAD;
}
int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *distancestr)
int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused, char *distancestr)
{
char *str = distancestr;
char dubbed = 0;
//printf("DetectDistanceSetup: s->match:%p,m:%p,distancestr:\'%s\'\n", s->match, m, distancestr);
/* strip "'s */
if (distancestr[0] == '\"' && distancestr[strlen(distancestr)-1] == '\"') {
str = SCStrdup(distancestr+1);
@ -35,16 +33,20 @@ int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, cha
dubbed = 1;
}
SigMatch *pm = m;
if (pm == NULL) {
if (s->pmatch == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two preceeding content options");
goto error;
}
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
pm = DetectContentFindPrevApplicableSM(m);
if (pm == NULL || DetectContentHasPrevSMPattern(pm) == NULL) {
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two preceeding content options");
if (dubbed) SCFree(str);
return -1;
}
if (DetectContentHasPrevSMPattern(pm) == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two preceeding content options");
if (dubbed) SCFree(str);
return -1;
@ -60,6 +62,12 @@ int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, cha
cd->distance = strtol(str, NULL, 10);
cd->flags |= DETECT_CONTENT_DISTANCE;
if (cd->flags & DETECT_CONTENT_WITHIN) {
if (cd->distance + cd->content_len > cd->within) {
cd->within = cd->distance + cd->content_len;
}
}
/** Propagate the modifiers through the first chunk
* (SigMatch) if we're dealing with chunks */
if (cd->flags & DETECT_CONTENT_IS_CHUNK)
@ -68,7 +76,7 @@ int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, cha
//DetectContentPrint(cd);
//printf("DetectDistanceSetup: set distance %" PRId32 " for previous content\n", cd->distance);
pm = DetectContentFindPrevApplicableSM(m->prev);
pm = DetectContentFindPrevApplicableSM(s->pmatch_tail->prev);
if (pm == NULL) {
SCLogError(SC_ERR_DISTANCE_MISSING_CONTENT, "distance needs two preceeding content options");
goto error;

@ -120,6 +120,9 @@ uint32_t UriPatternScan(ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
det_ctx->pmq.mode = PMQ_MODE_SCAN;
if (det_ctx->sgh->mpm_uri_ctx == NULL)
SCReturnUInt(0U);
uint32_t ret;
#ifndef __SC_CUDA_SUPPORT__
ret = mpm_table[det_ctx->sgh->mpm_uri_ctx->mpm_type].Scan
@ -133,13 +136,13 @@ uint32_t UriPatternScan(ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
ret = mpm_table[det_ctx->sgh->mpm_uri_ctx->mpm_type].Scan
(det_ctx->sgh->mpm_uri_ctx, &det_ctx->mtcu, &det_ctx->pmq,
uri, uri_len);
SCReturnInt(ret);
SCReturnUInt(ret);
}
SCCudaHlProcessUriWithDispatcher(uri, uri_len, det_ctx, /* scan */ 0, &ret);
#endif
SCReturnInt(ret);
SCReturnUInt(ret);
}
/** \brief Pattern match, search part -- searches for all other patterns
@ -430,7 +433,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
SigMatch *sm;
/* get the total no of patterns in this Signature, as well as find out
* if we have a fast_pattern set in this Signature */
for (sm = s->match; sm != NULL; sm = sm->next) {
for (sm = s->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *co = (DetectContentData *)sm->ctx;
if (co == NULL)
@ -438,6 +441,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
if (co->flags & DETECT_CONTENT_FAST_PATTERN) {
fast_pattern[sig] = 1;
SCLogDebug("sig %"PRIu32" has a fast pattern, id %"PRIu32"", s->id, co->id);
ContentHash *ch = ContentHashAlloc(co);
if (ch == NULL)
@ -463,14 +467,15 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
if (fast_pattern[sig] == 1) {
if (cnt == 1) {
ContentHash *ch = ContentHashAlloc(s->match->ctx);
ContentHash *ch = ContentHashAlloc(s->pmatch->ctx);
ch->nosearch = 1;
ch->use = 1;
SCLogDebug("sig %"PRIu32" has a fast pattern, id %"PRIu32"", s->id, ch->ptr->id);
}
continue;
}
for (sm = s->match; sm != NULL; sm = sm->next) {
for (sm = s->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *co = (DetectContentData *)sm->ctx;
if (co == NULL)
@ -499,7 +504,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
* so flag that we will use this content no matter
* what. */
if (cnt == 1) {
lookup_ch->use = 1;
//lookup_ch->use = 1;
}
/* only set the nosearch flag if all sigs have it
@ -523,17 +528,19 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
continue;
ContentHash *scan_ch = NULL;
SigMatch *sm = s->match;
SigMatch *sm = s->pmatch;
for ( ; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *co = (DetectContentData *)sm->ctx;
if (co == NULL)
continue;
if (fast_pattern[sig] == 1) {
if (!(co->flags & DETECT_CONTENT_FAST_PATTERN))
if (!(co->flags & DETECT_CONTENT_FAST_PATTERN)) {
SCLogDebug("not a fast pattern %"PRIu32"", co->id);
continue;
}
SCLogDebug("fast pattern %"PRIu32"", co->id);
} else if (co->content_len < sgh->mpm_content_maxlen) {
continue;
}
@ -553,7 +560,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
SCLogDebug("scan_ch == NULL, so selecting lookup_ch->ptr->id %"PRIu32"", lookup_ch->ptr->id);
scan_ch = lookup_ch;
} else {
if (lookup_ch->use == 0) {
///if (lookup_ch->use == 0) {
uint32_t ls = PatternStrength(lookup_ch->ptr->content,lookup_ch->ptr->content_len,sgh->mpm_content_maxlen);
uint32_t ss = PatternStrength(scan_ch->ptr->content,scan_ch->ptr->content_len,sgh->mpm_content_maxlen);
if (ls > ss) {
@ -569,6 +576,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
} else {
SCLogDebug("sticking with scan_ch");
}
#if 0
} else {
if (scan_ch->use == 0)
scan_ch = lookup_ch;
@ -588,6 +596,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
}
}
}
#endif
}
ContentHashFree(ch);
@ -612,7 +621,7 @@ static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead
SCLogDebug("%"PRIu32" no scan pattern selected", s->id);
}
/* add the rest of the patterns to the search ctx */
for (sm = s->match ; sm != NULL; sm = sm->next) {
for (sm = s->pmatch ; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *co = (DetectContentData *)sm->ctx;
if (co == NULL)
@ -683,7 +692,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
continue;
/* find flow setting of this rule */
for (sm = s->match; sm != NULL; sm = sm->next) {
for (sm = s->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
co_cnt++;
s->flags |= SIG_FLAG_MPM;
@ -755,7 +764,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
SigMatch *sm;
/* determine the length of the longest pattern */
for (sm = s->match; sm != NULL; sm = sm->next) {
for (sm = s->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
@ -787,7 +796,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
/* determine the min offset and max depth of the longest pattern(s) */
for (sm = s->match; sm != NULL; sm = sm->next) {
for (sm = s->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
//if (content_maxlen < 4) {
@ -812,7 +821,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
int content_depth_atleastone = 0;
int content_offset_atleastone = 0;
/* determine if we have at least one pattern with a depth */
for (sm = s->match; sm != NULL; sm = sm->next) {
for (sm = s->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd->depth) {
@ -867,9 +876,11 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (content_cnt) {
if (sh->mpm_content_maxlen == 0) sh->mpm_content_maxlen = content_maxlen;
if (sh->mpm_content_maxlen > content_maxlen)
if (sh->mpm_content_maxlen > content_maxlen) {
SCLogDebug("sgh (%p) sh->mpm_content_maxlen %u set to %u", sh, sh->mpm_content_maxlen, content_maxlen);
sh->mpm_content_maxlen = content_maxlen;
}
}
if (uricontent_cnt) {
if (sh->mpm_uricontent_maxlen == 0) sh->mpm_uricontent_maxlen = uricontent_maxlen;
if (sh->mpm_uricontent_maxlen > uricontent_maxlen)
@ -897,7 +908,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
uint16_t content_minlen = 0, uricontent_minlen = 0;
/* determine the length of the longest pattern */
for (sm = s->match; sm != NULL; sm = sm->next) {
for (sm = s->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
@ -918,7 +929,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
char uricontent_scanadded = 0;
for (sm = s->match; sm != NULL; sm = sm->next) {
for (sm = s->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_URICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
DetectUricontentData *ud = (DetectUricontentData *)sm->ctx;

@ -0,0 +1,300 @@
#include "suricata-common.h"
#include "suricata.h"
#include "decode.h"
#include "detect.h"
#include "detect-content.h"
#include "detect-uricontent.h"
#include "detect-pcre.h"
#include "detect-isdataat.h"
#include "detect-bytetest.h"
#include "detect-bytejump.h"
#include "detect-http-method.h"
#include "detect-http-cookie.h"
#include "util-spm.h"
#include "util-debug.h"
/** \brief Run the actual payload match functions
*
* \param de_ctx Detection engine context
* \param det_ctx Detection engine thread context
* \param s Signature to inspect
* \param sm SigMatch to inspect
* \param f Flow
* \param flags app layer flags
* \param state App layer state
* \param p Packet
* \param payload ptr to the payload to inspect
* \param payload_len length of the payload
*
* \retval 0 no match
* \retval 1 match
*/
static inline int DoInspectPacketPayload(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, Flow *f,
uint8_t flags, void *alstate, Packet *p, uint8_t *payload,
uint32_t payload_len)
{
SCEnter();
if (sm == NULL) {
SCReturnInt(0);
}
switch(sm->type) {
case DETECT_CONTENT:
{
if (payload_len == 0) {
SCReturnInt(0);
}
DetectContentData *cd = NULL;
cd = (DetectContentData *)sm->ctx;
SCLogDebug("inspecting content %"PRIu32" payload_len %"PRIu32, cd->id, payload_len);
/* rule parsers should take care of this */
BUG_ON(cd->depth != 0 && cd->depth <= cd->offset);
/* search for our pattern, checking the matches recursively.
* if we match we look for the next SigMatch as well */
uint8_t *found = NULL;
do {
uint32_t offset = 0;
uint32_t depth = payload_len;
if (cd->flags & DETECT_CONTENT_DISTANCE ||
cd->flags & DETECT_CONTENT_WITHIN) {
SCLogDebug("det_ctx->pkt_off %"PRIu32, det_ctx->pkt_off);
offset = det_ctx->pkt_off;
depth = payload_len;
if (cd->flags & DETECT_CONTENT_DISTANCE) {
/** \todo distance can be negative */
offset += cd->distance;
SCLogDebug("cd->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32,
cd->distance, offset, depth);
}
if (cd->flags & DETECT_CONTENT_WITHIN) {
if ((int32_t)depth > (int32_t)(det_ctx->pkt_off + cd->within)) {
depth = det_ctx->pkt_off + cd->within;
}
SCLogDebug("cd->within %"PRIi32", det_ctx->pkt_off %"PRIu32", depth %"PRIu32,
cd->within, det_ctx->pkt_off, depth);
}
if (cd->depth != 0) {
if ((cd->depth + det_ctx->pkt_off) < depth) {
depth = det_ctx->pkt_off + cd->depth;
}
SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32, cd->depth, depth);
}
if (cd->offset > offset) {
offset = cd->offset;
SCLogDebug("setting offset %"PRIu32, offset);
}
//PrintRawDataFp(stdout,payload+offset,depth);
} else { /* implied no relative matches */
/* set depth */
if (cd->depth != 0) {
depth = cd->depth;
}
/* set offset */
offset = cd->offset;
//PrintRawDataFp(stdout,payload+offset,depth);
}
//BUG_ON(depth == 0);
SCLogDebug("offset %"PRIu32", depth %"PRIu32, offset, depth);
if (depth > payload_len)
depth = payload_len;
/* if offset is bigger than depth we can never match on a pattern.
* We can however, match on a negated pattern. */
if (offset > depth || depth == 0) {
if (cd->negated == 1) {
goto match;
} else {
SCReturnInt(0);
}
}
//BUG_ON(offset > depth);
uint8_t *spayload = payload + offset;
uint32_t spayload_len = depth - offset;
SCLogDebug("spayload_len %"PRIu32, spayload_len);
BUG_ON(spayload_len > payload_len);
//PrintRawDataFp(stdout,cd->content,cd->content_len);
//PrintRawDataFp(stdout,spayload,spayload_len);
found = BasicSearch(spayload, spayload_len, cd->content, cd->content_len);
SCLogDebug("found %p cd->negated %d", found, cd->negated);
if (found == NULL && cd->negated == 0) {
SCReturnInt(0);
} else if (found == NULL && cd->negated == 1) {
goto match;
} else if (found != NULL && cd->negated == 1) {
uint32_t match_offset = (uint32_t)((found - payload) + cd->content_len);
SCLogDebug("content %"PRIu32" matched at offset %"PRIu32", but negated so no match", cd->id, match_offset);
SCReturnInt(0);
} else {
uint32_t match_offset = (uint32_t)((found - payload) + cd->content_len);
SCLogDebug("content %"PRIu32" matched at offset %"PRIu32"", cd->id, match_offset);
det_ctx->pkt_off = match_offset;
if (cd->flags & DETECT_CONTENT_ISDATAAT_RELATIVE) {
if (det_ctx->pkt_off + cd->isdataat > payload_len) {
SCLogDebug("det_ctx->pkt_off + cd->isdataat %"PRIu32" > %"PRIu32, det_ctx->pkt_off + cd->isdataat, payload_len);
SCReturnInt(0);
} else {
SCLogDebug("relative isdataat match");
}
}
}
SCLogDebug("content %"PRIu32", next? %s", cd->id, sm->next?"true":"false");
goto match;
} while(1);
}
case DETECT_ISDATAAT:
{
SCLogDebug("inspecting isdataat");
DetectIsdataatData *id = (DetectIsdataatData *)sm->ctx;
BUG_ON(id->flags & ISDATAAT_RELATIVE);
if (id->dataat < payload_len) {
SCLogDebug("absolute isdataat match");
goto match;
} else {
SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", payload_len %"PRIu32"", id->dataat,payload_len);
SCReturnInt(0);
}
}
case DETECT_PCRE:
{
SCLogDebug("inspecting pcre");
/** \todo consider ptrs */
int r = DetectPcreDoMatch(det_ctx, p, s, sm);
if (r == 1) {
goto match;
}
SCReturnInt(0);
}
case DETECT_PCRE_HTTPBODY:
{
SCLogDebug("inspecting pcre http body");
int r = DetectPcreALDoMatch(det_ctx, s, sm, f, flags, alstate);
if (r != 1) {
SCReturnInt(0);
}
goto match;
}
case DETECT_AL_HTTP_COOKIE:
{
int r = DetectHttpCookieDoMatch(det_ctx, s, sm, f, flags, alstate);
if (r != 1) {
SCReturnInt(0);
}
goto match;
}
case DETECT_AL_HTTP_METHOD:
{
int r = DetectHttpMethodDoMatch(det_ctx, s, sm, f, flags, alstate);
if (r != 1) {
SCReturnInt(0);
}
goto match;
}
case DETECT_BYTETEST:
{
if (DetectBytetestDoMatch(det_ctx,s,sm,payload,payload_len) != 1) {
SCReturnInt(0);
}
goto match;
}
case DETECT_BYTEJUMP:
{
if (DetectBytejumpDoMatch(det_ctx,s,sm,payload,payload_len) != 1) {
SCReturnInt(0);
}
goto match;
}
/* assume unsupported matches match */
default:
{
SCLogDebug("inspecting default, match assumed");
goto match;
}
}
SCReturnInt(0);
match:
if (sm->next != NULL) {
int r = DoInspectPacketPayload(de_ctx,det_ctx,s,sm->next, f, flags, alstate, p, payload, payload_len);
SCReturnInt(r);
} else {
SCReturnInt(1);
}
}
/** \brief Do the content inspection for a signature
*
* \param de_ctx Detection engine context
* \param det_ctx Detection engine thread context
* \param s Signature to inspect
* \param sm SigMatch to inspect
* \param f Flow
* \param flags app layer flags
* \param state App layer state
* \param p Packet
*
* \retval 0 no match
* \retval 1 match
*/
int DetectEngineInspectPacketPayload(DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx, Signature *s, Flow *f, uint8_t flags,
void *alstate, Packet *p)
{
SCEnter();
int r = 0;
if (s->pmatch == NULL) {
SCReturnInt(0);
}
det_ctx->pkt_off = 0;
r = DoInspectPacketPayload(de_ctx, det_ctx, s, s->pmatch, f, flags, alstate, p, p->payload, p->payload_len);
if (r == 1) {
SCReturnInt(1);
}
SCReturnInt(0);
}

@ -0,0 +1,9 @@
#ifndef __DETECT_ENGINE_PAYLOAD_H__
#define __DETECT_ENGINE_PAYLOAD_H__
int DetectEngineInspectPacketPayload(DetectEngineCtx *,
DetectEngineThreadCtx *, Signature *, Flow *, uint8_t,
void *, Packet *);
#endif /* __DETECT_ENGINE_PAYLOAD_H__ */

@ -428,7 +428,7 @@ uint32_t SigGroupHeadHashFunc(HashListTable *ht, void *data, uint16_t datalen)
uint32_t hash = 0;
uint32_t b = 0;
SCLogDebug("hashing sgh %p", sgh);
SCLogDebug("hashing sgh %p (mpm_content_maxlen %u)", sgh, sgh->mpm_content_maxlen);
for (b = 0; b < sgh->sig_size; b++)
hash += sgh->sig_array[b];
@ -522,10 +522,12 @@ int SigGroupHeadHashRemove(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
*/
SigGroupHead *SigGroupHeadHashLookup(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
{
SCEnter();
SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_hash_table,
(void *)sgh, 0);
return rsgh;
SCReturnPtr(rsgh, "SigGroupHead");
}
/**
@ -598,10 +600,12 @@ int SigGroupHeadDPortHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
SigGroupHead *SigGroupHeadDPortHashLookup(DetectEngineCtx *de_ctx,
SigGroupHead *sgh)
{
SCEnter();
SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_dport_hash_table,
(void *)sgh, 0);
return rsgh;
SCReturnPtr(rsgh,"SigGroupHead");
}
/**
@ -855,6 +859,8 @@ int SigGroupHeadAppendSig(DetectEngineCtx *de_ctx, SigGroupHead **sgh,
if ((*sgh)->mpm_content_maxlen > s->mpm_content_maxlen)
(*sgh)->mpm_content_maxlen = s->mpm_content_maxlen;
SCLogDebug("(%p)->mpm_content_maxlen %u", *sgh, (*sgh)->mpm_content_maxlen);
}
if (s->mpm_uricontent_maxlen > 0) {
if ((*sgh)->mpm_uricontent_maxlen == 0)
@ -1318,16 +1324,20 @@ int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
int SigGroupHeadContainsSigId(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
uint32_t sid)
{
SCEnter();
uint32_t sig = 0;
Signature *s = NULL;
uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx);
if (sgh == NULL)
return 0;
if (sgh == NULL) {
SCReturnInt(0);
}
for (sig = 0; sig < max_sid; sig++) {
if (sgh->sig_array == NULL)
return 0;
if (sgh->sig_array == NULL) {
SCReturnInt(0);
}
/* Check if the SigGroupHead has an entry for the sid */
if ( !(sgh->sig_array[sig / 8] & (1 << (sig % 8))) )
@ -1340,11 +1350,12 @@ int SigGroupHeadContainsSigId(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
continue;
/* If the retrieved Signature matches the sid arg, we have a match */
if (s->id == sid)
return 1;
if (s->id == sid) {
SCReturnInt(1);
}
}
return 0;
SCReturnInt(0);
}
/*----------------------------------Unittests---------------------------------*/

@ -44,7 +44,7 @@ void DetectFastPatternRegister(void)
* \retval 0 On success
* \retval -1 On failure
*/
int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, SigMatch *m,
int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused,
char *null_str)
{
if (null_str != NULL && strcmp(null_str, "") != 0) {
@ -53,23 +53,21 @@ int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, SigMatch *m,
return -1;
}
if (m == NULL) {
if (s->pmatch_tail == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside the "
"rule, without any preceding keywords");
return -1;
}
if (m->type != DETECT_CONTENT) {
m = SigMatchGetLastSM(s, DETECT_CONTENT);
if (m == NULL) {
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside "
"the rule, without a content context. Please use a "
"content keyword before using fast pattern");
return -1;
}
}
((DetectContentData *)m->ctx)->flags |= DETECT_CONTENT_FAST_PATTERN;
((DetectContentData *)pm->ctx)->flags |= DETECT_CONTENT_FAST_PATTERN;
return 0;
}
@ -103,7 +101,7 @@ int DetectFastPatternTest01(void)
goto end;
result = 0;
sm = de_ctx->sig_list->match;
sm = de_ctx->sig_list->pmatch;
while (sm != NULL) {
if (sm->type == DETECT_CONTENT) {
if ( ((DetectContentData *)sm->ctx)->flags &
@ -145,7 +143,7 @@ int DetectFastPatternTest02(void)
goto end;
result = 0;
sm = de_ctx->sig_list->match;
sm = de_ctx->sig_list->pmatch;
while (sm != NULL) {
if (sm->type == DETECT_CONTENT) {
if (((DetectContentData *)sm->ctx)->flags &
@ -186,7 +184,7 @@ int DetectFastPatternTest03(void)
goto end;
result = 0;
sm = de_ctx->sig_list->match;
sm = de_ctx->sig_list->pmatch;
while (sm != NULL) {
if (sm->type == DETECT_CONTENT) {
if ( !(((DetectContentData *)sm->ctx)->flags &
@ -264,8 +262,10 @@ int DetectFastPatternTest05(void)
"content:string2; content:strings3; fast_pattern; "
"content:strings_str4; content:strings_string5; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
if (de_ctx->sig_list == NULL) {
printf("sig parse failed: ");
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);

@ -51,24 +51,8 @@ void DetectHttpCookieRegister (void) {
sigmatch_table[DETECT_AL_HTTP_COOKIE].flags |= SIGMATCH_PAYLOAD;
}
/**
* \brief match the specified content in the signature with the received http
* cookie header in the http request.
*
* \param t pointer to thread vars
* \param det_ctx pointer to the pattern matcher thread
* \param f pointer to the current flow
* \param flags flags to indicate the direction of the received packet
* \param state pointer the app layer state, which will cast into HtpState
* \param s pointer to the current signature
* \param m pointer to the sigmatch that we will cast into DetectContentData
*
* \retval 0 no match
* \retval 1 match
*/
int DetectHttpCookieMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *m)
int DetectHttpCookieDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
SigMatch *sm, Flow *f, uint8_t flags, void *state)
{
SCEnter();
@ -78,7 +62,7 @@ int DetectHttpCookieMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
SCMutexLock(&f->m);
SCLogDebug("got lock %p", &f->m);
DetectHttpCookieData *co = (DetectHttpCookieData *)m->ctx;
DetectHttpCookieData *co = (DetectHttpCookieData *)sm->ctx;
HtpState *htp_state = (HtpState *)state;
if (htp_state == NULL) {
@ -132,6 +116,29 @@ end:
SCReturnInt(ret);
}
/**
* \brief match the specified content in the signature with the received http
* cookie header in the http request.
*
* \param t pointer to thread vars
* \param det_ctx pointer to the pattern matcher thread
* \param f pointer to the current flow
* \param flags flags to indicate the direction of the received packet
* \param state pointer the app layer state, which will cast into HtpState
* \param s pointer to the current signature
* \param m pointer to the sigmatch that we will cast into DetectContentData
*
* \retval 0 no match
* \retval 1 match
*/
int DetectHttpCookieMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state, Signature *s,
SigMatch *m)
{
int r = DetectHttpCookieDoMatch(det_ctx, s, m, f, flags, state);
SCReturnInt(r);
}
/**
* \brief this function setups the http_cookie modifier keyword used in the rule
*
@ -144,7 +151,7 @@ end:
* \retval -1 On failure
*/
int DetectHttpCookieSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m,
int DetectHttpCookieSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused,
char *str)
{
DetectHttpCookieData *hd = NULL;
@ -156,30 +163,28 @@ int DetectHttpCookieSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m,
return -1;
}
if (m == NULL) {
if (s->pmatch_tail == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_cookie found inside the "
"rule, without any preceding content keywords");
return -1;
}
if (m->type != DETECT_CONTENT) {
m = SigMatchGetLastSM(s, DETECT_CONTENT);
if (m == NULL) {
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL) {
SCLogWarning(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside "
"the rule, without a content context. Please use a "
"content keyword before using http_cookie");
return -1;
}
}
/* http_cookie should not be used with the fast_pattern rule */
if (((DetectContentData *) m->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) {
if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_cookie rule can not "
"be used with the fast_pattern rule keyword");
return -1;
/* http_cookie should not be used with the rawbytes rule */
} else if (((DetectContentData *) m->ctx)->flags & DETECT_CONTENT_RAWBYTES) {
} else if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_RAWBYTES) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "http_cookie rule can not "
"be used with the rawbytes rule keyword");
@ -194,19 +199,19 @@ int DetectHttpCookieSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m,
}
memset(hd, 0, sizeof(DetectHttpCookieData));
hd->data_len = ((DetectContentData *)m->ctx)->content_len;
hd->data_len = ((DetectContentData *)pm->ctx)->content_len;
hd->data = SCMalloc(hd->data_len);
if (hd->data == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "SCMalloc failed");
goto error;
}
memcpy(hd->data, ((DetectContentData *)m->ctx)->content, hd->data_len);
memcpy(hd->data, ((DetectContentData *)pm->ctx)->content, hd->data_len);
/* Okay we need to replace the type to HTTP_COOKIE from CONTENT */
SCFree(((DetectContentData *)m->ctx)->content);
SCFree(m->ctx);
m->type = DETECT_AL_HTTP_COOKIE;
m->ctx = (void *)hd;
SCFree(((DetectContentData *)pm->ctx)->content);
SCFree(pm->ctx);
pm->type = DETECT_AL_HTTP_COOKIE;
pm->ctx = (void *)hd;
/* Flagged the signature as to scan the app layer data */
s->flags |=SIG_FLAG_APPLAYER;
@ -299,7 +304,7 @@ int DetectHttpCookieTest03(void)
goto end;
result = 0;
sm = de_ctx->sig_list->match;
sm = de_ctx->sig_list->pmatch;
while (sm != NULL) {
if (sm->type == DETECT_AL_HTTP_COOKIE) {
result = 1;
@ -387,15 +392,17 @@ int DetectHttpCookieTest06(void)
Signature *s = de_ctx->sig_list;
if (s->match->type != DETECT_AL_HTTP_COOKIE)
BUG_ON(s->pmatch == NULL);
if (s->pmatch->type != DETECT_AL_HTTP_COOKIE)
goto end;
if (s->match->next == NULL) {
if (s->pmatch->next == NULL) {
printf("expected another SigMatch, got NULL: ");
goto end;
}
if (s->match->next->type != DETECT_URICONTENT) {
if (s->pmatch->next->type != DETECT_URICONTENT) {
goto end;
}

@ -15,5 +15,8 @@ typedef struct DetectHttpCookieData_ {
/* prototypes */
void DetectHttpCookieRegister (void);
int DetectHttpCookieDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s,
SigMatch *sm, Flow *f, uint8_t flags, void *state);
#endif /* _DETECT_HTTP_COOKIE_H */

@ -53,26 +53,10 @@ void DetectHttpMethodRegister(void) {
SCLogDebug("registering http_method rule option");
}
/**
* \brief match the specified version on a tls session
*
* \param t pointer to thread vars
* \param det_ctx pointer to the pattern matcher thread
* \param f pointer to the current flow
* \param flags flags to indicate the direction of the received packet
* \param state pointer the app layer state, which will cast into HtpState
* \param m pointer to the sigmatch cast into DetectHttpMethodData
*
* \retval 0 no match
* \retval 1 match
*/
int DetectHttpMethodMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state,
Signature *s, SigMatch *m)
{
int DetectHttpMethodDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, Flow *f, uint8_t flags, void *state) {
SCEnter();
uint8_t i;
DetectHttpMethodData *data = (DetectHttpMethodData *)m->ctx;
DetectHttpMethodData *data = (DetectHttpMethodData *)sm->ctx;
HtpState *hs = (HtpState *)state;
htp_tx_t *tx = NULL;
int ret = 0;
@ -117,6 +101,27 @@ int DetectHttpMethodMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
SCReturnInt(ret);
}
/**
* \brief match the specified version on a tls session
*
* \param t pointer to thread vars
* \param det_ctx pointer to the pattern matcher thread
* \param f pointer to the current flow
* \param flags flags to indicate the direction of the received packet
* \param state pointer the app layer state, which will cast into HtpState
* \param m pointer to the sigmatch cast into DetectHttpMethodData
*
* \retval 0 no match
* \retval 1 match
*/
int DetectHttpMethodMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
Flow *f, uint8_t flags, void *state,
Signature *s, SigMatch *sm)
{
int r = DetectHttpMethodDoMatch(det_ctx, s, sm, f, flags, state);
SCReturnInt(r);
}
/**
* \brief this function is used to add the parsed "http_method" option
* \brief into the current signature
@ -130,7 +135,7 @@ int DetectHttpMethodMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
* \retval -1 on Failure
*/
int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s,
SigMatch *m, char *str)
SigMatch *notused, char *str)
{
SCEnter();
DetectHttpMethodData *data = NULL;
@ -143,29 +148,27 @@ int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s,
SCReturnInt(-1);
}
if (m == NULL) {
if (s->pmatch_tail == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE,
"http_method modifier used before any signature match");
SCReturnInt(-1);
}
if (m->type != DETECT_CONTENT) {
m = SigMatchGetLastSM(s, DETECT_CONTENT);
if (m == NULL) {
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE,
"http_method modifies \"content\", but none was found");
SCReturnInt(-1);
}
}
/** \todo snort docs only mention rawbytes, not fast_pattern */
if (((DetectContentData *) m->ctx)->flags & DETECT_CONTENT_FAST_PATTERN)
if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN)
{
SCLogError(SC_ERR_INVALID_SIGNATURE,
"http_method cannot be used with \"fast_pattern\"");
SCReturnInt(-1);
} else if (((DetectContentData *) m->ctx)->flags & DETECT_CONTENT_RAWBYTES)
} else if (((DetectContentData *)pm->ctx)->flags & DETECT_CONTENT_RAWBYTES)
{
SCLogError(SC_ERR_INVALID_SIGNATURE,
"http_method cannot be used with \"rawbytes\"");
@ -180,7 +183,7 @@ int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s,
goto error;
}
data->content_len = ((DetectContentData *)m->ctx)->content_len;
data->content_len = ((DetectContentData *)pm->ctx)->content_len;
data->content = SCMalloc(data->content_len);
if (data->content == NULL) {
// XXX: Should we bother with an error - it may fail too?
@ -188,16 +191,17 @@ int DetectHttpMethodSetup(DetectEngineCtx *de_ctx, Signature *s,
goto error;
}
memcpy(data->content,
((DetectContentData *)m->ctx)->content, data->content_len);
((DetectContentData *)pm->ctx)->content, data->content_len);
method = bstr_memdup((char *)data->content, data->content_len);
/** \todo error check */
data->method = htp_convert_method_to_number(method);
/* Okay we need to replace the type to HTTP_METHOD from CONTENT */
SCFree(((DetectContentData *)m->ctx)->content);
SCFree(m->ctx);
m->type = DETECT_AL_HTTP_METHOD;
m->ctx = (void *)data;
SCFree(((DetectContentData *)pm->ctx)->content);
SCFree(pm->ctx);
pm->type = DETECT_AL_HTTP_METHOD;
pm->ctx = (void *)data;
/* Flagged the signature as to scan the app layer data */
s->flags |=SIG_FLAG_APPLAYER;
@ -244,6 +248,8 @@ int DetectHttpMethodTest01(void)
if (de_ctx->sig_list != NULL) {
result = 1;
} else {
printf("sig parse failed: ");
}
end:

@ -9,6 +9,7 @@ typedef struct DetectHttpMethodData_ {
/* prototypes */
void DetectHttpMethodRegister(void);
int DetectHttpMethodDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *sm, Flow *f, uint8_t flags, void *state);
#endif /* __DETECT_HTTP_METHOD_H__ */

@ -9,6 +9,7 @@
#include "debug.h"
#include "decode.h"
#include "detect.h"
#include "detect-parse.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
@ -208,7 +209,7 @@ error:
* \retval 0 on Success
* \retval -1 on Failure
*/
int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *isdataatstr)
int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused, char *isdataatstr)
{
DetectIsdataatData *idad = NULL;
SigMatch *sm = NULL;
@ -221,15 +222,16 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, cha
/** Set it in the last parsed contet because it is relative to that content match */
SCLogDebug("set it in the last parsed content because it is relative to that content match");
if( m == NULL ) {
if (s->pmatch_tail == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "No previous content, the flag "
"'relative' cant be used without content");
goto error;
} else {
}
SigMatch *pm = NULL;
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
pm = DetectContentFindPrevApplicableSM(m);
pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "Unknown previous keyword!");
return -1;
@ -247,7 +249,6 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, cha
/** Propagate the changes */
DetectContentPropagateIsdataat(pm);
}
}
else {
SCLogDebug("set it as a normal SigMatch");
@ -259,7 +260,7 @@ int DetectIsdataatSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, cha
sm->type = DETECT_ISDATAAT;
sm->ctx = (void *)idad;
SigMatchAppend(s,m,sm);
SigMatchAppendPayload(s,sm);
}
return 0;
@ -350,7 +351,7 @@ int DetectIsdataatTestPacket01 (void) {
char *sigs[5];
sigs[0]= "alert ip any any -> any any (msg:\"Testing window 1\"; isdataat:6; sid:1;)";
sigs[1]= "alert ip any any -> any any (msg:\"Testing window 2\"; content:\"all\"; isdataat:1, relative; isdataat:7; sid:2;)";
sigs[1]= "alert ip any any -> any any (msg:\"Testing window 2\"; content:\"all\"; isdataat:1, relative; isdataat:6; sid:2;)";
sigs[2]= "alert ip any any -> any any (msg:\"Testing window 3\"; isdataat:8; sid:3;)";
sigs[3]= "alert ip any any -> any any (msg:\"Testing window 4\"; content:\"Hi\"; isdataat:5, relative; sid:4;)";
sigs[4]= "alert ip any any -> any any (msg:\"Testing window 4\"; content:\"Hi\"; isdataat:6, relative; sid:5;)";

@ -24,7 +24,7 @@ void DetectNocaseRegister (void) {
sigmatch_table[DETECT_NOCASE].flags |= SIGMATCH_PAYLOAD;
}
int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *nullstr)
int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused, char *nullstr)
{
int ret = 0;
@ -33,8 +33,11 @@ int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
return -1;
}
SigMatch *pm = m;
for (; pm != NULL; pm = pm->prev) {
if (s->pmatch_tail == NULL)
return -1;
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm != NULL) {
if (pm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)pm->ctx;
//printf("DetectNocaseSetup: set nocase for previous content\n");

@ -23,7 +23,7 @@ void DetectOffsetRegister (void) {
sigmatch_table[DETECT_OFFSET].flags |= SIGMATCH_PAYLOAD;
}
int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *offsetstr)
int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused, char *offsetstr)
{
char *str = offsetstr;
char dubbed = 0;
@ -39,7 +39,7 @@ int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
SigMatch *pm = DetectContentFindPrevApplicableSM(m);
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL) {
SCLogError(SC_ERR_OFFSET_MISSING_CONTENT, "offset needs a preceeding content option");
if (dubbed) SCFree(str);

@ -107,6 +107,23 @@ SigTableElmt *SigTableGet(char *name) {
return NULL;
}
void SigMatchAppendPayload(Signature *s, SigMatch *new) {
if (s->pmatch == NULL) {
s->pmatch = new;
s->pmatch_tail = new;
new->next = NULL;
} else {
SigMatch *cur = s->pmatch;
for ( ; cur->next != NULL; cur = cur->next);
cur->next = new;
new->next = NULL;
new->prev = cur;
s->pmatch_tail = new;
}
}
/* Append 'new' SigMatch to the current Signature. If present
* append it to Sigmatch 'm', otherwise place it in the root.
*/
@ -158,7 +175,7 @@ void SigMatchReplace(Signature *s, SigMatch *m, SigMatch *new) {
/**
* \brief Returns a pointer to the last SigMatch instance of a particular type
* in a Signature.
* in a Signature of the payload list.
*
* \param s Pointer to the Signature.
* \param type SigMatch type which has to be searched for in the Signature.
@ -167,7 +184,7 @@ void SigMatchReplace(Signature *s, SigMatch *m, SigMatch *new) {
*/
SigMatch *SigMatchGetLastSM(Signature *s, uint8_t type)
{
SigMatch *sm = s->match;
SigMatch *sm = s->pmatch;
SigMatch *match = NULL;
while (sm != NULL) {
@ -576,6 +593,12 @@ void SigFree(Signature *s) {
sm = nsm;
}
sm = s->pmatch;
while (sm != NULL) {
nsm = sm->next;
SigMatchFree(sm);
sm = nsm;
}
DetectAddressHeadCleanup(&s->src);
DetectAddressHeadCleanup(&s->dst);
@ -621,7 +644,7 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) {
/* see if need to set the SIG_FLAG_MPM flag */
SigMatch *sm;
for (sm = sig->match; sm != NULL; sm = sm->next) {
for (sm = sig->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd == NULL)
@ -648,7 +671,7 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) {
sig->mpm_content_maxlen = 0;
sig->mpm_uricontent_maxlen = 0;
for (sm = sig->match; sm != NULL; sm = sm->next) {
for (sm = sig->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
@ -730,7 +753,7 @@ Signature *SigInitReal(DetectEngineCtx *de_ctx, char *sigstr) {
/* see if need to set the SIG_FLAG_MPM flag */
SigMatch *sm;
for (sm = sig->match; sm != NULL; sm = sm->next) {
for (sm = sig->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd == NULL)
@ -757,7 +780,7 @@ Signature *SigInitReal(DetectEngineCtx *de_ctx, char *sigstr) {
sig->mpm_content_maxlen = 0;
sig->mpm_uricontent_maxlen = 0;
for (sm = sig->match; sm != NULL; sm = sm->next) {
for (sm = sig->pmatch; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)sm->ctx;

@ -26,5 +26,6 @@ void SigParsePrepare(void);
void SigParseRegisterTests(void);
Signature *DetectEngineAppendSig(DetectEngineCtx *, char *);
void SigMatchReplace(Signature *, SigMatch *, SigMatch *);
void SigMatchAppendPayload(Signature *s, SigMatch *);
#endif /* __DETECT_PARSE_H__ */

@ -139,19 +139,7 @@ error:
return;
}
/**
* \brief match the specified pcre at http body, requesting it from htp/L7
*
* \param t pointer to thread vars
* \param det_ctx pointer to the pattern matcher thread
* \param p pointer to the current packet
* \param m pointer to the sigmatch that we will cast into DetectPcreData
*
* \retval int 0 no match; 1 match
*/
int DetectPcreALMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
uint8_t flags, void *state, Signature *s, SigMatch *m)
{
int DetectPcreALDoMatch(DetectEngineThreadCtx *det_ctx, Signature *s, SigMatch *m, Flow *f, uint8_t flags, void *state) {
#define MAX_SUBSTRINGS 30
SCEnter();
int ret = 0;
@ -235,17 +223,23 @@ unlock:
}
/**
* \brief DetectPcreMatch will try to match a regex on a single packet;
* DetectPcreALMatch is used if we parse the option 'P'
* \brief match the specified pcre at http body, requesting it from htp/L7
*
* \param t pointer to the threadvars structure
* \param t pointer to the threadvars structure
* \param t pointer to thread vars
* \param det_ctx pointer to the pattern matcher thread
* \param p pointer to the current packet
* \param m pointer to the sigmatch that we will cast into DetectPcreData
*
* \retval 1: match ; 0 No Match; -1: error
* \retval int 0 no match; 1 match
*/
int DetectPcreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
Signature *s, SigMatch *m)
int DetectPcreALMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
uint8_t flags, void *state, Signature *s, SigMatch *m)
{
int r = DetectPcreALDoMatch(det_ctx, s, m, f, flags, state);
SCReturnInt(r);
}
int DetectPcreDoMatch(DetectEngineThreadCtx *det_ctx, Packet *p, Signature *s, SigMatch *sm) {
SCEnter();
#define MAX_SUBSTRINGS 30
int ret = 0;
@ -256,7 +250,7 @@ int DetectPcreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
if (p->payload_len == 0)
SCReturnInt(0);
DetectPcreData *pe = (DetectPcreData *)m->ctx;
DetectPcreData *pe = (DetectPcreData *)sm->ctx;
/* If we want to inspect the http body, we will use HTP L7 parser */
if (pe->flags & DETECT_PCRE_HTTP_BODY_AL)
@ -297,48 +291,6 @@ int DetectPcreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
const char *str_ptr;
ret = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, 1, &str_ptr);
if (ret) {
if (strcmp(pe->capname,"http_uri") == 0) {
p->http_uri.raw[det_ctx->pkt_cnt] = (uint8_t *)str_ptr;
p->http_uri.raw_size[det_ctx->pkt_cnt] = ret;
p->http_uri.cnt = det_ctx->pkt_cnt + 1;
/* count how many uri's we handle for stats */
det_ctx->uris++;
//printf("DetectPcre: URI det_ctx->sgh %p, det_ctx->mcu %p\n", det_ctx->sgh, det_ctx->mcu);
//PrintRawUriFp(stdout,p->http_uri.raw[det_ctx->pkt_cnt],p->http_uri.raw_size[det_ctx->pkt_cnt]);
//printf(" (pkt_cnt %" PRIu32 ", mcu %p)\n", det_ctx->pkt_cnt, det_ctx->mcu);
#if 0
/* don't bother scanning if we don't have a pattern matcher ctx
* which means we don't have uricontent sigs */
if (det_ctx->sgh->mpm_uri_ctx != NULL) {
if (det_ctx->sgh->mpm_uricontent_maxlen <= p->http_uri.raw_size[det_ctx->pkt_cnt]) {
if (det_ctx->sgh->mpm_uricontent_maxlen == 1) det_ctx->pkts_uri_scanned1++;
else if (det_ctx->sgh->mpm_uricontent_maxlen == 2) det_ctx->pkts_uri_scanned2++;
else if (det_ctx->sgh->mpm_uricontent_maxlen == 3) det_ctx->pkts_uri_scanned3++;
else if (det_ctx->sgh->mpm_uricontent_maxlen == 4) det_ctx->pkts_uri_scanned4++;
else det_ctx->pkts_uri_scanned++;
det_ctx->pmq.mode = PMQ_MODE_SCAN;
ret = mpm_table[det_ctx->sgh->mpm_uri_ctx->mpm_type].Scan(det_ctx->sgh->mpm_uri_ctx, &det_ctx->mtcu, &det_ctx->pmq, p->http_uri.raw[det_ctx->pkt_cnt], p->http_uri.raw_size[det_ctx->pkt_cnt]);
if (ret > 0) {
if (det_ctx->sgh->mpm_uricontent_maxlen == 1) det_ctx->pkts_uri_searched1++;
else if (det_ctx->sgh->mpm_uricontent_maxlen == 2) det_ctx->pkts_uri_searched2++;
else if (det_ctx->sgh->mpm_uricontent_maxlen == 3) det_ctx->pkts_uri_searched3++;
else if (det_ctx->sgh->mpm_uricontent_maxlen == 4) det_ctx->pkts_uri_searched4++;
else det_ctx->pkts_uri_searched++;
det_ctx->pmq.mode = PMQ_MODE_SEARCH;
ret += mpm_table[det_ctx->sgh->mpm_uri_ctx->mpm_type].Search(det_ctx->sgh->mpm_uri_ctx, &det_ctx->mtcu, &det_ctx->pmq, p->http_uri.raw[det_ctx->pkt_cnt], p->http_uri.raw_size[det_ctx->pkt_cnt]);
/* indicate to uricontent that we have a uri,
* we scanned it _AND_ we found pattern matches. */
det_ctx->de_have_httpuri = TRUE;
}
}
}
#endif
} else {
if (pe->flags & DETECT_PCRE_CAPTURE_PKT) {
PktVarAdd(p, pe->capname, (uint8_t *)str_ptr, ret);
} else if (pe->flags & DETECT_PCRE_CAPTURE_FLOW) {
@ -346,7 +298,6 @@ int DetectPcreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
}
}
}
}
/* update ptrs for pcre RELATIVE */
det_ctx->pkt_ptr = ptr+ov[1];
det_ctx->pkt_off = (ptr+ov[1]) - p->payload;
@ -359,10 +310,25 @@ int DetectPcreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
SCLogDebug("pcre had matching error");
ret = 0;
}
SCReturnInt(ret);
}
/**
* \brief DetectPcreMatch will try to match a regex on a single packet;
* DetectPcreALMatch is used if we parse the option 'P'
*
* \param t pointer to the threadvars structure
* \param t pointer to the threadvars structure
*
* \retval 1: match ; 0 No Match; -1: error
*/
int DetectPcreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Packet *p,
Signature *s, SigMatch *sm)
{
SCEnter();
SCReturnInt(DetectPcreDoMatch(det_ctx,p,s,sm));
}
DetectPcreData *DetectPcreParse (char *regexstr)
{
const char *eb;
@ -591,7 +557,7 @@ error:
}
int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *regexstr)
int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused, char *regexstr)
{
DetectPcreData *pd = NULL;
SigMatch *sm = NULL;
@ -617,7 +583,7 @@ int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *r
pcre_need_htp_request_body = 1;
}
SigMatchAppend(s,m,sm);
SigMatchAppendPayload(s,sm);
return 0;

@ -37,6 +37,8 @@ typedef struct DetectPcreData_ {
} DetectPcreData;
/* prototypes */
int DetectPcreDoMatch(DetectEngineThreadCtx *, Packet *, Signature *, SigMatch *);
int DetectPcreALDoMatch(DetectEngineThreadCtx *, Signature *, SigMatch *, Flow *, uint8_t, void *);
void DetectPcreRegister (void);
#endif /* __DETECT_PCRE_H__ */

@ -26,30 +26,20 @@ void DetectRawbytesRegister (void) {
int DetectRawbytesSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *nullstr)
{
//printf("DetectRawbytesSetup: s->match:%p,m:%p\n", s->match, m);
if (nullstr != NULL) {
SCLogError(SC_ERR_INVALID_VALUE, "nocase has no value");
return -1;
}
SigMatch *pm = m;
if (s->pmatch_tail == NULL)
return -1;
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm != NULL) {
#if 0
if (pm->type == DETECT_PCRE) {
DetectPcreData *pe = (DetectPcreData *)pm->ctx;
printf("DetectRawbytesSetup: set depth %" PRIu32 " for previous pcre\n", pe->depth);
} else
#endif
if (pm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)pm->ctx;
//printf("DetectRawbytesSetup: set nocase for previous content\n");
cd->flags |= DETECT_CONTENT_RAWBYTES;
} else {
SCLogDebug("Unknown previous keyword!");
}
} else {
SCLogDebug("No previous match!");
}
return 0;

@ -282,8 +282,16 @@ error:
* \param rd pointer to DetectRpcData
*/
void DetectRpcFree(void *ptr) {
SCEnter();
if (ptr == NULL) {
SCReturn;
}
DetectRpcData *rd = (DetectRpcData *)ptr;
SCFree(rd);
SCReturn;
}
#ifdef UNITTESTS
@ -527,19 +535,19 @@ static int DetectRpcTestSig01(void) {
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (PacketAlertCheck(&p, 1) == 0) {
SCLogDebug("sid 1 didnt alert, but it should have.");
printf("sid 1 didnt alert, but it should have: ");
goto cleanup;
} else if (PacketAlertCheck(&p, 2) == 0) {
SCLogDebug("sid 2 didnt alert, but it should have.");
printf("sid 2 didnt alert, but it should have: ");
goto cleanup;
} else if (PacketAlertCheck(&p, 3) == 0) {
SCLogDebug("sid 3 didnt alert, but it should have.");
printf("sid 3 didnt alert, but it should have: ");
goto cleanup;
} else if (PacketAlertCheck(&p, 4) == 0) {
SCLogDebug("sid 4 didnt alert, but it should have.");
printf("sid 4 didnt alert, but it should have: ");
goto cleanup;
} else if (PacketAlertCheck(&p, 5) > 0) {
SCLogDebug("sid 5 did alert, but should not.");
printf("sid 5 did alert, but should not: ");
goto cleanup;
}

@ -415,7 +415,7 @@ error:
*
* \retval 0 on success, -1 on failure
*/
int DetectUricontentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m,
int DetectUricontentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused,
char *contentstr)
{
SCEnter();
@ -434,7 +434,7 @@ int DetectUricontentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m,
sm->type = DETECT_URICONTENT;
sm->ctx = (void *)cd;
SigMatchAppend(s,m,sm);
SigMatchAppendPayload(s,sm);
cd->id = de_ctx->uricontent_max_id;
de_ctx->uricontent_max_id++;
@ -874,7 +874,9 @@ int DetectUriSigTest01(void)
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
sm = de_ctx->sig_list->match;
BUG_ON(de_ctx->sig_list == NULL);
sm = de_ctx->sig_list->pmatch;
if (sm->type == DETECT_URICONTENT) {
result = 1;
} else {

@ -25,13 +25,11 @@ void DetectWithinRegister (void) {
sigmatch_table[DETECT_WITHIN].flags |= SIGMATCH_PAYLOAD;
}
int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *withinstr)
int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *notused, char *withinstr)
{
char *str = withinstr;
char dubbed = 0;
//printf("DetectWithinSetup: s->match:%p,m:%p,withinstr:\'%s\'\n", s->match, m, withinstr);
/* strip "'s */
if (withinstr[0] == '\"' && withinstr[strlen(withinstr)-1] == '\"') {
str = SCStrdup(withinstr+1);
@ -39,15 +37,14 @@ int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
dubbed = 1;
}
SigMatch *pm = m;
if (pm == NULL) {
if (s->pmatch == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two preceeding content options");
goto error;
}
/** Search for the first previous DetectContent
* SigMatch (it can be the same as this one) */
pm = DetectContentFindPrevApplicableSM(m);
SigMatch *pm = DetectContentFindPrevApplicableSM(s->pmatch_tail);
if (pm == NULL || DetectContentHasPrevSMPattern(pm) == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two preceeding content options");
goto error;
@ -62,6 +59,12 @@ int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
cd->within = strtol(str, NULL, 10);
cd->flags |= DETECT_CONTENT_WITHIN;
if (cd->flags & DETECT_CONTENT_DISTANCE) {
if (cd->distance > (cd->content_len + cd->within)) {
cd->within = cd->distance + cd->content_len;
}
}
/** Propagate the modifiers through the first chunk
* (SigMatch) if we're dealing with chunks */
if (cd->flags & DETECT_CONTENT_IS_CHUNK)
@ -70,7 +73,7 @@ int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
//DetectContentPrint(cd);
//printf("DetectWithinSetup: set within %" PRId32 " for previous content\n", cd->within);
pm = DetectContentFindPrevApplicableSM(m->prev);
pm = DetectContentFindPrevApplicableSM(s->pmatch_tail->prev);
if (pm == NULL) {
SCLogError(SC_ERR_WITHIN_MISSING_CONTENT, "within needs two preceeding content options");
goto error;

@ -17,6 +17,8 @@
#include "detect-engine-mpm.h"
#include "detect-engine-iponly.h"
#include "detect-engine-threshold.h"
#include "detect-engine-payload.h"
#include "detect-http-cookie.h"
#include "detect-http-method.h"
@ -194,6 +196,8 @@ void DetectExitPrintStats(ThreadVars *tv, void *data) {
det_ctx->pkts_uri_searched,
(float)(det_ctx->pkts_uri_searched/(float)(det_ctx->uris)*100),
(float)(det_ctx->pkts_uri_searched/(float)(det_ctx->pkts_uri_scanned)*100));
SCLogInfo("%"PRIu64" sigs per scan match on avg needed inspection, total scans %"PRIu64", less than 25 sigs need inspect %"PRIu64", more than 100 sigs need inspect %"PRIu64", more than 1000 %"PRIu64" max %"PRIu64"", det_ctx->scans_sigs / det_ctx->scans_match, det_ctx->scans_match, det_ctx->scans_sigsmin25, det_ctx->scans_sigsplus100, det_ctx->scans_sigsplus1000, det_ctx->scans_sigsmax);
}
/** \brief Create the path if default-rule-path was specified
@ -562,10 +566,25 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
else if (det_ctx->sgh->mpm_content_maxlen == 4) det_ctx->pkts_scanned4++;
else det_ctx->pkts_scanned++;
cnt += PacketPatternScan(th_v, det_ctx, p);
cnt = PacketPatternScan(th_v, det_ctx, p);
if (cnt > 0) {
det_ctx->scans_match++;
det_ctx->scans_sigs += det_ctx->pmq.sig_id_array_cnt;
if (det_ctx->pmq.sig_id_array_cnt < 25) {
det_ctx->scans_sigsmin25++;
} else if (det_ctx->pmq.sig_id_array_cnt > 1000) {
det_ctx->scans_sigsplus1000++;
} else if (det_ctx->pmq.sig_id_array_cnt > 100) {
det_ctx->scans_sigsplus100++;
}
if (det_ctx->pmq.sig_id_array_cnt > det_ctx->scans_sigsmax)
det_ctx->scans_sigsmax = det_ctx->pmq.sig_id_array_cnt;
}
//if (cnt != det_ctx->pmq.searchable)
SCLogDebug("post scan: cnt %" PRIu32 ", searchable %" PRIu32 "", cnt, det_ctx->pmq.searchable);
SCLogDebug("post scan: cnt %" PRIu32 ", searchable %" PRIu32 ", sigs %"PRIu32" (out of %"PRIu32")", cnt, det_ctx->pmq.searchable, det_ctx->pmq.sig_id_array_cnt, det_ctx->sgh->sig_cnt);
#if 0
if (det_ctx->pmq.searchable > 0) {
//printf("now search\n");
if (det_ctx->sgh->mpm_content_maxlen == 1) det_ctx->pkts_searched1++;
@ -578,6 +597,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
// printf("RAW: cnt %" PRIu32 ", det_ctx->pmq.sig_id_array_cnt %" PRIu32 "\n", cnt, det_ctx->pmq.sig_id_array_cnt);
}
#endif
det_ctx->pmq.searchable = 0;
}
}
@ -660,6 +680,12 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
}
/** we can't check the mpm flags if we do app layer inspection here as well */
//if (s->flags & SIG_FLAG_MPM) {
if (s->pmatch != NULL && DetectEngineInspectPacketPayload(de_ctx, det_ctx, s, p->flow, flags, alstate, p) != 1)
continue;
//}
/* if we get here but have no sigmatches to match against,
* we consider the sig matched. */
if (s->match == NULL) {
@ -879,6 +905,9 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) {
}
}
if (s->pmatch != NULL)
return 0;
SigMatch *sm = s->match;
if (sm == NULL)
goto iponly;
@ -905,7 +934,11 @@ iponly:
*/
static int SignatureIsInspectingPayload(DetectEngineCtx *de_ctx, Signature *s) {
SigMatch *sm = s->match;
if (s->pmatch != NULL) {
return 1;
}
#if 0
SigMatch *sm = s->pmatch;
if (sm == NULL)
return 0;
@ -916,7 +949,7 @@ static int SignatureIsInspectingPayload(DetectEngineCtx *de_ctx, Signature *s) {
return 1;
}
}
#endif
return 0;
}
@ -2175,7 +2208,8 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De
} else {
/* XXX write dedicated function for this */
dp->sh->mpm_ctx = mpmsh->mpm_ctx;
dp->sh->mpm_content_maxlen = mpmsh->mpm_content_maxlen;
//SCLogDebug("replacing dp->sh, so setting mpm_content_maxlen to %u", mpmsh->mpm_content_maxlen);
//dp->sh->mpm_content_maxlen = mpmsh->mpm_content_maxlen;
dp->sh->flags |= SIG_GROUP_HEAD_MPM_COPY;
SigGroupHeadClearContent(dp->sh);
@ -2411,6 +2445,8 @@ error:
}
int SigAddressCleanupStage1(DetectEngineCtx *de_ctx) {
BUG_ON(de_ctx == NULL);
if (!(de_ctx->flags & DE_QUIET)) {
SCLogInfo("cleaning up signature grouping structure...");
}
@ -3019,7 +3055,7 @@ static int SigTest01Real (int mpm_type) {
result = 0;
goto end;
}
#if 0
//printf("URI0 \"%s\", len %" PRIu32 "\n", p.http_uri.raw[0], p.http_uri.raw_size[0]);
//printf("URI1 \"%s\", len %" PRIu32 "\n", p.http_uri.raw[1], p.http_uri.raw_size[1]);
@ -3031,6 +3067,8 @@ static int SigTest01Real (int mpm_type) {
result = 1;
}
#endif
result = 1;
end:
if (p != NULL)
UTHFreePacket(p);
@ -3214,7 +3252,7 @@ static int SigTest05Real (int mpm_type) {
uint16_t buflen = strlen((char *)buf);
Packet p;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
@ -3235,17 +3273,19 @@ static int SigTest05Real (int mpm_type) {
de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP TEST\"; content:\"Host:\"; offset:20; depth:25; content:\"Host:\"; distance:48; within:52; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 0;
printf("sig parse failed: ");
goto end;
}
SigGroupBuild(de_ctx);
//PatternMatchPrepare(mpm_ctx, mpm_type);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
if (!PacketAlertCheck(&p, 1))
if (!PacketAlertCheck(&p, 1)) {
result = 1;
} else {
printf("sig matched but shouldn't have: ");
}
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
@ -6246,17 +6286,16 @@ int SigTest38Real(int mpm_type)
0x00, 0x22, 0xaa, 0x10
};
uint8_t buf[] = {
0x00, 0x00, 0x00, 0x08, 0x62, 0x6f, 0x6f,
0x65, 0x65, 0x6b, 0x0d, 0x0a, 0x4c, 0x45,
0x4e, 0x31, 0x20, 0x38, 0x0d, 0x0a, 0x66,
0x6f, 0x6f, 0x62, 0x61, 0x72, 0x0d, 0x0a,
0x4c, 0x45, 0x4e, 0x32, 0x20, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x0d, 0x0a, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x0d, 0x0a, 0x0d,
0x0a, 0x0d, 0x0a
0x00, 0x00, 0x00, 0x08, 0x62, 0x6f, 0x6f, 0x65,
0x65, 0x6b, 0x0d, 0x0a, 0x4c, 0x45, 0x4e, 0x31,
0x20, 0x38, 0x0d, 0x0a, 0x66, 0x6f, 0x30, 0x30, /* LEN1|20| ends at 17 */
0x30, 0x38, 0x0d, 0x0a, 0x4c, 0x45, 0x4e, 0x32, /* "0008" at offset 5 */
0x20, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x0d, 0x0a, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d,
0x0a
};
uint16_t ethlen = sizeof(raw_eth);
uint16_t ipv4len = sizeof(raw_ipv4);
@ -6277,7 +6316,6 @@ int SigTest38Real(int mpm_type)
p1.ethh = (EthernetHdr *)raw_eth;
p1.ip4h = (IPV4Hdr *)raw_ipv4;
p1.tcph = (TCPHdr *)raw_tcp;
//p1.tcpvars.hlen = TCP_GET_HLEN((&p));
p1.tcpvars.hlen = 0;
p1.src.family = AF_INET;
p1.dst.family = AF_INET;
@ -6313,7 +6351,6 @@ int SigTest38Real(int mpm_type)
}
SigGroupBuild(de_ctx);
//PatternMatchPrepare(mpm_ctx, mpm_type);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p1);
@ -6337,7 +6374,6 @@ cleanup:
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
//PatternMatchDestroy(mpm_ctx);
DetectEngineCtxFree(de_ctx);
end:
@ -6377,17 +6413,16 @@ int SigTest39Real(int mpm_type)
0x00, 0x22, 0xaa, 0x10
};
uint8_t buf[] = {
0x00, 0x00, 0x00, 0x08, 0x62, 0x6f, 0x6f,
0x65, 0x65, 0x6b, 0x0d, 0x0a, 0x4c, 0x45,
0x4e, 0x31, 0x20, 0x38, 0x0d, 0x0a, 0x66,
0x6f, 0x6f, 0x62, 0x61, 0x72, 0x0d, 0x0a,
0x4c, 0x45, 0x4e, 0x32, 0x20, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x0d, 0x0a, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x0d, 0x0a, 0x0d,
0x0a, 0x0d, 0x0a
0x00, 0x00, 0x00, 0x08, 0x62, 0x6f, 0x6f, 0x65,
0x65, 0x6b, 0x0d, 0x0a, 0x4c, 0x45, 0x4e, 0x31,
0x20, 0x38, 0x0d, 0x0a, 0x66, 0x30, 0x30, 0x30,
0x38, 0x72, 0x0d, 0x0a, 0x4c, 0x45, 0x4e, 0x32,
0x20, 0x39, 0x39, 0x4c, 0x45, 0x4e, 0x32, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
0x39, 0x39, 0x39, 0x0d, 0x0a, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d,
0x0a
};
uint16_t ethlen = sizeof(raw_eth);
uint16_t ipv4len = sizeof(raw_ipv4);
@ -6408,7 +6443,6 @@ int SigTest39Real(int mpm_type)
p1.ethh = (EthernetHdr *)raw_eth;
p1.ip4h = (IPV4Hdr *)raw_ipv4;
p1.tcph = (TCPHdr *)raw_tcp;
//p1.tcpvars.hlen = TCP_GET_HLEN((&p));
p1.tcpvars.hlen = 0;
p1.src.family = AF_INET;
p1.dst.family = AF_INET;
@ -6449,7 +6483,6 @@ int SigTest39Real(int mpm_type)
}
SigGroupBuild(de_ctx);
//PatternMatchPrepare(mpm_ctx, mpm_type);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p1);
@ -6473,7 +6506,6 @@ cleanup:
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
//PatternMatchDestroy(mpm_ctx);
DetectEngineCtxFree(de_ctx);
end:
@ -6668,14 +6700,28 @@ int SigTest37ContentAndIsdataatKeywords02Real (int mpm_type) {
de_ctx->mpm_matcher = mpm_type;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest36ContentAndIsdataatKeywords01 \"; content:\"HTTP\"; isdataat:500, relative; sid:101;)");
Signature *s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"SigTest37ContentAndIsdataatKeywords01 \"; content:\"HTTP\"; isdataat:500, relative; sid:101;)");
if (de_ctx->sig_list == NULL) {
printf("sig parse failed: ");
result = 0;
goto end;
}
if (s->pmatch->type != DETECT_CONTENT) {
printf("type not content: ");
goto end;
}
/*
if (s->pmatch->next == NULL) {
printf("s->pmatch->next == NULL: ");
goto end;
}
if (s->pmatch->next->type != DETECT_ISDATAAT) {
printf("type not isdataat: ");
goto end;
}
*/
SigGroupBuild(de_ctx);
//PatternMatchPrepare(mpm_ctx, mpm_type);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, &p);
@ -6683,6 +6729,7 @@ int SigTest37ContentAndIsdataatKeywords02Real (int mpm_type) {
result = 1;
goto end;
} else {
printf("sig matched, but should not have: ");
result=0;
}
@ -6690,7 +6737,6 @@ int SigTest37ContentAndIsdataatKeywords02Real (int mpm_type) {
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
//PatternMatchDestroy(mpm_ctx);
DetectEngineCtxFree(de_ctx);
FlowShutdown();
@ -6706,8 +6752,6 @@ end:
if(det_ctx)
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
//PatternMatchDestroy(mpm_ctx);
if(de_ctx)
DetectEngineCtxFree(de_ctx);
@ -6843,8 +6887,8 @@ int SigTest40NoPayloadInspection02(void) {
goto end;
}
sigmatch_table[DETECT_CONTENT].flags |= SIGMATCH_PAYLOAD;
de_ctx->sig_list->match->type = DETECT_CONTENT;
// sigmatch_table[DETECT_CONTENT].flags |= SIGMATCH_PAYLOAD;
// de_ctx->sig_list->pmatch->type = DETECT_CONTENT;
SigGroupBuild(de_ctx);
//PatternMatchPrepare(mpm_ctx,MPM_B2G);
@ -7045,6 +7089,10 @@ static int SigTestSgh01 (void) {
printf("internal id != 0: ");
goto end;
}
if (de_ctx->sig_list->mpm_content_maxlen != 3) {
printf("de_ctx->sig_list->mpm_content_maxlen %u, expected 3: ", de_ctx->sig_list->mpm_content_maxlen);
goto end;
}
de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any 81 (msg:\"2\"; content:\"two\"; content:\"abcd\"; sid:2;)");
if (de_ctx->sig_list->next == NULL) {
@ -7055,6 +7103,11 @@ static int SigTestSgh01 (void) {
printf("internal id != 1: ");
goto end;
}
if (de_ctx->sig_list->next->mpm_content_maxlen != 4) {
printf("de_ctx->sig_list->mpm_content_maxlen %u, expected 4: ", de_ctx->sig_list->next->mpm_content_maxlen);
goto end;
}
de_ctx->sig_list->next->next = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"3\"; content:\"three\"; sid:3;)");
if (de_ctx->sig_list->next->next == NULL) {
result = 0;
@ -7064,6 +7117,10 @@ static int SigTestSgh01 (void) {
printf("internal id != 2: ");
goto end;
}
if (de_ctx->sig_list->next->next->mpm_content_maxlen != 5) {
printf("de_ctx->sig_list->next->next->mpm_content_maxlen %u, expected 5: ", de_ctx->sig_list->next->next->mpm_content_maxlen);
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
@ -7079,7 +7136,6 @@ static int SigTestSgh01 (void) {
printf("sgh->mpm_uricontent_maxlen %u\n", sgh->mpm_uricontent_maxlen);
printf("sgh->sig_cnt %u\n", sgh->sig_cnt);
printf("sgh->sig_size %u\n", sgh->sig_size);
printf("sgh->refcnt %u\n", sgh->refcnt);
#endif
if (sgh->mpm_content_maxlen != 3) {
printf("sgh->mpm_content_maxlen %u, expected 3: ", sgh->mpm_content_maxlen);
@ -7102,26 +7158,41 @@ static int SigTestSgh01 (void) {
p.dp = 81;
sgh = SigMatchSignaturesGetSgh(&th_v, de_ctx, det_ctx, &p);
if (sgh == NULL) {
printf("no sgh: ");
SigGroupHead *sgh2 = SigMatchSignaturesGetSgh(&th_v, de_ctx, det_ctx, &p);
if (sgh2 == NULL) {
printf("no sgh2: ");
goto end;
}
#if 0
if (!(SigGroupHeadContainsSigId(de_ctx, sgh2, 1))) {
printf("sgh2 doesn't have sid 1: ");
goto end;
}
#endif
if (sgh2->sig_cnt != 1) {
printf("expected one sig, got %u in sgh2: ", sgh2->sig_cnt);
goto end;
}
if (sgh2->match_array[0] != 1) {
printf("sgh doesn't contain sid 2, should have (sgh2->match_array[0] %u, expected 0): ", sgh2->match_array[0]);
goto end;
}
#if 0
printf("-\n");
printf("sgh->mpm_content_maxlen %u\n", sgh->mpm_content_maxlen);
printf("sgh->mpm_uricontent_maxlen %u\n", sgh->mpm_uricontent_maxlen);
printf("sgh->sig_cnt %u\n", sgh->sig_cnt);
printf("sgh->sig_size %u\n", sgh->sig_size);
printf("sgh->refcnt %u\n", sgh->refcnt);
printf("sgh2->mpm_content_maxlen %u\n", sgh2->mpm_content_maxlen);
printf("sgh2->mpm_uricontent_maxlen %u\n", sgh2->mpm_uricontent_maxlen);
printf("sgh2->sig_cnt %u\n", sgh2->sig_cnt);
printf("sgh2->sig_size %u\n", sgh2->sig_size);
#endif
if (sgh->mpm_content_maxlen != 4) {
printf("sgh->mpm_content_maxlen %u, expected 4: ", sgh->mpm_content_maxlen);
if (sgh2->mpm_content_maxlen != 4) {
printf("sgh2->mpm_content_maxlen %u, expected 4: ", sgh2->mpm_content_maxlen);
goto end;
}
if (sgh->match_array[0] != 1) {
printf("sgh doesn't contain sid 2, should have: ");
if (sgh2->match_array[0] != 1) {
printf("sgh2 doesn't contain sid 2, should have: ");
goto end;
}
@ -7976,12 +8047,13 @@ static int SigTestContent04Wm (void) {
return SigTestContent04Real(MPM_WUMANBER);
}
/** \test sigs with patterns at the limit of the pm's size limit */
static int SigTestContent05Real (int mpm_type) {
uint8_t *buf = (uint8_t *)"01234567890123456789012345678901abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
uint16_t buflen = strlen((char *)buf);
Packet p;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
@ -7994,6 +8066,7 @@ static int SigTestContent05Real (int mpm_type) {
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
printf("de_ctx == NULL: ");
goto end;
}
@ -8002,10 +8075,12 @@ static int SigTestContent05Real (int mpm_type) {
de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 32\"; content:\"01234567890123456789012345678901\"; content:\"abcdefghijklmnopqrstuvwxyzABCDEF\"; distance:0; within:31; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("sig1 parse failed: ");
goto end;
}
de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"Test 32\"; content:\"01234567890123456789012345678901\"; content:\"abcdefghijklmnopqrstuvwxyzABCDEF\"; distance:1; within:33; sid:2;)");
if (de_ctx->sig_list->next == NULL) {
printf("sig2 parse failed: ");
goto end;
}
@ -8029,8 +8104,12 @@ end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
}
if (de_ctx != NULL) {
DetectEngineCtxFree(de_ctx);
}
return result;
}
static int SigTestContent05B2g (void) {

@ -169,7 +169,9 @@ typedef struct Signature_ {
DetectPort *sp, *dp;
/** ptr to the SigMatch list */
struct SigMatch_ *match;
struct SigMatch_ *match; /* non-payload matches */
struct SigMatch_ *pmatch; /* payload matches */
struct SigMatch_ *pmatch_tail; /* payload matches */
/** ptr to the next sig in the list */
struct Signature_ *next;
@ -344,8 +346,9 @@ enum {
*/
typedef struct DetectionEngineThreadCtx_ {
/* detection engine variables */
/** \todo rename & comment */
uint8_t *pkt_ptr; /* ptr to the current position in the pkt */
uint16_t pkt_off;
uint32_t pkt_off;
uint8_t pkt_cnt;
char de_checking_distancewithin;
@ -399,6 +402,13 @@ typedef struct DetectionEngineThreadCtx_ {
* thread can dump the packets once it has processed them */
Tmq *cuda_mpm_rc_disp_outq;
#endif
uint64_t scans_match;
uint64_t scans_sigs;
uint64_t scans_sigsmin25;
uint64_t scans_sigsplus100;
uint64_t scans_sigsplus1000;
uint64_t scans_sigsmax;
} DetectEngineThreadCtx;
/** \brief a single match condition for a signature */

@ -77,6 +77,7 @@ const char * SCErrorToString(SCError err)
CASE_CODE (SC_ERR_RULE_KEYWORD_UNKNOWN);
CASE_CODE (SC_ERR_FLAGS_MODIFIER);
CASE_CODE (SC_ERR_DISTANCE_MISSING_CONTENT);
CASE_CODE (SC_ERR_BYTETEST_MISSING_CONTENT);
CASE_CODE (SC_ERR_WITHIN_MISSING_CONTENT);
CASE_CODE (SC_ERR_DEPTH_MISSING_CONTENT);
CASE_CODE (SC_ERR_OFFSET_MISSING_CONTENT);

@ -103,6 +103,7 @@ typedef enum {
SC_ERR_WITHIN_MISSING_CONTENT,
SC_ERR_OFFSET_MISSING_CONTENT,
SC_ERR_DEPTH_MISSING_CONTENT,
SC_ERR_BYTETEST_MISSING_CONTENT,
SC_ERR_NO_URICONTENT_NEGATION,
SC_ERR_HASH_TABLE_INIT,
SC_ERR_STAT,

@ -126,6 +126,11 @@ static inline void B2gEndMatchAppend(MpmCtx *mpm_ctx, B2gPattern *p,
m = m->next;
SCLogDebug("m %p m->sig_id %"PRIu32"", m, m->sig_id);
}
p->em_len++;
if (p->flags & B2G_SCAN) {
//BUG_ON(p->em_len > 500);
}
}
#ifdef PRINTMATCH
@ -389,6 +394,7 @@ static inline int B2gAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
if (mpm_ctx->search_minlen == 0) mpm_ctx->search_minlen = patlen;
else if (mpm_ctx->search_minlen > patlen) mpm_ctx->search_minlen = patlen;
}
#if 0
} else {
/* if we're reusing a pattern, check we need to check that it is a
* scan pattern if that is what we're adding. If so we set the pattern
@ -405,6 +411,7 @@ static inline int B2gAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
if (mpm_ctx->scan_minlen == 0) mpm_ctx->scan_minlen = patlen;
else if (mpm_ctx->scan_minlen > patlen) mpm_ctx->scan_minlen = patlen;
}
#endif
}
/* we need a match */
@ -433,13 +440,15 @@ int B2gAddScanPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
int B2gAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
uint16_t offset, uint16_t depth, uint32_t pid, uint32_t sid)
{
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */0, pid, sid, 0);
return 0;
// return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */1, /* scan */0, pid, sid, 0);
}
int B2gAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
uint16_t offset, uint16_t depth, uint32_t pid, uint32_t sid)
{
return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */0, pid, sid, 0);
return 0;
// return B2gAddPattern(mpm_ctx, pat, patlen, offset, depth, /* nocase */0, /* scan */0, pid, sid, 0);
}
static inline uint32_t B2gBloomHash(void *data, uint16_t datalen, uint8_t iter, uint32_t hash_size) {
@ -493,6 +502,8 @@ static void B2gPrepareScanHash(MpmCtx *mpm_ctx) {
if (!(ctx->parray[i]->flags & B2G_SCAN))
continue;
//BUG_ON(ctx->parray[i]->em_len > 500);
if(ctx->parray[i]->len == 1) {
idx8 = (uint8_t)ctx->parray[i]->ci[0];
if (ctx->scan_hash1[idx8].flags == 0) {
@ -1889,14 +1900,14 @@ static int B2gTestInit01 (void) {
MpmInitCtx(&mpm_ctx, MPM_B2G, -1);
B2gCtx *ctx = (B2gCtx *)mpm_ctx.ctx;
B2gAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0); /* 1 match */
B2gAddScanPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); /* 1 match */
B2gPreparePatterns(&mpm_ctx);
if (ctx->search_m == 4)
if (ctx->scan_m == 4)
result = 1;
else
printf("4 != %" PRIu32 " ", ctx->search_m);
printf("4 != %" PRIu32 " ", ctx->scan_m);
B2gDestroyCtx(&mpm_ctx);
return result;
@ -2590,7 +2601,7 @@ static int B2gTestScan21 (void) {
B2gDestroyCtx(&mpm_ctx);
return result;
}
#if 0
static int B2gTestSearch01 (void) {
int result = 0;
MpmCtx mpm_ctx;
@ -2935,6 +2946,7 @@ static int B2gTestSearch12 (void) {
B2gDestroyCtx(&mpm_ctx);
return result;
}
#endif
#endif /* UNITTESTS */
void B2gRegisterTests(void) {
@ -2968,7 +2980,7 @@ void B2gRegisterTests(void) {
UtRegisterTest("B2gTestScan19", B2gTestScan19, 1);
UtRegisterTest("B2gTestScan20", B2gTestScan20, 1);
UtRegisterTest("B2gTestScan21", B2gTestScan21, 1);
#if 0
UtRegisterTest("B2gTestSearch01", B2gTestSearch01, 1);
UtRegisterTest("B2gTestSearch02", B2gTestSearch02, 1);
UtRegisterTest("B2gTestSearch03", B2gTestSearch03, 1);
@ -2981,6 +2993,7 @@ void B2gRegisterTests(void) {
UtRegisterTest("B2gTestSearch10", B2gTestSearch10, 1);
UtRegisterTest("B2gTestSearch11", B2gTestSearch11, 1);
UtRegisterTest("B2gTestSearch12", B2gTestSearch12, 1);
#endif
#endif /* UNITTESTS */
}

@ -42,6 +42,7 @@ typedef struct B2gPattern_ {
uint8_t *ci; /* case INsensitive */
struct B2gPattern_ *next;
MpmEndMatch *em;
uint32_t em_len;
} B2gPattern;
typedef struct B2gHashItem_ {

@ -3689,7 +3689,7 @@ int WmTestSearch20Hash16 (void) {
WmDestroyCtx(&mpm_ctx);
return result;
}
#if 0
int WmTestSearch21 (void) {
int result = 0;
MpmCtx mpm_ctx;
@ -3993,6 +3993,7 @@ static int WmTestSearch22Hash16 (void) {
WmDestroyCtx(&mpm_ctx);
return result;
}
#endif
#endif /* UNITTESTS */
void WmRegisterTests(void) {
@ -4017,7 +4018,7 @@ void WmRegisterTests(void) {
UtRegisterTest("WmTestPrepare04", WmTestPrepare01, 1);
UtRegisterTest("WmTestPrepare05", WmTestPrepare02, 1);
UtRegisterTest("WmTestPrepare06", WmTestPrepare03, 1);
#if 0
UtRegisterTest("WmTestSearch01", WmTestSearch01, 1);
UtRegisterTest("WmTestSearch01Hash12", WmTestSearch01Hash12, 1);
UtRegisterTest("WmTestSearch01Hash14", WmTestSearch01Hash14, 1);
@ -4071,6 +4072,7 @@ void WmRegisterTests(void) {
UtRegisterTest("WmTestSearch22Hash14", WmTestSearch22Hash14, 1);
UtRegisterTest("WmTestSearch22Hash15", WmTestSearch22Hash15, 1);
UtRegisterTest("WmTestSearch22Hash16", WmTestSearch22Hash16, 1);
#endif
#endif /* UNITTESTS */
}

@ -167,7 +167,7 @@ MpmMatchAppend(MpmThreadCtx *thread_ctx, PatternMatcherQueue *pmq, MpmEndMatch *
/* check depth */
if (em->depth && (offset+patlen) > em->depth)
return 0;
#if 0
/* ok all checks passed, now append the match */
MpmMatch *m;
/* pull a match from the spare list */
@ -205,7 +205,7 @@ MpmMatchAppend(MpmThreadCtx *thread_ctx, PatternMatcherQueue *pmq, MpmEndMatch *
}
BUG_ON(m == m->qnext);
#endif
if (pmq != NULL) {
/* make sure we only append a sig with a matching pattern once,
* so we won't inspect it more than once. For this we keep a
@ -224,7 +224,7 @@ MpmMatchAppend(MpmThreadCtx *thread_ctx, PatternMatcherQueue *pmq, MpmEndMatch *
}
}
SCLogDebug("len %" PRIu32 " (offset %" PRIu32 ")", mb->len, m->offset);
// SCLogDebug("len %" PRIu32 " (offset %" PRIu32 ")", mb->len, m->offset);
return 1;
}

@ -12,10 +12,10 @@
#include "suricata-common.h"
#include "suricata.h"
#include "util-debug.h"
#include "util-spm-bs.h"
#include <time.h>
#include <limits.h>
#include <string.h>
/**
* \brief Basic search improved. Limits are better handled, so
@ -29,34 +29,46 @@
* \retval ptr to start of the match; NULL if no match
*/
inline uint8_t *BasicSearch(const uint8_t *haystack, uint32_t haystack_len, const uint8_t *needle, uint32_t needle_len) {
SCEnter();
const uint8_t *h, *n;
const uint8_t *hmax = haystack + haystack_len;
const uint8_t *nmax = needle + needle_len;
if (needle_len == 0 || needle_len > haystack_len)
return NULL;
if (needle_len == 0 || needle_len > haystack_len) {
SCReturnPtr(NULL, "uint8_t");
}
//PrintRawDataFp(stdout,needle,needle_len);
//PrintRawDataFp(stdout,haystack,haystack_len);
for (n = needle; nmax - n <= hmax - haystack; haystack++) {
if (*haystack != *n) {
continue;
}
SCLogDebug("*haystack == *n, %c == %c", *haystack, *n);
/* one byte needles */
if (needle_len == 1)
return (uint8_t *)haystack;
if (needle_len == 1) {
SCReturnPtr((uint8_t *)haystack, "uint8_t");
}
for (h = haystack+1, n++; nmax - n <= hmax - haystack; h++, n++) {
if (*h != *n) {
break;
}
SCLogDebug("*haystack == *n, %c == %c", *haystack, *n);
/* if we run out of needle we fully matched */
if (n == nmax - 1) {
return (uint8_t *)haystack;
SCReturnPtr((uint8_t *)haystack, "uint8_t");
}
}
n = needle;
}
return NULL;
SCReturnPtr(NULL, "uint8_t");
}
/**

@ -300,6 +300,7 @@ int UTHGenericTest(Packet **pkt, int numpkts, char *sigs[], uint32_t sids[], uin
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
if (UTHAppendSigs(de_ctx, sigs, numsigs) == 0)
goto cleanup;
@ -505,7 +506,7 @@ int UTHPacketMatchSigMpm(Packet *p, char *sig, uint16_t mpm_type) {
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
result=0;
printf("de_ctx == NULL: ");
goto end;
}
@ -514,20 +515,20 @@ int UTHPacketMatchSigMpm(Packet *p, char *sig, uint16_t mpm_type) {
de_ctx->sig_list = SigInit(de_ctx, sig);
if (de_ctx->sig_list == NULL) {
result = 0;
printf("signature == NULL: ");
goto end;
}
SigGroupBuild(de_ctx);
//PatternMatchPrepare(mpm_ctx, mpm_type);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, de_ctx->sig_list->id) != 1) {
result = 0;
printf("signature didn't alert: ");
goto end;
}
result = 1;
end:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);

Loading…
Cancel
Save