]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2752 in SNORT/snort3 from ~CLJUDGE/snort3:snort3_add_netbios_doma...
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Mon, 22 Mar 2021 18:35:40 +0000 (18:35 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Mon, 22 Mar 2021 18:35:40 +0000 (18:35 +0000)
Squashed commit of the following:

commit 482176a1c83f2a63941308ec6dbef5f7f2109712
Author: cljudge <cljudge@cisco.com>
Date:   Wed Feb 17 04:55:19 2021 -0500

    appid: Make netbios domain available through appid api.

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_netbios.cc
src/network_inspectors/appid/service_plugins/test/service_netbios_test.cc
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_discovery_test.cc
src/pub_sub/appid_events.h

index e946f0eaa1f7bd43900190e1d9ca9873ce92f342..20837ce813d0e8d42288c0693cca0fa6ca3209a3 100644 (file)
@@ -646,8 +646,6 @@ void AppIdSession::delete_session_data(bool free_api)
     api.client.reset();
     api.payload.reset();
 
-    snort_free(netbios_domain);
-
     if (tsession)
         delete tsession;
 
@@ -908,7 +906,6 @@ void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits
 void AppIdSession::reset_session_data(AppidChangeBits& change_bits)
 {
     delete_session_data();
-    netbios_domain = nullptr;
     api.hsessions.clear();
 
     tp_payload_app_id = APP_ID_UNKNOWN;
index b9ac1cee41016e6054f2e264115dcfdb1eac8d2e..b62ad024c2b191693135af4ff09dc969199a2e65 100644 (file)
@@ -277,8 +277,6 @@ public:
     std::map<std::string, ClientDetector*> client_candidates;
     bool tried_reverse_service = false;
 
-    char* netbios_domain = nullptr;
-
     TlsSession* tsession = nullptr;
     unsigned scan_flags = 0;
     ThirdPartyAppIdSession* tpsession = nullptr;
@@ -567,6 +565,11 @@ public:
         api.set_netbios_name(change_bits, name);
     }
 
+    void set_netbios_domain(AppidChangeBits& change_bits, const char *domain)
+    {
+        api.set_netbios_domain(change_bits, domain);
+    }
+
     OdpContext& get_odp_ctxt() const
     {
         return odp_ctxt;
index 0e8d3eed076a1248312b2f3e8e5e19e71f369112..4830bfcb7094082287279ea567efe0fde7f132fd 100644 (file)
@@ -313,6 +313,11 @@ const char* AppIdSessionApi::get_netbios_name() const
     return netbios_name;
 }
 
+const char* AppIdSessionApi::get_netbios_domain() const
+{
+    return netbios_domain;
+}
+
 void AppIdSessionApi::set_netbios_name(AppidChangeBits& change_bits, const char* name)
 {
     if (netbios_name)
@@ -325,6 +330,18 @@ void AppIdSessionApi::set_netbios_name(AppidChangeBits& change_bits, const char*
     change_bits.set(APPID_NETBIOS_NAME_BIT);
 }
 
+void AppIdSessionApi::set_netbios_domain(AppidChangeBits& change_bits, const char* domain)
+{
+    if (netbios_domain)
+    {
+        if (strcmp(netbios_domain, domain) == 0)
+            return;
+        snort_free(netbios_domain);
+    }
+    netbios_domain = snort_strdup(domain);
+    change_bits.set(APPID_NETBIOS_DOMAIN_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 726e39cf90e9dd35a7563cfef615d0f663f505ff..f4e50cf74458fec30461997807134838333d017f 100644 (file)
@@ -126,6 +126,7 @@ public:
     const char* get_tls_host() const;
     bool is_http_inspection_done() const;
     const char* get_netbios_name() const;
+    const char* get_netbios_domain() 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.
@@ -166,6 +167,7 @@ private:
     ServiceAppDescriptor service;
     char* tls_host = nullptr;
     char* netbios_name = nullptr;
+    char* netbios_domain = nullptr;
     std::string session_id;
     bool user_logged_in = false;
 
@@ -182,6 +184,7 @@ private:
     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);
+    void set_netbios_domain(AppidChangeBits& change_bits, const char* domain);
 
     AppIdHttpSession* get_hsession(uint32_t stream_index = 0) const;
 
@@ -190,6 +193,7 @@ private:
         delete_all_http_sessions();
         snort_free(tls_host);
         snort_free(netbios_name);
+        snort_free(netbios_domain);
         delete dsession;
     }
 
index 65a66440a1fe4c4084bde710b5d4cebcc14aac78..1acd066932fd0c016aef303c24b7ce8a1c4f3941 100644 (file)
@@ -218,6 +218,7 @@ struct ServiceSMBTransactionHeader
 /* sc * 2 to get to the transaction name */
 
 #define SERVICE_SMB_STATUS_SUCCESS              0x00000000
+#define SERVICE_SMB_MORE_PROCESSING_REQUIRED    0xc0000016
 #define SERVICE_SMB_TRANSACTION_COMMAND         0x25
 #define SERVICE_SMB_COMMAND_SESSION_SETUP_ANDX_RESPONSE 0x73
 #define SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL          0x72
@@ -316,11 +317,11 @@ static int netbios_validate_name_and_decode(const uint8_t** data,
     for (i=0; i<(NBNS_NAME_LEN/2); i++)
     {
         int j = 2 * i;
-        if (lbl_data->data[j] < 'A' || lbl_data->data[j] > 'Z')
+        if (lbl_data->data[j] < 'A' or lbl_data->data[j] > 'Z')
             return -1;
         name[i] = (uint8_t)(((uint8_t)(lbl_data->data[j] - 'A')) << 4);
         j++;
-        if (lbl_data->data[i] < 'A' || lbl_data->data[i] > 'Z')
+        if (lbl_data->data[i] < 'A' or lbl_data->data[i] > 'Z')
             return -1;
         name[i] |= (uint8_t)(lbl_data->data[j] - 'A');
     }
@@ -370,7 +371,7 @@ static int netbios_validate_name(const uint8_t** data,
     if (lbl_data->zero)
         return -1;
     for (i=0; i<NBNS_NAME_LEN; i++)
-        if (lbl_data->data[i] < 'A' || lbl_data->data[i] > 'Z')
+        if (lbl_data->data[i] < 'A' or lbl_data->data[i] > 'Z')
             return -1;
     return 0;
 }
@@ -385,7 +386,7 @@ static int netbios_validate_label(const uint8_t** data, const uint8_t* const end
     lbl = (const NBNSLabel*)(*data);
     *data += sizeof(NBNSLabel);
     tmp = ntohs(lbl->type);
-    if (tmp != NBNS_NB && tmp != NBNS_NBSTAT)
+    if (tmp != NBNS_NB and tmp != NBNS_NBSTAT)
         return -1;
     return 0;
 }
@@ -467,9 +468,9 @@ int NbnsServiceDetector::validate(AppIdDiscoveryArgs& args)
     if (size < sizeof(NBNSHeader))
         goto fail;
     hdr = (const NBNSHeader*)data;
-    if ((hdr->Opcode > NBNS_OPCODE_QUERY &&
-        hdr->Opcode < NBNS_OPCODE_REGISTRATION) ||
-        (hdr->Opcode > NBNS_OPCODE_REFRESHALT &&
+    if ((hdr->Opcode > NBNS_OPCODE_QUERY and
+        hdr->Opcode < NBNS_OPCODE_REGISTRATION) or
+        (hdr->Opcode > NBNS_OPCODE_REFRESHALT and
         hdr->Opcode < NBNS_OPCODE_MHREGISTRATION))
     {
         goto fail;
@@ -574,7 +575,7 @@ static inline void smb_domain_skip_string(const uint8_t** data, uint16_t* size,
 {
     if (unicode)
     {
-        if (*size != 0 && ((*offset) % 2))
+        if (*size != 0 and ((*offset) % 2))
         {
             (*offset)++;
             (*data)++;
@@ -614,8 +615,8 @@ static inline void smb_domain_skip_string(const uint8_t** data, uint16_t* size,
     }
 }
 
-static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int,
-    AppIdSession& asd)
+static inline void smb_find_domain(const uint8_t* data, uint16_t size,
+    AppIdSession& asd, AppidChangeBits& change_bits)
 {
     const ServiceSMBHeader* smb;
     const ServiceSMBAndXResponse* resp;
@@ -631,7 +632,8 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int
     if (size < sizeof(*smb) + sizeof(wc))
         return;
     smb = (const ServiceSMBHeader*)data;
-    if (smb->status != SERVICE_SMB_STATUS_SUCCESS)
+    if (smb->status != SERVICE_SMB_STATUS_SUCCESS and 
+        smb->status != SERVICE_SMB_MORE_PROCESSING_REQUIRED)
         return;
     if (!(smb->flags[0] & SERVICE_SMB_FLAGS_RESPONSE))
         return;
@@ -641,7 +643,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int
     resp = (const ServiceSMBAndXResponse*)data;
     np = (const ServiceSMBNegotiateProtocolResponse*)data;
     wc = 2 * (uint16_t)*data;
-    offset = 1;
+    offset = 0;
     data++;
     size--;
     if (size < (wc + sizeof(byte_count)))
@@ -669,7 +671,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int
             return;
         smb_domain_skip_string(&data, &byte_count, &offset, unicode);
         smb_domain_skip_string(&data, &byte_count, &offset, unicode);
-        if (byte_count != 0 && (offset % 2))
+        if (byte_count != 0 and (offset % 2))
         {
             data++;
             byte_count--;
@@ -682,7 +684,7 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int
             capabilities = LETOHL_UNALIGNED(&np->capabilities);
             if (capabilities & SERVICE_SMB_CAPABILITIES_EXTENDED_SECURITY)
                 return;
-            unicode = (capabilities & SERVICE_SMB_CAPABILITIES_UNICODE) || unicode;
+            unicode = (capabilities & SERVICE_SMB_CAPABILITIES_UNICODE) or unicode;
         }
         else if (wc != 26)
             return;
@@ -719,11 +721,12 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int
                 data++;
             }
         }
-        if (!found && byte_count == 1 && *data == 0)
+        if (!found and byte_count == 1 and *data == 0)
         {
             byte_count--;
         }
-        if (byte_count && smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL)
+        if (byte_count and smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL and
+            smb->command != SERVICE_SMB_COMMAND_SESSION_SETUP_ANDX_RESPONSE)
             return;
     }
     else
@@ -747,12 +750,12 @@ static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int
                 data++;
             }
         }
-        if (byte_count && smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL)
+        if (byte_count and smb->command != SERVICE_SMB_COMMAND_NEGOTIATE_PROTOCOL)
             return;
     }
 
-    if ( pos && (!asd.netbios_domain) )
-        asd.netbios_domain = snort_strdup(domain);
+    if (pos)
+        asd.set_netbios_domain(change_bits, (const char *)domain);
 }
 
 NbssServiceDetector::NbssServiceDetector(ServiceDiscovery* sd)
@@ -823,16 +826,16 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
             switch (hdr->type)
             {
             case NBSS_TYPE_RESP_POSITIVE:
-                if (hdr->flags || hdr->length)
+                if (hdr->flags or hdr->length)
                     goto fail;
                 nd->state = NBSS_STATE_FLOW;
                 break;
             case NBSS_TYPE_RESP_NEGATIVE:
-                if (hdr->flags || ntohs(hdr->length) != 1)
+                if (hdr->flags or ntohs(hdr->length) != 1)
                     goto fail;
                 if (data >= end)
                     goto fail;
-                if (*data < 0x80 || (*data > 0x83 && *data < 0x8F) || *data > 0x8F)
+                if (*data < 0x80 or (*data > 0x83 and *data < 0x8F) or *data > 0x8F)
                     goto fail;
                 data++;
                 break;
@@ -842,8 +845,8 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
                 nd->length = ((uint32_t)(hdr->flags & 0x01)) << 16;
                 nd->length |= (uint32_t)ntohs(hdr->length);
                 tmp = end - data;
-                if (tmp >= sizeof(NB_SMB_BANNER) &&
-                    nd->length >= sizeof(NB_SMB_BANNER) &&
+                if (tmp >= sizeof(NB_SMB_BANNER) and
+                    nd->length >= sizeof(NB_SMB_BANNER) and
                     !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER)))
                 {
                     if (nd->serviceAppId != APP_ID_DCE_RPC)
@@ -854,11 +857,11 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
                     if (nd->length <= tmp)
                     {
                         smb_find_domain(data + sizeof(NB_SMB_BANNER),
-                            nd->length - sizeof(NB_SMB_BANNER), dir, args.asd);
+                            nd->length - sizeof(NB_SMB_BANNER), args.asd, args.change_bits);
                     }
                 }
-                else if (tmp >= 4 && nd->length >= 4 &&
-                    !(*((const uint32_t*)data)) &&
+                else if (tmp >= 4 and nd->length >= 4 and
+                    !(*((const uint32_t*)data)) and
                     dcerpc_validate(data+4, ((int)std::min(tmp, nd->length)) - 4) > 0)
                 {
                     nd->serviceAppId = APP_ID_DCE_RPC;
@@ -879,7 +882,7 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
                 }
                 break;
             case NBSS_TYPE_RESP_RETARGET:
-                if (hdr->flags || ntohs(hdr->length) != 6)
+                if (hdr->flags or ntohs(hdr->length) != 6)
                     goto fail;
                 if (end - data < 6)
                     goto fail;
@@ -897,7 +900,7 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
             switch (hdr->type)
             {
             case NBSS_TYPE_KEEP_ALIVE:
-                if (hdr->flags || hdr->length)
+                if (hdr->flags or hdr->length)
                     goto fail;
                 break;
             case NBSS_TYPE_MESSAGE:
@@ -906,8 +909,8 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
                 nd->length = ((uint32_t)(hdr->flags & 0x01)) << 16;
                 nd->length += (uint32_t)ntohs(hdr->length);
                 tmp = end - data;
-                if (tmp >= sizeof(NB_SMB_BANNER) &&
-                    nd->length >= sizeof(NB_SMB_BANNER) &&
+                if (tmp >= sizeof(NB_SMB_BANNER) and
+                    nd->length >= sizeof(NB_SMB_BANNER) and
                     !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER)))
                 {
                     if (nd->serviceAppId != APP_ID_DCE_RPC)
@@ -916,11 +919,12 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
                     }
                     if (nd->length <= tmp)
                     {
-                        smb_find_domain(data + sizeof(NB_SMB_BANNER), nd->length, dir, args.asd);
+                        smb_find_domain(data + sizeof(NB_SMB_BANNER), nd->length, args.asd,
+                            args.change_bits);
                     }
                 }
-                else if (tmp >= 4 && nd->length >= 4 &&
-                    !(*((const uint32_t*)data)) &&
+                else if (tmp >= 4 and nd->length >= 4 and
+                    !(*((const uint32_t*)data)) and
                     !(dcerpc_validate(data+4, ((int)std::min(tmp, nd->length)) - 4) > 0))
                 {
                     nd->serviceAppId = APP_ID_DCE_RPC;
@@ -1045,7 +1049,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args)
     data += sizeof(NBDgmHeader);
     if (hdr->zero)
         goto fail;
-    if (!hdr->first || hdr->more)
+    if (!hdr->first or hdr->more)
         goto fail;
 
     switch (hdr->type)
@@ -1072,7 +1076,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args)
             goto fail;
         if (data >= end)
             goto fail;
-        if (end-data >= (int)sizeof(NB_SMB_BANNER) &&
+        if (end-data >= (int)sizeof(NB_SMB_BANNER) and
             !memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER)))
         {
             if (!args.asd.is_service_detected())
@@ -1103,7 +1107,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args)
                 goto not_mailslot;
             data += sizeof(mailslot);
             browser = (const ServiceSMBBrowserHeader*)data;
