Ethereal-dev: [Ethereal-dev] Fixes for packet-tds.c

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

From: Yaniv Kaul <ykaul@xxxxxxxxxxxx>
Date: Wed, 04 Aug 2004 01:39:44 +0200
Please find attached svn diff for packet-tds.c

Fixes/additions:
1. define new TDS packet type (17) - NTLM authentication packet. Call the ntlmssp dissector to dissect it when needed. 2. define new TDS packet type (18) - donno what it is exactly, but it's there. Will dissect it someday.
3. heuristic in netlib_check_login_pkt should also check port 2433.
4. unify the dissection of msg and err token. They have the same structure.
5. improve the dissection of the above mentioned token.


Index: packet-tds.c
===================================================================
--- packet-tds.c	(revision 11599)
+++ packet-tds.c	(working copy)
@@ -175,6 +175,7 @@
 #define TDS_LOGOUT_CHN_PKT  13
 #define TDS_QUERY5_PKT      15  /* or "Normal tokenized request or response */
 #define TDS_LOGIN7_PKT      16	/* or "Urgent tokenized request or response */
+#define TDS_NTLMAUTH_PKT    17
 #define TDS_XXX7_PKT        18	/* seen in one capture */
 
 #define is_valid_tds_type(x) ((x) >= TDS_QUERY_PKT && (x) <= TDS_XXX7_PKT)
@@ -336,6 +337,8 @@
 	{TDS_CANCEL_PKT, "Cancel Packet"},
 	{TDS_QUERY5_PKT, "TDS5 Query Packet"},
 	{TDS_LOGIN7_PKT, "TDS7/8 Login Packet"},
+	{TDS_XXX7_PKT, "TDS7/8 0x12 Packet"},
+	{TDS_NTLMAUTH_PKT, "NTLM Authentication Packet"},
 	{0, NULL},
 };
 
@@ -802,8 +805,8 @@
 			return FALSE;
 		}
 	/* check if it is MS SQL default port */
-	} else if (pinfo->srcport != 1433 &&
-		pinfo->destport != 1433) {
+	} else if ((pinfo->srcport != 1433 &&
+		pinfo->destport != 1433) && (pinfo->srcport != 2433 && pinfo->destport != 2433)) {
 		/* otherwise, we can not ensure this is netlib */
 		/* beyond a reasonable doubt.                  */
           		return FALSE;
@@ -887,57 +890,10 @@
 }
 
 static void
