aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ptp.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-ptp.c')
-rw-r--r--epan/dissectors/packet-ptp.c46
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