aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2018-05-30 23:36:07 +0200
committerAnders Broman <a.broman58@gmail.com>2018-05-31 04:40:14 +0000
commitff2881808865b68bed20534cb3fcdc6844575063 (patch)
tree3ff8257cb3c1958ceffe51a414552ddb917a8da2 /epan
parentd8c19f859341b63bd745c328ae310e91b63c1e0b (diff)
mysql: fix packet length calculation
Instead of relying on heuristics (single TCP segment contains a whole MySQL packet) use the compression state from the greeting. This fixes bad dissection when a single TCP segment contains multiple MySQL packets with three other bytes at the end. Tested with the capture from the linked report as well as bug 10342. Bug: 13754 Change-Id: I9d9573f4705265d78ec3d75a195df70718de77b3 Reviewed-on: https://code.wireshark.org/review/27916 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-mysql.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/epan/dissectors/packet-mysql.c b/epan/dissectors/packet-mysql.c
index cba0450c94..c3e912dcf0 100644
--- a/epan/dissectors/packet-mysql.c
+++ b/epan/dissectors/packet-mysql.c
@@ -2195,16 +2195,24 @@ tvb_get_fle(tvbuff_t *tvb, int offset, guint64 *res, guint8 *is_null)
/* dissector helper: length of PDU */
static guint
-get_mysql_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
+get_mysql_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset, void *data _U_)
{
- int tvb_remain= tvb_reported_length_remaining(tvb, offset);
- guint plen= tvb_get_letoh24(tvb, offset);
-
- if ((tvb_remain - plen) == 7) {
- return plen + 7; /* compressed header 3+1+3 (len+id+cmp_len) */
- } else {
- return plen + 4; /* regular header 3+1 (len+id) */
+ /* Regular packet header: length (3) + sequence number (1) */
+ conversation_t *conversation;
+ mysql_conn_data_t *conn_data;
+ guint len = 4 + tvb_get_letoh24(tvb, offset);
+
+ conversation = find_conversation_pinfo(pinfo, 0);
+ if (conversation) {
+ conn_data = (mysql_conn_data_t *)conversation_get_proto_data(conversation, proto_mysql);
+ if (conn_data && conn_data->compressed_state == MYSQL_COMPRESS_ACTIVE &&
+ pinfo->num > conn_data->frame_start_compressed) {
+ /* Compressed packet header includes uncompressed packet length (3) */
+ len += 3;
+ }
}
+
+ return len;
}
/* dissector main function: handle one PDU */