Merge applayer detect function into normal match function. Should speed up detection.

remotes/origin/master-1.0.x
Victor Julien 15 years ago
parent bcd0682150
commit 4284276b11

@ -1465,8 +1465,6 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
aux->id = de_ctx->content_max_id;
de_ctx->content_max_id++;
s->flags |= SIG_FLAG_MPM;
/** We need to setup the modifiers for the chunks respect
* the last chunk installed inmediatelly before
* so do the propagation from the first one
@ -1507,10 +1505,6 @@ int DetectContentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char
cd->id = de_ctx->content_max_id;
de_ctx->content_max_id++;
s->flags |= SIG_FLAG_MPM;
if (cd->negated == 1)
s->flags |= SIG_FLAG_MPM_NEGCONTENT;
DetectContentPrint(cd);
}

@ -617,6 +617,28 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) {
sig->num = de_ctx->signum;
de_ctx->signum++;
/* see if need to set the SIG_FLAG_MPM flag */
SigMatch *sm;
for (sm = sig->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd == NULL)
continue;
sig->flags |= SIG_FLAG_MPM;
if (cd->negated == 1) {
sig->flags |= SIG_FLAG_MPM_NEGCONTENT;
}
} else if (sm->type == DETECT_URICONTENT) {
DetectUricontentData *ud = (DetectUricontentData *)sm->ctx;
if (ud == NULL)
continue;
sig->flags |= SIG_FLAG_MPM;
}
}
/* set mpm_content_len */
/* determine the length of the longest pattern in the sig */
@ -624,7 +646,6 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) {
sig->mpm_content_maxlen = 0;
sig->mpm_uricontent_maxlen = 0;
SigMatch *sm;
for (sm = sig->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
@ -705,6 +726,28 @@ Signature *SigInitReal(DetectEngineCtx *de_ctx, char *sigstr) {
sig->num = de_ctx->signum;
de_ctx->signum++;
/* see if need to set the SIG_FLAG_MPM flag */
SigMatch *sm;
for (sm = sig->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)sm->ctx;
if (cd == NULL)
continue;
sig->flags |= SIG_FLAG_MPM;
if (cd->negated == 1) {
sig->flags |= SIG_FLAG_MPM_NEGCONTENT;
}
} else if (sm->type == DETECT_URICONTENT) {
DetectUricontentData *ud = (DetectUricontentData *)sm->ctx;
if (ud == NULL)
continue;
sig->flags |= SIG_FLAG_MPM;
}
}
/* set mpm_content_len */
/* determine the length of the longest pattern in the sig */
@ -712,7 +755,6 @@ Signature *SigInitReal(DetectEngineCtx *de_ctx, char *sigstr) {
sig->mpm_content_maxlen = 0;
sig->mpm_uricontent_maxlen = 0;
SigMatch *sm;
for (sm = sig->match; sm != NULL; sm = sm->next) {
if (sm->type == DETECT_CONTENT) {
DetectContentData *cd = (DetectContentData *)sm->ctx;

@ -340,8 +340,6 @@ int DetectUricontentSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, c
cd->id = de_ctx->uricontent_max_id;
de_ctx->uricontent_max_id++;
s->flags |= SIG_FLAG_MPM;
if (dubbed) free(str);
return 0;

@ -509,199 +509,40 @@ inline SigGroupHead *SigMatchSignaturesGetSgh(ThreadVars *th_v, DetectEngineCtx
SCReturnPtr(sgh, "SigGroupHead");
}
/** \brief application layer detection
*
* \param sgh signature group head for this proto/addrs/ports
* \warning Make sure to exit this function using "goto end" if the flow
* use_cnt has already been incremented.
*/
static int SigMatchSignaturesAppLayer(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, SigGroupHead *sgh, Packet *p)
{
SCEnter();
int match = 0, fmatch = 0;
Signature *s = NULL;
SigMatch *sm = NULL;
uint32_t idx, sig;
uint8_t flags = 0;
uint16_t alproto = ALPROTO_UNKNOWN;
void *alstate = NULL;
/* if we didn't get a sig group head, we
* have nothing to do.... */
if (sgh == NULL) {
SCLogDebug("no sgh to detect");
SCReturnInt(0);
}
/* grab the protocol state we will detect on */
if (p->flow == NULL) {
SCReturnInt(0);
}
SCMutexLock(&p->flow->m);
p->flow->use_cnt++;
alstate = AppLayerGetProtoStateFromPacket(p);
alproto = AppLayerGetProtoFromPacket(p);
SCMutexUnlock(&p->flow->m);
if (alproto == ALPROTO_UNKNOWN) {
SCLogDebug("application layer state proto still unknown");
goto end;
}
if (alstate == NULL) {
SCLogDebug("no application layer state to detect");
goto end;
}
if (p->flowflags & FLOW_PKT_TOSERVER) {
flags |= STREAM_TOSERVER;
} else if (p->flowflags & FLOW_PKT_TOCLIENT) {
flags |= STREAM_TOCLIENT;
}
SCLogDebug("p->flowflags 0x%02X flags 0x%02X", p->flowflags, flags);
/* inspect the sigs against the packet */
for (idx = 0; idx < sgh->sig_cnt; idx++) {
sig = sgh->match_array[idx];
s = de_ctx->sig_array[sig];
SCLogDebug("s->id %"PRIu32"", s->id);
/* only inspect app layer sigs here */
if (!(s->flags & SIG_FLAG_APPLAYER))
continue;
/* filter out the sigs that inspects the payload, if packet
no payload inspection flag is set*/
if ((p->flags & PKT_NOPAYLOAD_INSPECTION) && (s->flags & SIG_FLAG_PAYLOAD)) {
continue;
}
/* check the source & dst port in the sig */
if (p->proto == IPPROTO_TCP || p->proto == IPPROTO_UDP) {
if (!(s->flags & SIG_FLAG_DP_ANY)) {
DetectPort *dport = DetectPortLookupGroup(s->dp,p->dp);
if (dport == NULL)
continue;
}
if (!(s->flags & SIG_FLAG_SP_ANY)) {
DetectPort *sport = DetectPortLookupGroup(s->sp,p->sp);
if (sport == NULL)
continue;
}
}
/* check the source address */
if (!(s->flags & SIG_FLAG_SRC_ANY)) {
DetectAddress *saddr = DetectAddressLookupInHead(&s->src,&p->src);
if (saddr == NULL)
continue;
}
/* check the destination address */
if (!(s->flags & SIG_FLAG_DST_ANY)) {
DetectAddress *daddr = DetectAddressLookupInHead(&s->dst,&p->dst);
if (daddr == NULL)
continue;
}
/* if we don't have sigmatches at this point we're a match
* XXX VJ can we ever get here? Applayer inspection w/o sigmatches */
if (s->match == NULL) {
fmatch = 1;
if (!(s->flags & SIG_FLAG_NOALERT)) {
PacketAlertHandle(de_ctx,s,p);
/* set verdict on packet */
p->action = s->action;
}
} else {
/* reset pkt ptr and offset */
det_ctx->pkt_ptr = NULL;
det_ctx->pkt_off = 0;
sm = s->match;
while (sm) {
if (sigmatch_table[sm->type].AppLayerMatch == NULL) {
/* if no match function we assume this sm is a match */
match = 1;
SCLogDebug("no app layer match function, sigmatch is (pkt)Match only");
} else if (sigmatch_table[sm->type].alproto != alproto) {
match = 0;
SCLogDebug("app layer match function %s is for proto "
"%"PRIu16", got proto %"PRIu16"",
sigmatch_table[sm->type].name,
sigmatch_table[sm->type].alproto, alproto);
} else {
match = sigmatch_table[sm->type].AppLayerMatch(th_v, det_ctx, p->flow, flags, alstate, s, sm);
SCLogDebug("sigmatch AppLayerMatch function returned match %"PRIu32"", match);
}
if (match) {
/* okay, try the next match */
sm = sm->next;
/* only if the last matched as well, we have a hit */
if (sm == NULL) {
fmatch = 1;
SCLogDebug("DE : sig %" PRIu32 " matched", s->id);
if (!(s->flags & SIG_FLAG_NOALERT)) {
/* if the sig also has a packet portion see if that has matched already */
if (s->flags & SIG_FLAG_PACKET) {
SCLogDebug("checking sid %"PRIu32"", s->id);
if (FlowAlertSidIsset(p->flow, s->id) ) {
SCLogDebug("flowalertsid sid %"PRIu32", isset", s->id);
PacketAlertHandle(de_ctx,s,p);
/* set verdict on packet */
p->action = s->action;
}
} else {
PacketAlertHandle(de_ctx,s,p);
/* set verdict on packet */
p->action = s->action;
}
}
}
} else {
/* done with this sig */
sm = NULL;
}
}
}
}
end:
SCMutexLock(&p->flow->m);
p->flow->use_cnt--;
SCMutexUnlock(&p->flow->m);
SCReturnInt(fmatch);
}
int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
{
int match = 0, fmatch = 0;
Signature *s = NULL;
SigMatch *sm = NULL;
uint32_t idx,sig;
uint16_t alproto = ALPROTO_UNKNOWN;
void *alstate = NULL;
uint8_t flags = 0;
SCEnter();
det_ctx->pkts++;
SCLogDebug("p->flowflags 0x%02x", p->flowflags);
/* grab the protocol state we will detect on */
if (p->flow != NULL) {
SCMutexLock(&p->flow->m);
p->flow->use_cnt++;
alstate = AppLayerGetProtoStateFromPacket(p);
alproto = AppLayerGetProtoFromPacket(p);
SCMutexUnlock(&p->flow->m);
if (p->flowflags & FLOW_PKT_TOSERVER) {
flags |= STREAM_TOSERVER;
} else if (p->flowflags & FLOW_PKT_TOCLIENT) {
flags |= STREAM_TOCLIENT;
}
SCLogDebug("p->flowflags 0x%02x", p->flowflags);
}
/* match the ip only signatures */
if ((p->flowflags & FLOW_PKT_TOSERVER && !(p->flowflags & FLOW_PKT_TOSERVER_IPONLY_SET)) ||
(p->flowflags & FLOW_PKT_TOCLIENT && !(p->flowflags & FLOW_PKT_TOCLIENT_IPONLY_SET))) {
SCLogDebug("testing against \"ip-only\"");
SCLogDebug("testing against \"ip-only\" signatures");
IPOnlyMatchPacket(de_ctx, &de_ctx->io_ctx, &det_ctx->io_ctx, p);
/* save in the flow that we scanned this direction... locking is
@ -718,7 +559,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
* have nothing to do.... */
if (det_ctx->sgh == NULL) {
SCLogDebug("no sgh for this packet, nothing to match against");
SCReturnInt(0);
goto end;
}
if (p->payload_len > 0 && det_ctx->sgh->mpm_ctx != NULL && !(p->flags & PKT_NOPAYLOAD_INSPECTION)) {
@ -772,12 +613,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
continue;
}
/* don't inspect app layer only sigs here */
if (!(s->flags & SIG_FLAG_PACKET)) {
SCLogDebug("sig id %"PRIu32" is app layer inspecting only", s->id);
continue;
}
/* filter out sigs that want pattern matches, but
* have no matches */
if (!(det_ctx->pmq.sig_bitarray[(sig / 8)] & (1<<(sig % 8))) &&
@ -849,12 +684,17 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
do {
sm = s->match;
while (sm) {
if (sigmatch_table[sm->type].Match == NULL) {
/* if no match function we assume this sm is a match */
match = 1;
} else {
match = 0;
/* app layer match has preference */
if (sigmatch_table[sm->type].AppLayerMatch != NULL &&
alproto == sigmatch_table[sm->type].alproto &&
alstate != NULL) {
match = sigmatch_table[sm->type].AppLayerMatch(th_v, det_ctx, p->flow, flags, alstate, s, sm);
} else if (sigmatch_table[sm->type].Match != NULL) {
match = sigmatch_table[sm->type].Match(th_v, det_ctx, p, s, sm);
}
if (match) {
/* okay, try the next match */
sm = sm->next;
@ -888,12 +728,17 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
SCLogDebug("running match functions, sm %p", sm);
while (sm) {
/* if this sm has no Match function we assume it's a match */
if (sigmatch_table[sm->type].Match == NULL) {
match = 1;
} else {
match = 0;
/* app layer match has preference */
if (sigmatch_table[sm->type].AppLayerMatch != NULL &&
alproto == sigmatch_table[sm->type].alproto &&
alstate != NULL) {
match = sigmatch_table[sm->type].AppLayerMatch(th_v, det_ctx, p->flow, flags, alstate, s, sm);
} else if (sigmatch_table[sm->type].Match != NULL) {
match = sigmatch_table[sm->type].Match(th_v, det_ctx, p, s, sm);
}
if (match) {
/* okay, try the next match */
sm = sm->next;
@ -902,18 +747,12 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
if (sm == NULL) {
fmatch = 1;
if (!(s->flags & SIG_FLAG_NOALERT)) {
SCLogDebug("sig matched, applayer flag set ? %s", s->flags & SIG_FLAG_APPLAYER ? "yes":"no");
/* set flowbit for this match */
if (s->flags & SIG_FLAG_APPLAYER) {
SCLogDebug("setting flowalertsid for sig %"PRIu32"", s->id);
FlowAlertSidSet(p->flow, s->id);
} else {
PacketAlertHandle(de_ctx,s,p);
PacketAlertHandle(de_ctx,s,p);
/* set verdict on packet */
p->action = s->action;
}
/* set verdict on packet */
p->action = s->action;
}
}
} else {
@ -929,10 +768,11 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* cleanup pkt specific part of the patternmatcher */
PacketPatternCleanup(th_v, det_ctx);
SCLogDebug("Running Application Layer match functions, sm %p", sm);
match = SigMatchSignaturesAppLayer(th_v, de_ctx, det_ctx, det_ctx->sgh, p);
if (match > 0) {
fmatch = 1;
end:
if (p->flow != NULL) {
SCMutexLock(&p->flow->m);
p->flow->use_cnt--;
SCMutexUnlock(&p->flow->m);
}
SCReturnInt(fmatch);

Loading…
Cancel
Save