From e15370658fcec6186a3c2afd21ff048d19997637 Mon Sep 17 00:00:00 2001 From: Huang Qiangxiong Date: Sun, 12 Mar 2023 11:41:48 +0800 Subject: [PATCH] SIP: add a preference to set default charset in raw text view Add the "Default charset of raw SIP messages" preference to set default charset for displaying the body of SIP messages in raw text view. --- docbook/release-notes.adoc | 3 ++ epan/dissectors/packet-sip.c | 70 +++++++++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/docbook/release-notes.adoc b/docbook/release-notes.adoc index 33e15f4f21..ccfb9e5abf 100644 --- a/docbook/release-notes.adoc +++ b/docbook/release-notes.adoc @@ -139,6 +139,9 @@ FiRa UWB Controller Interface (UCI) attribute of the XML declaration, and has a new preference to set default character encoding for some XML document without "encoding" attribute. +* The SIP dissector now has a new preference to set default charset for + displaying the body of SIP messages in raw text view. + Too many other protocols have been updated to list them all here. === New and Updated Capture File Support diff --git a/epan/dissectors/packet-sip.c b/epan/dissectors/packet-sip.c index 0d35a3f92f..49535bf184 100644 --- a/epan/dissectors/packet-sip.c +++ b/epan/dissectors/packet-sip.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -971,6 +972,8 @@ static gboolean global_sip_raw_text = FALSE; /* global_sip_raw_text_without_crlf determines whether we are going to display */ /* the raw text of the SIP message with or without the '\r\n'. */ static gboolean global_sip_raw_text_without_crlf = FALSE; +/* global_sip_raw_text_body_default_encoding determines what charset we are going to display the body */ +static gint global_sip_raw_text_body_default_encoding = IANA_CS_UTF_8; /* strict_sip_version determines whether the SIP dissector enforces * the SIP version to be "SIP/2.0". */ static gboolean strict_sip_version = TRUE; @@ -1212,7 +1215,7 @@ static gint sip_is_known_sip_header(gchar *header_name, guint header_len); static void dfilter_sip_request_line(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint offset, guint meth_len, gint linelen); static void dfilter_sip_status_line(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint line_end, gint offset); -static void tvb_raw_text_add(tvbuff_t *tvb, int offset, int length, proto_tree *tree); +static void tvb_raw_text_add(tvbuff_t *tvb, int offset, int length, int body_offset, packet_info* pinfo, proto_tree *tree); static guint sip_is_packet_resend(packet_info *pinfo, const char *cseq_method, gchar* call_id, @@ -3414,7 +3417,7 @@ static int dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info *pinfo, proto_tree *tree, gboolean dissect_other_as_continuation, gboolean use_reassembly) { - int orig_offset; + int orig_offset, body_offset; gint next_offset, linelen; int content_length, datalen, reported_datalen; line_type_t line_type; @@ -4666,6 +4669,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info if (reported_datalen > content_length) reported_datalen = content_length; } + body_offset = offset; if (!call_id) { call_id = wmem_strdup(pinfo->pool, ""); @@ -4950,7 +4954,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info proto_item_set_len(ts, offset - orig_offset); if (global_sip_raw_text) - tvb_raw_text_add(tvb, orig_offset, offset - orig_offset, tree); + tvb_raw_text_add(tvb, orig_offset, offset - orig_offset, body_offset, pinfo, tree); /* Append a brief summary to the SIP root item */ if (stat_info->request_method) { @@ -5218,19 +5222,42 @@ static gint sip_is_known_sip_header(gchar *header_name, guint header_len) * Display the entire message as raw text. */ static void -tvb_raw_text_add(tvbuff_t *tvb, int offset, int length, proto_tree *tree) +tvb_raw_text_add(tvbuff_t *tvb, int offset, int length, int body_offset, packet_info* pinfo, proto_tree *tree) { proto_tree *raw_tree; proto_item *ti; int next_offset, linelen, end_offset; char *str; + tvbuff_t* body_tvb = NULL; ti = proto_tree_add_item(tree, proto_raw_sip, tvb, offset, length, ENC_NA); raw_tree = proto_item_add_subtree(ti, ett_raw_text); end_offset = offset + length; - while (offset < end_offset) { + if (body_offset < end_offset + && global_sip_raw_text_body_default_encoding != IANA_CS_UTF_8 + /* UTF-8 compatible with ASCII */ + && global_sip_raw_text_body_default_encoding != IANA_CS_US_ASCII) + { + /* Create body tvb with new character encoding */ + guint32 iana_charset_id = global_sip_raw_text_body_default_encoding; + guint ws_encoding_id = mibenum_charset_to_encoding((guint)iana_charset_id); + + if (ws_encoding_id != (ENC_NA | ENC_ASCII) && ws_encoding_id != (ENC_NA | ENC_UTF_8)) { + /* Encoding body with the new encoding */ + gchar* encoding_name = val_to_str_ext_wmem(pinfo->pool, iana_charset_id, + &mibenum_vals_character_sets_ext, "UNKNOWN"); + const guint8* data_str = tvb_get_string_enc(wmem_packet_scope(), tvb, body_offset, + end_offset - body_offset, ws_encoding_id); + size_t l = strlen(data_str); + body_tvb = tvb_new_child_real_data(tvb, data_str, (guint)l, (gint)l); + add_new_data_source(pinfo, body_tvb, wmem_strdup_printf(pinfo->pool, "Decoded %s text", encoding_name)); + } + } + + /* Display the headers of SIP message as raw text */ + while (offset < body_offset) { tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE); linelen = next_offset - offset; if (raw_tree) { @@ -5245,6 +5272,33 @@ tvb_raw_text_add(tvbuff_t *tvb, int offset, int length, proto_tree *tree) } offset = next_offset; } + + DISSECTOR_ASSERT_HINT(offset == body_offset, "The offset must be equal to body_offset before dissect body as raw text."); + + if (body_offset < end_offset) { + /* Dissect the body of SIP message as raw text */ + if (body_tvb) { + offset = 0; + end_offset = tvb_captured_length_remaining(body_tvb, 0); + } else { + body_tvb = tvb; /* reuse old offset and end_offset */ + } + + while (offset < end_offset) { + tvb_find_line_end(body_tvb, offset, -1, &next_offset, FALSE); + linelen = next_offset - offset; + if (raw_tree) { + if (global_sip_raw_text_without_crlf) + str = tvb_format_text_wsp(wmem_packet_scope(), body_tvb, offset, linelen); + else + str = tvb_format_text(wmem_packet_scope(), body_tvb, offset, linelen); + + proto_tree_add_string_format(raw_tree, hf_sip_raw_line, body_tvb, offset, + linelen, str, "%s", str); + } + offset = next_offset; + } + } } /* Check to see if this packet is a resent request. Return value is the frame number @@ -7652,6 +7706,12 @@ void proto_register_sip(void) "return and line feed are not shown", &global_sip_raw_text_without_crlf); + prefs_register_enum_preference(sip_module, "raw_text_body_default_encoding", + "Default charset of raw SIP messages", + "Display sip body of raw text by using this charset. The default is UTF-8.", + &global_sip_raw_text_body_default_encoding, + ws_supported_mibenum_vals_character_sets_ev_array, FALSE); + prefs_register_bool_preference(sip_module, "strict_sip_version", "Enforce strict SIP version check (" SIP2_HDR ")", "If enabled, only " SIP2_HDR " traffic will be dissected as SIP. "