Bug #292 ยป 0001-add-flowbits-set-only-sigs-to-be-treated-as-ip-only.patch
src/detect-engine-iponly.c | ||
---|---|---|
#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"
|
||
... | ... | |
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
|
||
*
|
||
... | ... | |
* \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)
|
||
... | ... | |
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);
|
||
... | ... | |
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) {
|
||
... | ... | |
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;
|
||
}
|
||
src/detect-engine-iponly.h | ||
---|---|---|
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 *);
|
src/detect-flowbits.c | ||
---|---|---|
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;
|
||
... | ... | |
p->payload_len = buflen;
|
||
p->proto = IPPROTO_TCP;
|
||
p->flags |= PKT_HAS_FLOW;
|
||
p->flowflags |= FLOW_PKT_TOSERVER;
|
||
de_ctx = DetectEngineCtxInit();
|
||
src/detect.c | ||
---|---|---|
{
|
||
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);
|
||
... | ... | |
} 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);
|
||
}
|
||
... | ... | |
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:
|
src/util-var-name.c | ||
---|---|---|
if (variable_names != NULL) {
|
||
HashListTableFree(variable_names);
|
||
HashListTableFree(variable_idxs);
|
||
variable_names = NULL;
|
||
variable_idxs = NULL;
|
||
}
|
||
}
|
||
... | ... | |
error:
|
||
VariableNameFree(fn);
|
||
return NULL;
|
||
}
|
||
}
|