diff options
author | Peter Wu <peter@lekensteyn.nl> | 2018-05-30 23:36:07 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-05-31 04:40:14 +0000 |
commit | ff2881808865b68bed20534cb3fcdc6844575063 (patch) | |
tree | 3ff8257cb3c1958ceffe51a414552ddb917a8da2 /epan | |
parent | d8c19f859341b63bd745c328ae310e91b63c1e0b (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.c | 24 |
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 */ |