Wireshark-dev: [Wireshark-dev] [PATCH] Fix State management of MySQL dissector
From: Jess Balint <[email protected]>
Date: Mon, 18 Jun 2007 01:25:05 -0500
Hi, I've attached a patch to fix the state management for the MySQL
protocol dissector.

Jess

Index: epan/dissectors/packet-mysql.c
===================================================================
--- epan/dissectors/packet-mysql.c	(revision 22112)
+++ epan/dissectors/packet-mysql.c	(working copy)
@@ -320,8 +320,9 @@
 	{0, NULL}
 };
 
+/* starting state for each capture frame (per-conversation) */
+static GArray *conv_frame_states = NULL;
 
-
 /* protocol id */
 static int proto_mysql = -1;
 
@@ -466,6 +467,7 @@
 /* function prototypes */
 void proto_reg_handoff_mysql(void);
 void proto_register_mysql(void);
+static void mysql_dissect_init(void);
 static void dissect_mysql(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 static guint get_mysql_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
 static void dissect_mysql_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
@@ -496,7 +498,24 @@
 	dissector_add("tcp.port", TCP_PORT_MySQL, mysql_handle);
 }
 
+/* dissector init / memory mgmt */
+static void mysql_dissect_init(void)
+{
+	if(conv_frame_states)
+	{
+		guint i;
+		/* free the frame-state array for each conversation */
+		for(i = 0; i < conv_frame_states->len; ++i)
+		{
+			g_byte_array_free(g_array_index(conv_frame_states,
+							GByteArray *, i), TRUE);
+		}
+		g_array_free(conv_frame_states, TRUE);
+	}
 
+	conv_frame_states = g_array_new(FALSE, TRUE, sizeof(GByteArray *));
+}
+
 /* protocol registration */
 void proto_register_mysql(void)
 {
@@ -891,6 +910,7 @@
 
 	module_t *mysql_module;
 
+	register_init_routine(&mysql_dissect_init);
 	proto_mysql= proto_register_protocol("MySQL Protocol", "MySQL", "mysql");
 	proto_register_field_array(proto_mysql, hf, array_length(hf));
 	proto_register_subtree_array(ett, array_length(ett));
@@ -901,8 +921,6 @@
 				       "Whether the MySQL dissector should reassemble MySQL buffers spanning multiple TCP segments."
 				       " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
 				       &mysql_desegment);
-			       
-	register_dissector("mysql", dissect_mysql_pdu, proto_mysql);				       
 }
 
 
@@ -932,6 +950,7 @@
 	guint           packet_number;
 	gboolean        is_response;
 	my_conn_data_t  *conn_data;
+	GByteArray      *frame_states;
 #ifdef CTDEBUG
 	my_proto_state_t state_in, state_out;
 	guint64         generation;
@@ -948,6 +967,14 @@
 					       pinfo->destport, 0);
 	}
 
+	if (conv_frame_states->len <= conversation->index) {
+		frame_states = g_byte_array_new();
+		g_array_append_val(conv_frame_states, frame_states);
+	} else {
+		frame_states = g_array_index(conv_frame_states, GByteArray *,
+					     conversation->index);
+	}
+
 	/* get associated state information, create if neccessary */
 	conn_data= conversation_get_proto_data(conversation, proto_mysql);
 	if (!conn_data) {
@@ -963,6 +990,13 @@
 		conversation_add_proto_data(conversation, proto_mysql, conn_data);
 	}
 
+	if (frame_states->len <= pinfo->fd->num) {
+		g_byte_array_set_size(frame_states, pinfo->fd->num + 1);
+		frame_states->data[pinfo->fd->num] = conn_data->state;
+	} else {
+		conn_data->state = frame_states->data[pinfo->fd->num];
+	}
+
 	if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
 		col_set_str(pinfo->cinfo, COL_PROTOCOL, "MySQL");
 	}
@@ -1000,7 +1034,7 @@
 	}
 #endif
 
-	if (is_response ) {
+	if (is_response) {
 		if (packet_number == 0) {
 			if (check_col(pinfo->cinfo, COL_INFO)) {
 				col_add_str(pinfo->cinfo, COL_INFO, "Server Greeting" );