diff options
author | Guy Harris <guy@alum.mit.edu> | 2014-12-21 19:33:10 -0800 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2014-12-22 03:33:42 +0000 |
commit | 4cb19d48f58eb298e8f63f043e1cfd08bba35811 (patch) | |
tree | b17459a8a9b5dcefdadb13565b4c56c6ad1c8332 /epan/dissectors | |
parent | 859360a6c49e0c335d9a97c48b212f9b42844655 (diff) |
Use the messageLength field to indicate the message length.
Check it for sanity (and report errors), and use it to set the length of
the PTP packet tvbuff and the PTP top-level protocol item.
Bug: 10611
Change-Id: I9af6aad5f07d405ebb14885dc986a73e430d7bdb
Reviewed-on: https://code.wireshark.org/review/5967
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-ptp.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/epan/dissectors/packet-ptp.c b/epan/dissectors/packet-ptp.c index de871ee1bd..b09c9a8c9b 100644 --- a/epan/dissectors/packet-ptp.c +++ b/epan/dissectors/packet-ptp.c @@ -49,7 +49,8 @@ #include <epan/packet.h> #include <epan/etypes.h> - +#include <epan/expert.h> +#include <epan/exceptions.h> /**********************************************************/ /* Port definition's for PTP */ @@ -1557,6 +1558,9 @@ static gint ett_ptp_as_sig_tlv_flags = -1; static gint ett_ptp_v2_priority = -1; */ static gint ett_ptp_v2_transportspecific = -1; +static expert_field ei_ptp_v2_msg_len_too_large = EI_INIT; +static expert_field ei_ptp_v2_msg_len_too_small = EI_INIT; + /* END Definitions and fields for PTPv2 dissection. */ @@ -2356,7 +2360,7 @@ dissect_ptp_v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean ptp guint16 temp; /* Set up structures needed to add the protocol subtree and manage it */ - proto_item *ti, *transportspecific_ti, *flags_ti, *managementData_ti, *clockType_ti, *protocolAddress_ti; + proto_item *ti = NULL, *msg_len_item = NULL, *transportspecific_ti, *flags_ti, *managementData_ti, *clockType_ti, *protocolAddress_ti; proto_tree *ptp_tree, *ptp_transportspecific_tree, *ptp_flags_tree, *ptp_managementData_tree, *ptp_clockType_tree, *ptp_protocolAddress_tree; @@ -2369,6 +2373,8 @@ dissect_ptp_v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean ptp /* Get control field (what kind of message is this? (Sync, DelayReq, ...) */ ptp_v2_messageid = 0x0F & tvb_get_guint8 (tvb, PTP_V2_TRANSPORT_SPECIFIC_MESSAGE_ID_OFFSET); + msg_len = tvb_get_ntohs(tvb, PTP_V2_MESSAGE_LENGTH_OFFSET); + /* Extend Info column with managementId */ /* Create and set the string for "Info" column */ if ( ptp_v2_messageid == PTP_V2_MANAGEMENT_MESSAGE ) @@ -2439,9 +2445,31 @@ dissect_ptp_v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean ptp proto_tree_add_item(ptp_tree, hf_ptp_v2_versionptp, tvb, PTP_V2_VERSIONPTP_OFFSET, 1, ENC_BIG_ENDIAN); - msg_len = tvb_get_ntohs(tvb, PTP_V2_MESSAGE_LENGTH_OFFSET); - proto_tree_add_item(ptp_tree, + msg_len_item = proto_tree_add_item(ptp_tree, hf_ptp_v2_messagelength, tvb, PTP_V2_MESSAGE_LENGTH_OFFSET, 2, ENC_BIG_ENDIAN); + } + + /* + * Sanity-check the message length. + */ + if (msg_len > tvb_reported_length(tvb)) { + /* Bogus message length - runs past the end of the packet */ + expert_add_info(pinfo, msg_len_item, &ei_ptp_v2_msg_len_too_large); + msg_len = tvb_reported_length(tvb); + } else if (msg_len < PTP_V2_MESSAGE_LENGTH_OFFSET + 2) { + /* Bogus message length - not long enough to include the message length field */ + expert_add_info(pinfo, msg_len_item, &ei_ptp_v2_msg_len_too_small); + THROW(ReportedBoundsError); + } else { + /* + * Set the length of this tvbuff to the message length, chopping + * off extra data. + */ + set_actual_length(tvb, msg_len); + proto_item_set_len(ti, msg_len); + } + + if (tree) { proto_tree_add_item(ptp_tree, hf_ptp_v2_domainnumber, tvb, PTP_V2_DOMAIN_NUMBER_OFFSET, 1, ENC_BIG_ENDIAN); @@ -5930,6 +5958,13 @@ proto_register_ptp(void) &ett_ptp_as_sig_tlv_flags, }; + static ei_register_info ei[] = { + { &ei_ptp_v2_msg_len_too_large, { "ptp.v2.msg_len_too_large", PI_MALFORMED, PI_ERROR, "Message length goes past the end of the packet", EXPFILL }}, + { &ei_ptp_v2_msg_len_too_small, { "ptp.v2.msg_len_too_small", PI_MALFORMED, PI_ERROR, "Message length too short to include the message length field", EXPFILL }}, + }; + + expert_module_t* expert_ptp; + /* Register the protocol name and description */ proto_ptp = proto_register_protocol("Precision Time Protocol (IEEE1588)", "PTP", "ptp"); @@ -5937,6 +5972,9 @@ proto_register_ptp(void) /* Required function calls to register the header fields and subtrees used */ proto_register_field_array(proto_ptp, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); + + expert_ptp = expert_register_protocol(proto_ptp); + expert_register_field_array(expert_ptp, ei, array_length(ei)); } void |