From: Eric Leblond Date: Fri, 5 May 2017 14:53:38 +0000 (+0200) Subject: netflow: fix ttl logic X-Git-Tag: suricata-4.1.0-beta1~563 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ac6e0afb38470823355446eeb65f31df2ddb7bc;p=thirdparty%2Fsuricata.git netflow: fix ttl logic Use a per direction TTL min and max so we can log different values seen in the two half flows. Signed-off-by: Eric Leblond --- diff --git a/src/flow.c b/src/flow.c index b859d97055..0d13b2ab52 100644 --- a/src/flow.c +++ b/src/flow.c @@ -266,6 +266,29 @@ static inline int FlowUpdateSeenFlag(const Packet *p) return 1; } +static inline void FlowUpdateTTL(Flow *f, Packet *p, uint8_t ttl) +{ + if (FlowGetPacketDirection(f, p) == TOSERVER) { + if (ttl < f->min_ttl_toserver) { + f->min_ttl_toserver = ttl; + } else if (f->min_ttl_toserver == 0) { + f->min_ttl_toserver = ttl; + } + if (ttl > f->max_ttl_toserver) { + f->max_ttl_toserver = ttl; + } + } else { + if (ttl < f->min_ttl_toclient) { + f->min_ttl_toclient = ttl; + } else if (f->min_ttl_toclient == 0) { + f->min_ttl_toclient = ttl; + } + if (ttl > f->max_ttl_toclient) { + f->max_ttl_toclient = ttl; + } + } +} + /** \brief Update Packet and Flow * * Updates packet and flow based on the new packet. @@ -349,18 +372,10 @@ void FlowHandlePacketUpdate(Flow *f, Packet *p) /* update flow's ttl fields if needed */ if (PKT_IS_IPV4(p)) { uint8_t ttl = IPV4_GET_IPTTL(p); - if (ttl < f->min_ttl) { - f->min_ttl = ttl; - } else if (ttl > f->max_ttl) { - f->max_ttl = ttl; - } + FlowUpdateTTL(f, p, ttl); } else if (PKT_IS_IPV6(p)) { uint8_t ttl = IPV6_GET_HLIM(p); - if (ttl < f->min_ttl) { - f->min_ttl = ttl; - } else if (ttl > f->max_ttl) { - f->max_ttl = ttl; - } + FlowUpdateTTL(f, p, ttl); } } diff --git a/src/flow.h b/src/flow.h index 0ecedeee9c..aed1072606 100644 --- a/src/flow.h +++ b/src/flow.h @@ -184,13 +184,13 @@ typedef struct AppLayerParserState_ AppLayerParserState; } while (0) #define FLOW_SET_IPV4_TTL_FROM_PACKET(p, f) do { \ - (f)->min_ttl = IPV4_GET_IPTTL((p)); \ - (f)->max_ttl = IPV4_GET_IPTTL((p)); \ + (f)->min_ttl_toserver = IPV4_GET_IPTTL((p)); \ + (f)->max_ttl_toserver = IPV4_GET_IPTTL((p)); \ } while (0) #define FLOW_SET_IPV6_HLIM_FROM_PACKET(p, f) do { \ - (f)->min_ttl = IPV6_GET_HLIM((p)); \ - (f)->max_ttl = IPV6_GET_HLIM((p)); \ + (f)->min_ttl_toserver = IPV6_GET_HLIM((p)); \ + (f)->max_ttl_toserver = IPV6_GET_HLIM((p)); \ } while (0) /* pkt flow flags */ @@ -340,8 +340,10 @@ typedef struct Flow_ }; uint8_t proto; uint8_t recursion_level; - uint8_t min_ttl; - uint8_t max_ttl; + uint8_t min_ttl_toserver; + uint8_t max_ttl_toserver; + uint8_t min_ttl_toclient; + uint8_t max_ttl_toclient; uint16_t vlan_id[2]; /** flow hash - the flow hash before hash table size mod. */ diff --git a/src/output-json-netflow.c b/src/output-json-netflow.c index 59457b4207..40024a197d 100644 --- a/src/output-json-netflow.c +++ b/src/output-json-netflow.c @@ -214,8 +214,8 @@ static void JsonNetFlowLogJSONToServer(JsonNetFlowLogThread *aft, json_t *js, Fl json_object_set_new(hjs, "age", json_integer(age)); - json_object_set_new(hjs, "min_ttl", json_integer(f->min_ttl)); - json_object_set_new(hjs, "max_ttl", json_integer(f->max_ttl)); + json_object_set_new(hjs, "min_ttl", json_integer(f->min_ttl_toserver)); + json_object_set_new(hjs, "max_ttl", json_integer(f->max_ttl_toserver)); json_object_set_new(js, "netflow", hjs); @@ -266,6 +266,12 @@ static void JsonNetFlowLogJSONToClient(JsonNetFlowLogThread *aft, json_t *js, Fl json_object_set_new(hjs, "age", json_integer(age)); + /* To client is zero if we did not see any packet */ + if (f->max_ttl_toclient) { + json_object_set_new(hjs, "min_ttl", json_integer(f->min_ttl_toclient)); + json_object_set_new(hjs, "max_ttl", json_integer(f->max_ttl_toclient)); + } + json_object_set_new(js, "netflow", hjs); /* TCP */