-            if (browser->command != SERVICE_SMB_MAILSLOT_HOST &&
+            if (browser->command != SERVICE_SMB_MAILSLOT_HOST and
                 browser->command != SERVICE_SMB_MAILSLOT_LOCAL_MASTER)
             {
                 goto not_mailslot;
@@ -1123,7 +1127,7 @@ not_mailslot:
         data += sizeof(NBDgmError);
         if (end != data)
             goto fail;
-        if (err->code < NBDGM_ERROR_CODE_MIN ||
+        if (err->code < NBDGM_ERROR_CODE_MIN or
             err->code > NBDGM_ERROR_CODE_MAX)
         {
             goto fail;
index 33061e067c01d522ced77b2c3a91ed3544e626ff..6a916c611bc908732480c11c7beff07e1ecac43e 100644 (file)
@@ -50,6 +50,7 @@ int ServiceDiscovery::fail_service(AppIdSession&, const Packet*, AppidSessionDir
 int ServiceDiscovery::add_service_port(AppIdDetector*,
     const ServiceDetectorPort&) { return APPID_EINVALID; }
 void AppIdSessionApi::set_netbios_name(AppidChangeBits&, const char*) {}
+void AppIdSessionApi::set_netbios_domain(AppidChangeBits&, const char*) {}
 
 TEST_GROUP(service_netbios_test){};
 
index 53e5796fdb0ecc3e3af13ce9cf56789f578e0fd6..4ab780b3ba7b9028c55045448fdf62b7d0289d7b 100644 (file)
@@ -253,7 +253,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 == 000000000000000000", test_log);
+    STRCMP_EQUAL("Published change_bits == 0000000000000000000", test_log);
 
     service = APP_ID_NONE;
     client = APP_ID_NONE;
@@ -266,7 +266,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 == 000000000100011000", test_log);
+    STRCMP_EQUAL("Published change_bits == 0000000000100011000", 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);
@@ -282,7 +282,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 == 000000000100011000", test_log);
+    STRCMP_EQUAL("Published change_bits == 0000000000100011000", test_log);
 
     string host = "";
     val = appid_api.ssl_app_group_id_lookup(flow, (const char*)(host.c_str()), nullptr,
@@ -293,7 +293,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 == 000000000100000000", test_log);
+    STRCMP_EQUAL("Published change_bits == 0000000000100000000", test_log);
     mock().checkExpectations();
 }
 
index 657362570daf137c35e5d85ae29f8f5636f74cd9..e0abc440ebac331113ae84e853b1216c74435fee 100644 (file)
@@ -375,7 +375,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 == 000000000001111100", test_log);
+    STRCMP_EQUAL("Published change_bits == 0000000000001111100", test_log);
 
     delete &asd->get_api();
     delete asd;
@@ -407,7 +407,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 == 000000000001111100", test_log);
+    STRCMP_EQUAL("Published change_bits == 0000000000001111100", test_log);
     delete &asd->get_api();
     delete asd;
     delete flow;
@@ -503,10 +503,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, netbios-name");
+        " user-info, netbios-name, netbios-domain");
 
     // Failure of this test is a reminder that enum is changed, hence translator needs update
-    CHECK_EQUAL(APPID_MAX_BIT, 18);
+    CHECK_EQUAL(APPID_MAX_BIT, 19);
 }
 
 int main(int argc, char** argv)
index c660a68561d705d97ee2c06e51d7c81e1ca4e40d..c4337950fd61d07818d0e94a4ccae17f6aa396f1 100644 (file)
@@ -63,6 +63,7 @@ enum AppidChangeBit
     APPID_CLIENT_INFO_BIT,
     APPID_USER_INFO_BIT,
     APPID_NETBIOS_NAME_BIT,
+    APPID_NETBIOS_DOMAIN_BIT,
 
     APPID_MAX_BIT
 };
@@ -109,6 +110,8 @@ inline void change_bits_to_string(AppidChangeBits& change_bits, std::string& str
         --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 (change_bits.test(APPID_NETBIOS_DOMAIN_BIT))
+        --n? str.append("netbios-domain, ") : str.append("netbios-domain");
     if (n != 0) // make sure all bits from AppidChangeBit enum get translated
         str.append("change_bits_to_string error!");
 }