detect: group proto sghs

pull/1978/head
Victor Julien 10 years ago
parent d82df4eb8b
commit eda9552e95

@ -2879,6 +2879,127 @@ static void SigParseApplyDsizeToContent(Signature *s)
}
}
int RulesGroupByProto(DetectEngineCtx *de_ctx)
{
Signature *s = de_ctx->sig_list;
uint32_t max_idx = 0;
SigGroupHead *sgh_ts[256] = {NULL};
SigGroupHead *sgh_tc[256] = {NULL};
for ( ; s != NULL; s = s->next) {
if (s->flags & SIG_FLAG_IPONLY)
continue;
int p;
for (p = 0; p < 256; p++) {
if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
continue;
}
if (!(s->proto.proto[p / 8] & (1<<(p % 8)) || (s->proto.flags & DETECT_PROTO_ANY))) {
continue;
}
if (s->flags & SIG_FLAG_TOCLIENT) {
SigGroupHeadAppendSig(de_ctx, &sgh_tc[p], s);
max_idx = s->num;
}
if (s->flags & SIG_FLAG_TOSERVER) {
SigGroupHeadAppendSig(de_ctx, &sgh_ts[p], s);
max_idx = s->num;
}
}
}
SCLogDebug("max_idx %u", max_idx);
/* lets look at deduplicating this list */
SigGroupHeadHashFree(de_ctx);
SigGroupHeadHashInit(de_ctx);
uint32_t cnt = 0;
uint32_t own = 0;
uint32_t ref = 0;
int p;
for (p = 0; p < 256; p++) {
if (p == IPPROTO_TCP || p == IPPROTO_UDP)
continue;
if (sgh_ts[p] == NULL)
continue;
cnt++;
SigGroupHead *lookup_sgh = SigGroupHeadHashLookup(de_ctx, sgh_ts[p]);
if (lookup_sgh == NULL) {
SCLogDebug("proto group %d sgh %p is the original", p, sgh_ts[p]);
SigGroupHeadSetSigCnt(sgh_ts[p], max_idx);
SigGroupHeadBuildMatchArray(de_ctx, sgh_ts[p], max_idx);
SigGroupHeadHashAdd(de_ctx, sgh_ts[p]);
SigGroupHeadStore(de_ctx, sgh_ts[p]);
de_ctx->gh_unique++;
own++;
} else {
SCLogDebug("proto group %d sgh %p is a copy", p, sgh_ts[p]);
SigGroupHeadFree(sgh_ts[p]);
sgh_ts[p] = lookup_sgh;
sgh_ts[p]->flags |= SIG_GROUP_HEAD_REFERENCED;
de_ctx->gh_reuse++;
ref++;
}
}
SCLogInfo("OTHER %s: %u proto groups, %u unique SGH's, %u copies", "toserver", cnt, own, ref);
cnt = 0;
own = 0;
ref = 0;
for (p = 0; p < 256; p++) {
if (p == IPPROTO_TCP || p == IPPROTO_UDP)
continue;
if (sgh_tc[p] == NULL)
continue;
cnt++;
SigGroupHead *lookup_sgh = SigGroupHeadHashLookup(de_ctx, sgh_tc[p]);
if (lookup_sgh == NULL) {
SCLogDebug("proto group %d sgh %p is the original", p, sgh_tc[p]);
SigGroupHeadSetSigCnt(sgh_tc[p], max_idx);
SigGroupHeadBuildMatchArray(de_ctx, sgh_tc[p], max_idx);
SigGroupHeadHashAdd(de_ctx, sgh_tc[p]);
SigGroupHeadStore(de_ctx, sgh_tc[p]);
de_ctx->gh_unique++;
own++;
} else {
SCLogDebug("proto group %d sgh %p is a copy", p, sgh_tc[p]);
SigGroupHeadFree(sgh_tc[p]);
sgh_tc[p] = lookup_sgh;
sgh_tc[p]->flags |= SIG_GROUP_HEAD_REFERENCED;
de_ctx->gh_reuse++;
ref++;
}
}
SCLogInfo("OTHER %s: %u proto groups, %u unique SGH's, %u copies", "toclient", cnt, own, ref);
for (p = 0; p < 256; p++) {
if (p == IPPROTO_TCP || p == IPPROTO_UDP)
continue;
de_ctx->flow_gh[0].sgh[p] = sgh_tc[p];
de_ctx->flow_gh[1].sgh[p] = sgh_ts[p];
}
return 0;
}
static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, int ipproto, uint32_t direction) {
/* step 1: create a list of 'DetectPort' objects based on all the
* rules. Each object will have a SGH with the sigs added
@ -3092,41 +3213,6 @@ error:
return -1;
}
/**
* \brief add signature to the right flow group(s)
*/
static int DetectEngineLookupFlowAddSig(DetectEngineCtx *de_ctx, Signature *s)
{
SCLogDebug("s->id %u", s->id);
uint32_t cnt_ts = 0;
uint32_t cnt_tc = 0;
int p;
for (p = 0; p < 256; p++) {
if (p == IPPROTO_TCP || p == IPPROTO_UDP)
continue;
if (s->proto.proto[p / 8] & (1<<(p % 8)) || (s->proto.flags & DETECT_PROTO_ANY)) {
if (s->flags & SIG_FLAG_TOCLIENT) {
SigGroupHeadAppendSig(de_ctx, &de_ctx->flow_gh[0].sgh[p], s);
cnt_tc++;
}
if (s->flags & SIG_FLAG_TOSERVER) {
SigGroupHeadAppendSig(de_ctx, &de_ctx->flow_gh[1].sgh[p], s);
cnt_ts++;
}
}
}
/* see which rules use many protos. > 2 as alert icmp actually is also icmpv6. */
if (cnt_ts > 2 || cnt_tc > 2) {
SCLogDebug("Rule %u added to multiple proto groups (%u ts/%u tc)", s->id, cnt_ts, cnt_tc);
}
return 0;
}
//#define SMALL_MPM(c) 0
#define SMALL_MPM(c) ((c) == 1)
// || (c) == 2)
@ -3329,14 +3415,14 @@ int SigAddressPrepareStage2(DetectEngineCtx *de_ctx)
de_ctx->flow_gh[1].udp = RulesGroupByPorts(de_ctx, IPPROTO_UDP, SIG_FLAG_TOSERVER);
de_ctx->flow_gh[0].udp = RulesGroupByPorts(de_ctx, IPPROTO_UDP, SIG_FLAG_TOCLIENT);
/* Setup the other IP Protocols (so not TCP/UDP) */
RulesGroupByProto(de_ctx);
/* now for every rule add the source group to our temp lists */
for (tmp_s = de_ctx->sig_list; tmp_s != NULL; tmp_s = tmp_s->next) {
SCLogDebug("tmp_s->id %"PRIu32, tmp_s->id);
if (tmp_s->flags & SIG_FLAG_IPONLY) {
IPOnlyAddSignature(de_ctx, &de_ctx->io_ctx, tmp_s);
} else {
/* handle non-tcp/non-udp rules */
DetectEngineLookupFlowAddSig(de_ctx, tmp_s);
}
if (tmp_s->init_flags & SIG_FLAG_INIT_DEONLY) {
@ -3449,33 +3535,6 @@ int SigAddressPrepareStage4(DetectEngineCtx *de_ctx)
//SCLogInfo("sgh's %"PRIu32, de_ctx->sgh_array_cnt);
uint32_t idx = 0;
for (idx = 0; idx < 256; idx++) {
int f = 0;
for (f = 0; f <= 1; f++) {
SigGroupHead *sgh = de_ctx->flow_gh[f].sgh[idx];
if (sgh == NULL) {
//SCLogInfo("skipped %u/%d", idx, f);
continue;
}
uint32_t max_idx = DetectEngineGetMaxSigId(de_ctx);
SigGroupHeadSetSigCnt(sgh, max_idx);
SigGroupHeadSetProtoAndDirection(sgh, idx,
((f == 1) ? SIG_FLAG_TOSERVER : SIG_FLAG_TOCLIENT));
SigGroupHeadBuildMatchArray(de_ctx, sgh, max_idx);
SigGroupHeadSetFilemagicFlag(de_ctx, sgh);
SigGroupHeadSetFileMd5Flag(de_ctx, sgh);
SigGroupHeadSetFilesizeFlag(de_ctx, sgh);
SigGroupHeadSetFilestoreCount(de_ctx, sgh);
SCLogDebug("filestore count %u", sgh->filestore_cnt);
PatternMatchPrepareGroup(de_ctx, sgh);
SigGroupHeadBuildNonMpmArray(de_ctx, sgh);
}
}
for (idx = 0; idx < de_ctx->sgh_array_cnt; idx++) {
SigGroupHead *sgh = de_ctx->sgh_array[idx];
if (sgh == NULL)

Loading…
Cancel
Save