From: Masud Hasan (mashasan) Date: Tue, 1 Dec 2020 21:12:37 +0000 (+0000) Subject: Merge pull request #2640 in SNORT/snort3 from ~SMINUT/snort3:data_purge to master X-Git-Tag: 3.0.3-6~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8bce90674e9c5cbe51f9028be7bc1ac8e8c21a0b;p=thirdparty%2Fsnort3.git Merge pull request #2640 in SNORT/snort3 from ~SMINUT/snort3:data_purge to master Squashed commit of the following: commit a6bd13f8bafcf6c639ca28303a97309d860b0079 Author: Silviu Minut Date: Mon Nov 23 18:19:29 2020 -0500 rna: support data purge command --- diff --git a/src/host_tracker/host_cache.h b/src/host_tracker/host_cache.h index a18403874..bd80e7abe 100644 --- a/src/host_tracker/host_cache.h +++ b/src/host_tracker/host_cache.h @@ -78,7 +78,8 @@ public: LruCacheSharedMemcap(const LruCacheSharedMemcap& arg) = delete; LruCacheSharedMemcap& operator=(const LruCacheSharedMemcap& arg) = delete; - LruCacheSharedMemcap(const size_t initial_size) : LruCacheShared(initial_size) {} + LruCacheSharedMemcap(const size_t initial_size) : LruCacheShared(initial_size), + valid_id(invalid_id+1) {} size_t mem_size() override { @@ -154,6 +155,20 @@ public: return false; } + bool is_valid(size_t id) const + { + return id == valid_id; + } + + void invalidate() + { + valid_id++; + } + + size_t get_valid_id() const { return valid_id; } + + static constexpr size_t invalid_id = 0; + template friend class HostCacheAllocIp; @@ -205,6 +220,8 @@ private: current_size -= mem_chunk; } + std::atomic valid_id; + std::mutex reload_mutex; friend class TEST_host_cache_module_misc_Test; // for unit test }; diff --git a/src/host_tracker/host_tracker.cc b/src/host_tracker/host_tracker.cc index 478b2e016..181363cce 100644 --- a/src/host_tracker/host_tracker.cc +++ b/src/host_tracker/host_tracker.cc @@ -39,6 +39,14 @@ THREAD_LOCAL struct HostTrackerStats host_tracker_stats; const uint8_t snort::zero_mac[MAC_SIZE] = {0, 0, 0, 0, 0, 0}; + +HostTracker::HostTracker() : hops(-1) +{ + last_seen = nat_count_start = (uint32_t) packet_time(); + last_event = -1; + visibility = host_cache.get_valid_id(); +} + void HostTracker::update_last_seen() { lock_guard lck(host_tracker_lock); @@ -573,7 +581,7 @@ HostApplication* HostTracker::find_and_add_service_no_lock(Port port, IpProtocol return available; } - if ( max_services == 0 or num_visible_services < max_services ) + if ( max_services == 0 or num_visible_services < max_services ) { services.emplace_back(port, proto, appid, false, 1, lseen); return &services.back(); @@ -778,12 +786,15 @@ bool HostTracker::add_udp_fingerprint(uint32_t fpid) bool HostTracker::set_visibility(bool v) { + // get_valid_id may use its own lock, so get this outside our lock + size_t container_id = host_cache.get_valid_id(); + std::lock_guard lck(host_tracker_lock); - bool old_visibility = visibility; + size_t old_visibility = visibility; - visibility = v; + visibility = v ? container_id : HostCacheIp::invalid_id; - if ( visibility == false ) + if (visibility == HostCacheIp::invalid_id) { for (auto& proto : network_protos) proto.second = false; @@ -802,14 +813,14 @@ bool HostTracker::set_visibility(bool v) for (auto& info : s.info) info.visibility = false; s.user[0] = '\0'; - set_payload_visibility_no_lock(s.payloads, v, s.num_visible_payloads); + set_payload_visibility_no_lock(s.payloads, false, s.num_visible_payloads); } num_visible_services = 0; for ( auto& c : clients ) { c.visibility = false; - set_payload_visibility_no_lock(c.payloads, v, c.num_visible_payloads); + set_payload_visibility_no_lock(c.payloads, false, c.num_visible_payloads); } num_visible_clients = 0; @@ -817,9 +828,16 @@ bool HostTracker::set_visibility(bool v) ua_fps.clear(); } - return old_visibility; + return old_visibility == visibility; +} + +bool HostTracker::is_visible() const +{ + std::lock_guard lck(host_tracker_lock); + return visibility == host_cache.get_valid_id(); } + bool HostTracker::set_network_proto_visibility(uint16_t proto, bool v) { std::lock_guard lck(host_tracker_lock); diff --git a/src/host_tracker/host_tracker.h b/src/host_tracker/host_tracker.h index ea8f87934..026f63080 100644 --- a/src/host_tracker/host_tracker.h +++ b/src/host_tracker/host_tracker.h @@ -75,9 +75,11 @@ struct HostApplicationInfo HostApplicationInfo(const char *ver, const char *ven); char vendor[INFO_SIZE] = { '\0' }; char version[INFO_SIZE] = { '\0' }; - bool visibility = true; friend class HostTracker; +private: + bool visibility = true; + }; typedef HostCacheAllocIp HostAppInfoAllocator; @@ -207,11 +209,7 @@ public: typedef std::pair NetProto_t; typedef std::pair XProto_t; - HostTracker() : hops(-1) - { - last_seen = nat_count_start = (uint32_t) packet_time(); - last_event = -1; - } + HostTracker(); void update_last_seen(); uint32_t get_last_seen() const @@ -384,11 +382,7 @@ public: bool set_visibility(bool v = true); - bool is_visible() const - { - std::lock_guard lck(host_tracker_lock); - return visibility; - } + bool is_visible() const; // the control delete commands do not actually remove objects from // the host tracker, but just mark them as invisible, until rediscovered. @@ -436,7 +430,7 @@ private: uint32_t nat_count = 0; uint32_t nat_count_start; // the time nat counting starts for this host - bool visibility = true; + size_t visibility; uint32_t num_visible_services = 0; uint32_t num_visible_clients = 0; @@ -448,7 +442,7 @@ private: bool add_payload_no_lock(const AppId, HostApplication*, size_t); HostApplication* find_service_no_lock(Port, IpProtocol, AppId); void update_ha_no_lock(HostApplication& dst, HostApplication& src); - + HostApplication* find_and_add_service_no_lock(Port, IpProtocol, uint32_t lseen, bool& is_new, AppId, uint16_t max_services = 0); diff --git a/src/network_inspectors/rna/CMakeLists.txt b/src/network_inspectors/rna/CMakeLists.txt index 7cd8fc478..85bae0cb3 100644 --- a/src/network_inspectors/rna/CMakeLists.txt +++ b/src/network_inspectors/rna/CMakeLists.txt @@ -10,6 +10,8 @@ set (RNA_INCLUDES set ( RNA_SOURCES ${RNA_INCLUDES} + data_purge_cmd.cc + data_purge_cmd.h rna_app_discovery.cc rna_app_discovery.h rna_event_handler.cc diff --git a/src/network_inspectors/rna/data_purge_cmd.cc b/src/network_inspectors/rna/data_purge_cmd.cc new file mode 100644 index 000000000..67b05adc9 --- /dev/null +++ b/src/network_inspectors/rna/data_purge_cmd.cc @@ -0,0 +1,49 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- + +// data_purge_cmd.cc author Silviu Minut + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "data_purge_cmd.h" + +#include "managers/inspector_manager.h" + +#include "rna_inspector.h" +#include "rna_name.h" +#include "rna_pnd.h" + +using namespace snort; + +DataPurgeAC::~DataPurgeAC() +{ + auto rna_ins = (RnaInspector*) InspectorManager::get_inspector(RNA_NAME, true); + RnaPnd* pnd = rna_ins->get_pnd(); + delete pnd->host_cache_mac_ptr; + pnd->host_cache_mac_ptr = host_cache_mac; + set_host_cache_mac(host_cache_mac); +} + +bool DataPurgeAC::execute(Analyzer&, void**) +{ + set_host_cache_mac(host_cache_mac); + return true; +} + diff --git a/src/network_inspectors/rna/data_purge_cmd.h b/src/network_inspectors/rna/data_purge_cmd.h new file mode 100644 index 000000000..dfca23ac5 --- /dev/null +++ b/src/network_inspectors/rna/data_purge_cmd.h @@ -0,0 +1,43 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- + +// data_purge_cmd.h author Silviu Minut + +#ifndef DATA_PURGE_CMD_H +#define DATA_PURGE_CMD_H + +#include "main/analyzer_command.h" + +#include "rna_mac_cache.h" + +class DataPurgeAC : public snort::AnalyzerCommand +{ +public: + + DataPurgeAC(HostCacheMac* hcm) : host_cache_mac(hcm) { } + ~DataPurgeAC() override; + + bool execute(Analyzer&, void**) override; + + const char* stringify() override { return "DATA_PURGE"; } + +private: + HostCacheMac* host_cache_mac; +}; + +#endif diff --git a/src/network_inspectors/rna/rna_app_discovery.cc b/src/network_inspectors/rna/rna_app_discovery.cc index fd8a17a7e..19abe060f 100644 --- a/src/network_inspectors/rna/rna_app_discovery.cc +++ b/src/network_inspectors/rna/rna_app_discovery.cc @@ -50,7 +50,7 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, const auto& src_ip = p->ptrs.ip_api.get_src(); auto ht = host_cache.find(*src_ip); - if ( !ht ) + if ( !ht || !ht->is_visible() ) return; // should not happen as rna would get new flow event before appid event const uint8_t* src_mac; @@ -84,7 +84,7 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, if ( p->packet_flags & PKT_FROM_SERVER ) { auto cht = host_cache.find(p->flow->client_ip); - if ( cht ) + if ( cht && cht->is_visible() ) discover_client(p, cht, (const struct in6_addr*) &p->flow->client_ip, layer::get_eth_layer(p)->ether_dst, conf, logger, version, client, service); @@ -168,7 +168,7 @@ bool RnaAppDiscovery::discover_service(const Packet* p, IpProtocol proto, RnaTra if ( p->is_from_client() ) { htp = host_cache.find(ip); - if ( !htp ) + if ( !htp || !htp->is_visible() ) return false; if ( layer::get_eth_layer(p) ) @@ -238,7 +238,7 @@ void RnaAppDiscovery::discover_payload(const Packet* p, IpProtocol proto, RnaTra bool new_client_payload = false; auto client_ht = host_cache.find(p->flow->client_ip); - if (!client_ht) + if (!client_ht || !client_ht->is_visible()) return; HostClient hc(client, nullptr, service); @@ -259,7 +259,7 @@ void RnaAppDiscovery::update_service_info(const Packet* p, IpProtocol proto, con if ( p->is_from_client() ) { htp = host_cache.find(ip); - if ( !htp ) + if ( !htp || !htp->is_visible() ) return; if ( layer::get_eth_layer(p) ) diff --git a/src/network_inspectors/rna/rna_inspector.cc b/src/network_inspectors/rna/rna_inspector.cc index 4fbab04ce..6c6fe2991 100644 --- a/src/network_inspectors/rna/rna_inspector.cc +++ b/src/network_inspectors/rna/rna_inspector.cc @@ -102,7 +102,7 @@ bool RnaInspector::configure(SnortConfig* sc) // tinit is not called during reload, so pass processor pointers to threads via reload tuner if ( Snort::is_reloading() && InspectorManager::get_inspector(RNA_NAME, true) ) - sc->register_reload_resource_tuner(new FpProcReloadTuner(*mod_conf)); + sc->register_reload_resource_tuner(new FpProcReloadTuner(*mod_conf, pnd->host_cache_mac_ptr)); return true; } @@ -145,6 +145,7 @@ void RnaInspector::tinit() set_tcp_fp_processor(mod_conf->tcp_processor); set_ua_fp_processor(mod_conf->ua_processor); set_udp_fp_processor(mod_conf->udp_processor); + set_host_cache_mac(pnd->host_cache_mac_ptr); } void RnaInspector::tterm() diff --git a/src/network_inspectors/rna/rna_inspector.h b/src/network_inspectors/rna/rna_inspector.h index 227e34419..5001294d3 100644 --- a/src/network_inspectors/rna/rna_inspector.h +++ b/src/network_inspectors/rna/rna_inspector.h @@ -54,6 +54,8 @@ public: snort::UdpFpProcessor*&); void set_fp_processor(snort::TcpFpProcessor*, snort::UaFpProcessor*, snort::UdpFpProcessor*); + RnaPnd* get_pnd() const { return pnd; } + private: void load_rna_conf(); RnaModuleConfig* mod_conf = nullptr; diff --git a/src/network_inspectors/rna/rna_mac_cache.cc b/src/network_inspectors/rna/rna_mac_cache.cc index 2195fd512..d6294d11e 100644 --- a/src/network_inspectors/rna/rna_mac_cache.cc +++ b/src/network_inspectors/rna/rna_mac_cache.cc @@ -30,8 +30,6 @@ using namespace snort; using namespace std; -HostCacheMac host_cache_mac(MAC_CACHE_INITIAL_SIZE); - bool HostTrackerMac::add_network_proto(const uint16_t type) { lock_guard lck(host_tracker_mac_lock); @@ -97,6 +95,7 @@ void HostTrackerMac::stringify(string& str) TEST_CASE("RNA Mac Cache", "[rna_mac_cache]") { uint8_t a_mac[6] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6}; + HostCacheMac mac_cache(MAC_CACHE_INITIAL_SIZE); SECTION("HostCacheMac: store, retrieve") { @@ -112,28 +111,28 @@ TEST_CASE("RNA Mac Cache", "[rna_mac_cache]") bool new_host_mac = false; - auto a_ptr = host_cache_mac.find_else_create(a, &new_host_mac); + auto a_ptr = mac_cache.find_else_create(a, &new_host_mac); CHECK(new_host_mac == true); CHECK(a_ptr != nullptr); new_host_mac = false; - auto b_ptr = host_cache_mac.find_else_create(b, &new_host_mac); + auto b_ptr = mac_cache.find_else_create(b, &new_host_mac); CHECK(new_host_mac == true); CHECK(b_ptr != nullptr); new_host_mac = false; - auto c_ptr = host_cache_mac.find_else_create(c, &new_host_mac); + auto c_ptr = mac_cache.find_else_create(c, &new_host_mac); CHECK(new_host_mac == true); CHECK(c_ptr != nullptr); // Try to add one of the previous macs again new_host_mac = false; - auto test_ptr = host_cache_mac.find_else_create(test, &new_host_mac); + auto test_ptr = mac_cache.find_else_create(test, &new_host_mac); CHECK(new_host_mac == false); CHECK(test_ptr != nullptr); // Verify macs in cache in LRU order, where test mac (i.e., b) is the most recent - const auto&& lru_data = host_cache_mac.get_all_data(); + const auto&& lru_data = mac_cache.get_all_data(); CHECK(lru_data.size() == 3); CHECK(lru_data[2].first == a); CHECK(lru_data[1].first == c); @@ -149,7 +148,7 @@ TEST_CASE("RNA Mac Cache", "[rna_mac_cache]") SECTION("HostCacheMac: VLAN Tag Details") { MacKey a(a_mac); - auto a_ptr = host_cache_mac.find_else_create(a, nullptr); + auto a_ptr = mac_cache.find_else_create(a, nullptr); a_ptr->update_vlan(12345, 54321); uint8_t cfi, priority; diff --git a/src/network_inspectors/rna/rna_mac_cache.h b/src/network_inspectors/rna/rna_mac_cache.h index 90d6ded60..853c27d46 100644 --- a/src/network_inspectors/rna/rna_mac_cache.h +++ b/src/network_inspectors/rna/rna_mac_cache.h @@ -138,11 +138,12 @@ struct HashMac }; typedef LruCacheSharedMemcap HostCacheMac; -extern HostCacheMac host_cache_mac; + +extern HostCacheMac* get_host_cache_mac(); template HostCacheAllocMac::HostCacheAllocMac() { - lru = &host_cache_mac; + lru = get_host_cache_mac(); } #endif diff --git a/src/network_inspectors/rna/rna_module.cc b/src/network_inspectors/rna/rna_module.cc index 7f000ebf1..e3adcdf77 100644 --- a/src/network_inspectors/rna/rna_module.cc +++ b/src/network_inspectors/rna/rna_module.cc @@ -31,16 +31,21 @@ #include #include +#include "host_tracker/host_cache.h" #include "log/messages.h" #include "lua/lua.h" +#include "main/request.h" #include "main/snort_config.h" +#include "managers/inspector_manager.h" #include "managers/module_manager.h" #include "utils/util.h" +#include "data_purge_cmd.h" #include "rna_fingerprint_tcp.h" #include "rna_fingerprint_ua.h" #include "rna_fingerprint_udp.h" #include "rna_mac_cache.h" +#include "rna_pnd.h" #ifdef UNIT_TEST #include "catch/snort_catch.h" @@ -79,11 +84,30 @@ static inline string format_dump_mac(const uint8_t mac[MAC_SIZE]) return ss.str(); } +static int purge_data(lua_State* L) +{ + RnaModule* mod = (RnaModule*) ModuleManager::get_module(RNA_NAME); + if ( mod ) + { + HostCacheMac* mac_cache = new HostCacheMac(MAC_CACHE_INITIAL_SIZE); + main_broadcast_command(new DataPurgeAC(mac_cache), (L != nullptr)); + + host_cache.invalidate(); + + auto& request = get_dispatched_request(); + request.respond("data purge done\n", false, true); + LogMessage("data purge done\n"); + } + + return 0; +} + bool FpProcReloadTuner::tinit() { set_tcp_fp_processor(mod_conf.tcp_processor); set_ua_fp_processor(mod_conf.ua_processor); set_udp_fp_processor(mod_conf.udp_processor); + set_host_cache_mac(host_cache_mac_ptr); return false; // no work to do after this } @@ -155,7 +179,10 @@ static int delete_mac_host(lua_State* L) return 0; MacKey search_mk(mac); - bool success = host_cache_mac.remove((const uint8_t*) &search_mk); + HostCacheMac* mac_cache = get_host_cache_mac(); + assert(mac_cache); + + bool success = mac_cache->remove((const uint8_t*) &search_mk); if (!success) { @@ -188,7 +215,10 @@ static int delete_mac_host_proto(lua_State* L) return 0; MacKey search_mk(mac); - auto htm = host_cache_mac.find((const uint8_t*) &search_mk); + HostCacheMac* mac_cache = get_host_cache_mac(); + assert(mac_cache); + + auto htm = mac_cache->find((const uint8_t*) &search_mk); if (!htm) { @@ -234,6 +264,8 @@ static const Command rna_cmds[] = "delete a MAC from rna's MAC cache"}, { "delete_mac_host_proto", delete_mac_host_proto, mac_delete_proto_params, "delete a protocol associated with a MAC host"}, + { "purge_data", purge_data, nullptr, + "purge all host cache and mac cache data"}, { nullptr, nullptr, nullptr, nullptr } }; @@ -553,8 +585,10 @@ bool RnaModule::log_mac_cache(const char* outfile) } string str; - const auto&& lru_data = host_cache_mac.get_all_data(); - out_stream << "Current mac cache size: " << host_cache_mac.mem_size() << " bytes, " + HostCacheMac* host_cache_mac = get_host_cache_mac(); + assert(host_cache_mac); + const auto&& lru_data = host_cache_mac->get_all_data(); + out_stream << "Current mac cache size: " << host_cache_mac->mem_size() << " bytes, " << lru_data.size() << " trackers" << endl << endl; for ( const auto& elem : lru_data ) { diff --git a/src/network_inspectors/rna/rna_module.h b/src/network_inspectors/rna/rna_module.h index a3638b8f1..581084179 100644 --- a/src/network_inspectors/rna/rna_module.h +++ b/src/network_inspectors/rna/rna_module.h @@ -28,6 +28,7 @@ #include "rna_config.h" #include "rna_fingerprint.h" +#include "rna_mac_cache.h" #include "rna_name.h" struct RnaStats @@ -57,7 +58,8 @@ extern THREAD_LOCAL const snort::Trace* rna_trace; class FpProcReloadTuner : public snort::ReloadResourceTuner { public: - explicit FpProcReloadTuner(RnaModuleConfig& mod_conf) : mod_conf(mod_conf) { } + explicit FpProcReloadTuner(RnaModuleConfig& mod_conf, HostCacheMac* ptr = nullptr) + : mod_conf(mod_conf), host_cache_mac_ptr(ptr) { } ~FpProcReloadTuner() override = default; bool tinit() override; @@ -70,6 +72,7 @@ public: private: RnaModuleConfig& mod_conf; + HostCacheMac* host_cache_mac_ptr = nullptr; }; class RnaModule : public snort::Module diff --git a/src/network_inspectors/rna/rna_pnd.cc b/src/network_inspectors/rna/rna_pnd.cc index 3ba530237..577bc2436 100644 --- a/src/network_inspectors/rna/rna_pnd.cc +++ b/src/network_inspectors/rna/rna_pnd.cc @@ -53,6 +53,47 @@ using namespace std; #define RNA_NAT_COUNT_THRESHOLD 10 #define RNA_NAT_TIMEOUT_THRESHOLD 10 // timeout in seconds +static THREAD_LOCAL HostCacheMac* local_mac_cache_ptr = nullptr; + +HostCacheMac* get_host_cache_mac() +{ + return local_mac_cache_ptr; +} + +void set_host_cache_mac(HostCacheMac* mac_host) +{ + local_mac_cache_ptr = mac_host; +} + +HostCacheIp::Data RnaPnd::find_or_create_host_tracker(const SfIp& ip, bool& new_host) +{ + auto ht = host_cache.find_else_create(ip, &new_host); + + // If it's a new host, it's automatically visible, so we don't do anything. + // If it's not a new host, we're rediscovering it, so make it visible. + // Also if it was not new (we had it in the cache) and it went from + // not visible to visible, then it's as good as new. + if (!new_host and !ht->set_visibility(true)) + new_host = true; + + return ht; +} + +RnaPnd::RnaPnd(const bool en, const std::string& cp, RnaConfig* rc) : + logger(RnaLogger(en)), filter(DiscoveryFilter(cp)), conf(rc) +{ + update_timeout = (rc ? rc->update_timeout : 0); + host_cache_mac_ptr = new HostCacheMac(MAC_CACHE_INITIAL_SIZE); + set_host_cache_mac(host_cache_mac_ptr); +} + +RnaPnd::~RnaPnd() +{ + delete host_cache_mac_ptr; + host_cache_mac_ptr = nullptr; + set_host_cache_mac(nullptr); +} + void RnaPnd::analyze_appid_changes(DataEvent& event) { RnaAppDiscovery::process(static_cast(&event), filter, conf, logger); @@ -140,14 +181,7 @@ void RnaPnd::discover_network(const Packet* p, uint8_t ttl) const auto& src_ip = p->ptrs.ip_api.get_src(); const auto& src_ip_ptr = (const struct in6_addr*) src_ip->get_ip6_ptr(); - auto ht = host_cache.find_else_create(*src_ip, &new_host); - - // If it's a new host, it's automatically visible, so we don't do anything. - // If it's not a new host, we're rediscovering it, so make it visible. - // Also if it was not new (we had it in the cache) and it went from - // not visible to visible, then it's as good as new. - if (!new_host and !ht->set_visibility(true)) - new_host = true; + auto ht = find_or_create_host_tracker(*src_ip, new_host); uint32_t last_seen = ht->get_last_seen(); if ( !new_host ) @@ -225,12 +259,12 @@ void RnaPnd::analyze_dhcp_fingerprint(DataEvent& event) bool new_host = false; bool new_mac = false; const auto& src_ip = p->ptrs.ip_api.get_src(); - auto ht = host_cache.find_else_create(*src_ip, &new_host); + auto ht = find_or_create_host_tracker(*src_ip, new_host); if (!new_host) ht->update_last_seen(); MacKey mk(src_mac); - auto hm_ptr = host_cache_mac.find_else_create(mk, &new_mac); + auto hm_ptr = local_mac_cache_ptr->find_else_create(mk, &new_mac); if (new_mac) { ht->add_mac(mk.mac_addr, p->ptrs.ip_api.ttl(), 0); @@ -274,12 +308,12 @@ void RnaPnd::add_dhcp_info(DataEvent& event) SfIp router_ip = {(void*)&router, AF_INET}; bool new_host = false; bool new_mac = false; - auto ht = host_cache.find_else_create(leased_ip, &new_host); + auto ht = find_or_create_host_tracker(leased_ip, new_host); if (!new_host) ht->update_last_seen(); MacKey mk(src_mac); - auto hm_ptr = host_cache_mac.find_else_create(mk, &new_mac); + auto hm_ptr = local_mac_cache_ptr->find_else_create(mk, &new_mac); if (new_mac) { ht->add_mac(mk.mac_addr, p->ptrs.ip_api.ttl(), 0); @@ -396,7 +430,7 @@ void RnaPnd::generate_change_host_update() return; auto hosts = host_cache.get_all_data(); - auto mac_hosts = host_cache_mac.get_all_data(); + auto mac_hosts = local_mac_cache_ptr->get_all_data(); auto sec = time(nullptr); for ( auto & h : hosts ) @@ -416,7 +450,7 @@ void RnaPnd::generate_new_host_mac(const Packet* p, RnaTracker ht, bool discover bool new_host_mac = false; MacKey mk(layer::get_eth_layer(p)->ether_src); - auto hm_ptr = host_cache_mac.find_else_create(mk, &new_host_mac); + auto hm_ptr = local_mac_cache_ptr->find_else_create(mk, &new_host_mac); if ( new_host_mac ) { @@ -550,8 +584,9 @@ int RnaPnd::discover_network_arp(const Packet* p, RnaTracker* ht_ref) bool new_host = false; bool new_host_mac = false; - auto ht = host_cache.find_else_create(spa, &new_host); - auto hm_ptr = host_cache_mac.find_else_create(mk, &new_host_mac); + auto ht = find_or_create_host_tracker(spa, new_host); + + auto hm_ptr = local_mac_cache_ptr->find_else_create(mk, &new_host_mac); if ( !new_host_mac ) hm_ptr->update_last_seen(p->pkth->ts.tv_sec); @@ -634,7 +669,7 @@ int RnaPnd::discover_switch(const Packet* p, RnaTracker ht_ref) bool new_host_mac = false; MacKey mk(layer::get_eth_layer(p)->ether_src); - auto hm_ptr = host_cache_mac.find_else_create(mk, &new_host_mac); + auto hm_ptr = local_mac_cache_ptr->find_else_create(mk, &new_host_mac); if ( new_host_mac ) { diff --git a/src/network_inspectors/rna/rna_pnd.h b/src/network_inspectors/rna/rna_pnd.h index c85d5b227..c4d8caf5f 100644 --- a/src/network_inspectors/rna/rna_pnd.h +++ b/src/network_inspectors/rna/rna_pnd.h @@ -117,9 +117,8 @@ class RnaPnd { public: - RnaPnd(const bool en, const std::string& cp, RnaConfig* rc = nullptr) : - logger(RnaLogger(en)), filter(DiscoveryFilter(cp)), conf(rc) - { update_timeout = (rc ? rc->update_timeout : 0); } + RnaPnd(const bool en, const std::string& cp, RnaConfig* rc = nullptr); + ~RnaPnd(); void analyze_appid_changes(snort::DataEvent&); void analyze_flow_icmp(const snort::Packet*); @@ -133,6 +132,10 @@ public: // generate change event for all hosts in the ip cache void generate_change_host_update(); + static HostCacheIp::Data find_or_create_host_tracker(const snort::SfIp&, bool&); + + HostCacheMac* host_cache_mac_ptr = nullptr; + private: // generate change event for single host void generate_change_host_update(RnaTracker*, const snort::Packet*, @@ -177,4 +180,7 @@ private: time_t update_timeout; }; +HostCacheMac* get_host_cache_mac(); +void set_host_cache_mac(HostCacheMac* mac_host); + #endif diff --git a/src/network_inspectors/rna/test/CMakeLists.txt b/src/network_inspectors/rna/test/CMakeLists.txt index 9cdb23b50..080de0cc0 100644 --- a/src/network_inspectors/rna/test/CMakeLists.txt +++ b/src/network_inspectors/rna/test/CMakeLists.txt @@ -1,6 +1,7 @@ add_cpputest( rna_module_test SOURCES ../../../framework/parameter.cc + ../../../host_tracker/host_cache.cc ../rna_fingerprint.cc $ LIBS diff --git a/src/network_inspectors/rna/test/rna_module_mock.h b/src/network_inspectors/rna/test/rna_module_mock.h index 2bf28df52..6b95de894 100644 --- a/src/network_inspectors/rna/test/rna_module_mock.h +++ b/src/network_inspectors/rna/test/rna_module_mock.h @@ -21,6 +21,8 @@ #ifndef RNA_MODULE_MOCK_H #define RNA_MODULE_MOCK_H +#include "main/request.h" + #include "../rna_mac_cache.cc" THREAD_LOCAL RnaStats rna_stats; @@ -108,4 +110,17 @@ private: } // end of namespace snort +static Request mock_request; +void Request::respond(const char*, bool, bool) { } +Request& get_dispatched_request() { return mock_request; } + +HostCacheMac* get_host_cache_mac() { return nullptr; } + +DataPurgeAC::~DataPurgeAC() { } +bool DataPurgeAC::execute(Analyzer&, void**) { return true;} + +void snort::main_broadcast_command(AnalyzerCommand*, bool) { } +void set_host_cache_mac(HostCacheMac*) { } + + #endif