Huge thanks to our Platinum Members Endace and LiveAction,
and our Silver Member Veeam, for supporting the Wireshark Foundation and project.

Smb2-protocol: [Smb2-protocol] [PATCH] TID per UID

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: "Stefan (metze) Metzmacher" <metze@xxxxxxxxx>
Date: Thu, 08 Dec 2005 13:02:13 +0100
Hi Ronnie,

can you please apply this patch?

thanks!
metze
=== epan/dissectors/packet-smb2.c
==================================================================
--- epan/dissectors/packet-smb2.c	(revision 1031)
+++ epan/dissectors/packet-smb2.c	(local)
@@ -177,6 +177,7 @@
 static int hf_smb2_domain_name = -1;
 static int hf_smb2_host_name = -1;
 static int hf_smb2_auth_frame = -1;
+static int hf_smb2_tcon_frame = -1;
 static int hf_smb2_share_type = -1;
 
 static gint ett_smb2 = -1;
@@ -1679,8 +1680,10 @@
 	/* If we have found a uid->acct_name mapping, store it */
 	if(!pinfo->fd->flags.visited){
 		idx=0;
-		while(ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++)){
-			if(ntlmssph && ntlmssph->type==3){
+		while(TRUE){
+			ntlmssph=fetch_tapped_data(ntlmssp_tap_id, idx++);
+			if(!ntlmssph) break;
+			if(ntlmssph->type==3){
 				smb2_uid_info_t *uid;
 				uid=se_alloc(sizeof(smb2_uid_info_t));
 				uid->uid=si->uid;
@@ -1688,8 +1691,8 @@
 				uid->domain_name=se_strdup(ntlmssph->domain_name);
 				uid->host_name=se_strdup(ntlmssph->host_name);
 				uid->auth_frame=pinfo->fd->num;
+				uid->tids= g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
 				g_hash_table_insert(si->conv->uids, uid, uid);
-
 			}
 		}
 	}
@@ -1758,37 +1761,31 @@
 static int
 dissect_smb2_tree_connect_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, smb2_info_t *si _U_)
 {
+	guint16 share_type;
+
 	/* buffer code */
 	offset = dissect_smb2_buffercode(tree, tvb, offset, NULL);
 
 	/* share type */
+	share_type = tvb_get_letohs(tvb, offset);
 	proto_tree_add_item(tree, hf_smb2_share_type, tvb, offset, 2, TRUE);
 	offset += 2;
 
-	if(!pinfo->fd->flags.visited && si->saved && si->saved->private_data) {
+	if(!pinfo->fd->flags.visited && si->saved && si->saved->private_data && si->session) {
 		smb2_tid_info_t *tid, tid_key;
 
-
 		tid_key.tid=si->tid;
-		tid=g_hash_table_lookup(si->conv->tids, &tid_key);
+		tid=g_hash_table_lookup(si->session->tids, &tid_key);
 		if(tid){
-			g_hash_table_remove(si->conv->tids, &tid_key);
+			g_hash_table_remove(si->session->tids, &tid_key);
 		}
 		tid=se_alloc(sizeof(smb2_tid_info_t));
 		tid->tid=si->tid;
 		tid->name=(char *)si->saved->private_data;
-		tid->flags=0;
-		if(strlen(tid->name)>=4){
-			if(!strcmp(tid->name+strlen(tid->name)-4, "IPC$")){
-				tid->flags|=SMB2_FLAGS_TID_IS_IPC;
-			} else {
-				tid->flags|=SMB2_FLAGS_TID_IS_NOT_IPC;
-			}
-		} else {
-			tid->flags|=SMB2_FLAGS_TID_IS_NOT_IPC;
-		}
+		tid->connect_frame=pinfo->fd->num;
+		tid->share_type=share_type;
 
-		g_hash_table_insert(si->conv->tids, tid, tid);
+		g_hash_table_insert(si->session->tids, tid, tid);
 
 		si->saved->private_data=NULL;
 	}
@@ -2506,7 +2503,7 @@
 
 
 	/* data or dcerpc ?*/
-	if(length && si->tree && si->tree->flags&SMB2_FLAGS_TID_IS_IPC ){
+	if(length && si->tree && si->tree->share_type == SMB2_SHARE_TYPE_IPC){
 		offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si);
 		return offset;
 	}
@@ -2936,7 +2933,7 @@
 	offset += 8;
 
 	/* data or dcerpc ?*/
-	if(length && si->tree && si->tree->flags&SMB2_FLAGS_TID_IS_IPC ){
+	if(length && si->tree && si->tree->share_type == SMB2_SHARE_TYPE_IPC){
 		offset = dissect_file_data_dcerpc(tvb, pinfo, tree, offset, length, si);
 		return offset;
 	}
@@ -3868,75 +3865,90 @@
 }
 
 static int
-dissect_smb2_tid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
+dissect_smb2_tid_uid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
 {
 	proto_item *tid_item=NULL;
 	proto_tree *tid_tree=NULL;
 	smb2_tid_info_t tid_key;
+	int tid_offset;
+	proto_item *uid_item=NULL;
+	proto_tree *uid_tree=NULL;
+	smb2_uid_info_t uid_key;
+	int uid_offset;
+	proto_item *item;
 
 	/* Tree ID */
+	tid_offset = offset;
 	si->tid=tvb_get_letohl(tvb, offset);
 	tid_item=proto_tree_add_item(tree, hf_smb2_tid, tvb, offset, 4, TRUE);
 	if(tree){
 		tid_tree=proto_item_add_subtree(tid_item, ett_smb2_tid_tree);
 	}
-
-	/* see if we can find the name for this tid */
-	tid_key.tid=si->tid;
-	si->tree=g_hash_table_lookup(si->conv->tids, &tid_key);
-	if(si->tree){
-		proto_item *item;
-
-		item=proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, offset, 4, si->tree->name);
-		PROTO_ITEM_SET_GENERATED(item);
-
-		proto_item_append_text(tid_item, "  %s", si->tree->name);
-	}
-
 	offset += 4;
 
-	return offset;
-}
-
-static int
-dissect_smb2_uid(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, int offset, smb2_info_t *si)
-{
-	proto_item *uid_item=NULL;
-	proto_tree *uid_tree=NULL;
-	smb2_uid_info_t uid_key, *uid;
-
 	/* User ID */
+	uid_offset = offset;
 	si->uid=tvb_get_letoh64(tvb, offset);
 	uid_item=proto_tree_add_item(tree, hf_smb2_uid, tvb, offset, 8, TRUE);
 	if(tree){
 		uid_tree=proto_item_add_subtree(uid_item, ett_smb2_uid_tree);
 	}
+	offset += 8;
 
-	/* see if we can find the name for this uid */
+	/* now we need to first lookup the uid session */
 	uid_key.uid=si->uid;
-	uid=g_hash_table_lookup(si->conv->uids, &uid_key);
-	if(uid){
-		proto_item *item;
+	si->session=g_hash_table_lookup(si->conv->uids, &uid_key);
+	if(!si->session) {
+		if (si->opcode != 0x03) return offset;
 
-		item=proto_tree_add_string(uid_tree, hf_smb2_acct_name, tvb, offset, 0, uid->acct_name);
+		/* if we come to a session that is unknown, and the operation is 
+		 * a tree connect, we create a dummy sessison, so we can hang the
+		 * tree data on it
+		 */
+		si->session=se_alloc(sizeof(smb2_uid_info_t));
+		si->session->uid=si->uid;
+		si->session->acct_name=NULL;
+		si->session->domain_name=NULL;
+		si->session->host_name=NULL;
+		si->session->auth_frame=(guint32)-1;
+		si->session->tids= g_hash_table_new(smb2_tid_info_hash, smb2_tid_info_equal);
+		g_hash_table_insert(si->conv->uids, si->session, si->session);
+
+		return offset;
+	}
+
+	if (si->session->auth_frame != (guint32)-1) {
+		item=proto_tree_add_string(uid_tree, hf_smb2_acct_name, tvb, uid_offset, 0, si->session->acct_name);
 		PROTO_ITEM_SET_GENERATED(item);
-		proto_item_append_text(uid_item, "   Acct:%s", uid->acct_name);
+		proto_item_append_text(uid_item, " Acct:%s", si->session->acct_name);
 
-		item=proto_tree_add_string(uid_tree, hf_smb2_domain_name, tvb, offset, 0, uid->domain_name);
+		item=proto_tree_add_string(uid_tree, hf_smb2_domain_name, tvb, uid_offset, 0, si->session->domain_name);
 		PROTO_ITEM_SET_GENERATED(item);
-		proto_item_append_text(uid_item, " Domain:%s", uid->domain_name);
+		proto_item_append_text(uid_item, " Domain:%s", si->session->domain_name);
 
-		item=proto_tree_add_string(uid_tree, hf_smb2_host_name, tvb, offset, 0, uid->host_name);
+		item=proto_tree_add_string(uid_tree, hf_smb2_host_name, tvb, uid_offset, 0, si->session->host_name);
 		PROTO_ITEM_SET_GENERATED(item);
-		proto_item_append_text(uid_item, " Host:%s", uid->host_name);
+		proto_item_append_text(uid_item, " Host:%s", si->session->host_name);
 
-		item=proto_tree_add_uint(uid_tree, hf_smb2_auth_frame, tvb, offset, 0, uid->auth_frame);
+		item=proto_tree_add_uint(uid_tree, hf_smb2_auth_frame, tvb, uid_offset, 0, si->session->auth_frame);
 		PROTO_ITEM_SET_GENERATED(item);
-
 	}
 
-	offset += 8;
+	/* see if we can find the name for this tid */
+	tid_key.tid=si->tid;
+	si->tree=g_hash_table_lookup(si->session->tids, &tid_key);
+	if(!si->tree) return offset;
 
+	item=proto_tree_add_string(tid_tree, hf_smb2_tree, tvb, tid_offset, 4, si->tree->name);
+	PROTO_ITEM_SET_GENERATED(item);
+	proto_item_append_text(tid_item, "  %s", si->tree->name);
+
+	item=proto_tree_add_uint(tid_tree, hf_smb2_share_type, tvb, tid_offset, 0, si->tree->share_type);
+	PROTO_ITEM_SET_GENERATED(item);
+
+	item=proto_tree_add_uint(tid_tree, hf_smb2_tcon_frame, tvb, tid_offset, 0, si->tree->connect_frame);
+	PROTO_ITEM_SET_GENERATED(item);
+
 	return offset;
 }
 
@@ -3981,9 +3993,6 @@
 			smb2_saved_info_equal_matched);
 		si->conv->unmatched= g_hash_table_new(smb2_saved_info_hash_unmatched,
 			smb2_saved_info_equal_unmatched);
-		si->conv->tids= g_hash_table_new(smb2_tid_info_hash,
-			smb2_tid_info_equal);
-
 		si->conv->uids= g_hash_table_new(smb2_uid_info_hash,
 			smb2_uid_info_equal);
 
@@ -4058,12 +4067,9 @@
 	proto_tree_add_item(header_tree, hf_smb2_pid, tvb, offset, 4, TRUE);
 	offset += 4;
 
-	/* Tree ID */
-	offset = dissect_smb2_tid(pinfo, header_tree, tvb, offset, si);
+	/* Tree ID and User ID */
+	offset = dissect_smb2_tid_uid(pinfo, header_tree, tvb, offset, si);
 
-	/* User ID */
-	offset = dissect_smb2_uid(pinfo, header_tree, tvb, offset, si);
-
 	/* some unknown bytes */
 	proto_tree_add_item(header_tree, hf_smb2_unknown, tvb, offset, 4, FALSE);
 	offset += 4;
@@ -4648,6 +4654,10 @@
 		{ "Authenticated in Frame", "smb2.auth_frame", FT_UINT32, BASE_DEC,
 		NULL, 0, "Which frame this user was authenticated in", HFILL }},
 
