aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-mysql.c
diff options
context:
space:
mode:
authorBill Meier <wmeier@newsguy.com>2010-10-06 14:59:19 +0000
committerBill Meier <wmeier@newsguy.com>2010-10-06 14:59:19 +0000
commitaffd5e0207a6545687b2d03d4d782901fa68c1fb (patch)
tree457de72c239c63e77b5e31d8d16e968c1bdbebd7 /epan/dissectors/packet-mysql.c
parentc522f01e2bd5909ea8221f9167e94197cf87b08b (diff)
From Alexis La Goutte: MYSQL: Fix FIELD_PACKET dissection;
From me: Two additional fixes for FIELD_PACKET dissection; Revision of the original patch from Alexis to properly dissect a SHOW_FIELDS response message. svn path=/trunk/; revision=34395
Diffstat (limited to 'epan/dissectors/packet-mysql.c')
-rw-r--r--epan/dissectors/packet-mysql.c74
1 files changed, 48 insertions, 26 deletions
diff --git a/epan/dissectors/packet-mysql.c b/epan/dissectors/packet-mysql.c
index 31f0af9e98..39a67f22bd 100644
--- a/epan/dissectors/packet-mysql.c
+++ b/epan/dissectors/packet-mysql.c
@@ -215,8 +215,7 @@ static const value_string mysql_charset_vals[] = {
/* collation codes may change over time, recreate with the following SQL
-SELECT CONCAT(' {', ID, ',"', CHARACTER_SET_NAME,
- ' COLLATE ', COLLATION_NAME, '"},')
+SELECT CONCAT(' {', ID, ',"', CHARACTER_SET_NAME, ' COLLATE ', COLLATION_NAME, '"},')
FROM INFORMATION_SCHEMA.COLLATIONS
ORDER BY ID
INTO OUTFILE '/tmp/mysql-collations';
@@ -450,6 +449,7 @@ static int hf_mysql_fld_auto_increment = -1;
static int hf_mysql_fld_timestamp = -1;
static int hf_mysql_fld_set = -1;
static int hf_mysql_fld_decimals = -1;
+static int hf_mysql_fld_default = -1;
static int hf_mysql_row_length = -1;
static int hf_mysql_row_text = -1;
@@ -494,6 +494,7 @@ typedef enum mysql_state
RESPONSE_OK,
RESPONSE_MESSAGE,
RESPONSE_TABULAR,
+ RESPONSE_SHOW_FIELDS,
FIELD_PACKET,
ROW_PACKET,
RESPONSE_PREPARE,
@@ -502,16 +503,17 @@ typedef enum mysql_state
#ifdef CTDEBUG
static const value_string state_vals[] = {
- {UNDEFINED, "undefined"},
- {LOGIN, "login"},
- {REQUEST, "request"},
- {RESPONSE_OK, "response OK"},
- {RESPONSE_MESSAGE, "response message"},
- {RESPONSE_TABULAR, "tabular response"},
- {FIELD_PACKET, "field packet"},
- {ROW_PACKET, "row packet"},
- {RESPONSE_PREPARE, "response to PREPARE"},
- {PARAM_PACKET, "parameter packet"},
+ {UNDEFINED, "undefined"},
+ {LOGIN, "login"},
+ {REQUEST, "request"},
+ {RESPONSE_OK, "response OK"},
+ {RESPONSE_MESSAGE, "response message"},
+ {RESPONSE_TABULAR, "tabular response"},
+ {RESPONSE_SHOW_FIELDS, "response to SHOW FIELDS"},
+ {FIELD_PACKET, "field packet"},
+ {ROW_PACKET, "row packet"},
+ {RESPONSE_PREPARE, "response to PREPARE"},
+ {PARAM_PACKET, "parameter packet"},
{0, NULL}
};
#endif
@@ -529,7 +531,7 @@ typedef struct mysql_conn_data
} mysql_conn_data_t;
struct mysql_frame_data {
- mysql_state_t state;
+ mysql_state_t state;
};
typedef struct my_stmt_data
@@ -991,7 +993,7 @@ void proto_register_mysql(void)
{ &hf_mysql_fld_type,
{ "Type", "mysql.field.type",
- FT_STRING, BASE_NONE, NULL, 0x0,
+ FT_UINT8, BASE_DEC, VALS(type_constants), 0x0,
"Field: type", HFILL }},
{ &hf_mysql_fld_flags,
@@ -1064,6 +1066,11 @@ void proto_register_mysql(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
"Field: decimals", HFILL }},
+ { &hf_mysql_fld_default,
+ { "Default", "mysql.field.default",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ "Field: default", HFILL }},
+
{ &hf_mysql_row_length,
{ "length", "mysql.row.length",
FT_UINT8, BASE_DEC, NULL, 0x0,
@@ -1099,10 +1106,10 @@ void proto_register_mysql(void)
"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);
- prefs_register_bool_preference(mysql_module, "show_sql_query",
- "Show SQL Query string in INFO column",
- "Whether the MySQL dissector should display the SQL query string in the INFO column.",
- &mysql_showquery);
+ prefs_register_bool_preference(mysql_module, "show_sql_query",
+ "Show SQL Query string in INFO column",
+ "Whether the MySQL dissector should display the SQL query string in the INFO column.",
+ &mysql_showquery);
register_dissector("mysql", dissect_mysql_pdu, proto_mysql);
}
@@ -1141,7 +1148,7 @@ dissect_mysql_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint64 generation;
proto_item *pi;
#endif
- struct mysql_frame_data *mysql_frame_data_p;
+ struct mysql_frame_data *mysql_frame_data_p;
/* get conversation, create if neccessary*/
conversation= find_or_create_conversation(pinfo);
@@ -1170,11 +1177,22 @@ dissect_mysql_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
mysql_frame_data_p = se_alloc(sizeof(struct mysql_frame_data));
mysql_frame_data_p->state = conn_data->state;
p_add_proto_data(pinfo->fd, proto_mysql, mysql_frame_data_p);
+
} else if (conn_data->state != FIELD_PACKET && conn_data->state != ROW_PACKET ) {
/* We have seen this frame before. Set the connection state
* to whatever state it had the first time we saw this frame
* (e.g., based on whatever frames came before it).
* The state may change as we dissect this packet.
+ * XXX: I think the logic of the above else if test is as follows:
+ * During the first (sequential) dissection pass thru the capture
+ * file the conversation connection state as of the beginning of each frame
+ * is saved in the connection_state for that frame.
+ * Any state changes *within* a mysql "message" (ie: query/response/etc)
+ * while processing mysql PDUS (aka "packets") in that message must be preserved.
+ * It appears that FIELD_PACKET & ROW_PACKET are the only two
+ * state changes which can occur within a mysql message which affect
+ * subsequent processing within the message.
+ * Question: Does this logic work OK for a reassembled message ?
*/
conn_data->state= mysql_frame_data_p->state;
}
@@ -1543,7 +1561,7 @@ mysql_dissect_request(tvbuff_t *tvb,packet_info *pinfo, int offset,
proto_tree_add_text(req_tree, tvb, offset, strlen, "Table name: %s",
tvb_get_ephemeral_string(tvb, offset, strlen));
offset+= strlen;
- conn_data->state= RESPONSE_TABULAR;
+ conn_data->state= RESPONSE_SHOW_FIELDS;
break;
case MYSQL_PROCESS_KILL:
@@ -1695,7 +1713,7 @@ mysql_dissect_response(tvbuff_t *tvb, packet_info *pinfo, int offset,
proto_tree *tree, mysql_conn_data_t *conn_data)
{
gint response_code;
- gint strlen;
+ gint strlen;
response_code= tvb_get_guint8(tvb, offset);
@@ -1704,7 +1722,7 @@ mysql_dissect_response(tvbuff_t *tvb, packet_info *pinfo, int offset,
conn_data->state= REQUEST;
}
- else if (response_code == 0xfe && tvb_reported_length_remaining(tvb, offset) < 9) {
+ else if (response_code == 0xfe && tvb_reported_length_remaining(tvb, offset) < 9) {
proto_tree_add_uint_format(tree, hf_mysql_eof, tvb, offset, 1,
response_code, "EOF marker (%u)",
@@ -1753,6 +1771,7 @@ mysql_dissect_response(tvbuff_t *tvb, packet_info *pinfo, int offset,
break;
case FIELD_PACKET:
+ case RESPONSE_SHOW_FIELDS:
offset= mysql_dissect_field_packet(tvb, offset, tree, conn_data);
break;
@@ -2018,14 +2037,12 @@ mysql_dissect_field_packet(tvbuff_t *tvb, int offset, proto_tree *tree, mysql_co
offset += 2; /* charset */
proto_tree_add_item(tree, hf_mysql_fld_length, tvb, offset, 4, TRUE);
offset += 4; /* length */
- proto_tree_add_string(tree, hf_mysql_fld_type, tvb, offset, -1,
- val_to_str(tvb_get_guint8(tvb, offset), type_constants, "Unknown (%u)"));
+ proto_tree_add_item(tree, hf_mysql_fld_type, tvb, offset, 1, FALSE);
offset++; /* type */
flags = tvb_get_letohs(tvb, offset);
- offset += 2; /* flags */
tf = proto_tree_add_uint_format(tree, hf_mysql_fld_flags, tvb, offset,
- 2, flags, "Field flags: 0x%016X", flags);
+ 2, flags, "Field flags: 0x%04X", flags);
flags_tree = proto_item_add_subtree(tf, ett_field_flags);
proto_tree_add_boolean(flags_tree, hf_mysql_fld_not_null, tvb, offset, 2, flags);
proto_tree_add_boolean(flags_tree, hf_mysql_fld_primary_key, tvb, offset, 2, flags);
@@ -2039,12 +2056,17 @@ mysql_dissect_field_packet(tvbuff_t *tvb, int offset, proto_tree *tree, mysql_co
proto_tree_add_boolean(flags_tree, hf_mysql_fld_auto_increment, tvb, offset, 2, flags);
proto_tree_add_boolean(flags_tree, hf_mysql_fld_timestamp, tvb, offset, 2, flags);
proto_tree_add_boolean(flags_tree, hf_mysql_fld_set, tvb, offset, 2, flags);
+ offset += 2; /* flags */
proto_tree_add_item(tree, hf_mysql_fld_decimals, tvb, offset, 1, FALSE);
offset++; /* decimals */
offset += 2; /* filler */
+ /* default (Only use for show fields) */
+ if (tree && tvb_reported_length_remaining(tvb, offset) > 0) {
+ offset = mysql_field_add_lestring(tvb, offset, tree, hf_mysql_fld_default);
+ }
return offset;
}