diff --git a/src/detect-engine-iponly.c b/src/detect-engine-iponly.c index 209839143e..b6205fbc1d 100644 --- a/src/detect-engine-iponly.c +++ b/src/detect-engine-iponly.c @@ -48,6 +48,7 @@ #include "util-classification-config.h" #include "util-rule-vars.h" +#include "flow-util.h" #include "util-debug.h" #include "util-unittest.h" #include "util-unittest-helper.h" @@ -919,6 +920,31 @@ void DetectEngineIPOnlyThreadDeinit(DetectEngineIPOnlyThreadCtx *io_tctx) { SCFree(io_tctx->sig_match_array); } +static inline +int IPOnlyMatchCompatSMs(ThreadVars *tv, + DetectEngineThreadCtx *det_ctx, + Signature *s, Packet *p) +{ + SigMatch *sm = s->sm_lists[DETECT_SM_LIST_MATCH]; + int match; + + while (sm != NULL) { + if (sm->type != DETECT_FLOWBITS) { + sm = sm->next; + continue; + } + + match = sigmatch_table[sm->type].Match(tv, det_ctx, p, s, sm); + if (match > 0) { + sm = sm->next; + continue; + } + return 0; + } + + return 1; +} + /** * \brief Match a packet against the IP Only detection engine contexts * @@ -927,7 +953,8 @@ void DetectEngineIPOnlyThreadDeinit(DetectEngineIPOnlyThreadCtx *io_tctx) { * \param io_ctx Pointer to the current ip only thread detection engine * \param p Pointer to the Packet to match against */ -void IPOnlyMatchPacket(DetectEngineCtx *de_ctx, +void IPOnlyMatchPacket(ThreadVars *tv, + DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, DetectEngineIPOnlyCtx *io_ctx, DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p) @@ -1002,6 +1029,10 @@ void IPOnlyMatchPacket(DetectEngineCtx *de_ctx, if (!(s->proto.proto[(IP_GET_IPPROTO(p)/8)] & (1 << (IP_GET_IPPROTO(p) % 8)))) continue; + if (!IPOnlyMatchCompatSMs(tv, det_ctx, s, p)) { + continue; + } + SCLogDebug("Signum %"PRIu16" match (sid: %"PRIu16", msg: %s)", u * 8 + i, s->id, s->msg); @@ -1998,6 +2029,107 @@ int IPOnlyTestSig12(void) { return result; } +static int IPOnlyTestSig13(void) +{ + int result = 0; + DetectEngineCtx de_ctx; + + memset(&de_ctx, 0, sizeof(DetectEngineCtx)); + + de_ctx.flags |= DE_QUIET; + + Signature *s = SigInit(&de_ctx, + "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; " + "flowbits:set,myflow1; sid:1; rev:1;)"); + if (s == NULL) { + goto end; + } + if (SignatureIsIPOnly(&de_ctx, s)) + result = 1; + else + printf("expected a IPOnly signature: "); + + SigFree(s); +end: + return result; +} + +static int IPOnlyTestSig14(void) +{ + int result = 0; + DetectEngineCtx de_ctx; + + memset(&de_ctx, 0, sizeof(DetectEngineCtx)); + + de_ctx.flags |= DE_QUIET; + + Signature *s = SigInit(&de_ctx, + "alert tcp any any -> any any (msg:\"Test flowbits ip only\"; " + "flowbits:set,myflow1; flowbits:isset,myflow2; sid:1; rev:1;)"); + if (s == NULL) { + goto end; + } + if (SignatureIsIPOnly(&de_ctx, s)) + printf("expected a IPOnly signature: "); + else + result = 1; + + SigFree(s); +end: + return result; +} + +int IPOnlyTestSig15(void) +{ + int result = 0; + uint8_t *buf = (uint8_t *)"Hi all!"; + uint16_t buflen = strlen((char *)buf); + + uint8_t numpkts = 1; + uint8_t numsigs = 7; + + Packet *p[1]; + Flow f; + GenericVar flowvar; + memset(&f, 0, sizeof(Flow)); + memset(&flowvar, 0, sizeof(GenericVar)); + FLOW_INITIALIZE(&f); + + p[0] = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP); + + p[0]->flow = &f; + p[0]->flow->flowvar = &flowvar; + p[0]->flags |= PKT_HAS_FLOW; + p[0]->flowflags |= FLOW_PKT_TOSERVER; + + char *sigs[numsigs]; + sigs[0]= "alert tcp 192.168.1.5 any -> any any (msg:\"Testing src ip (sid 1)\"; " + "flowbits:set,one; sid:1;)"; + sigs[1]= "alert tcp any any -> 192.168.1.1 any (msg:\"Testing dst ip (sid 2)\"; " + "flowbits:set,two; sid:2;)"; + sigs[2]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 3)\"; " + "flowbits:set,three; sid:3;)"; + sigs[3]= "alert tcp 192.168.1.5 any -> 192.168.1.1 any (msg:\"Testing src/dst ip (sid 4)\"; " + "flowbits:set,four; sid:4;)"; + sigs[4]= "alert tcp 192.168.1.0/24 any -> any any (msg:\"Testing src/dst ip (sid 5)\"; " + "flowbits:set,five; sid:5;)"; + sigs[5]= "alert tcp any any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 6)\"; " + "flowbits:set,six; sid:6;)"; + sigs[6]= "alert tcp 192.168.1.0/24 any -> 192.168.0.0/16 any (msg:\"Testing src/dst ip (sid 7)\"; " + "flowbits:set,seven; content:\"Hi all\"; sid:7;)"; + + /* Sid numbers (we could extract them from the sig) */ + uint32_t sid[7] = { 1, 2, 3, 4, 5, 6, 7}; + uint32_t results[7] = { 1, 1, 1, 1, 1, 1, 1}; + + result = UTHGenericTest(p, numpkts, sigs, sid, (uint32_t *) results, numsigs); + + UTHFreePackets(p, numpkts); + + FLOW_DESTROY(&f); + return result; +} + #endif /* UNITTESTS */ void IPOnlyRegisterTests(void) { @@ -2016,6 +2148,11 @@ void IPOnlyRegisterTests(void) { UtRegisterTest("IPOnlyTestSig10", IPOnlyTestSig10, 1); UtRegisterTest("IPOnlyTestSig11", IPOnlyTestSig11, 1); UtRegisterTest("IPOnlyTestSig12", IPOnlyTestSig12, 1); + UtRegisterTest("IPOnlyTestSig13", IPOnlyTestSig13, 1); + UtRegisterTest("IPOnlyTestSig14", IPOnlyTestSig14, 1); + UtRegisterTest("IPOnlyTestSig15", IPOnlyTestSig15, 1); #endif + + return; } diff --git a/src/detect-engine-iponly.h b/src/detect-engine-iponly.h index 32d0bde955..f4d59cd26f 100644 --- a/src/detect-engine-iponly.h +++ b/src/detect-engine-iponly.h @@ -51,9 +51,9 @@ int IPOnlyCIDRItemParseSingle(IPOnlyCIDRItem *dd, char *str); int IPOnlyCIDRItemSetup(IPOnlyCIDRItem *gh, char *s); void IPOnlyCIDRListPrint(IPOnlyCIDRItem *); -void IPOnlyMatchPacket(DetectEngineCtx *, DetectEngineThreadCtx *, - DetectEngineIPOnlyCtx *, DetectEngineIPOnlyThreadCtx *, - Packet *); +void IPOnlyMatchPacket(ThreadVars *tv, DetectEngineCtx *, + DetectEngineThreadCtx *, DetectEngineIPOnlyCtx *, + DetectEngineIPOnlyThreadCtx *, Packet *); void IPOnlyInit(DetectEngineCtx *, DetectEngineIPOnlyCtx *); void IPOnlyPrint(DetectEngineCtx *, DetectEngineIPOnlyCtx *); void IPOnlyDeinit(DetectEngineCtx *, DetectEngineIPOnlyCtx *); diff --git a/src/detect-flowbits.c b/src/detect-flowbits.c index 7fcf1931a7..86b62c860f 100644 --- a/src/detect-flowbits.c +++ b/src/detect-flowbits.c @@ -61,6 +61,8 @@ void DetectFlowbitsRegister (void) { sigmatch_table[DETECT_FLOWBITS].Setup = DetectFlowbitSetup; sigmatch_table[DETECT_FLOWBITS].Free = DetectFlowbitFree; sigmatch_table[DETECT_FLOWBITS].RegisterTests = FlowBitsRegisterTests; + /* this is compatible to ip-only signatures */ + sigmatch_table[DETECT_FLOWBITS].flags |= SIGMATCH_IPONLY_COMPAT; const char *eb; int eo; @@ -750,6 +752,7 @@ static int FlowBitsTestSig06(void) { p->payload_len = buflen; p->proto = IPPROTO_TCP; p->flags |= PKT_HAS_FLOW; + p->flowflags |= FLOW_PKT_TOSERVER; de_ctx = DetectEngineCtxInit(); diff --git a/src/detect.c b/src/detect.c index 7303ac189a..61a92cf590 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1352,7 +1352,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh { SCLogDebug("testing against \"ip-only\" signatures"); - IPOnlyMatchPacket(de_ctx, det_ctx, &de_ctx->io_ctx, &det_ctx->io_ctx, p); + IPOnlyMatchPacket(th_v, de_ctx, det_ctx, &de_ctx->io_ctx, &det_ctx->io_ctx, p); /* save in the flow that we scanned this direction... locking is * done in the FlowSetIPOnlyFlag function. */ FlowSetIPOnlyFlag(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0); @@ -1383,7 +1383,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh } else { /* no flow */ /* Even without flow we should match the packet src/dst */ - IPOnlyMatchPacket(de_ctx, det_ctx, &de_ctx->io_ctx, &det_ctx->io_ctx, p); + IPOnlyMatchPacket(th_v, de_ctx, det_ctx, &de_ctx->io_ctx, + &det_ctx->io_ctx, p); det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, p); } @@ -1914,9 +1915,15 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, Signature *s) { if (sm == NULL) goto iponly; - for ( ;sm != NULL; sm = sm->next) { + for ( ; sm != NULL; sm = sm->next) { if ( !(sigmatch_table[sm->type].flags & SIGMATCH_IPONLY_COMPAT)) return 0; + /* we have enabled flowbits to be compatible with ip only sigs, as long + * as the sig only has a "set" flowbits */ + if (sm->type == DETECT_FLOWBITS && + (((DetectFlowbitsData *)sm->ctx)->cmd != DETECT_FLOWBITS_CMD_SET) ) { + return 0; + } } iponly: diff --git a/src/util-var-name.c b/src/util-var-name.c index f42675dd36..6194159113 100644 --- a/src/util-var-name.c +++ b/src/util-var-name.c @@ -121,6 +121,8 @@ void VariableNameFreeHash() { if (variable_names != NULL) { HashListTableFree(variable_names); HashListTableFree(variable_idxs); + variable_names = NULL; + variable_idxs = NULL; } } @@ -195,4 +197,4 @@ char *VariableIdxGetName(uint16_t idx, uint8_t type) error: VariableNameFree(fn); return NULL; -} \ No newline at end of file +}