+	{ &hf_smb2_tcon_frame,
+		{ "Connected in Frame", "smb2.tcon_frame", FT_UINT32, BASE_DEC,
+		NULL, 0, "Which frame this share was connected in", HFILL }},
+
 	{ &hf_smb2_tag,
 		{ "Tag", "smb2.tag", FT_STRING, BASE_NONE,
 		NULL, 0, "Tag of chain entry", HFILL }},
=== epan/dissectors/packet-smb2.h
==================================================================
--- epan/dissectors/packet-smb2.h	(revision 1031)
+++ epan/dissectors/packet-smb2.h	(local)
@@ -50,18 +50,10 @@
 	nstime_t req_time;
 } smb2_saved_info_t;
 
-/* at most one of these two bits may be set.
- * if ipc$ status is unknown none is set.
- *
- * if the tid name ends with "IPC$" we assume that all files on this tid
- * are dcerpc pipes.
- */
-#define SMB2_FLAGS_TID_IS_IPC		0x00000001
-#define SMB2_FLAGS_TID_IS_NOT_IPC	0x00000002
-
 typedef struct _smb2_tid_info_t {
 	guint32 tid;
-	guint32 flags;
+	guint32 connect_frame;
+	guint16 share_type;
 	char *name;
 } smb2_tid_info_t;
 
@@ -71,6 +63,7 @@
 	char *acct_name;
 	char *domain_name;
 	char *host_name;
+	GHashTable *tids;
 } smb2_uid_info_t;
 
 /* Structure to keep track of conversations and the hash tables.
@@ -80,7 +73,6 @@
 	/* these two tables are used to match requests with responses */
 	GHashTable *unmatched;
 	GHashTable *matched;
-	GHashTable *tids;
 	GHashTable *uids;
 } smb2_conv_info_t;
 
@@ -99,6 +91,7 @@
 	smb2_conv_info_t	*conv;
 	smb2_saved_info_t	*saved;
 	smb2_tid_info_t		*tree;
+	smb2_uid_info_t		*session;
 	proto_tree *top_tree;	
 } smb2_info_t;
 

Attachment: signature.asc
Description: OpenPGP digital signature