From: Masud Hasan (mashasan) Date: Fri, 28 Aug 2020 01:20:50 +0000 (+0000) Subject: Merge pull request #2420 in SNORT/snort3 from ~MASHASAN/snort3:rna_app_service to... X-Git-Tag: 3.0.2-6~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7d36e3ece00c7d552e97c868fbd6f8f6b4c55ff3;p=thirdparty%2Fsnort3.git Merge pull request #2420 in SNORT/snort3 from ~MASHASAN/snort3:rna_app_service to master Squashed commit of the following: commit ad66c9f37f7beb0a3cbf0a18834a1b8994dd7d54 Author: Masud Hasan Date: Fri Aug 14 21:45:23 2020 -0400 rna: Support service discovery from appid event changes commit 9aa8d405eda1fe08496ea613d3049c5eb75da235 Author: Shravan Rangaraju Date: Fri Aug 14 06:22:01 2020 -0400 appid: Generate events for service info changes --- diff --git a/src/host_tracker/host_tracker.cc b/src/host_tracker/host_tracker.cc index 8f9463cbc..aa7ab58cf 100644 --- a/src/host_tracker/host_tracker.cc +++ b/src/host_tracker/host_tracker.cc @@ -23,7 +23,6 @@ #endif #include "host_tracker.h" -#include "host_cache_allocator.cc" #include "utils/util.h" @@ -99,6 +98,21 @@ const HostMac* HostTracker::get_hostmac(const uint8_t* mac) return nullptr; } +const uint8_t* HostTracker::get_last_seen_mac() +{ + lock_guard lck(host_tracker_lock); + const HostMac* max_hm = nullptr; + + for ( const auto& hm : macs ) + if ( !max_hm or max_hm->last_seen < hm.last_seen) + max_hm = &hm; + + if ( max_hm ) + return max_hm->mac; + + return zero_mac; +} + bool HostTracker::update_mac_ttl(const uint8_t* mac, uint8_t new_ttl) { if ( !mac or !memcmp(mac, zero_mac, MAC_SIZE) ) @@ -205,7 +219,8 @@ void HostTracker::copy_data(uint8_t& p_hops, uint32_t& p_last_seen, list(macs.begin(), macs.end()); } -bool HostTracker::add_service(Port port, IpProtocol proto, AppId appid, bool inferred_appid, bool* added) +bool HostTracker::add_service(Port port, IpProtocol proto, AppId appid, bool inferred_appid, + bool* added) { host_tracker_stats.service_adds++; lock_guard lck(host_tracker_lock); @@ -225,21 +240,23 @@ bool HostTracker::add_service(Port port, IpProtocol proto, AppId appid, bool inf } } - services.emplace_back( HostApplication{port, proto, appid, inferred_appid} ); + services.emplace_back(port, proto, appid, inferred_appid); if (added) *added = true; return true; } -AppId HostTracker::get_appid(Port port, IpProtocol proto, bool inferred_only, bool allow_port_wildcard) +AppId HostTracker::get_appid(Port port, IpProtocol proto, bool inferred_only, + bool allow_port_wildcard) { host_tracker_stats.service_finds++; lock_guard lck(host_tracker_lock); for ( const auto& s : services ) { - bool matched = (s.port == port and s.proto == proto and (!inferred_only or s.inferred_appid == inferred_only)); + bool matched = (s.port == port and s.proto == proto and + (!inferred_only or s.inferred_appid == inferred_only)); if ( matched or ( allow_port_wildcard and s.inferred_appid ) ) return s.appid; } @@ -247,6 +264,92 @@ AppId HostTracker::get_appid(Port port, IpProtocol proto, bool inferred_only, bo return APP_ID_NONE; } +size_t HostTracker::get_service_count() +{ + lock_guard lck(host_tracker_lock); + return services.size(); +} + +HostApplication HostTracker::get_service(Port port, IpProtocol proto, uint32_t lseen, + bool& is_new, AppId appid) +{ + host_tracker_stats.service_finds++; + lock_guard lck(host_tracker_lock); + + for ( auto& s : services ) + { + if ( s.port == port and s.proto == proto ) + { + if ( s.appid != appid and appid != APP_ID_NONE ) + { + s.appid = appid; + is_new = true; + } + else if ( s.last_seen == 0 ) + is_new = true; + s.last_seen = lseen; + ++s.hits; + return s; + } + } + + is_new = true; + host_tracker_stats.service_adds++; + services.emplace_back(port, proto, appid, false, 1, lseen); + return services.back(); +} + +void HostTracker::update_service(const HostApplication& ha) +{ + host_tracker_stats.service_finds++; + lock_guard lck(host_tracker_lock); + + for ( auto& s : services ) + { + if ( s.port == ha.port and s.proto == ha.proto ) + { + s.hits = ha.hits; + s.last_seen = ha.last_seen; + if ( ha.appid > APP_ID_NONE ) + s.appid = ha.appid; + return; + } + } +} + +bool HostTracker::update_service_info(HostApplication& ha, const char* vendor, const char* version) +{ + host_tracker_stats.service_finds++; + lock_guard lck(host_tracker_lock); + + for ( auto& s : services ) + { + if ( s.port == ha.port and s.proto == ha.proto ) + { + bool changed = false; + if ( vendor and strncmp(s.vendor, vendor, INFO_SIZE) ) + { + strncpy(s.vendor, vendor, INFO_SIZE); + s.vendor[INFO_SIZE-1] = '\0'; + changed = true; + } + if ( version and strncmp(s.version, version, INFO_SIZE) ) + { + strncpy(s.version, version, INFO_SIZE); + s.version[INFO_SIZE-1] = '\0'; + changed = true; + } + if ( !changed ) + return false; + + ha.appid = s.appid; // copy these info for the caller + ha.hits = s.hits; + return true; + } + } + return false; +} + void HostTracker::remove_inferred_services() { lock_guard lck(host_tracker_lock); @@ -314,6 +417,10 @@ void HostTracker::stringify(string& str) if ( s.inferred_appid ) str += ", inferred"; } + if ( s.vendor[0] != '\0' ) + str += ", vendor: " + string(s.vendor); + if ( s.version[0] != '\0' ) + str += ", version: " + string(s.version); } } diff --git a/src/host_tracker/host_tracker.h b/src/host_tracker/host_tracker.h index bc45d0a0e..b5a1a79d7 100644 --- a/src/host_tracker/host_tracker.h +++ b/src/host_tracker/host_tracker.h @@ -50,6 +50,7 @@ extern THREAD_LOCAL struct HostTrackerStats host_tracker_stats; namespace snort { +#define INFO_SIZE 32 #define MAC_SIZE 6 extern const uint8_t zero_mac[MAC_SIZE]; @@ -67,10 +68,18 @@ struct HostMac struct HostApplication { + HostApplication() = default; + HostApplication(Port pt, IpProtocol pr, AppId ap, bool in, uint32_t ht = 0, uint32_t ls = 0) : + port(pt), proto(pr), appid(ap), inferred_appid(in), hits(ht), last_seen(ls) { } + Port port; IpProtocol proto; AppId appid; bool inferred_appid; + uint32_t hits; + uint32_t last_seen; + char vendor[INFO_SIZE] = { 0 }; + char version[INFO_SIZE] = { 0 }; }; enum HostType @@ -153,6 +162,8 @@ public: // Returns the matching host_mac const HostMac* get_hostmac(const uint8_t* mac); + const uint8_t* get_last_seen_mac(); + void update_vlan(uint16_t vth_pri_cfi_vlan, uint16_t vth_proto); bool has_vlan(); uint16_t get_vlan(); @@ -169,8 +180,14 @@ public: bool add_service(Port port, IpProtocol proto, AppId appid = APP_ID_NONE, bool inferred_appid = false, bool* added = nullptr); - AppId get_appid(Port port, IpProtocol proto, bool inferred_only = false, bool allow_port_wildcard = false); + AppId get_appid(Port port, IpProtocol proto, bool inferred_only = false, + bool allow_port_wildcard = false); + size_t get_service_count(); + HostApplication get_service(Port port, IpProtocol proto, uint32_t lseen, bool& is_new, + AppId appid = APP_ID_NONE); + void update_service(const HostApplication& ha); + bool update_service_info(HostApplication& ha, const char* vendor, const char* version); void remove_inferred_services(); bool add_tcp_fingerprint(uint32_t fpid); @@ -183,7 +200,7 @@ private: uint8_t hops; // hops from the snort inspector, e.g., zero for ARP uint32_t last_seen; // the last time this host was seen uint32_t last_event; // the last time an event was generated - std::vector macs; + std::list macs; // list guarantees iterator validity on insertion std::vector> network_protos; std::vector> xport_protos; std::vector services; diff --git a/src/host_tracker/test/host_cache_allocator_test.cc b/src/host_tracker/test/host_cache_allocator_test.cc index 2c56f4159..49bf94aee 100644 --- a/src/host_tracker/test/host_cache_allocator_test.cc +++ b/src/host_tracker/test/host_cache_allocator_test.cc @@ -66,10 +66,6 @@ public: typedef LruCacheSharedMemcap> CacheType; CacheType cache(100); -// Unorthodox, but necessary because we need the implementation of -// HostCacheAlloc in this file, which we inherit. -#include "host_tracker/host_cache_allocator.cc" - // Implement the allocator constructor AFTER we have a cache object // to point to and the implementation of our base HostCacheAlloc: template diff --git a/src/main/test/distill_verdict_test.cc b/src/main/test/distill_verdict_test.cc index e2aeccc0b..29c5f4492 100644 --- a/src/main/test/distill_verdict_test.cc +++ b/src/main/test/distill_verdict_test.cc @@ -40,7 +40,7 @@ int SFDAQInstance::finalize_message(DAQ_Msg_h, DAQ_Verdict verdict) return -1; } void DeferredTrust::finalize(Active&) { } -void DeferredTrust::set_deferred_trust(unsigned module_id, bool on) +void DeferredTrust::set_deferred_trust(unsigned, bool on) { deferred_trust = on ? TRUST_DEFER_ON : TRUST_DEFER_OFF; } diff --git a/src/network_inspectors/appid/appid_app_descriptor.h b/src/network_inspectors/appid/appid_app_descriptor.h index 516e241c9..648a9f13b 100644 --- a/src/network_inspectors/appid/appid_app_descriptor.h +++ b/src/network_inspectors/appid/appid_app_descriptor.h @@ -32,6 +32,7 @@ #include "protocols/packet.h" #include "pub_sub/appid_events.h" +#include "utils/util.h" #include "appid_types.h" #include "application_ids.h" @@ -49,7 +50,6 @@ public: virtual void reset() { my_id = APP_ID_NONE; - my_vendor.clear(); my_version.clear(); } @@ -70,17 +70,6 @@ public: virtual void set_id(const snort::Packet& p, AppIdSession& asd, AppidSessionDirection dir, AppId app_id, AppidChangeBits& change_bits); - const char* get_vendor() const - { - return my_vendor.empty() ? nullptr : my_vendor.c_str(); - } - - void set_vendor(const char* vendor) - { - if ( vendor ) - my_vendor = vendor; - } - const char* get_version() const { return my_version.empty() ? nullptr : my_version.c_str(); @@ -97,21 +86,47 @@ public: private: AppId my_id = APP_ID_NONE; - std::string my_vendor; std::string my_version; }; +struct AppIdServiceSubtype +{ + AppIdServiceSubtype* next = nullptr; + std::string service; + std::string vendor; + std::string version; +}; + class ServiceAppDescriptor : public ApplicationDescriptor { public: ServiceAppDescriptor() = default; + ~ServiceAppDescriptor() override + { + AppIdServiceSubtype* tmp_subtype = subtype; + while (tmp_subtype) + { + subtype = tmp_subtype->next; + delete tmp_subtype; + tmp_subtype = subtype; + } + } void set_id(AppId app_id, OdpContext& odp_ctxt); void reset() override { ApplicationDescriptor::reset(); + my_vendor.clear(); port_service_id = APP_ID_NONE; + + AppIdServiceSubtype* tmp_subtype = subtype; + while (tmp_subtype) + { + subtype = tmp_subtype->next; + delete tmp_subtype; + tmp_subtype = subtype; + } } void update_stats(AppId id) override; @@ -128,10 +143,41 @@ public: return deferred; } + const char* get_vendor() const + { + return my_vendor.empty() ? nullptr : my_vendor.c_str(); + } + + void set_vendor(const char* vendor, AppidChangeBits& change_bits) + { + if ( vendor ) + { + my_vendor = vendor; + change_bits.set(APPID_SERVICE_VENDOR_BIT); + } + } + + void add_subtype(AppIdServiceSubtype& more_subtype, AppidChangeBits& change_bits) + { + AppIdServiceSubtype** tmp_subtype; + + for (tmp_subtype = &subtype; *tmp_subtype; tmp_subtype = &(*tmp_subtype)->next) + ; + *tmp_subtype = &more_subtype; + change_bits.set(APPID_SERVICE_SUBTYPE_BIT); + } + + const AppIdServiceSubtype* get_subtype() const + { + return subtype; + } + private: AppId port_service_id = APP_ID_NONE; bool deferred = false; using ApplicationDescriptor::set_id; + std::string my_vendor; + AppIdServiceSubtype* subtype = nullptr; }; class ClientAppDescriptor : public ApplicationDescriptor diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index 6495eafe3..d1933ef0c 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -528,33 +528,26 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction, { if ( asd.get_service_id() == APP_ID_NONE or asd.get_service_id() == APP_ID_HTTP or asd.get_service_id() == APP_ID_HTTP2) + { + char* vendorVersion = nullptr; + char* vendor = nullptr; + AppIdServiceSubtype* subtype = nullptr; + + http_matchers.get_server_vendor_version(server->c_str(), server->size(), + &vendorVersion, &vendor, &subtype); + if (vendor || vendorVersion) { - char* vendorVersion = nullptr; - char* vendor = nullptr; - AppIdServiceSubtype* subtype = nullptr; - - http_matchers.get_server_vendor_version(server->c_str(), server->size(), - &vendorVersion, &vendor, &subtype); - if (vendor || vendorVersion) - { - asd.set_service_vendor(vendor); - asd.set_service_version(vendorVersion, change_bits); - asd.scan_flags &= ~SCAN_HTTP_VENDOR_FLAG; - - snort_free(vendor); - snort_free(vendorVersion); - } - - if (subtype) - { - AppIdServiceSubtype** tmp_subtype; - - for (tmp_subtype = &asd.subtype; *tmp_subtype; tmp_subtype = &(*tmp_subtype)->next) - ; - - *tmp_subtype = subtype; - } + asd.set_service_vendor(vendor, change_bits); + asd.set_service_version(vendorVersion, change_bits); + asd.scan_flags &= ~SCAN_HTTP_VENDOR_FLAG; + + snort_free(vendor); + snort_free(vendorVersion); } + + if (subtype) + asd.add_service_subtype(*subtype, change_bits); + } } if (is_webdav) diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index 76adeea2e..29c34a88c 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -627,17 +627,6 @@ void AppIdSession::delete_session_data(bool free_api) snort_free(netbios_name); snort_free(netbios_domain); - AppIdServiceSubtype* rna_ss = subtype; - while (rna_ss) - { - subtype = rna_ss->next; - snort_free(const_cast(rna_ss->service)); - snort_free(const_cast(rna_ss->vendor)); - snort_free(const_cast(rna_ss->version)); - snort_free(rna_ss); - rna_ss = subtype; - } - if (tsession) delete tsession; diff --git a/src/network_inspectors/appid/appid_session.h b/src/network_inspectors/appid/appid_session.h index 98ab3ae1b..794421249 100644 --- a/src/network_inspectors/appid/appid_session.h +++ b/src/network_inspectors/appid/appid_session.h @@ -265,7 +265,6 @@ public: APPID_DISCOVERY_STATE service_disco_state = APPID_DISCO_STATE_NONE; SESSION_SERVICE_SEARCH_STATE service_search_state = SESSION_SERVICE_SEARCH_STATE::START; ServiceDetector* service_detector = nullptr; - AppIdServiceSubtype* subtype = nullptr; std::vector service_candidates; // Following field is used only for non-http sessions. For HTTP traffic, @@ -478,9 +477,14 @@ public: api.service.set_version(version, change_bits); } - void set_service_vendor(const char* vendor) + void set_service_vendor(const char* vendor, AppidChangeBits& change_bits) { - api.service.set_vendor(vendor); + api.service.set_vendor(vendor, change_bits); + } + + void add_service_subtype(AppIdServiceSubtype& subtype, AppidChangeBits& change_bits) + { + api.service.add_subtype(subtype, change_bits); } AppId get_client_id() const diff --git a/src/network_inspectors/appid/appid_session_api.cc b/src/network_inspectors/appid/appid_session_api.cc index 420566bed..4adcdf83b 100644 --- a/src/network_inspectors/appid/appid_session_api.cc +++ b/src/network_inspectors/appid/appid_session_api.cc @@ -48,6 +48,14 @@ AppId AppIdSessionApi::get_service_app_id() const return application_ids[APP_PROTOID_SERVICE]; } +void AppIdSessionApi::get_service_info(const char*& vendor, const char*& version, + const AppIdServiceSubtype*& subtype) const +{ + vendor = service.get_vendor(); + version = service.get_version(); + subtype = service.get_subtype(); +} + AppId AppIdSessionApi::get_misc_app_id(uint32_t stream_index) const { if (get_service_app_id() == APP_ID_HTTP2) diff --git a/src/network_inspectors/appid/appid_session_api.h b/src/network_inspectors/appid/appid_session_api.h index 4a061c451..bf4d5bb5e 100644 --- a/src/network_inspectors/appid/appid_session_api.h +++ b/src/network_inspectors/appid/appid_session_api.h @@ -105,12 +105,16 @@ class SO_PUBLIC AppIdSessionApi : public StashGenericObject { public: AppId get_service_app_id() const; + void get_service_info(const char*& vendor, const char*& version, + const AppIdServiceSubtype*& subtype) const; AppId get_misc_app_id(uint32_t stream_index = 0) const; AppId get_client_app_id(uint32_t stream_index = 0) const; AppId get_payload_app_id(uint32_t stream_index = 0) const; AppId get_referred_app_id(uint32_t stream_index = 0) const; - void get_app_id(AppId& service, AppId& client, AppId& payload, AppId& misc, AppId& referred, uint32_t stream_index = 0) const; - void get_app_id(AppId* service, AppId* client, AppId* payload, AppId* misc, AppId* referred, uint32_t stream_index = 0) const; + void get_app_id(AppId& service, AppId& client, AppId& payload, AppId& misc, AppId& referred, + uint32_t stream_index = 0) const; + void get_app_id(AppId* service, AppId* client, AppId* payload, AppId* misc, AppId* referred, + uint32_t stream_index = 0) const; bool is_appid_inspecting_session() const; bool is_appid_available() const; const char* get_client_version(uint32_t stream_index = 0) const; @@ -121,8 +125,8 @@ public: const char* get_tls_host() const; bool is_http_inspection_done() const; - // For protocols such as HTTP2 which can have multiple streams within a single flow, get_first_stream_* - // methods return the appids in the first stream seen in a packet. + // For protocols such as HTTP2 which can have multiple streams within a single flow, + // get_first_stream_* methods return the appids in the first stream seen in a packet. void get_first_stream_app_ids(AppId& service, AppId& client, AppId& payload, AppId& misc) const; void get_first_stream_app_ids(AppId& service, AppId& client, AppId& payload) const; diff --git a/src/network_inspectors/appid/appid_types.h b/src/network_inspectors/appid/appid_types.h index f1de4a6e5..0e3c1460f 100644 --- a/src/network_inspectors/appid/appid_types.h +++ b/src/network_inspectors/appid/appid_types.h @@ -65,12 +65,4 @@ enum AppidSessionDirection APP_ID_APPID_SESSION_DIRECTION_MAX }; -struct AppIdServiceSubtype -{ - AppIdServiceSubtype* next; - const char* service; - const char* vendor; - const char* version; -}; - #endif diff --git a/src/network_inspectors/appid/detector_plugins/detector_pop3.cc b/src/network_inspectors/appid/detector_plugins/detector_pop3.cc index 10628baa0..7dfbe3505 100644 --- a/src/network_inspectors/appid/detector_plugins/detector_pop3.cc +++ b/src/network_inspectors/appid/detector_plugins/detector_pop3.cc @@ -256,11 +256,7 @@ static void pop3_free_state(void* data) { AppIdServiceSubtype* sub = sd->subtype; sd->subtype = sub->next; - if (sub->service) - snort_free((void*)sub->service); - if (sub->version) - snort_free((void*)sub->version); - snort_free(sub); + delete sub; } ClientPOP3Data* cd = &dd->client; if (cd->username) @@ -495,13 +491,11 @@ static int pop3_server_validate(POP3DetectorData* dd, const uint8_t* data, uint1 ; if (p == s || p >= line_end || !(*p)) goto ven_ver_done; - sub = (AppIdServiceSubtype*)snort_calloc(sizeof(AppIdServiceSubtype)); unsigned sub_len; sub_len = p - s; - sub->service = (const char*)snort_calloc(sub_len+1); - memcpy(const_cast(sub->service), s, sub_len); - (const_cast(sub->service))[sub_len] = 0; + sub = new AppIdServiceSubtype(); + sub->service.assign(reinterpret_cast(s), sub_len); sub->next = pd->subtype; pd->subtype = sub; if (line_end-p > (int)sizeof(subver_po)-1 @@ -513,9 +507,7 @@ static int pop3_server_validate(POP3DetectorData* dd, const uint8_t* data, uint1 if (p != s && p < line_end && *p) { sub_len = p - s; - sub->version = (const char*)snort_calloc(sub_len+1); - memcpy(const_cast(sub->version), s, sub_len); - (const_cast(sub->version))[sub_len] = 0; + sub->version.assign(reinterpret_cast(s), sub_len); } } } diff --git a/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc b/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc index d8939d25e..a2f9807ef 100644 --- a/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc +++ b/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc @@ -1656,21 +1656,11 @@ void HttpPatternMatchers::get_server_vendor_version(const char* data, int len, c { if ( subname && subname_len > 0 && subver && *subname ) { - AppIdServiceSubtype* sub = - (AppIdServiceSubtype*)snort_calloc( - sizeof(AppIdServiceSubtype)); - char* tmp = (char*)snort_calloc(subname_len + 1); - memcpy(tmp, subname, subname_len); - tmp[subname_len] = 0; - sub->service = tmp; + AppIdServiceSubtype* sub = new AppIdServiceSubtype(); + sub->service.assign(subname, subname_len); int subver_len = p - subver; if (subver_len > 0 && *subver) - { - tmp = (char*)snort_calloc(subver_len + 1); - memcpy(tmp, subver, subver_len); - tmp[subver_len] = 0; - sub->version = tmp; - } + sub->version.assign(subver, subver_len); sub->next = *subtype; *subtype = sub; } @@ -1690,21 +1680,12 @@ void HttpPatternMatchers::get_server_vendor_version(const char* data, int len, c if ( subname && subname_len > 0 && subver && *subname ) { - AppIdServiceSubtype* sub = - (AppIdServiceSubtype*)snort_calloc(sizeof(AppIdServiceSubtype)); - char* tmp = (char*)snort_calloc(subname_len + 1); - memcpy(tmp, subname, subname_len); - tmp[subname_len] = 0; - sub->service = tmp; + AppIdServiceSubtype* sub = new AppIdServiceSubtype(); + sub->service.assign(subname, subname_len); int subver_len = p - subver; if ( subver_len > 0 && *subver ) - { - tmp = (char*)snort_calloc(subver_len + 1); - memcpy(tmp, subver, subver_len); - tmp[subver_len] = 0; - sub->version = tmp; - } + sub->version.assign(subver, subver_len); sub->next = *subtype; *subtype = sub; } diff --git a/src/network_inspectors/appid/detector_plugins/http_url_patterns.h b/src/network_inspectors/appid/detector_plugins/http_url_patterns.h index 7fea1d40c..7eb6ecbe9 100644 --- a/src/network_inspectors/appid/detector_plugins/http_url_patterns.h +++ b/src/network_inspectors/appid/detector_plugins/http_url_patterns.h @@ -40,6 +40,7 @@ struct Packet; } class AppIdHttpSession; class AppIdContext; +struct AppIdServiceSubtype; class OdpContext; enum httpPatternType diff --git a/src/network_inspectors/appid/service_plugins/service_detector.cc b/src/network_inspectors/appid/service_plugins/service_detector.cc index 0b5ec30da..c6b5024bf 100644 --- a/src/network_inspectors/appid/service_plugins/service_detector.cc +++ b/src/network_inspectors/appid/service_plugins/service_detector.cc @@ -80,15 +80,18 @@ int ServiceDetector::service_inprocess(AppIdSession& asd, const Packet* pkt, App return APPID_SUCCESS; } -int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir, AppId appId, - const char* vendor, const char* version, AppidChangeBits& change_bits) +int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, + AppidSessionDirection dir, AppId appId, const char* vendor, const char* version, + AppidChangeBits& change_bits, AppIdServiceSubtype* subtype) { uint16_t port = 0; const SfIp* ip = nullptr; asd.service_detector = this; - asd.set_service_vendor(vendor); + asd.set_service_vendor(vendor, change_bits); asd.set_service_version(version, change_bits); + if (subtype) + asd.add_service_subtype(*subtype, change_bits); asd.set_service_detected(); asd.set_service_id(appId, asd.get_odp_ctxt()); @@ -136,34 +139,23 @@ int ServiceDetector::add_service_consume_subtype(AppIdSession& asd, const Packet AppidSessionDirection dir, AppId appId, const char* vendor, const char* version, AppIdServiceSubtype* subtype, AppidChangeBits& change_bits) { - asd.subtype = subtype; - return update_service_data(asd, pkt, dir, appId, vendor, version, change_bits); + return update_service_data(asd, pkt, dir, appId, vendor, version, change_bits, subtype); } int ServiceDetector::add_service(AppidChangeBits& change_bits, AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir, AppId appId, const char* vendor, - const char* version, const AppIdServiceSubtype* subtype) + const char* version, AppIdServiceSubtype* subtype) { AppIdServiceSubtype* new_subtype = nullptr; for (; subtype; subtype = subtype->next) { - AppIdServiceSubtype* tmp_subtype = (AppIdServiceSubtype*)snort_calloc( - sizeof(AppIdServiceSubtype)); - if (subtype->service) - tmp_subtype->service = snort_strdup(subtype->service); - - if (subtype->vendor) - tmp_subtype->vendor = snort_strdup(subtype->vendor); - - if (subtype->version) - tmp_subtype->version = snort_strdup(subtype->version); + AppIdServiceSubtype* tmp_subtype = new AppIdServiceSubtype(*subtype); tmp_subtype->next = new_subtype; new_subtype = tmp_subtype; } - asd.subtype = new_subtype; - return update_service_data(asd, pkt, dir, appId, vendor, version, change_bits); + return update_service_data(asd, pkt, dir, appId, vendor, version, change_bits, new_subtype); } int ServiceDetector::incompatible_data(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir) diff --git a/src/network_inspectors/appid/service_plugins/service_detector.h b/src/network_inspectors/appid/service_plugins/service_detector.h index 291f8d1c1..1a54561df 100644 --- a/src/network_inspectors/appid/service_plugins/service_detector.h +++ b/src/network_inspectors/appid/service_plugins/service_detector.h @@ -37,7 +37,7 @@ public: int add_service(AppidChangeBits&, AppIdSession&, const snort::Packet*, AppidSessionDirection, AppId, const char* vendor = nullptr, - const char* version = nullptr, const AppIdServiceSubtype* = nullptr); + const char* version = nullptr, AppIdServiceSubtype* = nullptr); int add_service_consume_subtype(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, AppId, const char* vendor, const char* version, @@ -57,8 +57,8 @@ public: } private: - int update_service_data(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, AppId, - const char* vendor, const char* version, AppidChangeBits& change_bits); + int update_service_data(AppIdSession&, const snort::Packet*, AppidSessionDirection, AppId, + const char*, const char*, AppidChangeBits&, AppIdServiceSubtype*); }; #endif diff --git a/src/network_inspectors/appid/service_plugins/service_rpc.cc b/src/network_inspectors/appid/service_plugins/service_rpc.cc index 31cd6bc07..3e2acf78a 100644 --- a/src/network_inspectors/appid/service_plugins/service_rpc.cc +++ b/src/network_inspectors/appid/service_plugins/service_rpc.cc @@ -497,14 +497,12 @@ done: { if (pname && *pname) { - memset(&sub, 0, sizeof(sub)); sub.service = pname; subtype = ⊂ } else if (program) { snprintf(subname, sizeof(subname), "(%u)", program); - memset(&sub, 0, sizeof(sub)); sub.service = subname; subtype = ⊂ } @@ -844,14 +842,12 @@ inprocess: { if (pname && *pname) { - memset(&sub, 0, sizeof(sub)); sub.service = pname; subtype = ⊂ } else if (program) { sprintf(subname, "(%u)", program); - memset(&sub, 0, sizeof(sub)); sub.service = subname; subtype = ⊂ } diff --git a/src/network_inspectors/appid/test/appid_api_test.cc b/src/network_inspectors/appid/test/appid_api_test.cc index f2936b3a0..7057aa74f 100644 --- a/src/network_inspectors/appid/test/appid_api_test.cc +++ b/src/network_inspectors/appid/test/appid_api_test.cc @@ -315,7 +315,7 @@ TEST(appid_api, ssl_app_group_id_lookup) CHECK_EQUAL(service, APPID_UT_ID); CHECK_EQUAL(client, APPID_UT_ID); CHECK_EQUAL(payload, APPID_UT_ID); - STRCMP_EQUAL("Published change_bits == 000000000000000", test_log); + STRCMP_EQUAL("Published change_bits == 00000000000000000", test_log); service = APP_ID_NONE; client = APP_ID_NONE; @@ -328,7 +328,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_first_alt_name(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); - STRCMP_EQUAL("Published change_bits == 000000100011000", test_log); + STRCMP_EQUAL("Published change_bits == 00000000100011000", test_log); mock_session->tsession->set_tls_host("www.cisco.com", 13, change_bits); mock_session->tsession->set_tls_cname("www.cisco.com", 13, change_bits); @@ -344,7 +344,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Cisco"); - STRCMP_EQUAL("Published change_bits == 000000100011000", test_log); + STRCMP_EQUAL("Published change_bits == 00000000100011000", test_log); string host = ""; val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()), nullptr, @@ -355,7 +355,7 @@ TEST(appid_api, ssl_app_group_id_lookup) STRCMP_EQUAL(mock_session->tsession->get_tls_host(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_cname(), APPID_UT_TLS_HOST); STRCMP_EQUAL(mock_session->tsession->get_tls_org_unit(), "Google"); - STRCMP_EQUAL("Published change_bits == 000000100000000", test_log); + STRCMP_EQUAL("Published change_bits == 00000000100000000", test_log); mock().checkExpectations(); } diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index 709a22c3c..6ffa57f18 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -379,7 +379,7 @@ TEST(appid_discovery_tests, event_published_when_ignoring_flow) // Detect changes in service, client, payload, and misc appid mock().checkExpectations(); - STRCMP_EQUAL("Published change_bits == 000000001111100", test_log); + STRCMP_EQUAL("Published change_bits == 00000000001111100", test_log); delete &asd->get_api(); delete asd; @@ -411,7 +411,7 @@ TEST(appid_discovery_tests, event_published_when_processing_flow) // Detect changes in service, client, payload, and misc appid mock().checkExpectations(); - STRCMP_EQUAL("Published change_bits == 000000001111100", test_log); + STRCMP_EQUAL("Published change_bits == 00000000001111100", test_log); delete &asd->get_api(); delete asd; delete flow; @@ -506,10 +506,10 @@ TEST(appid_discovery_tests, change_bits_to_string) change_bits.set(); change_bits_to_string(change_bits, str); STRCMP_EQUAL(str.c_str(), "created, reset, service, client, payload, misc, referred, host," - " tls-host, url, user-agent, response, referrer, dns-host, version"); + " tls-host, url, user-agent, response, referrer, dns-host, version, service-vendor, service-subtype"); // Failure of this test is a reminder that enum is changed, hence translator needs update - CHECK_EQUAL(APPID_MAX_BIT, 15); + CHECK_EQUAL(APPID_MAX_BIT, 17); } int main(int argc, char** argv) diff --git a/src/network_inspectors/appid/test/appid_mock_session.h b/src/network_inspectors/appid/test/appid_mock_session.h index 91c195438..af0cb4b9d 100644 --- a/src/network_inspectors/appid/test/appid_mock_session.h +++ b/src/network_inspectors/appid/test/appid_mock_session.h @@ -88,9 +88,9 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInsp set_client_user(APPID_UT_ID, APPID_UT_USERNAME); set_client_version(APPID_UT_CLIENT_VERSION, change_bits); - set_service_vendor(APPID_UT_SERVICE_VENDOR); + set_service_vendor(APPID_UT_SERVICE_VENDOR, change_bits); set_service_version(APPID_UT_SERVICE_VERSION, change_bits); - subtype = &APPID_UT_SERVICE_SUBTYPE; + add_service_subtype(*(new AppIdServiceSubtype(APPID_UT_SERVICE_SUBTYPE)), change_bits); tsession = new TlsSession; diff --git a/src/network_inspectors/rna/CMakeLists.txt b/src/network_inspectors/rna/CMakeLists.txt index 7408e79db..57d672cf7 100644 --- a/src/network_inspectors/rna/CMakeLists.txt +++ b/src/network_inspectors/rna/CMakeLists.txt @@ -8,6 +8,8 @@ set (RNA_INCLUDES set ( RNA_SOURCES ${RNA_INCLUDES} + rna_app_discovery.cc + rna_app_discovery.h rna_event_handler.cc rna_event_handler.h rna_fingerprint.cc diff --git a/src/network_inspectors/rna/rna_app_discovery.cc b/src/network_inspectors/rna/rna_app_discovery.cc new file mode 100644 index 000000000..27949ec09 --- /dev/null +++ b/src/network_inspectors/rna/rna_app_discovery.cc @@ -0,0 +1,143 @@ +//-------------------------------------------------------------------------- +// 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. +//-------------------------------------------------------------------------- + +// rna_app_discovery.cc authors: Masud Hasan + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rna_app_discovery.h" + +#include "detection/detection_engine.h" +#include "network_inspectors/appid/appid_session_api.h" + +#include "rna_logger_common.h" + +using namespace snort; + +void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter, + RnaConfig* conf, RnaLogger& logger) +{ + const Packet* p = DetectionEngine::get_current_packet(); + + // Published appid events may be on rebuilt packets + if ( !p->flow or !filter.is_host_monitored(p) ) + return; + + IpProtocol proto; + if ( p->flow->pkt_type == PktType::TCP ) + proto = IpProtocol::TCP; + else if ( p->flow->pkt_type == PktType::UDP ) + proto = IpProtocol::UDP; + else + return; + + const auto& src_ip = p->ptrs.ip_api.get_src(); + auto ht = host_cache.find(*src_ip); + if ( !ht ) + return; // should not happen as rna would get new flow event before appid event + + const uint8_t* src_mac; + if ( layer::get_eth_layer(p) ) + src_mac = layer::get_eth_layer(p)->ether_src; + else + src_mac = ht->get_last_seen_mac(); + + ht->update_last_seen(); + const auto& appid_change_bits = appid_event->get_change_bitset(); + const auto& appid_session_api = appid_event->get_appid_session_api(); + + if ( appid_change_bits[APPID_SERVICE_BIT] or appid_change_bits[APPID_CLIENT_BIT] or + appid_change_bits[APPID_PAYLOAD_BIT] ) + { + AppId service, client, payload; + appid_session_api.get_app_id(&service, &client, &payload, nullptr, nullptr); + + if ( appid_change_bits[APPID_SERVICE_BIT] and service > APP_ID_NONE ) + discover_service(p, proto, ht, (const struct in6_addr*) src_ip->get_ip6_ptr(), + src_mac, conf, logger, service); + } + + if ( appid_change_bits[APPID_SERVICE_VENDOR_BIT] or appid_change_bits[APPID_VERSION_BIT] ) + { + const char* vendor; + const char* version; + const AppIdServiceSubtype* subtype; + appid_session_api.get_service_info(vendor, version, subtype); + update_service_info(p, proto, vendor, version, ht, src_ip, src_mac, logger); + } +} + +void RnaAppDiscovery::discover_service(const Packet* p, IpProtocol proto, RnaTracker& rt, + const struct in6_addr* src_ip, const uint8_t* src_mac, RnaConfig* conf, + RnaLogger& logger, AppId service) +{ + if ( conf and conf->max_host_services and conf->max_host_services <= rt->get_service_count() ) + return; + + bool is_new = false; + + // Work on a local copy instead of reference as we release lock during event generations + auto ha = rt->get_service(p->flow->server_port, proto, (uint32_t) packet_time(), is_new); + if ( is_new ) + { + if ( proto == IpProtocol::TCP ) + logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, &rt, src_ip, src_mac, &ha); + else + logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, &rt, src_ip, src_mac, &ha); + + ha.hits = 0; // hit count is reset after logs are written + ha.appid = service; + rt->update_service(ha); + } +} + +void RnaAppDiscovery::update_service_info(const Packet* p, IpProtocol proto, const char* vendor, + const char* version, RnaTracker& rt, const SfIp* ip, const uint8_t* src_mac, RnaLogger& logger) +{ + if ( !vendor and !version ) + return; + + HostApplication ha(p->flow->server_port, proto, APP_ID_NONE, false); + if ( !rt->update_service_info(ha, vendor, version) ) + return; + + // Work on a local copy for eventing purpose + ha.last_seen = (uint32_t) packet_time(); + if ( vendor ) + { + strncpy(ha.vendor, vendor, INFO_SIZE); + ha.vendor[INFO_SIZE-1] = '\0'; + } + if ( version ) + { + strncpy(ha.version, version, INFO_SIZE); + ha.version[INFO_SIZE-1] = '\0'; + } + + if ( proto == IpProtocol::TCP ) + logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, &rt, + (const struct in6_addr*) ip->get_ip6_ptr(), src_mac, &ha); + else + logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, &rt, + (const struct in6_addr*) ip->get_ip6_ptr(), src_mac, &ha); + + ha.hits = 0; + rt->update_service(ha); +} diff --git a/src/network_inspectors/rna/rna_app_discovery.h b/src/network_inspectors/rna/rna_app_discovery.h new file mode 100644 index 000000000..9acd143c1 --- /dev/null +++ b/src/network_inspectors/rna/rna_app_discovery.h @@ -0,0 +1,40 @@ +//-------------------------------------------------------------------------- +// 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. +//-------------------------------------------------------------------------- + +#ifndef RNA_APP_DISCOVERY_H +#define RNA_APP_DISCOVERY_H + +#include "rna_pnd.h" + +class RnaAppDiscovery +{ +public: + static void process(AppidEvent* appid_event, DiscoveryFilter& filter, + RnaConfig* conf, RnaLogger& logger); + + static void discover_service(const snort::Packet* p, IpProtocol proto, RnaTracker& rt, + const struct in6_addr* src_ip, const uint8_t* src_mac, RnaConfig* conf, + RnaLogger& logger, AppId service = APP_ID_NONE); + +private: + static void update_service_info(const snort::Packet* p, IpProtocol proto, const char* vendor, + const char* version, RnaTracker& rt, const snort::SfIp* ip, const uint8_t* src_mac, + RnaLogger& logger); +}; + +#endif diff --git a/src/network_inspectors/rna/rna_event_handler.cc b/src/network_inspectors/rna/rna_event_handler.cc index a0b4c9938..72f8c93cb 100644 --- a/src/network_inspectors/rna/rna_event_handler.cc +++ b/src/network_inspectors/rna/rna_event_handler.cc @@ -26,6 +26,13 @@ using namespace snort; +void RnaAppidEventHandler::handle(DataEvent& event, Flow*) +{ + Profile profile(rna_perf_stats); + ++rna_stats.appid_change; + pnd.analyze_appid_changes(event); +} + void RnaIcmpBidirectionalEventHandler::handle(DataEvent& event, Flow*) { Profile profile(rna_perf_stats); diff --git a/src/network_inspectors/rna/rna_event_handler.h b/src/network_inspectors/rna/rna_event_handler.h index 653c8c844..980842bc2 100644 --- a/src/network_inspectors/rna/rna_event_handler.h +++ b/src/network_inspectors/rna/rna_event_handler.h @@ -26,6 +26,15 @@ #include "rna_module.h" #include "rna_pnd.h" +class RnaAppidEventHandler : public snort::DataHandler +{ +public: + RnaAppidEventHandler(RnaPnd& nd) : DataHandler(RNA_NAME), pnd(nd) { } + void handle(snort::DataEvent&, snort::Flow*) override; +private: + RnaPnd& pnd; +}; + class RnaIcmpNewFlowEventHandler : public snort::DataHandler { public: diff --git a/src/network_inspectors/rna/rna_inspector.cc b/src/network_inspectors/rna/rna_inspector.cc index bf4daca61..e70fc14f1 100644 --- a/src/network_inspectors/rna/rna_inspector.cc +++ b/src/network_inspectors/rna/rna_inspector.cc @@ -56,11 +56,10 @@ RnaInspector::RnaInspector(RnaModule* mod) { mod_conf = mod->get_config(); load_rna_conf(); - time_t update_timeout = rna_conf ? rna_conf->update_timeout : 0; if ( mod_conf ) - pnd = new RnaPnd(mod_conf->enable_logger, mod_conf->rna_conf_path, update_timeout); + pnd = new RnaPnd(mod_conf->enable_logger, mod_conf->rna_conf_path, rna_conf); else - pnd = new RnaPnd(false, "", update_timeout); + pnd = new RnaPnd(false, "", rna_conf); } RnaInspector::~RnaInspector() @@ -74,6 +73,8 @@ RnaInspector::~RnaInspector() bool RnaInspector::configure(SnortConfig* sc) { + DataBus::subscribe_global( APPID_EVENT_ANY_CHANGE, new RnaAppidEventHandler(*pnd), sc ); + DataBus::subscribe_global( STREAM_ICMP_NEW_FLOW_EVENT, new RnaIcmpNewFlowEventHandler(*pnd), sc ); DataBus::subscribe_global( STREAM_ICMP_BIDIRECTIONAL_EVENT, new RnaIcmpBidirectionalEventHandler(*pnd), sc ); diff --git a/src/network_inspectors/rna/rna_logger.cc b/src/network_inspectors/rna/rna_logger.cc index 95a42120f..ceb0e2e14 100644 --- a/src/network_inspectors/rna/rna_logger.cc +++ b/src/network_inspectors/rna/rna_logger.cc @@ -29,8 +29,10 @@ #include "managers/event_manager.h" #include "protocols/packet.h" + #include "rna_fingerprint_tcp.h" #include "rna_logger_common.h" +#include "rna_module.h" #ifdef UNIT_TEST #include "catch/snort_catch.h" @@ -43,25 +45,91 @@ using namespace snort; -bool RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht, - const struct in6_addr* src_ip, const uint8_t* src_mac, uint32_t event_time, - void* cond_var, const HostMac* hm, const uint16_t proto, - const TcpFingerprint* tfp) +#ifdef DEBUG_MSGS +static inline void rna_logger_message(const RnaLoggerEvent& rle) +{ + char macbuf[19]; + snprintf(macbuf, 19, "%02X:%02X:%02X:%02X:%02X:%02X", + rle.mac[0], rle.mac[1], rle.mac[2], rle.mac[3], rle.mac[4], rle.mac[5]); + if ( rle.ip ) + { + SfIp ip; + SfIpString ipbuf; + ip.set(rle.ip); // using this instead of packet's ip to support ARP + debug_logf(rna_trace, nullptr, "RNA log: type %u, subtype %u, mac %s, ip %s\n", + rle.type, rle.subtype, macbuf, ip.ntop(ipbuf)); + } + else + debug_logf(rna_trace, nullptr, "RNA log: type %u, subtype %u, mac %s\n", + rle.type, rle.subtype, macbuf); +} +#endif + +void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht, + const struct in6_addr* src_ip, const uint8_t* src_mac, const HostApplication* ha) +{ + log(type, subtype, src_ip, src_mac, ht, p, 0, 0, + nullptr, ha, nullptr, nullptr); +} + +void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht, + const struct in6_addr* src_ip, const uint8_t* src_mac, const TcpFingerprint* tfp) +{ + log(type, subtype, src_ip, src_mac, ht, p, 0, 0, + nullptr, nullptr, tfp, nullptr); +} + +void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht, + const struct in6_addr* src_ip, const uint8_t* src_mac, uint32_t event_time) +{ + log(type, subtype, src_ip, src_mac, ht, p, event_time, 0, + nullptr, nullptr, nullptr, nullptr); +} + +void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht, + const struct in6_addr* src_ip, const uint8_t* src_mac, const HostMac* hm, uint32_t event_time) +{ + log(type, subtype, src_ip, src_mac, ht, p, event_time, 0, + hm, nullptr, nullptr, nullptr); +} + +void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht, + uint16_t proto, const uint8_t* src_mac, const struct in6_addr* src_ip, uint32_t event_time) +{ + log(type, subtype, src_ip, src_mac, ht, p, event_time, proto, + nullptr, nullptr, nullptr, nullptr); +} + +void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, const uint8_t* src_mac, + const struct in6_addr* src_ip, RnaTracker* ht, uint32_t event_time, void* cond_var) +{ + log(type, subtype, src_ip, src_mac, ht, p, event_time, 0, + nullptr, nullptr, nullptr, cond_var); +} + +bool RnaLogger::log(uint16_t type, uint16_t subtype, const struct in6_addr* src_ip, + const uint8_t* src_mac, RnaTracker* ht, const Packet* p, uint32_t event_time, + uint16_t proto, const HostMac* hm, const HostApplication* ha, const TcpFingerprint* tfp, + void* cond_var) { if ( !enabled ) return false; assert(ht); - RnaLoggerEvent rle(type, subtype, ht, src_mac, hm, proto, tfp); + + RnaLoggerEvent rle(type, subtype, src_mac, ht, hm, proto, cond_var, ha, tfp); if ( src_ip and (!IN6_IS_ADDR_V4MAPPED(src_ip) or src_ip->s6_addr32[3]) ) rle.ip = src_ip; - + else + rle.ip = nullptr; if ( event_time ) (*ht)->update_last_event(event_time); - if ( subtype == CHANGE_HOST_UPDATE and type == RNA_EVENT_CHANGE ) - rle.cond_var = cond_var; EventManager::call_loggers(nullptr, const_cast(p), "RNA", &rle); + +#ifdef DEBUG_MSGS + rna_logger_message(rle); +#endif return true; } @@ -71,11 +139,14 @@ TEST_CASE("RNA logger", "[rna_logger]") SECTION("Checking enabled flag") { RnaTracker ht; + uint8_t mac[6] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6}; RnaLogger logger1(false); - CHECK(logger1.log(0, 0, 0, &ht, 0, 0) == false); + CHECK(logger1.log(0, 0, nullptr, mac, &ht, nullptr, 0, 0, + nullptr, nullptr, nullptr, nullptr) == false); RnaLogger logger2(true); - CHECK(logger2.log(0, 0, 0, &ht, 0, 0) == true); + CHECK(logger2.log(0, 0, nullptr, mac, &ht, nullptr, 0, 0, + nullptr, nullptr, nullptr, nullptr) == true); } } #endif diff --git a/src/network_inspectors/rna/rna_logger.h b/src/network_inspectors/rna/rna_logger.h index 99430afd6..381fc12ee 100644 --- a/src/network_inspectors/rna/rna_logger.h +++ b/src/network_inspectors/rna/rna_logger.h @@ -35,30 +35,60 @@ using RnaTracker = std::shared_ptr; struct RnaLoggerEvent : public Event { - RnaLoggerEvent(uint16_t p_type, uint16_t p_subtype, const RnaTracker* p_ht, - const uint8_t* p_mac, const snort::HostMac* p_hm, const uint16_t p_proto, - const snort::TcpFingerprint* tcp_fp) - : type(p_type), subtype(p_subtype), ht(p_ht), mac(p_mac), hm(p_hm), proto(p_proto), tfp(tcp_fp) { } + RnaLoggerEvent (uint16_t t, uint16_t st, const uint8_t* mc, const RnaTracker* rt, + const snort::HostMac* hmp, uint16_t pr, void* cv, const snort::HostApplication* hap, + const snort::TcpFingerprint* tf) : type(t), subtype(st), mac(mc), ht(rt), hm(hmp), + proto(pr), cond_var(cv), ha(hap), tfp(tf) { } + uint16_t type; uint16_t subtype; - const RnaTracker* ht; + const struct in6_addr* ip; const uint8_t* mac; - const struct in6_addr* ip = nullptr; - void* cond_var = nullptr; + const RnaTracker* ht; const snort::HostMac* hm; - const uint16_t proto; - const snort::TcpFingerprint* tfp = nullptr; + uint16_t proto; + void* cond_var; + const snort::HostApplication* ha; + const snort::TcpFingerprint* tfp; }; class RnaLogger { public: RnaLogger(const bool enable) : enabled(enable) { } - bool log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht, - const struct in6_addr* src_ip, const uint8_t* src_mac, - uint32_t event_time = 0, void* cond_var = nullptr, - const snort::HostMac* hm = nullptr, const uint16_t proto = 0, - const snort::TcpFingerprint* tfp = nullptr); + + // for host application + void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht, + const struct in6_addr* src_ip, const uint8_t* src_mac, const snort::HostApplication* ha); + + // for tcp fingerprint + void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht, + const struct in6_addr* src_ip, const uint8_t* src_mac, const snort::TcpFingerprint* tfp); + + // for event time + void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht, + const struct in6_addr* src_ip, const uint8_t* src_mac, uint32_t event_time); + + // for mac event + void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht, + const struct in6_addr* src_ip, const uint8_t* src_mac, + const snort::HostMac* hm = nullptr, uint32_t event_time = 0); + + // for protocol event + void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht, + uint16_t proto, const uint8_t* mac, const struct in6_addr* ip = nullptr, + uint32_t event_time = 0); + + // for timeout update + void log(uint16_t type, uint16_t subtype, const snort::Packet* p, const uint8_t* src_mac, + const struct in6_addr* src_ip, RnaTracker* ht, uint32_t event_time, void* cond_var); + + // for all + bool log(uint16_t type, uint16_t subtype, const struct in6_addr* src_ip, + const uint8_t* src_mac, RnaTracker* ht, const snort::Packet* p = nullptr, + uint32_t event_time = 0, uint16_t proto = 0, const snort::HostMac* hm = nullptr, + const snort::HostApplication* ha = nullptr, const snort::TcpFingerprint* tfp = nullptr, + void* cond_var = nullptr); private: const bool enabled; diff --git a/src/network_inspectors/rna/rna_logger_common.h b/src/network_inspectors/rna/rna_logger_common.h index 99bce39f5..cd25272d7 100644 --- a/src/network_inspectors/rna/rna_logger_common.h +++ b/src/network_inspectors/rna/rna_logger_common.h @@ -23,12 +23,16 @@ // Common definitions between rna logger and pnd modules #define RNA_EVENT_NEW 1000 #define NEW_HOST 1 + #define NEW_TCP_SERVICE 2 #define NEW_NET_PROTOCOL 3 #define NEW_XPORT_PROTOCOL 4 + #define NEW_UDP_SERVICE 6 #define NEW_OS 8 #define RNA_EVENT_CHANGE 1001 #define CHANGE_HOPS 5 + #define CHANGE_TCP_SERVICE_INFO 6 + #define CHANGE_UDP_SERVICE_INFO 10 #define CHANGE_MAC_INFO 13 #define CHANGE_MAC_ADD 14 #define CHANGE_HOST_UPDATE 15 diff --git a/src/network_inspectors/rna/rna_mac_cache.h b/src/network_inspectors/rna/rna_mac_cache.h index 436d6c0a4..0007c1e7b 100644 --- a/src/network_inspectors/rna/rna_mac_cache.h +++ b/src/network_inspectors/rna/rna_mac_cache.h @@ -97,7 +97,7 @@ private: uint32_t last_seen = 0; uint32_t last_event = 0; bool vlan_tag_present = false; - snort::vlan::VlanTagHdr vlan_tag; + snort::vlan::VlanTagHdr vlan_tag = { }; std::vector> network_protos; }; diff --git a/src/network_inspectors/rna/rna_module.cc b/src/network_inspectors/rna/rna_module.cc index 3806c262b..9ca7f840c 100644 --- a/src/network_inspectors/rna/rna_module.cc +++ b/src/network_inspectors/rna/rna_module.cc @@ -49,6 +49,8 @@ using namespace snort; using namespace std; +THREAD_LOCAL const Trace* rna_trace = nullptr; + //------------------------------------------------------------------------- // rna commands, params, and pegs //------------------------------------------------------------------------- @@ -172,6 +174,7 @@ static const Parameter rna_params[] = static const PegInfo rna_pegs[] = { + { CountType::SUM, "appid_change", "count of appid change events received" }, { CountType::SUM, "icmp_bidirectional", "count of bidirectional ICMP flows received" }, { CountType::SUM, "icmp_new", "count of new ICMP flows received" }, { CountType::SUM, "ip_bidirectional", "count of bidirectional IP received" }, @@ -321,6 +324,15 @@ const PegInfo* RnaModule::get_pegs() const ProfileStats* RnaModule::get_profile() const { return &rna_perf_stats; } +void RnaModule::set_trace(const Trace* trace) const +{ rna_trace = trace; } + +const TraceOption* RnaModule::get_trace_options() const +{ + static const TraceOption rna_trace_options(nullptr, 0, nullptr); + return &rna_trace_options; +} + bool RnaModule::log_mac_cache(const char* outfile) { if ( !outfile ) diff --git a/src/network_inspectors/rna/rna_module.h b/src/network_inspectors/rna/rna_module.h index 0124bd6a2..c22f420f6 100644 --- a/src/network_inspectors/rna/rna_module.h +++ b/src/network_inspectors/rna/rna_module.h @@ -22,6 +22,7 @@ #define RNA_MODULE_H #include "framework/module.h" +#include "main/snort_debug.h" #include "profiler/profiler.h" #include "rna_config.h" @@ -30,6 +31,7 @@ struct RnaStats { + PegCount appid_change; PegCount icmp_bidirectional; PegCount icmp_new; PegCount ip_bidirectional; @@ -45,6 +47,7 @@ struct RnaStats extern THREAD_LOCAL RnaStats rna_stats; extern THREAD_LOCAL snort::ProfileStats rna_perf_stats; +extern THREAD_LOCAL const snort::Trace* rna_trace; class RnaModule : public snort::Module { @@ -66,6 +69,9 @@ public: Usage get_usage() const override { return CONTEXT; } + void set_trace(const snort::Trace*) const override; + const snort::TraceOption* get_trace_options() const override; + private: RnaModuleConfig* mod_conf = nullptr; const char* dump_file = nullptr; diff --git a/src/network_inspectors/rna/rna_pnd.cc b/src/network_inspectors/rna/rna_pnd.cc index 1b55812c5..775cd90e8 100644 --- a/src/network_inspectors/rna/rna_pnd.cc +++ b/src/network_inspectors/rna/rna_pnd.cc @@ -31,10 +31,9 @@ #include "protocols/arp.h" #include "protocols/bpdu.h" #include "protocols/icmp4.h" -#include "protocols/packet.h" #include "protocols/protocol_ids.h" -#include "protocols/tcp.h" +#include "rna_app_discovery.h" #include "rna_fingerprint_tcp.h" #include "rna_logger_common.h" @@ -46,44 +45,9 @@ using namespace snort; using namespace snort::bpdu; using namespace std; -static inline bool is_eligible_packet(const Packet* p) +void RnaPnd::analyze_appid_changes(DataEvent& event) { - if ( p->has_ip() or - memcmp(layer::get_eth_layer(p)->ether_src, zero_mac, MAC_SIZE) ) - return true; - return false; -} - -static inline bool is_eligible_ip(const Packet* p) -{ - // If payload needs to be inspected ever, allow rebuilt packet when is_proxied - if ( !p->has_ip() or p->is_rebuilt() or !p->flow ) - return false; - return true; -} - -static inline bool is_eligible_tcp(const Packet* p) -{ - if ( !is_eligible_ip(p) or p->ptrs.tcph->is_rst() ) - return false; - return true; -} - -static inline bool is_eligible_udp(const Packet* p) -{ - if ( !is_eligible_ip(p) ) - return false; - if ( p->is_from_client() ) - { - const SfIp* src = p->ptrs.ip_api.get_src(); - const SfIp* dst = p->ptrs.ip_api.get_dst(); - // FIXIT-M this code checking the v6 address unconditionally is almost certainly wrong, - // especially since it's looking for an IPv4-specific protocol - if ( !src->is_set() and ((const uint8_t *) dst->get_ip6_ptr())[0] == 0XFF and - p->ptrs.sp == 68 and p->ptrs.dp == 67 ) - return false; // skip BOOTP - } - return true; + RnaAppDiscovery::process(static_cast(&event), filter, conf, logger); } void RnaPnd::analyze_flow_icmp(const Packet* p) @@ -182,12 +146,12 @@ void RnaPnd::discover_network(const Packet* p, uint8_t ttl) if ( new_mac and !new_host ) logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_ADD, p, &ht, - src_ip_ptr, src_mac, packet_time(), nullptr, ht->get_hostmac(src_mac)); + src_ip_ptr, src_mac, ht->get_hostmac(src_mac), packet_time()); if ( ht->update_mac_ttl(src_mac, ttl) ) { logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_INFO, p, &ht, - src_ip_ptr, src_mac, packet_time(), nullptr, ht->get_hostmac(src_mac)); + src_ip_ptr, src_mac, ht->get_hostmac(src_mac), packet_time()); HostMac* hm = ht->get_max_ttl_hostmac(); if (hm and hm->primary and ht->get_hops()) @@ -201,14 +165,21 @@ void RnaPnd::discover_network(const Packet* p, uint8_t ttl) if ( ptype > to_utype(ProtocolId::ETHERTYPE_MINIMUM) ) { if ( ht->add_network_proto(ptype) ) - logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, src_ip_ptr, src_mac, - packet_time(), nullptr, nullptr, ptype); + logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ptype, src_mac, src_ip_ptr, + packet_time()); } ptype = to_utype(p->get_ip_proto_next()); if ( ht->add_xport_proto(ptype) ) - logger.log(RNA_EVENT_NEW, NEW_XPORT_PROTOCOL, p, &ht, src_ip_ptr, src_mac, - packet_time(), nullptr, nullptr, ptype); + logger.log(RNA_EVENT_NEW, NEW_XPORT_PROTOCOL, p, &ht, ptype, src_mac, src_ip_ptr, + packet_time()); + + if ( p->flow->two_way_traffic() ) + { + auto proto = p->get_ip_proto_next(); + if ( proto == IpProtocol::TCP or proto == IpProtocol::UDP ) + RnaAppDiscovery::discover_service(p, proto, ht, src_ip_ptr, src_mac, conf, logger); + } if ( !new_host ) { @@ -225,10 +196,7 @@ void RnaPnd::discover_network(const Packet* p, uint8_t ttl) const TcpFingerprint* tfp = processor->get(p, rna_flow); if (tfp && ht->add_tcp_fingerprint(tfp->fpid)) - { - logger.log(RNA_EVENT_NEW, NEW_OS, p, &ht, src_ip_ptr, - src_mac, 0, nullptr, nullptr, ptype, tfp); - } + logger.log(RNA_EVENT_NEW, NEW_OS, p, &ht, src_ip_ptr, src_mac, tfp); } } @@ -260,8 +228,7 @@ void RnaPnd::generate_change_vlan_update(RnaTracker *rt, const Packet* p, update_vlan(p, hm); rt->get()->update_vlan(vh->vth_pri_cfi_vlan, vh->vth_proto); - logger.log(RNA_EVENT_CHANGE, CHANGE_VLAN_TAG, p, rt, nullptr, - src_mac, rt->get()->get_last_seen()); + logger.log(RNA_EVENT_CHANGE, CHANGE_VLAN_TAG, p, rt, nullptr, src_mac, packet_time()); } } @@ -280,8 +247,7 @@ void RnaPnd::generate_change_vlan_update(RnaTracker *rt, const Packet* p, { rt->get()->update_vlan(vh->vth_pri_cfi_vlan, vh->vth_proto); logger.log(RNA_EVENT_CHANGE, CHANGE_VLAN_TAG, p, rt, - (const struct in6_addr*) src_ip->get_ip6_ptr(), - src_mac, rt->get()->get_last_seen()); + (const struct in6_addr*) src_ip->get_ip6_ptr(), src_mac, packet_time()); } } @@ -295,8 +261,8 @@ void RnaPnd::generate_change_host_update(RnaTracker* ht, const Packet* p, uint32_t last_event = (*ht)->get_last_event(); time_t timestamp = sec - update_timeout; if ( last_seen > last_event && (time_t) last_event + update_timeout <= sec ) - logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_UPDATE, p, ht, - (const struct in6_addr*) src_ip->get_ip6_ptr(), src_mac, last_seen, (void*) ×tamp); + logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_UPDATE, p, src_mac, + (const struct in6_addr*) src_ip->get_ip6_ptr(), ht, last_seen, (void*) ×tamp); // FIXIT-M: deal with host service hits. } @@ -323,8 +289,8 @@ void RnaPnd::generate_change_host_update_eth(HostTrackerMac* mt, const Packet* p if ( last_seen > last_event && (time_t) last_event + update_timeout <= sec ) { - logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_UPDATE, p, &rt, - nullptr, src_mac, last_seen, (void*) ×tamp); + logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_UPDATE, p, src_mac, nullptr, + &rt, last_seen, (void*) ×tamp); mt->update_last_event(sec); } @@ -384,8 +350,7 @@ void RnaPnd::generate_new_host_mac(const Packet* p, RnaTracker ht, bool discover { if ( hm_ptr->add_network_proto(ntype) ) { - logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, nullptr, mk.mac_addr, - 0, nullptr, nullptr, ntype); + logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ntype, mk.mac_addr); hm_ptr->update_last_event(p->pkth->ts.tv_sec); } } @@ -397,8 +362,7 @@ void RnaPnd::generate_new_host_mac(const Packet* p, RnaTracker ht, bool discover ntype = ((const RNA_LLC*) lyr.start)->s.proto; if ( hm_ptr->add_network_proto(ntype) ) { - logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, nullptr, mk.mac_addr, - 0, nullptr, nullptr, ntype); + logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ntype, mk.mac_addr); hm_ptr->update_last_event(p->pkth->ts.tv_sec); } } @@ -509,15 +473,13 @@ int RnaPnd::discover_network_arp(const Packet* p, RnaTracker* ht_ref) if ( ht->add_mac(src_mac, 0, 0) ) { logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_ADD, p, ht_ref, - (const struct in6_addr*) spa.get_ip6_ptr(), src_mac, - 0, nullptr, ht->get_hostmac(src_mac)); + (const struct in6_addr*) spa.get_ip6_ptr(), src_mac, ht->get_hostmac(src_mac)); hm_ptr->update_last_event(p->pkth->ts.tv_sec); } else if (ht->make_primary(src_mac)) { logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_INFO, p, ht_ref, - (const struct in6_addr*) spa.get_ip6_ptr(), src_mac, - 0, nullptr, ht->get_hostmac(src_mac)); + (const struct in6_addr*) spa.get_ip6_ptr(), src_mac, ht->get_hostmac(src_mac)); hm_ptr->update_last_event(p->pkth->ts.tv_sec); } @@ -526,8 +488,7 @@ int RnaPnd::discover_network_arp(const Packet* p, RnaTracker* ht_ref) if ( hm_ptr->add_network_proto(ntype) ) { - logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, nullptr, src_mac, - 0, nullptr, nullptr, ntype); + logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ntype, src_mac); hm_ptr->update_last_event(p->pkth->ts.tv_sec); } @@ -535,8 +496,7 @@ int RnaPnd::discover_network_arp(const Packet* p, RnaTracker* ht_ref) { ht->update_hops(0); logger.log(RNA_EVENT_CHANGE, CHANGE_HOPS, p, ht_ref, - (const struct in6_addr*) spa.get_ip6_ptr(), src_mac, 0, nullptr, - ht->get_hostmac(src_mac)); + (const struct in6_addr*) spa.get_ip6_ptr(), src_mac, ht->get_hostmac(src_mac)); hm_ptr->update_last_event(p->pkth->ts.tv_sec); } diff --git a/src/network_inspectors/rna/rna_pnd.h b/src/network_inspectors/rna/rna_pnd.h index ce9c6f04d..6bd5c29cd 100644 --- a/src/network_inspectors/rna/rna_pnd.h +++ b/src/network_inspectors/rna/rna_pnd.h @@ -26,19 +26,18 @@ #include "host_tracker/host_tracker.h" #include "protocols/eth.h" #include "protocols/layer.h" +#include "protocols/packet.h" +#include "protocols/tcp.h" #include "protocols/vlan.h" +#include "pub_sub/appid_events.h" #include "sfip/sf_ip.h" +#include "rna_config.h" #include "rna_logger.h" #include "rna_mac_cache.h" #define USHRT_MAX std::numeric_limits::max() -namespace snort -{ -struct Packet; -} - enum class TcpPacketType { SYN, SYN_ACK, MIDSTREAM @@ -60,6 +59,46 @@ struct RNA_LLC }; #pragma pack() +static inline bool is_eligible_packet(const snort::Packet* p) +{ + if ( p->has_ip() or + memcmp(snort::layer::get_eth_layer(p)->ether_src, snort::zero_mac, MAC_SIZE) ) + return true; + return false; +} + +static inline bool is_eligible_ip(const snort::Packet* p) +{ + // If payload needs to be inspected ever, allow rebuilt packet when is_proxied + if ( !p->has_ip() or p->is_rebuilt() or !p->flow ) + return false; + return true; +} + +static inline bool is_eligible_tcp(const snort::Packet* p) +{ + if ( !is_eligible_ip(p) or p->ptrs.tcph->is_rst() ) + return false; + return true; +} + +static inline bool is_eligible_udp(const snort::Packet* p) +{ + if ( !is_eligible_ip(p) ) + return false; + if ( p->is_from_client() ) + { + const snort::SfIp* src = p->ptrs.ip_api.get_src(); + const snort::SfIp* dst = p->ptrs.ip_api.get_dst(); + // FIXIT-M this code checking the v6 address unconditionally is almost certainly wrong, + // especially since it's looking for an IPv4-specific protocol + if ( !src->is_set() and ((const uint8_t *) dst->get_ip6_ptr())[0] == 0XFF and + p->ptrs.sp == 68 and p->ptrs.dp == 67 ) + return false; // skip BOOTP + } + return true; +} + static inline unsigned short rna_get_eth(const snort::Packet* p) { const snort::vlan::VlanTagHdr* vh = nullptr; @@ -79,9 +118,11 @@ class RnaPnd { public: - RnaPnd(const bool en, const std::string& conf, time_t ut = 0) - : logger(RnaLogger(en)), filter(DiscoveryFilter(conf)), update_timeout(ut) { } + 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); } + void analyze_appid_changes(snort::DataEvent& event); void analyze_flow_icmp(const snort::Packet* p); void analyze_flow_ip(const snort::Packet* p); void analyze_flow_non_ip(const snort::Packet* p); @@ -123,6 +164,7 @@ private: RnaLogger logger; DiscoveryFilter filter; + RnaConfig* conf; time_t update_timeout; }; diff --git a/src/pub_sub/appid_events.h b/src/pub_sub/appid_events.h index c4f4a704d..d387654b8 100644 --- a/src/pub_sub/appid_events.h +++ b/src/pub_sub/appid_events.h @@ -60,6 +60,8 @@ enum AppidChangeBit // other APPID_VERSION_BIT, + APPID_SERVICE_VENDOR_BIT, + APPID_SERVICE_SUBTYPE_BIT, APPID_MAX_BIT }; @@ -100,6 +102,10 @@ inline void change_bits_to_string(AppidChangeBits& change_bits, std::string& str --n? str.append("dns-host, ") : str.append("dns-host"); if (change_bits.test(APPID_VERSION_BIT)) --n? str.append("version, ") : str.append("version"); + if (change_bits.test(APPID_SERVICE_VENDOR_BIT)) + --n? str.append("service-vendor, ") : str.append("service-vendor"); + if (change_bits.test(APPID_SERVICE_SUBTYPE_BIT)) + --n? str.append("service-subtype, ") : str.append("service-subtype"); if (n != 0) // make sure all bits from AppidChangeBit enum get translated str.append("change_bits_to_string error!"); }