update pmp to return whole set of matches, rather than a single match.

pull/567/head
Anoop Saldanha 12 years ago
parent 4f7339c423
commit 00f546e739

@ -354,14 +354,18 @@ void AppLayerDetectProtoThreadInit(void) {
* \param buflen Lenght of the buffer * \param buflen Lenght of the buffer
* \param flags Flags. * \param flags Flags.
* *
* \retval proto App Layer proto, or ALPROTO_UNKNOWN if unknown * \retval pm_matches Returns the no of alproto matches.
*/ */
uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx, uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx,
AlpProtoDetectThreadCtx *tctx, AlpProtoDetectThreadCtx *tctx,
uint8_t *buf, uint16_t buflen, uint8_t *buf, uint16_t buflen,
uint8_t flags, uint8_t ipproto) { uint8_t flags, uint8_t ipproto,
uint16_t *pm_results) {
SCEnter(); SCEnter();
uint16_t pm_matches = 0;
pm_results[0] = ALPROTO_UNKNOWN;
AlpProtoDetectDirection *dir; AlpProtoDetectDirection *dir;
AlpProtoDetectDirectionThread *tdir; AlpProtoDetectDirectionThread *tdir;
@ -374,7 +378,7 @@ uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx,
} }
if (dir->id == 0) { if (dir->id == 0) {
SCReturnUInt(ALPROTO_UNKNOWN); SCReturnUInt(pm_matches);
} }
/* see if we can limit the data we inspect */ /* see if we can limit the data we inspect */
@ -382,39 +386,33 @@ uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx,
if (searchlen > dir->max_len) if (searchlen > dir->max_len)
searchlen = dir->max_len; searchlen = dir->max_len;
uint16_t proto = ALPROTO_UNKNOWN; uint32_t search_cnt = 0;
uint32_t cnt = 0;
/* do the mpm search */ /* do the mpm search */
cnt = mpm_table[dir->mpm_ctx.mpm_type].Search(&dir->mpm_ctx, search_cnt = mpm_table[dir->mpm_ctx.mpm_type].Search(&dir->mpm_ctx,
&tdir->mpm_ctx, &tdir->mpm_ctx,
&tdir->pmq, buf, &tdir->pmq, buf,
searchlen); searchlen);
SCLogDebug("search cnt %" PRIu32 "", cnt); SCLogDebug("search cnt %" PRIu32 "", search_cnt);
if (cnt == 0) { if (search_cnt == 0)
proto = ALPROTO_UNKNOWN;
goto end;
}
/* We just work with the first match */
uint16_t patid = tdir->pmq.pattern_id_array[0];
SCLogDebug("array count is %"PRIu32" patid %"PRIu16"",
tdir->pmq.pattern_id_array_cnt, patid);
AlpProtoSignature *s = ctx->map[patid];
if (s == NULL) {
goto end; goto end;
}
uint8_t s_cnt = 1;
while (proto == ALPROTO_UNKNOWN && s != NULL) {
proto = AlpProtoMatchSignature(s, buf, buflen, ipproto);
s = s->map_next; /* alproto bit field */
if (s == NULL && s_cnt < tdir->pmq.pattern_id_array_cnt) { uint8_t pm_results_bf[ALPROTO_MAX / 8];
patid = tdir->pmq.pattern_id_array[s_cnt]; memset(pm_results_bf, 0, sizeof(pm_results_bf));
s = ctx->map[patid];
s_cnt++; for (uint8_t s_cnt = 0; s_cnt < search_cnt; s_cnt++) {
AlpProtoSignature *s = ctx->map[tdir->pmq.pattern_id_array[s_cnt]];
SCLogDebug("array count is %"PRIu32" patid %"PRIu16"",
tdir->pmq.pattern_id_array_cnt,
tdir->pmq.pattern_id_array[s_cnt]);
while (s != NULL) {
uint16_t proto = AlpProtoMatchSignature(s, buf, buflen, ipproto);
if (proto != ALPROTO_UNKNOWN && !(pm_results_bf[proto / 8] & (1 << (proto % 8))) ) {
pm_results[pm_matches++] = proto;
pm_results_bf[proto / 8] |= 1 << (proto % 8);
}
s = s->map_next;
} }
} }
@ -479,7 +477,7 @@ end:
break; break;
} }
#endif #endif
SCReturnUInt(proto); SCReturnUInt(pm_matches);
} }
/** /**
@ -581,8 +579,6 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
uint8_t *buf, uint32_t buflen, uint8_t *buf, uint32_t buflen,
uint8_t flags, uint8_t ipproto) uint8_t flags, uint8_t ipproto)
{ {
uint16_t alproto = ALPROTO_UNKNOWN;
if (flags & STREAM_TOSERVER) { if (flags & STREAM_TOSERVER) {
if (buflen >= alp_proto_ctx.toserver.max_len) { if (buflen >= alp_proto_ctx.toserver.max_len) {
if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) { if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) {
@ -590,10 +586,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
* upto the probing parser */ * upto the probing parser */
; ;
} else { } else {
alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, uint16_t pm_results[ALPROTO_MAX];
flags, ipproto); if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
if (alproto != ALPROTO_UNKNOWN) flags, ipproto, pm_results) != 0) {
return alproto; return pm_results[0];
}
/* the alproto hasn't been detected at this point */ /* the alproto hasn't been detected at this point */
if (f->flags & FLOW_TS_PP_ALPROTO_DETECT_DONE) { if (f->flags & FLOW_TS_PP_ALPROTO_DETECT_DONE) {
f->flags |= FLOW_TS_PM_PP_ALPROTO_DETECT_DONE; f->flags |= FLOW_TS_PM_PP_ALPROTO_DETECT_DONE;
@ -602,10 +599,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
f->flags |= FLOW_TS_PM_ALPROTO_DETECT_DONE; f->flags |= FLOW_TS_PM_ALPROTO_DETECT_DONE;
} }
} else { } else {
alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, uint16_t pm_results[ALPROTO_MAX];
flags, ipproto); if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
if (alproto != ALPROTO_UNKNOWN) flags, ipproto, pm_results) != 0) {
return alproto; return pm_results[0];
}
} }
/* If we have reached here, the PM parser has failed to detect the /* If we have reached here, the PM parser has failed to detect the
* alproto */ * alproto */
@ -618,10 +616,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) { if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) {
; ;
} else { } else {
alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, uint16_t pm_results[ALPROTO_MAX];
flags, ipproto); if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
if (alproto != ALPROTO_UNKNOWN) flags, ipproto, pm_results) != 0) {
return alproto; return pm_results[0];
}
if (f->flags & FLOW_TC_PP_ALPROTO_DETECT_DONE) { if (f->flags & FLOW_TC_PP_ALPROTO_DETECT_DONE) {
f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE; f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE;
return ALPROTO_UNKNOWN; return ALPROTO_UNKNOWN;
@ -629,10 +628,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx,
f->flags |= FLOW_TC_PM_ALPROTO_DETECT_DONE; f->flags |= FLOW_TC_PM_ALPROTO_DETECT_DONE;
} }
} else { } else {
alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, uint16_t pm_results[ALPROTO_MAX];
flags, ipproto); if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen,
if (alproto != ALPROTO_UNKNOWN) flags, ipproto, pm_results) != 0) {
return alproto; return pm_results[0];
}
} }
return AppLayerDetectGetProtoProbingParser(ctx, f, buf, buflen, return AppLayerDetectGetProtoProbingParser(ctx, f, buf, buflen,
flags, ipproto); flags, ipproto);
@ -875,9 +875,10 @@ int AlpDetectTest05(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); uint16_t pm_results[ALPROTO_MAX];
if (proto != ALPROTO_HTTP) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); if (pm_results[0] != ALPROTO_HTTP) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
r = 0; r = 0;
} }
@ -921,9 +922,10 @@ int AlpDetectTest06(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); uint16_t pm_results[ALPROTO_MAX];
if (proto != ALPROTO_FTP) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_FTP); if (pm_results[0] != ALPROTO_FTP) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_FTP);
r = 0; r = 0;
} }
@ -955,9 +957,10 @@ int AlpDetectTest07(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); uint16_t pm_results[ALPROTO_MAX];
if (proto != ALPROTO_UNKNOWN) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_UNKNOWN); if (pm_results[0] != ALPROTO_UNKNOWN) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_UNKNOWN);
r = 0; r = 0;
} }
@ -1000,9 +1003,10 @@ int AlpDetectTest08(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); uint16_t pm_results[ALPROTO_MAX];
if (proto != ALPROTO_SMB) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_SMB); if (pm_results[0] != ALPROTO_SMB) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_SMB);
r = 0; r = 0;
} }
@ -1042,9 +1046,10 @@ int AlpDetectTest09(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); uint16_t pm_results[ALPROTO_MAX];
if (proto != ALPROTO_SMB2) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_SMB2); if (pm_results[0] != ALPROTO_SMB2) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_SMB2);
r = 0; r = 0;
} }
@ -1080,9 +1085,10 @@ int AlpDetectTest10(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); uint16_t pm_results[ALPROTO_MAX];
if (proto != ALPROTO_DCERPC) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_DCERPC); if (pm_results[0] != ALPROTO_DCERPC) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_DCERPC);
r = 0; r = 0;
} }
@ -1122,15 +1128,16 @@ int AlpDetectTest11(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); uint16_t pm_results[ALPROTO_MAX];
if (proto == ALPROTO_HTTP) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); if (pm_results[0] == ALPROTO_HTTP) {
printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
r = 0; r = 0;
} }
proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP); AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP, pm_results);
if (proto != ALPROTO_HTTP) { if (pm_results[0] != ALPROTO_HTTP) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
r = 0; r = 0;
} }
@ -1211,15 +1218,16 @@ int AlpDetectTest13(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); uint16_t pm_results[ALPROTO_MAX];
if (proto == ALPROTO_HTTP) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results);
printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); if (pm_results[0] == ALPROTO_HTTP) {
printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
r = 0; r = 0;
} }
proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP); AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP, pm_results);
if (proto == ALPROTO_HTTP) { if (pm_results[0] == ALPROTO_HTTP) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
r = 0; r = 0;
} }
@ -1262,15 +1270,16 @@ int AlpDetectTest14(void) {
AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeGlobal(&ctx);
AlpProtoFinalizeThread(&ctx, &tctx); AlpProtoFinalizeThread(&ctx, &tctx);
uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_UDP); uint16_t pm_results[ALPROTO_MAX];
if (proto == ALPROTO_HTTP) { AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_UDP, pm_results);
printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); if (pm_results[0] == ALPROTO_HTTP) {
printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
r = 0; r = 0;
} }
proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_UDP); AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_UDP, pm_results);
if (proto != ALPROTO_HTTP) { if (pm_results[0] != ALPROTO_HTTP) {
printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP);
r = 0; r = 0;
} }

@ -84,10 +84,11 @@ void *AppLayerDetectProtoThread(void *td);
void AppLayerDetectProtoThreadInit(void); void AppLayerDetectProtoThreadInit(void);
uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *, uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx,
AlpProtoDetectThreadCtx *, AlpProtoDetectThreadCtx *tctx,
uint8_t *, uint16_t, uint8_t *buf, uint16_t buflen,
uint8_t, uint8_t); uint8_t flags, uint8_t ipproto,
uint16_t *pm_results);
uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *, Flow *, uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *, Flow *,
uint8_t *, uint32_t, uint8_t *, uint32_t,
uint8_t, uint8_t); uint8_t, uint8_t);

Loading…
Cancel
Save