diff --git a/src/app-layer.c b/src/app-layer.c index a581aaaefe..5d0fa13581 100644 --- a/src/app-layer.c +++ b/src/app-layer.c @@ -116,10 +116,10 @@ void AppLayerIncTxCounter(ThreadVars *tv, Flow *f, uint64_t step) * * For IPS things are much simpler, and we don't use the flow * flag. We just tag the packet directly. */ -static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t dir) +static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t flags) { if (EngineModeIsIPS()) { - if (dir == STREAM_TOSERVER) { + if (flags & STREAM_TOSERVER) { if (p->flowflags & FLOW_PKT_TOSERVER) { p->flags |= PKT_PROTO_DETECT_TS_DONE; } else { @@ -133,7 +133,7 @@ static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t dir) } } } else { - if (dir == STREAM_TOSERVER) { + if (flags & STREAM_TOSERVER) { f->flags |= FLOW_PROTO_DETECT_TS_DONE; } else { f->flags |= FLOW_PROTO_DETECT_TC_DONE; @@ -141,7 +141,7 @@ static inline void FlagPacketFlow(Packet *p, Flow *f, uint8_t dir) } } -static void DisableAppLayer(Flow *f, Packet *p) +static void DisableAppLayer(ThreadVars *tv, Flow *f, Packet *p) { SCLogDebug("disable app layer for flow %p alproto %u ts %u tc %u", f, f->alproto, f->alproto_ts, f->alproto_tc); @@ -149,6 +149,7 @@ static void DisableAppLayer(Flow *f, Packet *p) TcpSession *ssn = f->protoctx; ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; f->alproto = ALPROTO_FAILED; + AppLayerIncFlowCounter(tv, f); if (f->alproto_tc != ALPROTO_FAILED) { if (f->alproto_tc == ALPROTO_UNKNOWN) { @@ -185,7 +186,8 @@ static void DisableAppLayer(Flow *f, Packet *p) * * Giving up means we disable applayer an set an applayer event */ -static void TCPProtoDetectCheckBailConditions(Flow *f, TcpSession *ssn, Packet *p) +static void TCPProtoDetectCheckBailConditions(ThreadVars *tv, + Flow *f, TcpSession *ssn, Packet *p) { uint32_t size_ts = ssn->client.last_ack - ssn->client.isn - 1; uint32_t size_tc = ssn->server.last_ack - ssn->server.isn - 1; @@ -253,7 +255,7 @@ static void TCPProtoDetectCheckBailConditions(Flow *f, TcpSession *ssn, Packet * return; failure: - DisableAppLayer(f, p); + DisableAppLayer(tv, f, p); return; } @@ -369,10 +371,7 @@ static int TCPProtoDetect(ThreadVars *tv, StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream); TcpSessionSetReassemblyDepth(ssn, AppLayerParserGetStreamDepth(f->proto, f->alproto)); - if (flags & STREAM_TOCLIENT) - FlagPacketFlow(p, f, STREAM_TOCLIENT); - else - FlagPacketFlow(p, f, STREAM_TOSERVER); + FlagPacketFlow(p, f, flags); /* account flow if we have both sides */ if (*alproto_otherdir != ALPROTO_UNKNOWN) { @@ -392,7 +391,7 @@ static int TCPProtoDetect(ThreadVars *tv, if (TCPProtoDetectTriggerOpposingSide(tv, ra_ctx, p, ssn, stream, flags) != 0) { - DisableAppLayer(f, p); + DisableAppLayer(tv, f, p); goto failure; } } @@ -420,7 +419,7 @@ static int TCPProtoDetect(ThreadVars *tv, if (first_data_dir && !(first_data_dir & ssn->data_first_seen_dir)) { AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, APPLAYER_WRONG_DIRECTION_FIRST_DATA); - DisableAppLayer(f, p); + DisableAppLayer(tv, f, p); goto failure; } /* This can happen if the current direction is not the @@ -471,7 +470,7 @@ static int TCPProtoDetect(ThreadVars *tv, if (FLOW_IS_PM_DONE(f, STREAM_TOSERVER) && FLOW_IS_PP_DONE(f, STREAM_TOSERVER)) { SCLogDebug("midstream end pd %p", ssn); /* midstream and toserver detection failed: give up */ - DisableAppLayer(f, p); + DisableAppLayer(tv, f, p); goto end; } } @@ -498,7 +497,7 @@ static int TCPProtoDetect(ThreadVars *tv, if ((ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) && (first_data_dir) && !(first_data_dir & flags)) { - DisableAppLayer(f, p); + DisableAppLayer(tv, f, p); goto failure; } @@ -524,11 +523,7 @@ static int TCPProtoDetect(ThreadVars *tv, TcpSessionSetReassemblyDepth(ssn, AppLayerParserGetStreamDepth(f->proto, f->alproto)); *alproto = ALPROTO_FAILED; - - if (flags & STREAM_TOCLIENT) - FlagPacketFlow(p, f, STREAM_TOCLIENT); - else - FlagPacketFlow(p, f, STREAM_TOSERVER); + FlagPacketFlow(p, f, flags); SCLogDebug("packet %u: pd done(us %u them %u), parser called (r==%d), APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION set", (uint)p->pcap_cnt, *alproto, *alproto_otherdir, r); @@ -537,7 +532,7 @@ static int TCPProtoDetect(ThreadVars *tv, } } else { /* both sides unknown, let's see if we need to give up */ - TCPProtoDetectCheckBailConditions(f, ssn, p); + TCPProtoDetectCheckBailConditions(tv, f, ssn, p); } } end: @@ -676,6 +671,7 @@ int AppLayerHandleUdp(ThreadVars *tv, AppLayerThreadCtx *tctx, Packet *p, Flow * PACKET_PROFILING_APP_END(tctx, f->alproto); } else { f->alproto = ALPROTO_FAILED; + AppLayerIncFlowCounter(tv, f); SCLogDebug("ALPROTO_UNKNOWN flow %p", f); } /* we do only inspection in one direction, so flag both @@ -827,19 +823,19 @@ void AppLayerSetupCounters() uint8_t ipproto; AppProto alproto; AppProto alprotos[ALPROTO_MAX]; + const char *str = "app_layer.flow."; AppLayerProtoDetectSupportedAppProtocols(alprotos); for (ipproto = 0; ipproto < IPPROTOS_MAX; ipproto++) { + uint8_t ipproto_map = FlowGetProtoMapping(ipprotos[ipproto]); uint8_t other_ipproto = (ipprotos[ipproto] == IPPROTO_TCP) ? IPPROTO_UDP : IPPROTO_TCP; const char *ipproto_suffix = (ipprotos[ipproto] == IPPROTO_TCP) ? "_tcp" : "_udp"; for (alproto = 0; alproto < ALPROTO_MAX; alproto++) { if (alprotos[alproto] == 1) { - const char *str = "app_layer.flow."; const char *tx_str = "app_layer.tx."; const char *alproto_str = AppLayerGetProtoName(alproto); - uint8_t ipproto_map = FlowGetProtoMapping(ipprotos[ipproto]); if (AppLayerParserProtoIsRegistered(ipprotos[ipproto], alproto) && AppLayerParserProtoIsRegistered(other_ipproto, alproto)) @@ -862,6 +858,10 @@ void AppLayerSetupCounters() "%s%s", tx_str, alproto_str); } } + } else if (alproto == ALPROTO_FAILED) { + snprintf(applayer_counter_names[ipproto_map][alproto].name, + sizeof(applayer_counter_names[ipproto_map][alproto].name), + "%s%s%s", str, "failed", ipproto_suffix); } } } @@ -877,9 +877,10 @@ void AppLayerRegisterThreadCounters(ThreadVars *tv) AppLayerProtoDetectSupportedAppProtocols(alprotos); for (ipproto = 0; ipproto < IPPROTOS_MAX; ipproto++) { + uint8_t ipproto_map = FlowGetProtoMapping(ipprotos[ipproto]); + for (alproto = 0; alproto < ALPROTO_MAX; alproto++) { if (alprotos[alproto] == 1) { - uint8_t ipproto_map = FlowGetProtoMapping(ipprotos[ipproto]); applayer_counters[ipproto_map][alproto].counter_id = StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv); @@ -887,6 +888,9 @@ void AppLayerRegisterThreadCounters(ThreadVars *tv) applayer_counters[ipproto_map][alproto].counter_tx_id = StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].tx_name, tv); } + } else if (alproto == ALPROTO_FAILED) { + applayer_counters[ipproto_map][alproto].counter_id = + StatsRegisterCounter(applayer_counter_names[ipproto_map][alproto].name, tv); } } }