]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2437 in SNORT/snort3 from ~ARMANDAV/snort3:rna_client_disc to...
authorMasud Hasan (mashasan) <mashasan@cisco.com>
Tue, 1 Sep 2020 14:24:21 +0000 (14:24 +0000)
committerMasud Hasan (mashasan) <mashasan@cisco.com>
Tue, 1 Sep 2020 14:24:21 +0000 (14:24 +0000)
Squashed commit of the following:

commit c3efbd690571824a3ced29722fae510d055b33df
Author: Arun Mandava <armandav@cisco.com>
Date:   Fri Aug 28 12:18:56 2020 -0400

    rna: Support client discovery from appid event changes

src/host_tracker/host_tracker.cc
src/host_tracker/host_tracker.h
src/network_inspectors/rna/rna_app_discovery.cc
src/network_inspectors/rna/rna_app_discovery.h
src/network_inspectors/rna/rna_logger.cc
src/network_inspectors/rna/rna_logger.h
src/network_inspectors/rna/rna_logger_common.h

index aa7ab58cf53cedc414467086f64d2f0b14450451..591cb25b11486db30aa302f14aa00cb21c6e1140 100644 (file)
@@ -369,6 +369,31 @@ bool HostTracker::add_tcp_fingerprint(uint32_t fpid)
     return result.second;
 }
 
+size_t HostTracker::get_client_count()
+{
+    lock_guard<mutex> lck(host_tracker_lock);
+    return clients.size();
+}
+
+HostClient HostTracker::get_client(AppId id, const char* version, AppId service, bool& is_new)
+{
+    lock_guard<mutex> lck(host_tracker_lock);
+
+    for ( const auto& c : clients )
+    {
+        if (c.id != APP_ID_NONE and c.id == id and c.service == service
+            and ((c.version[0] == '\0' and !version) or
+            (version and strncmp(c.version, version, INFO_SIZE) == 0)))
+        {
+            return c;
+        }
+    }
+
+    is_new = true;
+    clients.emplace_back(id, version, service);
+    return clients.back();
+}
+
 static inline string to_time_string(uint32_t p_time)
 {
     time_t raw_time = (time_t) p_time;
@@ -424,6 +449,18 @@ void HostTracker::stringify(string& str)
         }
     }
 
+    if ( !clients.empty() )
+    {
+        str += "\nclients size: " + to_string(clients.size());
+        for ( const auto& c : clients )
+        {
+            str += "\n    id: " + to_string(c.id)
+                + ", service: " + to_string(c.service);
+            if ( c.version[0] != '\0' )
+                str += ", version: " + string(c.version);
+        }
+    }
+
     auto total = network_protos.size();
     if ( total )
     {
index b5a1a79d7bf9ac2f944582a401abe1f377f538fb..e34f5db5959122a8a915d1f16694d948ca2f1e77 100644 (file)
@@ -82,6 +82,24 @@ struct HostApplication
     char version[INFO_SIZE] = { 0 };
 };
 
+struct HostClient
+{
+    HostClient() = default;
+    HostClient(AppId clientid, const char *ver, AppId ser) :
+        id(clientid), service(ser)
+    {
+        if (ver)
+        {
+            strncpy(version, ver, INFO_SIZE);
+            version[INFO_SIZE-1] = '\0';
+        }
+    }
+
+    AppId id;
+    char version[INFO_SIZE] = { 0 };
+    AppId service;
+};
+
 enum HostType
 {
     HOST_TYPE_HOST=0,
@@ -93,6 +111,7 @@ enum HostType
 
 typedef HostCacheAllocIp<HostMac> HostMacAllocator;
 typedef HostCacheAllocIp<HostApplication> HostAppAllocator;
+typedef HostCacheAllocIp<HostClient> HostClientAllocator;
 
 class SO_PUBLIC HostTracker
 {
@@ -190,6 +209,8 @@ public:
     bool update_service_info(HostApplication& ha, const char* vendor, const char* version);
     void remove_inferred_services();
 
+    size_t get_client_count();
+    HostClient get_client(AppId id, const char* version, AppId service, bool& is_new);
     bool add_tcp_fingerprint(uint32_t fpid);
 
     //  This should be updated whenever HostTracker data members are changed
@@ -204,6 +225,7 @@ private:
     std::vector<uint16_t, HostCacheAllocIp<uint16_t>> network_protos;
     std::vector<uint8_t, HostCacheAllocIp<uint8_t>> xport_protos;
     std::vector<HostApplication, HostAppAllocator> services;
+    std::vector<HostClient, HostClientAllocator> clients;
     std::set<uint32_t, std::less<uint32_t>, HostCacheAllocIp<uint32_t>> tcp_fpids;
 
     bool vlan_tag_present = false;
index 27949ec0945865b0b795bfe273cab6c2380a89b5..0ebd1402ad206172dbae26894309daf93761b91d 100644 (file)
@@ -72,6 +72,14 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
         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_CLIENT_BIT] and client > APP_ID_NONE
+            and service > APP_ID_NONE)
+        {
+            const char* version = appid_session_api.get_client_version();
+            discover_client(p, ht, (const struct in6_addr*) src_ip->get_ip6_ptr(), src_mac,
+                conf, logger, version, client, service);
+        }
     }
 
     if ( appid_change_bits[APPID_SERVICE_VENDOR_BIT] or appid_change_bits[APPID_VERSION_BIT] )
