From 7c31a2327eecf494c871a0ba266ea202a5e69668 Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Fri, 29 Apr 2011 17:18:06 +0530 Subject: [PATCH] Add support for port based probing parsers for alproto detection --- src/app-layer-detect-proto.c | 193 ++- src/app-layer-detect-proto.h | 11 +- src/app-layer-parser.c | 3105 +++++++++++++++++++++++++++++++++- src/app-layer-parser.h | 52 + src/app-layer.c | 13 +- src/flow.h | 47 +- 6 files changed, 3376 insertions(+), 45 deletions(-) diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index d8625bb4a5..9e35facb22 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -344,7 +344,8 @@ void AppLayerDetectProtoThreadInit(void) { } /** - * \brief Get the app layer proto based on a buffer + * \brief Get the app layer proto based on a buffer using a Patter matcher + * parser. * * \param ctx Global app layer detection context * \param tctx Thread app layer detection context @@ -354,7 +355,10 @@ void AppLayerDetectProtoThreadInit(void) { * * \retval proto App Layer proto, or ALPROTO_UNKNOWN if unknown */ -uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx, AlpProtoDetectThreadCtx *tctx, uint8_t *buf, uint16_t buflen, uint8_t flags, uint8_t ipproto) { +uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *ctx, + AlpProtoDetectThreadCtx *tctx, + uint8_t *buf, uint16_t buflen, + uint8_t flags, uint8_t ipproto) { SCEnter(); AlpProtoDetectDirection *dir; @@ -500,6 +504,167 @@ end: SCReturnUInt(proto); } +/** + * \brief Call the probing parser if it exists for this src or dst port. + */ +uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *ctx, Flow *f, + uint8_t *buf, uint16_t buflen, + uint8_t flags, uint8_t ipproto) +{ + AppLayerProbingParserElement *pe = NULL; + AppLayerProbingParser *pp = NULL; + + if (flags & STREAM_TOSERVER) { + pp = AppLayerGetProbingParsers(ipproto, f->dp); + if (pp == NULL) { + SCLogDebug("toserver-No probing parser registered for port %"PRIu16, + f->dp); + if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) { + f->flags |= FLOW_TS_PM_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + f->flags |= FLOW_TS_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + if (pp->toserver_max_depth != 0 && buflen > pp->toserver_max_depth) { + if (f->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) { + f->flags |= FLOW_TS_PM_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + f->flags |= FLOW_TS_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + pe = pp->toserver; + } else { + pp = AppLayerGetProbingParsers(ipproto, f->sp); + if (pp == NULL) { + SCLogDebug("toclient-No probing parser registered for port %"PRIu16, + f->sp); + if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) { + f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + f->flags |= FLOW_TC_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + if (pp->toclient_max_depth != 0 && buflen > pp->toclient_max_depth) { + if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) { + f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + f->flags |= FLOW_TC_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + pe = pp->toclient; + } + + while (pe != NULL) { + if (buflen < pe->min_depth || + (pe->max_depth != 0 && buflen > pe->max_depth)) { + pe = pe->next; + continue; + } + + uint16_t alproto = pe->ProbingParser(buf, buflen); + if (alproto != ALPROTO_UNKNOWN) + return alproto; + + pe = pe->next; + } + + return ALPROTO_UNKNOWN; +} + +/** + * \brief Get the app layer proto. + * + * \param ctx Global app layer detection context. + * \param tctx Thread app layer detection context. + * \param f Pointer to the flow. + * \param buf Pointer to the buffer to inspect. + * \param buflen Lenght of the buffer. + * \param flags Flags. + * + * \retval proto App Layer proto, or ALPROTO_UNKNOWN if unknown + */ +uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *ctx, + AlpProtoDetectThreadCtx *tctx, Flow *f, + 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) { + /* the PM parser has already tried and failed. Now it is + * upto the probing parser */ + ; + } else { + alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, + flags, ipproto); + if (alproto != ALPROTO_UNKNOWN) + return alproto; + /* 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; + return ALPROTO_UNKNOWN; + } + f->flags |= FLOW_TS_PM_ALPROTO_DETECT_DONE; + } + } else { + alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, + flags, ipproto); + if (alproto != ALPROTO_UNKNOWN) + return alproto; + } + /* If we have reached here, the PM parser has failed to detect the + * alproto. + * + * Check if the probing parser has already finished its duties. If it + * has, set flag to indicate both parsers have done all they could have + * to detect the alproto and failed. If it isn't through as yet, run + * the probing parser */ + if (flags & FLOW_TS_PP_ALPROTO_DETECT_DONE) { + f->flags |= FLOW_TS_PM_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } else { + return AppLayerDetectGetProtoProbingParser(ctx, f, buf, buflen, + flags, ipproto); + } + + /* STREAM_TOCLIENT */ + } else { + if (buflen >= alp_proto_ctx.toclient.max_len) { + if (f->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE) { + ; + } else { + alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, + flags, ipproto); + if (alproto != ALPROTO_UNKNOWN) + return alproto; + if (f->flags & FLOW_TC_PP_ALPROTO_DETECT_DONE) { + f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } + f->flags |= FLOW_TC_PM_ALPROTO_DETECT_DONE; + } + } else { + alproto = AppLayerDetectGetProtoPMParser(ctx, tctx, buf, buflen, + flags, ipproto); + if (alproto != ALPROTO_UNKNOWN) + return alproto; + } + if (flags & FLOW_TC_PP_ALPROTO_DETECT_DONE) { + f->flags |= FLOW_TC_PM_PP_ALPROTO_DETECT_DONE; + return ALPROTO_UNKNOWN; + } else { + return AppLayerDetectGetProtoProbingParser(ctx, f, buf, buflen, + flags, ipproto); + } + } +} + /* VJ Originally I thought of having separate app layer * handling threads, leaving this here in case we'll revisit that */ #if 0 @@ -816,7 +981,7 @@ int AlpDetectTest05(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); if (proto != ALPROTO_HTTP) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); r = 0; @@ -885,7 +1050,7 @@ int AlpDetectTest06(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); if (proto != ALPROTO_FTP) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_FTP); r = 0; @@ -942,7 +1107,7 @@ int AlpDetectTest07(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); if (proto != ALPROTO_UNKNOWN) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_UNKNOWN); r = 0; @@ -1010,7 +1175,7 @@ int AlpDetectTest08(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); if (proto != ALPROTO_SMB) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_SMB); r = 0; @@ -1075,7 +1240,7 @@ int AlpDetectTest09(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); if (proto != ALPROTO_SMB2) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_SMB2); r = 0; @@ -1135,7 +1300,7 @@ int AlpDetectTest10(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data,sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); if (proto != ALPROTO_DCERPC) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_DCERPC); r = 0; @@ -1192,13 +1357,13 @@ int AlpDetectTest11(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); if (proto == ALPROTO_HTTP) { printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); r = 0; } - proto = AppLayerDetectGetProto(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP); + proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP); if (proto != ALPROTO_HTTP) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); r = 0; @@ -1281,13 +1446,13 @@ int AlpDetectTest13(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_TCP); if (proto == ALPROTO_HTTP) { printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); r = 0; } - proto = AppLayerDetectGetProto(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP); + proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_TCP); if (proto == ALPROTO_HTTP) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); r = 0; @@ -1332,13 +1497,13 @@ int AlpDetectTest14(void) { AlpProtoFinalizeGlobal(&ctx); AlpProtoFinalizeThread(&ctx, &tctx); - uint8_t proto = AppLayerDetectGetProto(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_UDP); + uint8_t proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data, sizeof(l7data), STREAM_TOCLIENT, IPPROTO_UDP); if (proto == ALPROTO_HTTP) { printf("proto %" PRIu8 " == %" PRIu8 ": ", proto, ALPROTO_HTTP); r = 0; } - proto = AppLayerDetectGetProto(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_UDP); + proto = AppLayerDetectGetProtoPMParser(&ctx, &tctx, l7data_resp, sizeof(l7data_resp), STREAM_TOSERVER, IPPROTO_UDP); if (proto != ALPROTO_HTTP) { printf("proto %" PRIu8 " != %" PRIu8 ": ", proto, ALPROTO_HTTP); r = 0; diff --git a/src/app-layer-detect-proto.h b/src/app-layer-detect-proto.h index aaefb39547..1a327634d9 100644 --- a/src/app-layer-detect-proto.h +++ b/src/app-layer-detect-proto.h @@ -82,7 +82,16 @@ void *AppLayerDetectProtoThread(void *td); void AppLayerDetectProtoThreadInit(void); -uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *, AlpProtoDetectThreadCtx *, uint8_t *, uint16_t, uint8_t, uint8_t); +uint16_t AppLayerDetectGetProtoPMParser(AlpProtoDetectCtx *, + AlpProtoDetectThreadCtx *, + uint8_t *, uint16_t, + uint8_t, uint8_t); +uint16_t AppLayerDetectGetProtoProbingParser(AlpProtoDetectCtx *, Flow *, + uint8_t *, uint16_t, + uint8_t, uint8_t); +uint16_t AppLayerDetectGetProto(AlpProtoDetectCtx *, AlpProtoDetectThreadCtx *, + Flow *, uint8_t *, uint32_t, + uint8_t, uint8_t); void AlpProtoAdd(AlpProtoDetectCtx *, uint16_t, uint16_t, char *, uint16_t, uint16_t, uint8_t); void AppLayerDetectProtoThreadSpawn(void); diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index e862ff1ac1..51d56a22d4 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -1315,7 +1315,285 @@ void AppLayerParsersInitPostProcess(void) } } -/* UNITTESTS*/ +/********************************Probing Parsers*******************************/ + +AppLayerProbingParser *probing_parsers = NULL; + +static AppLayerProbingParserElement * +AppLayerCreateAppLayerProbingParserElement(const char *al_proto_name, + uint16_t al_proto, + uint16_t min_depth, + uint16_t max_depth, + uint16_t port, + uint8_t priority, + uint8_t top, + uint16_t (*AppLayerProbingParser) + (uint8_t *input, uint32_t input_len)) +{ + AppLayerProbingParserElement *pe = SCMalloc(sizeof(AppLayerProbingParserElement)); + if (pe == NULL) { + return NULL; + } + + pe->al_proto_name = al_proto_name; + pe->al_proto = al_proto; + pe->min_depth = min_depth; + pe->max_depth = max_depth; + pe->port = port; + pe->priority = priority; + pe->top = top; + pe->ProbingParser = AppLayerProbingParser; + pe->next = NULL; + + return pe; +} + +static void AppLayerInsertNewProbingParserElement(AppLayerProbingParserElement *new_pe, + uint8_t flags) +{ + AppLayerProbingParser *pp = probing_parsers; + while (pp != NULL) { + if (pp->port == new_pe->port) { + break; + } + pp = pp->next; + } + + if (pp == NULL) { + AppLayerProbingParser *new_pp = SCMalloc(sizeof(AppLayerProbingParser)); + if (new_pp == NULL) + return; + memset(new_pp, 0, sizeof(AppLayerProbingParser)); + + new_pp->port = new_pe->port; + + if (probing_parsers == NULL) { + probing_parsers = new_pp; + } else { + AppLayerProbingParser *pp = probing_parsers; + while (pp->next != NULL) { + pp = pp->next; + } + pp->next = new_pp; + } + + pp = new_pp; + } + + AppLayerProbingParserElement *pe = NULL; + if (flags & STREAM_TOSERVER) { + pe = pp->toserver; + } else { + pe = pp->toclient; + } + + if (pe == NULL) { + if (flags & STREAM_TOSERVER) { + pp->toserver = new_pe; + pp->toserver_max_depth = new_pe->max_depth; + } else { + pp->toclient = new_pe; + pp->toclient_max_depth = new_pe->max_depth; + } + } else { + uint8_t break_priority; + if (new_pe->top) { + break_priority = new_pe->priority; + } else { + break_priority = new_pe->priority + 1; + } + + AppLayerProbingParserElement *prev_pe = pe; + while (pe != NULL) { + if (pe->priority < break_priority) { + prev_pe = pe; + pe = pe->next; + continue; + } + break; + } + if (prev_pe == pe) { + if (flags & STREAM_TOSERVER) { + new_pe->next = pp->toserver; + pp->toserver = new_pe; + } else { + new_pe->next = pp->toclient; + pp->toclient = new_pe; + } + } else { + new_pe->next = prev_pe->next; + prev_pe->next = new_pe; + } + + if (flags & STREAM_TOSERVER) { + if (new_pe->max_depth == 0) { + pp->toserver_max_depth = 0; + } else { + if (pp->toserver_max_depth != 0 && + pp->toserver_max_depth < new_pe->max_depth) { + pp->toserver_max_depth = new_pe->max_depth; + } + } + } else { + if (new_pe->max_depth == 0) { + pp->toclient_max_depth = 0; + } else { + if (pp->toclient_max_depth != 0 && + pp->toclient_max_depth < new_pe->max_depth) { + pp->toclient_max_depth = new_pe->max_depth; + } + } + } /* else - if (flags & STREAM_TOSERVER) */ + + } /* else - if (pe == NULL) */ + + return; +} + +void AppLayerPrintProbingParsers(void) +{ + AppLayerProbingParser *pp = probing_parsers; + AppLayerProbingParserElement *pe = NULL; + + printf("\n"); + while (pp != NULL) { + printf("Port: %"PRIu16 "\n", pp->port); + printf(" to_server: max-depth: %"PRIu16 "\n", pp->toserver_max_depth); + pe = pp->toserver; + while (pe != NULL) { + printf(" name: %s\n", pe->al_proto_name); + + if (pe->al_proto == ALPROTO_HTTP) + printf(" alproto: ALPROTO_HTTP\n"); + else if (pe->al_proto == ALPROTO_FTP) + printf(" alproto: ALPROTO_FTP\n"); + else if (pe->al_proto == ALPROTO_SMTP) + printf(" alproto: ALPROTO_SMTP\n"); + else if (pe->al_proto == ALPROTO_TLS) + printf(" alproto: ALPROTO_TLS\n"); + else if (pe->al_proto == ALPROTO_SSH) + printf(" alproto: ALPROTO_SSH\n"); + else if (pe->al_proto == ALPROTO_IMAP) + printf(" alproto: ALPROTO_IMAP\n"); + else if (pe->al_proto == ALPROTO_MSN) + printf(" alproto: ALPROTO_MSN\n"); + else if (pe->al_proto == ALPROTO_JABBER) + printf(" alproto: ALPROTO_JABBER\n"); + else if (pe->al_proto == ALPROTO_SMB) + printf(" alproto: ALPROTO_SMB\n"); + else if (pe->al_proto == ALPROTO_SMB2) + printf(" alproto: ALPROTO_SMB2\n"); + else if (pe->al_proto == ALPROTO_DCERPC) + printf(" alproto: ALPROTO_DCERPC\n"); + else if (pe->al_proto == ALPROTO_DCERPC_UDP) + printf(" alproto: ALPROTO_DCERPC_UDP\n"); + else + printf("impossible\n"); + + printf(" port: %"PRIu16 "\n", pe->port); + + if (pe->priority == APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + printf(" priority: HIGH\n"); + else if (pe->priority == APP_LAYER_PROBING_PARSER_PRIORITY_MEDIUM) + printf(" priority: MEDIUM\n"); + else if (pe->priority == APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + printf(" priority: LOW\n"); + else + printf(" priority: impossible\n"); + + printf(" top: %"PRIu8 "\n", pe->top); + + printf(" min_depth: %"PRIu32 "\n", pe->min_depth); + printf(" max_depth: %"PRIu32 "\n", pe->max_depth); + + printf("\n"); + pe = pe->next; + } + printf(" to_client: max-depth: %"PRIu16 "\n", pp->toclient_max_depth); + pp = pp->next; + } + + return; +} + +void AppLayerRegisterProbingParser(uint16_t port, + uint16_t ip_proto, + const char *al_proto_name, + uint16_t al_proto, + uint16_t min_depth, + uint16_t max_depth, + uint8_t flags, + uint8_t priority, + uint8_t top, + uint16_t (*ProbingParser) + (uint8_t *input, uint32_t input_len)) +{ + AppLayerProbingParserElement *pe = NULL; + AppLayerProbingParser *pp = AppLayerGetProbingParsers(ip_proto, port); + if (pp != NULL) { + if (flags & STREAM_TOSERVER) { + pe = pp->toserver; + } else { + pe = pp->toclient; + } + } + + /* check if this parser has already been registered for this port + dir */ + if (pe != NULL) { + AppLayerProbingParserElement *tmp_pe = pe; + while (tmp_pe != NULL) { + if (pe->al_proto == al_proto || + strcmp(pe->al_proto_name, al_proto_name) == 0) { + /* looks like we have it registered for this port + dir */ + SCLogWarning(SC_ERR_ALPARSER, "App layer probing parser already " + "registered for this port, direction"); + return; + } + tmp_pe = tmp_pe->next; + } + } + + /* Get a new parser element */ + AppLayerProbingParserElement *new_pe = + AppLayerCreateAppLayerProbingParserElement(al_proto_name, al_proto, + min_depth, max_depth, + port, priority, top, + ProbingParser); + if (new_pe == NULL) + return; + + AppLayerInsertNewProbingParserElement(new_pe, flags); + return; +} + +void AppLayerFreeProbingParsers(void) +{ + while (probing_parsers != NULL) { + AppLayerProbingParserElement *pe; + AppLayerProbingParserElement *next_pe; + + pe = probing_parsers->toserver; + while (pe != NULL) { + next_pe = pe->next; + SCFree(pe); + pe = next_pe; + } + + pe = probing_parsers->toclient; + while (pe != NULL) { + next_pe = pe->next; + SCFree(pe); + pe = next_pe; + } + + probing_parsers = probing_parsers->next; + } + + return; +} + +/**************************************Unittests*******************************/ + #ifdef UNITTESTS typedef struct TestState_ { @@ -1473,12 +1751,2825 @@ end: return result; } -#endif /* UNITESTS */ +static int AppLayerProbingParserTest01(void) +{ + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + if (probing_parsers == NULL) + return 0; + + AppLayerFreeProbingParsers(); + return 1; +} -void AppLayerParserRegisterTests(void) +static int AppLayerProbingParserTest02(void) { -#ifdef UNITTESTS - UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01, 1); - UtRegisterTest("AppLayerParserTest02", AppLayerParserTest02, 1); -#endif /* UNITTESTS */ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest03(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest04(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest05(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest06(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 0, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest07(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest08(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest09(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest10(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 0, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 10) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next == NULL) + goto end; + if (pp->toserver->next->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* third one */ + pe = pp->toserver->next->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest11(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(81, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + /* first pp */ + if (pp->toclient != NULL) + goto end; + if (pp->next == NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp */ + if (pp->next->next != NULL) + goto end; + if (pp->next->toclient != NULL) + goto end; + if (pp->next->port != 81) + goto end; + if (pp->next->toserver_max_depth != 10) + goto end; + if (pp->next->toclient_max_depth != 0) + goto end; + if (pp->next->toserver == NULL) + goto end; + if (pp->next->toserver->next != NULL) + goto end; + /* second pp - first one */ + pe = pp->next->toserver; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(81, + IPPROTO_TCP, + "ftp", + ALPROTO_FTP, + 7, 15, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + /* first pp */ + if (pp->toclient != NULL) + goto end; + if (pp->next == NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp */ + if (pp->next->next != NULL) + goto end; + if (pp->next->toclient != NULL) + goto end; + if (pp->next->port != 81) + goto end; + if (pp->next->toserver_max_depth != 15) + goto end; + if (pp->next->toclient_max_depth != 0) + goto end; + if (pp->next->toserver == NULL) + goto end; + if (pp->next->toserver->next == NULL) + goto end; + if (pp->next->toserver->next->next != NULL) + goto end; + /* second pp - first one */ + pe = pp->next->toserver; + if (strcmp(pe->al_proto_name, "ftp") != 0) + goto end; + if (pe->al_proto != ALPROTO_FTP) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 7) + goto end; + if (pe->max_depth != 15) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp - second one */ + pe = pp->next->toserver->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest12(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(81, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + /* first pp */ + if (pp->toclient != NULL) + goto end; + if (pp->next == NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp */ + if (pp->next->next != NULL) + goto end; + if (pp->next->toclient != NULL) + goto end; + if (pp->next->port != 81) + goto end; + if (pp->next->toserver_max_depth != 10) + goto end; + if (pp->next->toclient_max_depth != 0) + goto end; + if (pp->next->toserver == NULL) + goto end; + if (pp->next->toserver->next != NULL) + goto end; + /* second pp - first one */ + pe = pp->next->toserver; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next == NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp */ + if (pp->next->next != NULL) + goto end; + if (pp->next->toclient != NULL) + goto end; + if (pp->next->port != 81) + goto end; + if (pp->next->toserver_max_depth != 10) + goto end; + if (pp->next->toclient_max_depth != 0) + goto end; + if (pp->next->toserver == NULL) + goto end; + if (pp->next->toserver->next != NULL) + goto end; + /* second pp - first one */ + pe = pp->next->toserver; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(81, + IPPROTO_TCP, + "ftp", + ALPROTO_FTP, + 7, 15, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + /* first pp */ + if (pp->toclient != NULL) + goto end; + if (pp->next == NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp */ + if (pp->next->next != NULL) + goto end; + if (pp->next->toclient != NULL) + goto end; + if (pp->next->port != 81) + goto end; + if (pp->next->toserver_max_depth != 15) + goto end; + if (pp->next->toclient_max_depth != 0) + goto end; + if (pp->next->toserver == NULL) + goto end; + if (pp->next->toserver->next == NULL) + goto end; + if (pp->next->toserver->next->next != NULL) + goto end; + /* second pp - first one */ + pe = pp->next->toserver; + if (strcmp(pe->al_proto_name, "ftp") != 0) + goto end; + if (pe->al_proto != ALPROTO_FTP) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 7) + goto end; + if (pe->max_depth != 15) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp - second one */ + pe = pp->next->toserver->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +static int AppLayerProbingParserTest13(void) +{ + int result = 0; + AppLayerProbingParser *pp; + AppLayerProbingParserElement *pe; + + AppLayerFreeProbingParsers(); + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "http", + ALPROTO_HTTP, + 5, 8, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next != NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(81, + IPPROTO_TCP, + "dcerpc", + ALPROTO_DCERPC, + 9, 10, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_LOW, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + /* first pp */ + if (pp->toclient != NULL) + goto end; + if (pp->next == NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp */ + if (pp->next->next != NULL) + goto end; + if (pp->next->toclient != NULL) + goto end; + if (pp->next->port != 81) + goto end; + if (pp->next->toserver_max_depth != 10) + goto end; + if (pp->next->toclient_max_depth != 0) + goto end; + if (pp->next->toserver == NULL) + goto end; + if (pp->next->toserver->next != NULL) + goto end; + /* second pp - first one */ + pe = pp->next->toserver; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(80, + IPPROTO_TCP, + "smb", + ALPROTO_SMB, + 5, 5, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 0, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + if (pp->toclient != NULL) + goto end; + if (pp->next == NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp */ + if (pp->next->next != NULL) + goto end; + if (pp->next->toclient != NULL) + goto end; + if (pp->next->port != 81) + goto end; + if (pp->next->toserver_max_depth != 10) + goto end; + if (pp->next->toclient_max_depth != 0) + goto end; + if (pp->next->toserver == NULL) + goto end; + if (pp->next->toserver->next != NULL) + goto end; + /* second pp - first one */ + pe = pp->next->toserver; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerRegisterProbingParser(81, + IPPROTO_TCP, + "ftp", + ALPROTO_FTP, + 7, 15, + STREAM_TOSERVER, + APP_LAYER_PROBING_PARSER_PRIORITY_HIGH, 1, + NULL); + pp = probing_parsers; + if (probing_parsers == NULL) { + goto end; + } + /* first pp */ + if (pp->toclient != NULL) + goto end; + if (pp->next == NULL) + goto end; + if (pp->port != 80) + goto end; + if (pp->toserver_max_depth != 8) + goto end; + if (pp->toclient_max_depth != 0) + goto end; + if (pp->toserver == NULL) + goto end; + if (pp->toserver->next == NULL) + goto end; + if (pp->toserver->next->next != NULL) + goto end; + /* first one */ + pe = pp->toserver; + if (strcmp(pe->al_proto_name, "http") != 0) + goto end; + if (pe->al_proto != ALPROTO_HTTP) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 8) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second one */ + pe = pp->toserver->next; + if (strcmp(pe->al_proto_name, "smb") != 0) + goto end; + if (pe->al_proto != ALPROTO_SMB) + goto end; + if (pe->port != 80) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 5) + goto end; + if (pe->max_depth != 5) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp */ + if (pp->next->next != NULL) + goto end; + if (pp->next->toclient != NULL) + goto end; + if (pp->next->port != 81) + goto end; + if (pp->next->toserver_max_depth != 15) + goto end; + if (pp->next->toclient_max_depth != 0) + goto end; + if (pp->next->toserver == NULL) + goto end; + if (pp->next->toserver->next == NULL) + goto end; + if (pp->next->toserver->next->next != NULL) + goto end; + /* second pp - first one */ + pe = pp->next->toserver; + if (strcmp(pe->al_proto_name, "ftp") != 0) + goto end; + if (pe->al_proto != ALPROTO_FTP) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_HIGH) + goto end; + if (pe->min_depth != 7) + goto end; + if (pe->max_depth != 15) + goto end; + if (pe->ProbingParser != NULL) + goto end; + /* second pp - second one */ + pe = pp->next->toserver->next; + if (strcmp(pe->al_proto_name, "dcerpc") != 0) + goto end; + if (pe->al_proto != ALPROTO_DCERPC) + goto end; + if (pe->port != 81) + goto end; + if (pe->priority != APP_LAYER_PROBING_PARSER_PRIORITY_LOW) + goto end; + if (pe->min_depth != 9) + goto end; + if (pe->max_depth != 10) + goto end; + if (pe->ProbingParser != NULL) + goto end; + + AppLayerPrintProbingParsers(); + + result = 1; + + end: + AppLayerFreeProbingParsers(); + return result; +} + +#endif /* UNITESTS */ + +void AppLayerParserRegisterTests(void) +{ +#ifdef UNITTESTS + UtRegisterTest("AppLayerParserTest01", AppLayerParserTest01, 1); + UtRegisterTest("AppLayerParserTest02", AppLayerParserTest02, 1); + UtRegisterTest("AppLayerProbingParserTest01", AppLayerProbingParserTest01, 1); + UtRegisterTest("AppLayerProbingParserTest02", AppLayerProbingParserTest02, 1); + UtRegisterTest("AppLayerProbingParserTest03", AppLayerProbingParserTest03, 1); + UtRegisterTest("AppLayerProbingParserTest04", AppLayerProbingParserTest04, 1); + UtRegisterTest("AppLayerProbingParserTest05", AppLayerProbingParserTest05, 1); + UtRegisterTest("AppLayerProbingParserTest06", AppLayerProbingParserTest06, 1); + UtRegisterTest("AppLayerProbingParserTest07", AppLayerProbingParserTest07, 1); + UtRegisterTest("AppLayerProbingParserTest08", AppLayerProbingParserTest08, 1); + UtRegisterTest("AppLayerProbingParserTest09", AppLayerProbingParserTest09, 1); + UtRegisterTest("AppLayerProbingParserTest10", AppLayerProbingParserTest10, 1); + UtRegisterTest("AppLayerProbingParserTest11", AppLayerProbingParserTest11, 1); + UtRegisterTest("AppLayerProbingParserTest12", AppLayerProbingParserTest12, 1); + UtRegisterTest("AppLayerProbingParserTest13", AppLayerProbingParserTest13, 1); +#endif /* UNITTESTS */ + + return; } diff --git a/src/app-layer-parser.h b/src/app-layer-parser.h index 623050bd1e..c5d139ac35 100644 --- a/src/app-layer-parser.h +++ b/src/app-layer-parser.h @@ -132,6 +132,58 @@ typedef struct AppLayerParserTableElement_ { to be a certain size */ } AppLayerParserTableElement; +typedef struct AppLayerProbingParserElement_ { + const char *al_proto_name; + uint16_t al_proto; + uint16_t port; + uint8_t priority; + uint8_t top; + /* the min length of data that has to be supplied to invoke the parser */ + uint32_t min_depth; + /* the max length of data after which this parser won't be invoked */ + uint32_t max_depth; + /* the probing parser function */ + uint16_t (*ProbingParser)(uint8_t *input, uint32_t input_len); + + struct AppLayerProbingParserElement_ *next; +} AppLayerProbingParserElement; + +typedef struct AppLayerProbingParser_ { + /* the port no for which probing parser(s) are invoked */ + uint16_t port; + /* the max depth for all the probing parsers registered for this port */ + uint16_t toserver_max_depth; + uint16_t toclient_max_depth; + + AppLayerProbingParserElement *toserver; + AppLayerProbingParserElement *toclient; + + struct AppLayerProbingParser_ *next; +} AppLayerProbingParser; + +#define APP_LAYER_PROBING_PARSER_PRIORITY_HIGH 1 +#define APP_LAYER_PROBING_PARSER_PRIORITY_MEDIUM 2 +#define APP_LAYER_PROBING_PARSER_PRIORITY_LOW 3 + +extern AppLayerProbingParser *probing_parsers; + +static inline AppLayerProbingParser *AppLayerGetProbingParsers(uint16_t ip_proto, + uint16_t port) +{ + if (probing_parsers == NULL) + return NULL; + + AppLayerProbingParser *pp = probing_parsers; + while (pp != NULL) { + if (pp->port == port) { + break; + } + pp = pp->next; + } + + return pp; +} + /* prototypes */ void AppLayerParsersInitPostProcess(void); void RegisterAppLayerParsers(void); diff --git a/src/app-layer.c b/src/app-layer.c index 95187f3c08..44e78a786d 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -153,7 +153,8 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f, printf("=> Init Stream Data -- end\n"); } #endif - alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, + + alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, f, data, data_len, flags, IPPROTO_TCP); if (alproto != ALPROTO_UNKNOWN) { /* store the proto and setup the L7 data array */ @@ -164,13 +165,13 @@ int AppLayerHandleTCPData(AlpProtoDetectThreadCtx *dp_ctx, Flow *f, } else { if (flags & STREAM_TOSERVER) { SCLogDebug("alp_proto_ctx.toserver.max_len %u", alp_proto_ctx.toserver.max_len); - if (data_len >= alp_proto_ctx.toserver.max_len) { + if (f->flags & FLOW_TS_PM_PP_ALPROTO_DETECT_DONE) { ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; SCLogDebug("ALPROTO_UNKNOWN flow %p", f); StreamTcpSetSessionNoReassemblyFlag(ssn, 0); } - } else if (flags & STREAM_TOCLIENT) { - if (data_len >= alp_proto_ctx.toclient.max_len) { + } else { + if (f->flags & FLOW_TC_PM_PP_ALPROTO_DETECT_DONE) { ssn->flags |= STREAMTCP_FLAG_APPPROTO_DETECTION_COMPLETED; SCLogDebug("ALPROTO_UNKNOWN flow %p", f); StreamTcpSetSessionNoReassemblyFlag(ssn, 1); @@ -326,7 +327,7 @@ int AppLayerHandleMsg(AlpProtoDetectThreadCtx *dp_ctx, StreamMsg *smsg) //PrintRawDataFp(stdout, smsg->init.data, smsg->init.data_len); //printf("=> Init Stream Data -- end\n"); - alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, + alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, f smsg->data.data, smsg->data.data_len, smsg->flow->alflags, IPPROTO_TCP); if (alproto != ALPROTO_UNKNOWN) { /* store the proto and setup the L7 data array */ @@ -480,7 +481,7 @@ int AppLayerHandleUdp(AlpProtoDetectThreadCtx *dp_ctx, Flow *f, Packet *p) //PrintRawDataFp(stdout, smsg->init.data, smsg->init.data_len); //printf("=> Init Stream Data -- end\n"); - alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, + alproto = AppLayerDetectGetProto(&alp_proto_ctx, dp_ctx, f, p->payload, p->payload_len, flags, IPPROTO_UDP); if (alproto != ALPROTO_UNKNOWN) { /* store the proto and setup the L7 data array */ diff --git a/src/flow.h b/src/flow.h index 85b7a1ad31..76a00483c7 100644 --- a/src/flow.h +++ b/src/flow.h @@ -38,44 +38,57 @@ /* per flow flags */ /** At least on packet from the source address was seen */ -#define FLOW_TO_SRC_SEEN 0x00000001 +#define FLOW_TO_SRC_SEEN 0x00000001 /** At least on packet from the destination address was seen */ -#define FLOW_TO_DST_SEEN 0x00000002 +#define FLOW_TO_DST_SEEN 0x00000002 /** Flow lives in the flow-state-NEW list */ -#define FLOW_NEW_LIST 0x00000004 +#define FLOW_NEW_LIST 0x00000004 /** Flow lives in the flow-state-EST (established) list */ -#define FLOW_EST_LIST 0x00000008 +#define FLOW_EST_LIST 0x00000008 /** Flow lives in the flow-state-CLOSED list */ -#define FLOW_CLOSED_LIST 0x00000010 +#define FLOW_CLOSED_LIST 0x00000010 /** Flow was inspected against IP-Only sigs in the toserver direction */ -#define FLOW_TOSERVER_IPONLY_SET 0x00000020 +#define FLOW_TOSERVER_IPONLY_SET 0x00000020 /** Flow was inspected against IP-Only sigs in the toclient direction */ -#define FLOW_TOCLIENT_IPONLY_SET 0x00000040 +#define FLOW_TOCLIENT_IPONLY_SET 0x00000040 /** Packet belonging to this flow should not be inspected at all */ -#define FLOW_NOPACKET_INSPECTION 0x00000080 +#define FLOW_NOPACKET_INSPECTION 0x00000080 /** Packet payloads belonging to this flow should not be inspected */ -#define FLOW_NOPAYLOAD_INSPECTION 0x00000100 +#define FLOW_NOPAYLOAD_INSPECTION 0x00000100 /** All packets in this flow should be dropped */ -#define FLOW_ACTION_DROP 0x00000200 +#define FLOW_ACTION_DROP 0x00000200 /** All packets in this flow should be accepted */ -#define FLOW_ACTION_PASS 0x00000400 +#define FLOW_ACTION_PASS 0x00000400 /** Sgh for toserver direction set (even if it's NULL) */ -#define FLOW_SGH_TOSERVER 0x00000800 +#define FLOW_SGH_TOSERVER 0x00000800 /** Sgh for toclient direction set (even if it's NULL) */ -#define FLOW_SGH_TOCLIENT 0x00001000 +#define FLOW_SGH_TOCLIENT 0x00001000 /** packet to server direction has been logged in drop file (only in IPS mode) */ -#define FLOW_TOSERVER_DROP_LOGGED 0x00002000 +#define FLOW_TOSERVER_DROP_LOGGED 0x00002000 /** packet to client direction has been logged in drop file (only in IPS mode) */ -#define FLOW_TOCLIENT_DROP_LOGGED 0x00004000 +#define FLOW_TOCLIENT_DROP_LOGGED 0x00004000 /** alproto detect done. Right now we need it only for udp */ -#define FLOW_ALPROTO_DETECT_DONE 0x00008000 -#define FLOW_NO_APPLAYER_INSPECTION 0x00010000 +#define FLOW_ALPROTO_DETECT_DONE 0x00008000 +#define FLOW_NO_APPLAYER_INSPECTION 0x00010000 + +/* Pattern matcher alproto detection done */ +#define FLOW_TS_PM_ALPROTO_DETECT_DONE 0x00020000 +/* Probing parser alproto detection done */ +#define FLOW_TS_PP_ALPROTO_DETECT_DONE 0x00040000 +/* Both pattern matcher and probing parser alproto detection done */ +#define FLOW_TS_PM_PP_ALPROTO_DETECT_DONE 0x00080000 +/* Pattern matcher alproto detection done */ +#define FLOW_TC_PM_ALPROTO_DETECT_DONE 0x00100000 +/* Probing parser alproto detection done */ +#define FLOW_TC_PP_ALPROTO_DETECT_DONE 0x00200000 +/* Both pattern matcher and probing parser alproto detection done */ +#define FLOW_TC_PM_PP_ALPROTO_DETECT_DONE 0x00400000 /* pkt flow flags */ #define FLOW_PKT_TOSERVER 0x01