]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2727 in SNORT/snort3 from ~SMINUT/snort3:rna_netbios to master
authorMasud Hasan (mashasan) <mashasan@cisco.com>
Mon, 8 Feb 2021 14:36:43 +0000 (14:36 +0000)
committerMasud Hasan (mashasan) <mashasan@cisco.com>
Mon, 8 Feb 2021 14:36:43 +0000 (14:36 +0000)
Squashed commit of the following:

commit b3850b1ddb6329274d502de7c4c7312cf8f0207b
Author: Silviu Minut <sminut@cisco.com>
Date:   Fri Jan 29 12:30:22 2021 -0500

    rna: discover NetBIOS name

    Discover NetBIOS in appid, publish an event and log it in rna.

20 files changed:
src/host_tracker/host_tracker.cc
src/host_tracker/host_tracker.h
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_session_api.cc
src/network_inspectors/appid/appid_session_api.h
src/network_inspectors/appid/service_plugins/service_detector.h
src/network_inspectors/appid/service_plugins/service_discovery.h
src/network_inspectors/appid/service_plugins/service_netbios.cc
src/network_inspectors/appid/service_plugins/test/service_netbios_test.cc
src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_mock_session.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
src/pub_sub/appid_events.h

index 74ee2941baf0f009671010e8c096e19f41a35452..c849db07b81ca59c5bd5a1bff5b6e5d3b5a29cd7 100644 (file)
@@ -199,7 +199,7 @@ bool HostTracker::get_hostmac(const uint8_t* mac, HostMac& hm)
     for ( auto& ahm : macs )
         if ( !memcmp(mac, ahm.mac, MAC_SIZE) )
         {
-            if (!ahm.visibility)
+            if ( !ahm.visibility )
                 return false;
 
             hm = static_cast<HostMac>(ahm);
@@ -216,7 +216,7 @@ const uint8_t* HostTracker::get_last_seen_mac()
 
     for ( const auto& hm : macs )
         if ( !max_hm or max_hm->last_seen < hm.last_seen )
-            if (hm.visibility)
+            if ( hm.visibility )
                 max_hm = &hm;
 
     if ( max_hm )
@@ -235,7 +235,7 @@ bool HostTracker::update_mac_ttl(const uint8_t* mac, uint8_t new_ttl)
     for ( auto& hm : macs )
         if ( !memcmp(mac, hm.mac, MAC_SIZE) )
         {
-            if (hm.ttl < new_ttl and hm.visibility)
+            if ( hm.ttl < new_ttl and hm.visibility )
             {
                 hm.ttl = new_ttl;
                 return true;
@@ -349,7 +349,7 @@ bool HostTracker::add_service(Port port, IpProtocol proto, AppId appid, bool inf
             {
                 s.appid = appid;
                 s.inferred_appid = inferred_appid;
-                if (added)
+                if ( added )
                     *added = true;
             }
 
@@ -367,7 +367,7 @@ bool HostTracker::add_service(Port port, IpProtocol proto, AppId appid, bool inf
 
     services.emplace_back(port, proto, appid, inferred_appid);
     num_visible_services++;
-    if (added)
+    if ( added )
         *added = true;
 
     return true;
@@ -445,13 +445,13 @@ bool HostTracker::add_service(const HostApplication& app, bool* added)
             {
                 s.appid = app.appid;
                 s.inferred_appid = app.inferred_appid;
-                if (added)
+                if ( added )
                     *added = true;
             }
 
             if ( s.visibility == false )
             {
-                if (added)
+                if ( added )
                     *added = true;
                 s.visibility = true;
                 num_visible_services++;
@@ -498,7 +498,7 @@ HostApplication* HostTracker::find_service_no_lock(Port port, IpProtocol proto,
     {
         if ( s.port == port and s.proto == proto )
         {
-            if (s.visibility == false)
+            if ( s.visibility == false )
                 return nullptr;
             if ( appid != APP_ID_NONE and s.appid == appid )
                 return &s;
@@ -764,7 +764,7 @@ void HostTracker::remove_inferred_services()
     lock_guard<mutex> lck(host_tracker_lock);
     for ( auto s = services.begin(); s != services.end(); )
     {
-        if (s->inferred_appid)
+        if ( s->inferred_appid )
             s = services.erase(s);
         else
             s++;
@@ -785,6 +785,18 @@ bool HostTracker::add_udp_fingerprint(uint32_t fpid)
     return result.second;
 }
 
+bool HostTracker::set_netbios_name(const char* nb_name)
+{
+    std::lock_guard<std::mutex> lck(host_tracker_lock);
+    if ( nb_name && netbios_name != nb_name )
+    {
+        netbios_name = nb_name;
+        return true;
+    }
+    else
+        return false;
+}
+
 bool HostTracker::set_visibility(bool v)
 {
     // get_valid_id may use its own lock, so get this outside our lock
@@ -795,23 +807,23 @@ bool HostTracker::set_visibility(bool v)
 
     visibility = v ? container_id : HostCacheIp::invalid_id;
 
-    if (visibility == HostCacheIp::invalid_id)
+    if ( visibility == HostCacheIp::invalid_id )
     {
-        for (auto& proto : network_protos)
+        for ( auto& proto : network_protos )
             proto.second = false;
 
-        for (auto& proto : xport_protos)
+        for ( auto& proto : xport_protos )
             proto.second = false;
 
-        for (auto& mac_t : macs)
+        for ( auto& mac_t : macs )
             mac_t.visibility = false;
 
         num_visible_macs = 0;
 
-        for (auto& s : services)
+        for ( auto& s : services )
         {
             s.visibility = false;
-            for (auto& info : s.info)
+            for ( auto& info : s.info )
                 info.visibility = false;
             s.user[0] = '\0';
             set_payload_visibility_no_lock(s.payloads, false, s.num_visible_payloads);
@@ -1067,7 +1079,7 @@ void HostTracker::remove_flows()
     // to avoid the deadlock from the first case, but we SHOULD lock on
     // a different mutex to protect the HT::flows set.
     lock_guard<mutex> lck(flows_lock);
-    for (auto& rna_flow : flows)
+    for ( auto& rna_flow : flows )
     {
         rna_flow->clear_ht(*this);
     }
@@ -1140,7 +1152,7 @@ void HostTracker::stringify(string& str)
 
         for ( const auto& s : services )
         {
-            if (s.visibility == false)
+            if ( s.visibility == false )
                 continue;
 
             str += "\n    port: " + to_string(s.port)
@@ -1155,7 +1167,7 @@ void HostTracker::stringify(string& str)
             if ( !s.info.empty() )
                 for ( const auto& i : s.info )
                 {
-                    if (i.visibility == false)
+                    if ( i.visibility == false )
                         continue;
 
                     if ( i.vendor[0] != '\0' )
@@ -1263,4 +1275,7 @@ void HostTracker::stringify(string& str)
         for ( const auto& fpid : udp_fpids )
             str += to_string(fpid) + (--total ? ", " : "");
     }
+
+    if ( !netbios_name.empty() )
+        str += "\nnetbios name: " + netbios_name;
 }
index bfee92dcd1ee14c9627e2f27b5029feb3635849f..b1cf2a6dea62e4cf840bdbb9dc5c2367f4f27a6d 100644 (file)
@@ -382,6 +382,8 @@ public:
         return ++nat_count;
     }
 
+    bool set_netbios_name(const char*);
+
     bool set_visibility(bool v = true);
 
     bool is_visible() const;
@@ -430,6 +432,7 @@ private:
     std::set<uint32_t, std::less<uint32_t>, HostCacheAllocIp<uint32_t>> tcp_fpids;
     std::set<uint32_t, std::less<uint32_t>, HostCacheAllocIp<uint32_t>> udp_fpids;
     std::vector<DeviceFingerprint, HostDeviceFpAllocator> ua_fps;
+    std::string netbios_name;
 
     // flows that we belong to
     std::unordered_set<RNAFlow*> flows;
index 5f0e65fe57c6b093b076666dfc667b499ba5defa..b3fbe470398249790c24c7733e79d0d78a36398e 100644 (file)
@@ -647,7 +647,6 @@ void AppIdSession::delete_session_data(bool free_api)
     api.client.reset();
     api.payload.reset();
 
-    snort_free(netbios_name);
     snort_free(netbios_domain);
 
     if (tsession)
@@ -910,7 +909,6 @@ void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits
 void AppIdSession::reset_session_data(AppidChangeBits& change_bits)
 {
     delete_session_data();
-    netbios_name = nullptr;
     netbios_domain = nullptr;
     api.hsessions.clear();
 
index 2eb364d476935e8e31bfde86bd64c0fc380b5d65..1f4360092a7af8f10a5423ccc39dd4309e00a159 100644 (file)
@@ -277,8 +277,6 @@ public:
     std::map<std::string, ClientDetector*> client_candidates;
     bool tried_reverse_service = false;
 
-    // FIXIT-RC netbios_name is never set to a valid value; set when netbios_domain is set?
-    char* netbios_name = nullptr;
     char* netbios_domain = nullptr;
 
     TlsSession* tsession = nullptr;
@@ -567,6 +565,11 @@ public:
         api.set_tls_host(tls_host);
     }
 
+    void set_netbios_name(AppidChangeBits& change_bits, const char *name)
+    {
+        api.set_netbios_name(change_bits, name);
+    }
+
     OdpContext& get_odp_ctxt() const
     {
         return odp_ctxt;
index e5b0789b72830eb2b5f224a9d8721056fa4e3f32..0e8d3eed076a1248312b2f3e8e5e19e71f369112 100644 (file)
@@ -308,6 +308,23 @@ bool AppIdSessionApi::is_http_inspection_done() const
             (asd->service_disco_state!= APPID_DISCO_STATE_FINISHED)));
 }
 
+const char* AppIdSessionApi::get_netbios_name() const
+{
+    return netbios_name;
+}
+
+void AppIdSessionApi::set_netbios_name(AppidChangeBits& change_bits, const char* name)
+{
+    if (netbios_name)
+    {
+        if (strcmp(netbios_name, name) == 0)
+            return;
+        snort_free(netbios_name);
+    }
+    netbios_name = snort_strdup(name);
+    change_bits.set(APPID_NETBIOS_NAME_BIT);
+}
+
 void AppIdSessionApi::set_ss_application_ids(AppId service_id, AppId client_id,
     AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits, Flow& flow)
 {
index 6f4e17e173f03f9b4c4a02dabe2146fd52ba86c8..2898b0a2adcdbac738ddd405526ae96cb6de44a5 100644 (file)
@@ -124,6 +124,7 @@ public:
     const AppIdHttpSession* get_http_session(uint32_t stream_index = 0) const;
     const char* get_tls_host() const;
     bool is_http_inspection_done() const;
+    const char* get_netbios_name() 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.
@@ -163,6 +164,7 @@ private:
     snort::SfIp initiator_ip;
     ServiceAppDescriptor service;
     char* tls_host = nullptr;
+    char* netbios_name = nullptr;
     std::string session_id;
     bool user_logged_in = false;
 
@@ -178,6 +180,7 @@ private:
         AppId referred, AppidChangeBits& change_bits, Flow& flow);
     void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits, Flow& flow);
     void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits, Flow& flow);
+    void set_netbios_name(AppidChangeBits& change_bits, const char* name);
 
     AppIdHttpSession* get_hsession(uint32_t stream_index = 0) const;
 
@@ -185,6 +188,7 @@ private:
     {
         delete_all_http_sessions();
         snort_free(tls_host);
+        snort_free(netbios_name);
         delete dsession;
     }
 
index be992c2730e8b722ca4b26918fc28008c1c9face..60740073cdf8313de5a6ddbe93e134372b69ca0c 100644 (file)
@@ -45,11 +45,6 @@ public:
     int incompatible_data(AppIdSession&, const snort::Packet*, AppidSessionDirection dir);
     int fail_service(AppIdSession&, const snort::Packet*, AppidSessionDirection dir);
 
-    void add_host_info(AppIdSession&, SERVICE_HOST_INFO_CODE, const void*)
-    {
-        // FIXIT-L - this function is called but does nothing... what if anything should it do...
-    }
-
     void add_miscellaneous_info(AppIdSession& asd, AppId miscId)
     {
         asd.misc_app_id = miscId;
index b158e9ca0bdb318bb60c2583bf9847a4d670f2d5..e8d9ce5739fe773413abaa8987a1df2bd05ba3f5 100644 (file)
@@ -47,11 +47,6 @@ struct Packet;
 #define STATE_ID_NEEDED_DUPE_DETRACT_COUNT   3
 #define STATE_ID_MAX_VALID_COUNT 5
 
-enum SERVICE_HOST_INFO_CODE
-{
-    SERVICE_HOST_INFO_NETBIOS_NAME = 1
-};
-
 /* Service state stored per flow, which acts based on global ServiceState
  * at the beginning of the flow, then independently do service discovery, and
  * synchronize findings at the end of service discovery by the flow.
index ffe1f16c4cf804a6dbe348c76ba13ba64b4e92a0..65a66440a1fe4c4084bde710b5d4cebcc14aac78 100644 (file)
@@ -375,8 +375,7 @@ static int netbios_validate_name(const uint8_t** data,
     return 0;
 }
 
-static int netbios_validate_label(const uint8_t** data,
-    const uint8_t* const end)
+static int netbios_validate_label(const uint8_t** data, const uint8_t* const end)
 {
     const NBNSLabel* lbl;
     uint16_t tmp;
@@ -1114,7 +1113,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args)
         }
 not_mailslot:
         if (source_name[0])
-            add_host_info(args.asd, SERVICE_HOST_INFO_NETBIOS_NAME, source_name);
+            args.asd.set_netbios_name(args.change_bits, (const char *)source_name);
         args.asd.set_session_flags(APPID_SESSION_CONTINUE);
         goto success;
     case NBDGM_TYPE_ERROR:
@@ -1186,4 +1185,3 @@ void NbdgmServiceDetector::AppIdFreeSMBData(FpSMBData* sd)
 {
     snort_free(sd);
 }
-
index 9de9e4bc1b112e2e905e820475d75b783ee1ab74..2ec89eab0b54413c11dfb916d1ec282f46223787 100644 (file)
@@ -49,6 +49,7 @@ int ServiceDiscovery::fail_service(AppIdSession&, const Packet*, AppidSessionDir
     ServiceDetector*, ServiceDiscoveryState*) { return 0; }
 int ServiceDiscovery::add_service_port(AppIdDetector*,
     const ServiceDetectorPort&) { return APPID_EINVALID; }
+void AppIdSessionApi::set_netbios_name(AppidChangeBits&, const char*) {}
 
 TEST_GROUP(service_netbios_test){};
 
index 3b45180b3da1155f3cf7e2d07064b134bc197773..6df7daa5b67aca997237e078d0b24a360f83e17c 100644 (file)
@@ -119,6 +119,7 @@ int AppIdSession::add_flow_data(void* data, unsigned type, AppIdFreeFCN)
     }
     return 0;
 }
+
 int dcerpc_validate(const uint8_t*, int){return 0; }
 AppIdDiscovery::~AppIdDiscovery() { }
 void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
index 1a5c1f6e6240fe4d69b88c0d26bdd3e2b7b02ef0..d581d8d9d27d594a5fa93d2b97d872eec502be71 100644 (file)
@@ -251,7 +251,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 == 00000000000000000", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000000000000000", test_log);
 
     service = APP_ID_NONE;
     client = APP_ID_NONE;
@@ -264,7 +264,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 == 00000000100011000", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000000100011000", 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);
@@ -280,7 +280,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 == 00000000100011000", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000000100011000", test_log);
 
     string host = "";
     val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()), nullptr,
@@ -291,7 +291,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 == 00000000100000000", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000000100000000", test_log);
     mock().checkExpectations();
 }
 
index 6bed3a5df9c96ed1939625ba6306cfa4c47fd5a1..fd2d4ca33619f90123e41bd0f7ab8cef49f2c47b 100644 (file)
@@ -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 == 00000000001111100", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000000001111100", 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 == 00000000001111100", test_log);
+    STRCMP_EQUAL("Published change_bits == 000000000001111100", test_log);
     delete &asd->get_api();
     delete asd;
     delete flow;
@@ -507,10 +507,10 @@ TEST(appid_discovery_tests, change_bits_to_string)
     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, service-info, client-info,"
-        " user-info");
+        " user-info, netbios-name");
 
     // Failure of this test is a reminder that enum is changed, hence translator needs update
-    CHECK_EQUAL(APPID_MAX_BIT, 17);
+    CHECK_EQUAL(APPID_MAX_BIT, 18);
 }
 
 int main(int argc, char** argv)
index eef95e2b795703ef6898d2479b164c9818aa933e..b647ac93e158dda1510d8d5daadbd28986b15d3d 100644 (file)
@@ -34,8 +34,6 @@ char const* APPID_UT_TLS_HOST = "vpn.topsecret.com";
 char const* APPID_UT_SERVICE_IP_ADDR = "192.168.0.2";
 char const* APPID_UT_INITIATOR_IP_ADDR = "192.168.0.3";
 
-char const* APPID_UT_NETBIOS_NAME = "I AM NETBIOS!";
-
 char const* APPID_ID_UT_DNS_HOST = "delphi.opendns.com";
 #define APPID_UT_DNS_HOST_OFFSET 22
 #define APPID_UT_DNS_PATTERN_CNAME_REC  5
@@ -105,8 +103,6 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInsp
     set_service_ip(svc_ip);
     api.initiator_ip.pton(AF_INET, APPID_UT_INITIATOR_IP_ADDR);
 
-    netbios_name = snort_strdup(APPID_UT_NETBIOS_NAME);
-
     api.dsession = new MockAppIdDnsSession;
     tp_app_id = APPID_UT_ID;
     set_service_id(APPID_UT_ID + 1, odp_ctxt);
@@ -121,8 +117,6 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInsp
 AppIdSession::~AppIdSession()
 {
     delete tsession;
-    if (netbios_name)
-        snort_free(netbios_name);
 }
 
 void* AppIdSession::get_flow_data(unsigned) const
index 0e2580a0dfc13cda8e4a6562dbd87102116d17b4..cb73033e7d21884a793045650852aeafd25423fb 100644 (file)
@@ -159,6 +159,12 @@ void RnaAppDiscovery::process(AppidEvent* appid_event, DiscoveryFilter& filter,
             }
         }
     }
+
+    if ( appid_change_bits[APPID_NETBIOS_NAME_BIT] )
+    {
+        const char* netbios_name = appid_session_api.get_netbios_name();
+        discover_netbios_name(p, filter, rna_flow, logger, netbios_name);
+    }
 }
 
 bool RnaAppDiscovery::discover_service(const Packet* p, DiscoveryFilter& filter, RNAFlow* rna_flow,
@@ -168,7 +174,7 @@ bool RnaAppDiscovery::discover_service(const Packet* p, DiscoveryFilter& filter,
     RnaTracker htp;
     SfIp ip = p->flow->server_ip;
 
-    if (!is_client)
+    if ( !is_client )
     {
         if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
             return false;
@@ -266,7 +272,7 @@ void RnaAppDiscovery::discover_payload(const Packet* p, DiscoveryFilter& filter,
     HostClient hc(client, nullptr, service);
     new_client_payload = crt->add_client_payload(hc, payload, max_payloads);
 
-    if (new_client_payload)
+    if ( new_client_payload )
         logger.log(RNA_EVENT_CHANGE, CHANGE_CLIENT_APP_UPDATE, p, &crt,
             (const struct in6_addr*) p->flow->client_ip.get_ip6_ptr(),
             crt->get_last_seen_mac(), &hc);
@@ -278,7 +284,7 @@ void RnaAppDiscovery::update_service_info(const Packet* p, DiscoveryFilter& filt
 {
     RnaTracker htp;
     SfIp ip = p->flow->server_ip;
-    if (!is_client)
+    if ( !is_client )
     {
         if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
             return;
@@ -404,6 +410,39 @@ void RnaAppDiscovery::discover_user(const Packet* p, DiscoveryFilter& filter, RN
     }
 }
 
+void RnaAppDiscovery::discover_netbios_name(const snort::Packet* p, DiscoveryFilter& filter,
+    RNAFlow* rna_flow, RnaLogger& logger, const char* nb_name)
+{
+    RnaTracker rt;
+    if ( p->is_from_server() )
+    {
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_SERVER) )
+            return;
+        rt = get_server_rna_tracker(p, rna_flow);
+    }
+    else
+    {
+        if ( !filter.is_host_monitored(p, nullptr, nullptr, FlowCheckDirection::DF_CLIENT) )
+            return;
+        rt = get_client_rna_tracker(p, rna_flow);
+    }
+
+    if ( !rt or !rt->is_visible() )
+        return;
+    rt->update_last_seen();
+
+    if ( rt->set_netbios_name(nb_name) )
+    {
+        const auto& src_ip = p->ptrs.ip_api.get_src();
+        const auto& src_ip_ptr = (const struct in6_addr*) src_ip->get_ip6_ptr();
+        const auto& src_mac = layer::get_eth_layer(p)->ether_src;
+
+        logger.log(RNA_EVENT_CHANGE, CHANGE_NETBIOS_NAME, src_ip_ptr, src_mac,
+            &rt, p, (uint32_t) packet_time(), 0, nullptr, nullptr, nullptr, nullptr, nullptr,
+            nullptr, APP_ID_NONE, nullptr, false, 0, 0, nullptr, nb_name);
+    }
+}
+
 void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, DiscoveryFilter& filter,
     RNAFlow* rna_flow, const char* host, const char* uagent, RnaLogger& logger,
     UaFpProcessor& processor)
index aa9e741395a4fb8bbc5687ab54c49df589602da7..67731ac30e7353ef883eda64036b02081d7210bb 100644 (file)
@@ -42,6 +42,10 @@ public:
 
     static void discover_banner(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol,
         RnaLogger&, AppId);
+
+    static void discover_netbios_name(const snort::Packet*, DiscoveryFilter&,
+        RNAFlow*, RnaLogger&, const char*);
+
 private:
     static void update_service_info(const snort::Packet*, DiscoveryFilter&, RNAFlow*, IpProtocol,
         uint16_t, const char* vendor, const char* version, RnaLogger&, RnaConfig*, AppId service,
index 0aa52d041e9f80b454c5a190ac893f364defc85e..6d568d968e2cbc76807ed249110c7f85d9d89474 100644 (file)
@@ -196,7 +196,7 @@ bool RnaLogger::log(uint16_t type, uint16_t subtype, const struct in6_addr* src_
     uint16_t proto, const HostMac* hm, const HostApplication* ha,
     const FpFingerprint* fp, void* cond_var, const HostClient* hc,
     const char* user, AppId appid, const char* di, bool jb, uint32_t lease,
-    uint32_t netmask, const struct in6_addr* router)
+    uint32_t netmask, const struct in6_addr* router, const char* nb_name)
 {
     if ( !enabled )
         return false;
@@ -204,7 +204,7 @@ bool RnaLogger::log(uint16_t type, uint16_t subtype, const struct in6_addr* src_
     assert(ht);
 
     RnaLoggerEvent rle(type, subtype, src_mac, ht, hm, proto, cond_var,
-        ha, fp, hc, user, appid, di, jb, lease, netmask, router, p);
+        ha, fp, hc, user, appid, di, jb, lease, netmask, router, p, nb_name);
     if ( src_ip and (!IN6_IS_ADDR_V4MAPPED(src_ip) or src_ip->s6_addr32[3]) )
         rle.ip = src_ip;
     else
index 29c31c2c3ce6bb71df44f137a8e0b19df51539a8..3d1c584827d1d40f78dc0b351f439a66bb503ea9 100644 (file)
@@ -39,10 +39,10 @@ struct RnaLoggerEvent : public Event
         const snort::HostMac* hmp, uint16_t pr, void* cv, const snort::HostApplication* hap,
         const snort::FpFingerprint* fpr, const snort::HostClient* hcp, const char* u,
         int32_t app, const char* di, bool jb, uint32_t ls, uint32_t nm,
-        const struct in6_addr* rtr, const snort::Packet* p) : type(t), subtype(st),
+        const struct in6_addr* rtr, const snort::Packet* p, const char* nb_name) : type(t), subtype(st),
         mac(mc), ht(rt), hm(hmp), proto(pr), cond_var(cv), ha(hap), fp(fpr), hc(hcp),
         user(u), appid(app), device_info(di), jail_broken(jb), lease(ls), netmask(nm),
-        router(rtr), pkt(p) { }
+        router(rtr), pkt(p), netbios_name(nb_name) { }
 
     uint32_t event_time = 0;
     uint16_t type;
@@ -64,6 +64,7 @@ struct RnaLoggerEvent : public Event
     uint32_t netmask;
     const struct in6_addr* router;
     const snort::Packet* pkt;
+    const char* netbios_name = nullptr;
 };
 
 class RnaLogger
@@ -119,7 +120,7 @@ public:
         void* cond_var = nullptr, const snort::HostClient* hc = nullptr,
         const char* user = nullptr, AppId appid = APP_ID_NONE, const char* device_info = nullptr,
         bool jail_broken = false, uint32_t lease = 0, uint32_t netmask = 0,
-        const struct in6_addr* router = nullptr);
+        const struct in6_addr* router = nullptr, const char* nb_name = nullptr);
 
 private:
     const bool enabled;
index 2792efeb6d04c33563a844f0239d634e5f9327b5..d0cc231e15c71422e8c79c7a9c45db5904907794 100644 (file)
@@ -39,6 +39,7 @@
     #define CHANGE_HOST_UPDATE         15
     #define CHANGE_HOST_TYPE           16
     #define CHANGE_VLAN_TAG            18
+    #define CHANGE_NETBIOS_NAME        21
     #define CHANGE_BANNER_UPDATE       24
     #define CHANGE_CLIENT_APP_UPDATE   32
     #define CHANGE_FULL_DHCP_INFO      33
index 928c6bb315b2aa506d44da22ae17b1f4d3272e63..c660a68561d705d97ee2c06e51d7c81e1ca4e40d 100644 (file)
@@ -62,6 +62,7 @@ enum AppidChangeBit
     APPID_SERVICE_INFO_BIT,
     APPID_CLIENT_INFO_BIT,
     APPID_USER_INFO_BIT,
+    APPID_NETBIOS_NAME_BIT,
 
     APPID_MAX_BIT
 };
@@ -106,6 +107,8 @@ inline void change_bits_to_string(AppidChangeBits& change_bits, std::string& str
         --n? str.append("client-info, ") : str.append("client-info");
     if (change_bits.test(APPID_USER_INFO_BIT))
         --n? str.append("user-info, ") : str.append("user-info");
+    if (change_bits.test(APPID_NETBIOS_NAME_BIT))
+        --n? str.append("netbios-name, ") : str.append("netbios-name");
     if (n != 0) // make sure all bits from AppidChangeBit enum get translated
         str.append("change_bits_to_string error!");
 }