Project

General

Profile

Bug #292 ยป 0001-add-flowbits-set-only-sigs-to-be-treated-as-ip-only.patch

Victor Julien, 07/14/2011 04:03 AM

View differences:

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;
}
}
    (1-1/1)