diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index 231c8f7673..367de788ba 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -354,14 +354,18 @@ void AppLayerDetectProtoThreadInit(void) { * \param buflen Lenght of the buffer * \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, AlpProtoDetectThreadCtx *tctx, uint8_t *buf, uint16_t buflen, - uint8_t flags, uint8_t ipproto) { + uint8_t flags, uint8_t ipproto, + uint16_t *pm_results) { SCEnter(); + uint16_t pm_matches = 0; + pm_results[0] = ALPROTO_UNKNOWN; + AlpProtoDetectDirection *dir; AlpProtoDetectDirectionThread *tdir; @@ -374,7 +378,7 @@ uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx, } if (dir->id == 0) { - SCReturnUInt(ALPROTO_UNKNOWN); + SCReturnUInt(pm_matches); } /* see if we can limit the data we inspect */ @@ -382,39 +386,33 @@ uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx, if (searchlen > dir->max_len) searchlen = dir->max_len; - uint16_t proto = ALPROTO_UNKNOWN; - uint32_t cnt = 0; + uint32_t search_cnt = 0; /* do the mpm search */ - cnt = mpm_table[dir->mpm_ctx.mpm_type].Search(&dir->mpm_ctx, - &tdir->mpm_ctx, - &tdir->pmq, buf, - searchlen); - SCLogDebug("search cnt %" PRIu32 "", cnt); - if (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) { + search_cnt = mpm_table[dir->mpm_ctx.mpm_type].Search(&dir->mpm_ctx, + &tdir->mpm_ctx, + &tdir->pmq, buf, + searchlen); + SCLogDebug("search cnt %" PRIu32 "", search_cnt); + if (search_cnt == 0) goto end; - } - uint8_t s_cnt = 1; - - while (proto == ALPROTO_UNKNOWN && s != NULL) { - proto = AlpProtoMatchSignature(s, buf, buflen, ipproto); - s = s->map_next; - if (s == NULL && s_cnt < tdir->pmq.pattern_id_array_cnt) { - patid = tdir->pmq.pattern_id_array[s_cnt]; - s = ctx->map[patid]; - s_cnt++; + /* alproto bit field */ + uint8_t pm_results_bf[ALPROTO_MAX / 8]; + memset(pm_results_bf, 0, sizeof(pm_results_bf)); + + 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; } #endif - SCReturnUInt(proto); + SCReturnUInt(pm_matches); } /** @@ -581,8 +579,6 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx, uint8_t *buf, uint32_t buflen, uint8_t flags, uint8_t ipproto) { - uint16_t alproto = ALPROTO_UNKNOWN; - if (flags & STREAM_TOSERVER) { if (buflen >= alp_proto_ctx.toserver.max_len) { if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) { @@ -590,10 +586,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx, * upto the probing parser */ ; } else { - alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, - flags, ipproto); - if (alproto != ALPROTO_UNKNOWN) - return alproto; + uint16_t pm_results[ALPROTO_MAX]; + if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, + flags, ipproto, pm_results) != 0) { + return pm_results[0]; + } /* the alproto hasn't been detected at this point */ if (f->flags & FLOW_TS_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; } } else { - alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, - flags, ipproto); - if (alproto != ALPROTO_UNKNOWN) - return alproto; + uint16_t pm_results[ALPROTO_MAX]; + if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, + flags, ipproto, pm_results) != 0) { + return pm_results[0]; + } } /* If we have reached here, the PM parser has failed to detect the * alproto */ @@ -618,10 +616,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx, if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) { ; } else { - alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, - flags, ipproto); - if (alproto != ALPROTO_UNKNOWN) - return alproto; + uint16_t pm_results[ALPROTO_MAX]; + if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, + flags, ipproto, pm_results) != 0) { + return pm_results[0]; + } if (f->flags & FLOW_TC_PP_ALPROTO_DETECT_DONE) { f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE; return ALPROTO_UNKNOWN; @@ -629,10 +628,11 @@ uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx, f->flags |= FLOW_TC_PM_ALPROTO_DETECT_DONE; } } else { - alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, - flags, ipproto); - if (alproto != ALPROTO_UNKNOWN) - return alproto; + uint16_t pm_results[ALPROTO_MAX]; + if (AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, + flags, ipproto, pm_results) != 0) { + return pm_results[0]; + } } return AppLayerDetectGetProtoProbingParser(ctx, f, buf, buflen, flags, ipproto); @@ -875,9 +875,10 @@ int AlpDetectTest05(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); - if (proto != ALPROTO_HTTP) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results); + if (pm_results[0] != ALPROTO_HTTP) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP); r = 0; } @@ -921,9 +922,10 @@ int AlpDetectTest06(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); - if (proto != ALPROTO_FTP) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_FTP); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results); + if (pm_results[0] != ALPROTO_FTP) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_FTP); r = 0; } @@ -955,9 +957,10 @@ int AlpDetectTest07(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); - if (proto != ALPROTO_UNKNOWN) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_UNKNOWN); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results); + if (pm_results[0] != ALPROTO_UNKNOWN) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_UNKNOWN); r = 0; } @@ -1000,9 +1003,10 @@ int AlpDetectTest08(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); - if (proto != ALPROTO_SMB) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_SMB); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results); + if (pm_results[0] != ALPROTO_SMB) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_SMB); r = 0; } @@ -1042,9 +1046,10 @@ int AlpDetectTest09(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); - if (proto != ALPROTO_SMB2) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_SMB2); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results); + if (pm_results[0] != ALPROTO_SMB2) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_SMB2); r = 0; } @@ -1080,9 +1085,10 @@ int AlpDetectTest10(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); - if (proto != ALPROTO_DCERPC) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_DCERPC); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results); + if (pm_results[0] != ALPROTO_DCERPC) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_DCERPC); r = 0; } @@ -1122,15 +1128,16 @@ int AlpDetectTest11(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); - if (proto == ALPROTO_HTTP) { - printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results); + if (pm_results[0] == ALPROTO_HTTP) { + printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP); r = 0; } - proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP); - if (proto != ALPROTO_HTTP) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP, pm_results); + if (pm_results[0] != ALPROTO_HTTP) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP); r = 0; } @@ -1211,15 +1218,16 @@ int AlpDetectTest13(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); - if (proto == ALPROTO_HTTP) { - printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP, pm_results); + if (pm_results[0] == ALPROTO_HTTP) { + printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP); r = 0; } - proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP); - if (proto == ALPROTO_HTTP) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP, pm_results); + if (pm_results[0] == ALPROTO_HTTP) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP); r = 0; } @@ -1262,15 +1270,16 @@ int AlpDetectTest14(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_UDP); - if (proto == ALPROTO_HTTP) { - printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); + uint16_t pm_results[ALPROTO_MAX]; + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_UDP, pm_results); + if (pm_results[0] == ALPROTO_HTTP) { + printf("proto %" PRIu8 " == %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP); r = 0; } - proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_UDP); - if (proto != ALPROTO_HTTP) { - printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); + AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_UDP, pm_results); + if (pm_results[0] != ALPROTO_HTTP) { + printf("proto %" PRIu8 " != %" PRIu8 ": ", pm_results[0], ALPROTO_HTTP); r = 0; } diff --git a/src/app-layer-detect-proto.h b/src/app-layer-detect-proto.h index cfe254aca5..e482f0d351 100644 --- a/src/app-layer-detect-proto.h +++ b/src/app-layer-detect-proto.h @@ -84,10 +84,11 @@ void *AppLayerDetectProtoThread(void *td); void AppLayerDetectProtoThreadInit(void); -uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *, - AlpProtoDetectThreadCtx *, - uint8_t *, uint16_t, - uint8_t, uint8_t); +uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx, + AlpProtoDetectThreadCtx *tctx, + uint8_t *buf, uint16_t buflen, + uint8_t flags, uint8_t ipproto, + uint16_t *pm_results); uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *, Flow *, uint8_t *, uint32_t, uint8_t, uint8_t);