diff options
author | Simon Cornish <cgpmp5vkq2@liamekaens.com> | 2022-03-01 19:10:09 +0000 |
---|---|---|
committer | John Thacker <johnthacker@gmail.com> | 2022-07-29 01:39:40 +0000 |
commit | 72b4b216233665bd400fa7cc6c6d3863c060e8d3 (patch) | |
tree | f4e1e46ca1db7fde86f12025550f08d4083b013e | |
parent | 9c5f1255aff592e8480a5f6191e91d3093b51c13 (diff) |
SCCP: Fix handling of XUDT segmentation parameter
Q.713 s1.5 states optional parameters may be received in any
order. Q.714 s1.1.42 states unrecognized parameters within a
message are ignored.
This patch fixes Wireshark's compliance with the specs and allows
the segmentation parameter to occur anywhere with the options
-rw-r--r-- | epan/dissectors/packet-sccp.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/epan/dissectors/packet-sccp.c b/epan/dissectors/packet-sccp.c index 8186c6b0fc..8ec97ddb6b 100644 --- a/epan/dissectors/packet-sccp.c +++ b/epan/dissectors/packet-sccp.c @@ -2877,7 +2877,8 @@ dissect_xudt_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, guint16 *optional_pointer_p, guint16 *orig_opt_ptr_p) { guint16 variable_pointer1 = 0, variable_pointer2 = 0, variable_pointer3 = 0; - guint16 optional_pointer = 0, orig_opt_ptr = 0; + guint16 optional_pointer = 0, orig_opt_ptr = 0, optional_pointer1 = 0; + guint8 optional_param_type = 0; tvbuff_t *new_tvb = NULL; guint32 source_local_ref = 0; guint msg_offset = tvb_offset_from_real_beginning(tvb); @@ -2933,7 +2934,16 @@ dissect_xudt_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, PARAMETER_CALLING_PARTY_ADDRESS, variable_pointer2, sccp_info); - if (tvb_get_guint8(tvb, optional_pointer) == PARAMETER_SEGMENTATION) { + + optional_pointer1 = optional_pointer; + while((optional_param_type = tvb_get_guint8(tvb, optional_pointer1)) != PARAMETER_END_OF_OPTIONAL_PARAMETERS) { + if (optional_param_type == PARAMETER_SEGMENTATION) + break; + optional_pointer1 += PARAMETER_TYPE_LENGTH; + optional_pointer1 += tvb_get_guint8(tvb, optional_pointer1) + PARAMETER_LENGTH_LENGTH; + } + + if (tvb_get_guint8(tvb, optional_pointer1) == PARAMETER_SEGMENTATION) { if (!sccp_reassemble) { proto_tree_add_item(sccp_tree, hf_sccp_segmented_data, tvb, variable_pointer3, tvb_get_guint8(tvb, variable_pointer3)+1, ENC_NA); } else { @@ -2950,8 +2960,8 @@ dissect_xudt_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *sccp_tree, * The values 0000 to 1111 are possible; the value 0000 indicates * the last segment. */ - octet = tvb_get_guint8(tvb, optional_pointer+2); - source_local_ref = tvb_get_letoh24(tvb, optional_pointer+3); + octet = tvb_get_guint8(tvb, optional_pointer1+2); + source_local_ref = tvb_get_letoh24(tvb, optional_pointer1+3); if ((octet & 0x0f) == 0) more_frag = FALSE; |