From: Steve Chew (stechew) Date: Mon, 20 Sep 2021 20:30:30 +0000 (+0000) Subject: Merge pull request #3067 in SNORT/snort3 from ~DERAMADA/snort3:netflow_unique_templat... X-Git-Tag: 3.1.13.0~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91cf494d30c770262367eb22c221cb76e18525b2;p=thirdparty%2Fsnort3.git Merge pull request #3067 in SNORT/snort3 from ~DERAMADA/snort3:netflow_unique_templates to master Squashed commit of the following: commit d936e929feacc641f05d7da7965a460c75a55e58 Author: Deepak Ramadass Date: Fri Sep 17 10:45:56 2021 -0400 fix cppucheck commit 2d612e6f89852f66e6ccdfba40c79105364f2b41 Author: Deepak Ramadass Date: Fri Sep 17 10:02:41 2021 -0400 netflow: use device ip and template id to ensure that the template cache keys are unique --- diff --git a/src/service_inspectors/netflow/netflow.cc b/src/service_inspectors/netflow/netflow.cc index 75025ee60..d9865ba57 100644 --- a/src/service_inspectors/netflow/netflow.cc +++ b/src/service_inspectors/netflow/netflow.cc @@ -65,7 +65,7 @@ static THREAD_LOCAL NetflowCache* netflow_cache = nullptr; static NetflowCache* dump_cache = nullptr; // Netflow version 9 Template fields cache. -typedef std::unordered_map> TemplateFieldCache; +typedef std::unordered_map, std::vector, TemplateIpHash> TemplateFieldCache; static THREAD_LOCAL TemplateFieldCache* template_cache = nullptr; // ----------------------------------------------------------------------------- @@ -358,6 +358,7 @@ static bool decode_netflow_v9(const unsigned char* data, uint16_t size, header.unix_secs -= header.sys_uptime; const int zone = p->pkth->ingress_index; + const snort::SfIp device_ip = *p->ptrs.ip_api.get_src(); data += sizeof(Netflow9Hdr); @@ -384,11 +385,13 @@ static bool decode_netflow_v9(const unsigned char* data, uint16_t size, // field id f_id = ntohs(flowset->field_id); + auto ti_key = std::make_pair(f_id, device_ip); + // It's a data flowset - if ( f_id > 255 && template_cache->count(f_id) > 0 ) + if ( f_id > 255 && template_cache->count(ti_key) > 0 ) { std::vector tf; - tf = template_cache->at(f_id); + tf = template_cache->at(ti_key); while( data < flowset_end && records ) { @@ -482,15 +485,17 @@ static bool decode_netflow_v9(const unsigned char* data, uint16_t size, if ( field_count > 0 ) { + auto t_key = std::make_pair(t_id, device_ip); + // remove if there any entry exists for this template - auto is_erased = template_cache->erase(t_id); + auto is_erased = template_cache->erase(t_key); // count only unique templates if ( is_erased == 1 ) --netflow_stats.v9_templates; // add template to cache - template_cache->emplace(t_id, tf); + template_cache->emplace(t_key, tf); // update the total templates count ++netflow_stats.v9_templates; diff --git a/src/service_inspectors/netflow/netflow_module.h b/src/service_inspectors/netflow/netflow_module.h index 0a7bc975c..f886e2d04 100644 --- a/src/service_inspectors/netflow/netflow_module.h +++ b/src/service_inspectors/netflow/netflow_module.h @@ -50,6 +50,19 @@ struct NetflowHash } }; +// Generate hash of template id and device ip +struct TemplateIpHash +{ + size_t operator()(const std::pair &ti) const + { + const uint64_t* ip64 = (const uint64_t*) ti.second.get_ip6_ptr(); + + return std::hash() (ip64[0]) ^ + std::hash() (ip64[1]) ^ + std::hash() ((uint64_t)ti.first); + } +}; + struct NetflowRule { NetflowRule() { reset(); }