-dissect_tds_msg_token(tvbuff_t *tvb, guint offset, guint token_sz, proto_tree *tree)
-{
-	guint16 msg_len;
-	guint8 srvr_len;
-	char *msg;
-	gboolean is_unicode = FALSE;
-
-	proto_tree_add_text(tree, tvb, offset, 4, "SQL Message Number: %d", tvb_get_letohl(tvb, offset));
-	offset += 4;
-	proto_tree_add_text(tree, tvb, offset, 1, "State: %u", tvb_get_guint8(tvb, offset));
-	offset +=1;
-	proto_tree_add_text(tree, tvb, offset, 1, "Level: %u", tvb_get_guint8(tvb, offset));
-	offset +=1;
-	
-	msg_len = tvb_get_letohs(tvb, offset);
-	proto_tree_add_text(tree, tvb, offset, 2, "Message length: %u characters", msg_len);
-	offset +=2;
-	
-	srvr_len = tvb_get_guint8(tvb, offset + msg_len);
-	
-	if(msg_len + srvr_len + 9U + 3U != token_sz) /* 9 is the length of message number (4), state (1), level (1), msg_len (2), srvr_len (1) fields */
-		is_unicode = TRUE;
-
-	if(is_unicode) {
-		msg = tvb_fake_unicode(tvb, offset, msg_len, TRUE);
-		msg_len *= 2;
-	} else {
-		msg = tvb_get_string(tvb, offset, msg_len);
-	}
-	proto_tree_add_string(tree, hf_tds7_message, tvb, offset, msg_len, msg);
-	g_free(msg);
-	offset += msg_len;
-
-	proto_tree_add_text(tree, tvb, offset, 1, "Server name length: %u characters", srvr_len);
-	offset +=1;
-	
-	if (is_unicode) {
-		msg = tvb_fake_unicode(tvb, offset, srvr_len, TRUE);
-		srvr_len *=2;
-	} else {
-		msg = tvb_get_string(tvb, offset, srvr_len);
-	}
-	proto_tree_add_text(tree, tvb, offset, srvr_len, "Server name: %s", msg);
-	g_free(msg);
-}
-
-static void
 dissect_tds_err_token(tvbuff_t *tvb, guint offset, guint token_sz, proto_tree *tree)
 {
 	guint16 msg_len;
-	guint8 srvr_len;
+	guint8 srvr_len, proc_len;
 	char *msg;
 	gboolean is_unicode = FALSE;
 
@@ -945,16 +901,14 @@
 	offset += 4;
 	proto_tree_add_text(tree, tvb, offset, 1, "State: %u", tvb_get_guint8(tvb, offset));
 	offset +=1;
-	proto_tree_add_text(tree, tvb, offset, 1, "Level: %u", tvb_get_guint8(tvb, offset));
+	proto_tree_add_text(tree, tvb, offset, 1, "Severity Level: %u", tvb_get_guint8(tvb, offset));
 	offset +=1;
 
 	msg_len = tvb_get_letohs(tvb, offset);
-	proto_tree_add_text(tree, tvb, offset, 1, "Error length: %u characters", msg_len);
+	proto_tree_add_text(tree, tvb, offset, 1, "Error message length: %u characters", msg_len);
 	offset +=2;
 
-	srvr_len = tvb_get_guint8(tvb, offset + msg_len);
-	
-	if(msg_len + srvr_len + 9U + 3U != token_sz) /* 9 is the length of message number (4), state (1), level (1), msg_len (2), srvr_len (1) fields */
+	if(tvb_get_guint8(tvb, offset+1) == 0) /* FIXME: It's probably unicode, if the 2nd byte of the message is zero. It's not a good detection method, but it works */
 		is_unicode = TRUE;
 
 	if(is_unicode) {
@@ -966,18 +920,40 @@
 	proto_tree_add_text(tree, tvb, offset, msg_len, "Error: %s", format_text(msg, strlen(msg)));
 	g_free(msg);
 	offset += msg_len;
-
+	
+	srvr_len = tvb_get_guint8(tvb, offset);
+	
 	proto_tree_add_text(tree, tvb, offset, 1, "Server name length: %u characters", srvr_len);
 	offset +=1;
+	if(srvr_len) {
+		if (is_unicode) {
+			msg = tvb_fake_unicode(tvb, offset, srvr_len, TRUE);
+			srvr_len *=2;
+		} else {
+			msg = tvb_get_string(tvb, offset, srvr_len);
+		}
+		proto_tree_add_text(tree, tvb, offset, srvr_len, "Server name: %s", msg);
+		offset += srvr_len;
+		g_free(msg);
+	}
+
+	proc_len = tvb_get_guint8(tvb, offset);
 	
-	if (is_unicode) {
-		msg = tvb_fake_unicode(tvb, offset, srvr_len, TRUE);
-		srvr_len *=2;
-	} else {
-		msg = tvb_get_string(tvb, offset, srvr_len);
+	proto_tree_add_text(tree, tvb, offset, 1, "Process name length: %u characters", proc_len);
+	offset +=1;
+	if(proc_len) {
+		if (is_unicode) {
+			msg = tvb_fake_unicode(tvb, offset, proc_len, TRUE);
+			proc_len *=2;
+		} else {
+			msg = tvb_get_string(tvb, offset, proc_len);
+		}
+		proto_tree_add_text(tree, tvb, offset, proc_len, "Process name: %s", msg);
+		offset += proc_len;
+		g_free(msg);
 	}
-	proto_tree_add_text(tree, tvb, offset, srvr_len, "Server name: %s", msg);
-	g_free(msg);
+
+	proto_tree_add_text(tree, tvb, offset, 2, "line number: %d", tvb_get_letohs(tvb, offset));
 }
 
 static void
@@ -1097,9 +1073,9 @@
 static void
 dissect_tds_done_token(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
-	proto_tree_add_text(tree, tvb, offset, 2, "bit flag");
+	proto_tree_add_text(tree, tvb, offset, 2, "Status flags");
 	offset += 2;
-	proto_tree_add_text(tree, tvb, offset, 2, "unknown");
+	proto_tree_add_text(tree, tvb, offset, 2, "Operation");
 	offset += 2;
 	proto_tree_add_text(tree, tvb, offset, 4, "row count: %u", tvb_get_letohl(tvb, offset));
 	offset += 2;
@@ -1199,10 +1175,8 @@
 			dissect_tds_ntlmssp(tvb, pinfo, token_tree, pos + 3,
 			    token_sz - 3);
 			break;
-		case TDS_MSG_TOKEN:
-			dissect_tds_msg_token(tvb, pos + 3, token_sz - 3, token_tree);
-			break;
 		case TDS_ERR_TOKEN:
+		case TDS_MSG_TOKEN:
 			dissect_tds_err_token(tvb, pos + 3, token_sz - 3, token_tree);
 			break;
 		case TDS_DONE_TOKEN:
@@ -1330,6 +1304,9 @@
 		case TDS_QUERY_PKT:
 			dissect_tds_query_packet(next_tvb, pinfo, tds_tree);
 			break;
+		case TDS_NTLMAUTH_PKT:
+			dissect_tds_ntlmssp(next_tvb, pinfo, tds_tree, offset - 8, -1);
+			break;
 		default:
 			proto_tree_add_text(tds_tree, next_tvb, 0, -1,
 			    "TDS Packet");