aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndersBroman <anders.broman@ericsson.com>2016-09-02 15:25:41 +0200
committerAnders Broman <a.broman58@gmail.com>2016-09-02 15:31:06 +0000
commit12eee8420567f7bdcae50ce998e5e114f7328b25 (patch)
tree9a85f99838ab0a77b7fa1c5302431655ea09720b
parent2c5a485eefd84a2a08c375dca793ba87f343b9a5 (diff)
[SIP] Call sub dissectors for Diagnostics in SIP reason texts.
Change-Id: I68cbcf257b63a86ee37e1357876a90ea683a1d5a Reviewed-on: https://code.wireshark.org/review/17455 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--epan/dissectors/packet-sip.c100
-rw-r--r--epan/dissectors/packet-sip.h12
2 files changed, 96 insertions, 16 deletions
diff --git a/epan/dissectors/packet-sip.c b/epan/dissectors/packet-sip.c
index 2492b7773a..24f1f7b118 100644
--- a/epan/dissectors/packet-sip.c
+++ b/epan/dissectors/packet-sip.c
@@ -75,6 +75,8 @@ static gint exported_pdu_tap = -1;
static dissector_handle_t sigcomp_handle;
static dissector_handle_t sip_diag_handle;
static dissector_handle_t sip_uri_userinfo_handle;
+/* Dissector to dissect the text part of an reason code */
+static dissector_handle_t sip_reason_code_handle;
/* Initialize the protocol and registered fields */
static gint proto_sip = -1;
@@ -196,7 +198,10 @@ static gint hf_sip_rack_cseq_no = -1;
static gint hf_sip_rack_cseq_method = -1;
static gint hf_sip_reason_protocols = -1;
-static gint hf_sip_reason_cause = -1;
+static gint hf_sip_reason_cause_q850 = -1;
+static gint hf_sip_reason_cause_sip = -1;
+static gint hf_sip_reason_cause_other = -1;
+static gint hf_sip_reason_text = -1;
static gint hf_sip_msg_body = -1;
static gint hf_sip_sec_mechanism = -1;
@@ -2001,14 +2006,23 @@ dissect_sip_authorization_item(tvbuff_t *tvb, proto_tree *tree, gint start_offse
return current_offset;
}
-/* Dissect the details of a Reason header */
+/* Dissect the details of a Reason header
+ * Reason = "Reason" HCOLON reason-value *(COMMA reason-value)
+ * reason-value = protocol *(SEMI reason-params)
+ * protocol = "SIP" / "Q.850" / token
+ * reason-params = protocol-cause / reason-text / reason-extension
+ * protocol-cause = "cause" EQUAL cause
+ * cause = 1*DIGIT
+ * reason-text = "text" EQUAL quoted-string
+ * reason-extension = generic-param
+ */
static void
-dissect_sip_reason_header(tvbuff_t *tvb, proto_tree *tree, gint start_offset, gint line_end_offset){
+dissect_sip_reason_header(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint start_offset, gint line_end_offset){
- gint current_offset, semi_colon_offset, length;
+ gint current_offset, semi_colon_offset, length, end_quote_offset;
const guint8 *param_name = NULL;
guint cause_value;
- proto_item* ti;
+ sip_reason_code_info_t sip_reason_code_info;
/* skip Spaces and Tabs */
start_offset = tvb_skip_wsp(tvb, start_offset, line_end_offset - start_offset);
@@ -2027,20 +2041,57 @@ dissect_sip_reason_header(tvbuff_t *tvb, proto_tree *tree, gint start_offset, gi
length = semi_colon_offset - current_offset;
proto_tree_add_item_ret_string(tree, hf_sip_reason_protocols, tvb, start_offset, length, ENC_UTF_8|ENC_NA, wmem_packet_scope(), &param_name);
+ current_offset = tvb_find_guint8(tvb, semi_colon_offset, line_end_offset - semi_colon_offset, '=') + 1;
+ /* Do we have a text parameter too? */
+ semi_colon_offset = tvb_find_guint8(tvb, current_offset, line_end_offset - current_offset, ';');
- if (g_ascii_strcasecmp(param_name, "Q.850") == 0){
- current_offset = tvb_find_guint8(tvb, semi_colon_offset, line_end_offset-semi_colon_offset, '=')+1;
+ if (semi_colon_offset == -1){
length = line_end_offset - current_offset;
+ } else {
+ /* Text parmeter exist, set length accordingly */
+ length = semi_colon_offset - current_offset;
+ }
- /* q850_cause_code_vals */
- cause_value = (guint)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, current_offset, length, ENC_UTF_8|ENC_NA), NULL, 10);
- ti = proto_tree_add_uint(tree, hf_sip_reason_cause, tvb, current_offset, 1, cause_value);
- /*, "Cause: %u(0x%x)[%s]", cause_value, cause_value,
- val_to_str_ext(cause_value, &q850_cause_code_vals_ext, "Unknown (%d)" )); */
- proto_item_set_len(ti, length);
+ /* Get cause value */
+ cause_value = (guint)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, current_offset, length, ENC_UTF_8 | ENC_NA), NULL, 10);
+ if (g_ascii_strcasecmp(param_name, "Q.850") == 0){
+ proto_tree_add_uint(tree, hf_sip_reason_cause_q850, tvb, current_offset, length, cause_value);
+ sip_reason_code_info.protocol_type_num = SIP_PROTO_Q850;
+ }
+ else if (g_ascii_strcasecmp(param_name, "SIP") == 0) {
+ proto_tree_add_uint(tree, hf_sip_reason_cause_sip, tvb, current_offset, length, cause_value);
+ sip_reason_code_info.protocol_type_num = SIP_PROTO_SIP;
}
+ else {
+ proto_tree_add_uint(tree, hf_sip_reason_cause_other, tvb, current_offset, length, cause_value);
+ sip_reason_code_info.protocol_type_num = SIP_PROTO_OTHER;
+ }
+
+ if (semi_colon_offset == -1)
+ /* Nothing to parse */
+ return;
+
+ /* reason-text = "text" EQUAL quoted-string */
+ current_offset = tvb_find_guint8(tvb, semi_colon_offset, line_end_offset - semi_colon_offset, '"') + 1;
+ if (current_offset == -1)
+ /* Nothing to parse */
+ return;
+ end_quote_offset = tvb_find_guint8(tvb, current_offset, line_end_offset - current_offset, '"');
+ if (end_quote_offset == -1)
+ /* Nothing to parse */
+ return;
+ length = end_quote_offset - current_offset;
+ proto_tree_add_item(tree, hf_sip_reason_text, tvb, current_offset, length, ENC_UTF_8 | ENC_NA);
+ if (sip_reason_code_handle) {
+ tvbuff_t *next_tvb;
+
+ sip_reason_code_info.cause_value = cause_value;
+
+ next_tvb = tvb_new_subset_length(tvb, current_offset, length);
+ call_dissector_with_data(sip_reason_code_handle, next_tvb, pinfo, tree, &sip_reason_code_info);
+ }
}
/* Dissect the details of a security client header
@@ -3849,7 +3900,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info
sip_proto_set_format_text(hdr_tree, sip_element_item, tvb, offset, linelen);
reason_tree = proto_item_add_subtree(sip_element_item, ett_sip_reason);
- dissect_sip_reason_header(tvb, reason_tree, value_offset, line_end_offset);
+ dissect_sip_reason_header(tvb, reason_tree, pinfo, value_offset, line_end_offset);
}
break;
case POS_CONTENT_ENCODING:
@@ -6404,11 +6455,26 @@ void proto_register_sip(void)
FT_STRING, BASE_NONE, NULL, 0x0,
NULL, HFILL}
},
- { &hf_sip_reason_cause,
- { "Cause", "sip.reason_cause",
+ { &hf_sip_reason_cause_q850,
+ { "Cause", "sip.reason_cause_q850",
FT_UINT32, BASE_DEC_HEX|BASE_EXT_STRING, &q850_cause_code_vals_ext, 0x0,
NULL, HFILL}
},
+ { &hf_sip_reason_cause_sip,
+ { "Cause", "sip.reason_cause_sip",
+ FT_UINT32, BASE_DEC, VALS(response_code_vals), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_sip_reason_cause_other,
+ { "Cause", "sip.reason_cause_other",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_sip_reason_text,
+ { "Text", "sip.reason_text",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_sip_msg_body,
{ "Message Body", "sip.msg_body",
FT_NONE, BASE_NONE, NULL, 0x0,
@@ -6726,6 +6792,8 @@ proto_reg_handoff_sip(void)
sigcomp_handle = find_dissector_add_dependency("sigcomp", proto_sip);
sip_diag_handle = find_dissector("sip.diagnostic");
sip_uri_userinfo_handle = find_dissector("sip.uri_userinfo");
+ /* Check for a dissector to parse Reason Code texts */
+ sip_reason_code_handle = find_dissector("sip.reason_code");
/* SIP content type and internet media type used by other dissectors are the same */
media_type_dissector_table = find_dissector_table("media_type");
diff --git a/epan/dissectors/packet-sip.h b/epan/dissectors/packet-sip.h
index 11d4c8e149..5fcfb12a1c 100644
--- a/epan/dissectors/packet-sip.h
+++ b/epan/dissectors/packet-sip.h
@@ -38,6 +38,18 @@ typedef struct _sip_info_value_t
gchar *reason_phrase;
} sip_info_value_t;
+typedef enum {
+ SIP_PROTO_OTHER = 0,
+ SIP_PROTO_SIP = 1,
+ SIP_PROTO_Q850 = 2
+} sip_reason_code_proto_t;
+
+typedef struct _sip_reason_code_info_t
+{
+ sip_reason_code_proto_t protocol_type_num;
+ guint cause_value;
+} sip_reason_code_info_t;
+
extern void dfilter_store_sip_from_addr(tvbuff_t *tvb, proto_tree *tree,
guint parameter_offset, guint parameter_len);