@@ -141,3 +149,20 @@ void RnaAppDiscovery::update_service_info(const Packet* p, IpProtocol proto, con
     ha.hits = 0;
     rt->update_service(ha);
 }
+
+void RnaAppDiscovery::discover_client(const Packet* p, RnaTracker& rt,
+    const struct in6_addr* src_ip, const uint8_t* src_mac, RnaConfig* conf,
+    RnaLogger& logger, const char* version, AppId client, AppId service)
+{
+    if (conf and conf->max_host_client_apps and
+        conf->max_host_client_apps <= rt->get_client_count())
+        return;
+
+    bool is_new = false;
+
+    auto hc = rt->get_client(client, version, service, is_new);
+    if ( is_new )
+    {
+        logger.log(RNA_EVENT_NEW, NEW_CLIENT_APP, p, &rt, src_ip, src_mac, &hc);
+    }
+}
index 9acd143c16f7957d44147a7fc8c2d13d5b8e32f3..3717b76796ddefdcca6f590a49bd9d963a8a19e0 100644 (file)
@@ -31,6 +31,9 @@ public:
         const struct in6_addr* src_ip, const uint8_t* src_mac, RnaConfig* conf,
         RnaLogger& logger, AppId service = APP_ID_NONE);
 
+    static void discover_client(const snort::Packet* p, RnaTracker& rt,
+        const struct in6_addr* src_ip, const uint8_t* src_mac, RnaConfig* conf,
+        RnaLogger& logger, const char* version, AppId client, AppId service);
 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,
index ceb0e2e140a7d5d581cbde2425dc6ac044d672fe..a4e7a9c165eaa43f32b5d2d8b77e9f6d818d0c79 100644 (file)
@@ -58,6 +58,16 @@ static inline void rna_logger_message(const RnaLoggerEvent& rle)
         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));
+        if (rle.hc)
+        {
+            if (rle.hc->version[0] != '\0')
+                debug_logf(rna_trace, nullptr,
+                    "RNA client log: client %u, service %u, version %s\n",
+                    rle.hc->id, rle.hc->service, rle.hc->version);
+            else
+                debug_logf(rna_trace, nullptr, "RNA client log: client %u, service %u\n",
+                    rle.hc->id, rle.hc->service);
+        }
     }
     else
         debug_logf(rna_trace, nullptr, "RNA log: type %u, subtype %u, mac %s\n",
@@ -69,55 +79,62 @@ void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker
    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);
+        nullptr, ha, 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 HostClient* hc)
+{
+    log(type, subtype, src_ip, src_mac, ht, p, 0, 0,
+        nullptr, nullptr, nullptr, nullptr, hc);
 }
 
 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);
+        nullptr, nullptr, tfp, 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, uint32_t event_time)
 {
     log(type, subtype, src_ip, src_mac, ht, p, event_time, 0,
-        nullptr, nullptr, nullptr, nullptr);
+        nullptr, 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);
+        hm, nullptr, 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);
+        nullptr, 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);
+        nullptr, nullptr, nullptr, cond_var, nullptr);
 }
 
 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)
+    void* cond_var, const HostClient* hc)
 {
     if ( !enabled )
         return false;
 
     assert(ht);
 
-    RnaLoggerEvent rle(type, subtype, src_mac, ht, hm, proto, cond_var, ha, tfp);
+    RnaLoggerEvent rle(type, subtype, src_mac, ht, hm, proto, cond_var, ha, tfp, hc);
     if ( src_ip and (!IN6_IS_ADDR_V4MAPPED(src_ip) or src_ip->s6_addr32[3]) )
         rle.ip = src_ip;
     else
index 381fc12ee04a2a58a9527673e2446b9b1b3b8f2e..34e9539e48e275b6d73435340828237f0e8545d4 100644 (file)
@@ -37,8 +37,8 @@ struct RnaLoggerEvent : public Event
 {
     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) { }
+        const snort::TcpFingerprint* tf, const snort::HostClient* hcp) : type(t), subtype(st),
+            mac(mc), ht(rt), hm(hmp), proto(pr), cond_var(cv), ha(hap), tfp(tf), hc(hcp) { }
 
     uint16_t type;
     uint16_t subtype;
@@ -50,6 +50,7 @@ struct RnaLoggerEvent : public Event
     void* cond_var;
     const snort::HostApplication* ha;
     const snort::TcpFingerprint* tfp;
+    const snort::HostClient* hc;
 };
 
 class RnaLogger
@@ -61,6 +62,10 @@ public:
     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 host client
+    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::HostClient* hcp);
+
     // 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);
@@ -88,7 +93,7 @@ public:
         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);
+        void* cond_var = nullptr, const snort::HostClient* hc = nullptr);
 
 private:
     const bool enabled;
index cd25272d7ec7ea329e40fdf1c7129136e5cb8d16..56174674c3894a03fbffd188395953676bff26a6 100644 (file)
@@ -27,6 +27,7 @@
     #define NEW_NET_PROTOCOL    3
     #define NEW_XPORT_PROTOCOL  4
     #define NEW_UDP_SERVICE     6
+    #define NEW_CLIENT_APP      7
     #define NEW_OS              8
 
 #define RNA_EVENT_CHANGE    1001