app-layer counters: count failed protocol detect

pull/2359/head
Victor Julien 9 years ago
parent 3b98feef01
commit 93298e91c7

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

Loading…
Cancel
Save