aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Cornish <cgpmp5vkq2@liamekaens.com>2022-03-01 19:10:09 +0000
committerJohn Thacker <johnthacker@gmail.com>2022-07-29 01:39:40 +0000
commit72b4b216233665bd400fa7cc6c6d3863c060e8d3 (patch)
treef4e1e46ca1db7fde86f12025550f08d4083b013e
parent9c5f1255aff592e8480a5f6191e91d3093b51c13 (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.c18
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;