diff options
author | Pascal Quantin <pascal.quantin@gmail.com> | 2013-06-12 16:59:59 +0000 |
---|---|---|
committer | Pascal Quantin <pascal.quantin@gmail.com> | 2013-06-12 16:59:59 +0000 |
commit | 0975d03e8df9b1dd24215ccec50fbb93d6f18a1f (patch) | |
tree | cf12d5d45948d43612123fbff35080adf945db08 /epan/dissectors/packet-ansi_637.c | |
parent | 855870768130ba53bcaaa61b243b4ba79cf5edc1 (diff) |
Fix dissection of 3GPP2 SMS messages when the User Data Header field is present (for fragmented SMS)
svn path=/trunk/; revision=49910
Diffstat (limited to 'epan/dissectors/packet-ansi_637.c')
-rw-r--r-- | epan/dissectors/packet-ansi_637.c | 133 |
1 files changed, 106 insertions, 27 deletions
diff --git a/epan/dissectors/packet-ansi_637.c b/epan/dissectors/packet-ansi_637.c index 404b41e1ec..78cf5b027a 100644 --- a/epan/dissectors/packet-ansi_637.c +++ b/epan/dissectors/packet-ansi_637.c @@ -185,6 +185,7 @@ static int hf_ansi_637_trans_bin_addr = -1; static int hf_ansi_637_tele_msg_type = -1; static int hf_ansi_637_tele_msg_id = -1; static int hf_ansi_637_tele_msg_status = -1; +static int hf_ansi_637_tele_msg_ind = -1; static int hf_ansi_637_tele_msg_rsvd = -1; static int hf_ansi_637_tele_subparam_id = -1; static int hf_ansi_637_tele_user_data_text = -1; @@ -321,20 +322,18 @@ decode_7_bits(tvbuff_t *tvb, guint32 *offset, guint8 num_fields, guint8 *last_oc static void tele_param_msg_id(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) { - guint32 octs; - EXACT_DATA_CHECK(len, 3); - octs = tvb_get_ntoh24(tvb, offset); + proto_tree_add_item(tree, hf_ansi_637_tele_msg_type, tvb, offset, 3, ENC_BIG_ENDIAN); - proto_tree_add_uint(tree, hf_ansi_637_tele_msg_type, - tvb, offset, 3, octs); + proto_tree_add_item(tree, hf_ansi_637_tele_msg_id, tvb, offset, 3, ENC_BIG_ENDIAN); - proto_tree_add_uint(tree, hf_ansi_637_tele_msg_id, - tvb, offset, 3, octs); + proto_tree_add_item(tree, hf_ansi_637_tele_msg_ind, tvb, offset, 3, ENC_BIG_ENDIAN); + if ((tvb_get_guint8(tvb, offset+2) & 0x08) == 0x08) { + g_pinfo->private_data = GUINT_TO_POINTER((guint) TRUE); + } - proto_tree_add_uint(tree, hf_ansi_637_tele_msg_rsvd, - tvb, offset, 3, octs); + proto_tree_add_item(tree, hf_ansi_637_tele_msg_rsvd, tvb, offset, 3, ENC_BIG_ENDIAN); } /* Adamek Jan - IS637C Message status decoding procedure */ @@ -451,6 +450,8 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) guint32 saved_offset; guint32 i , out_len; const gchar *str = NULL; + gchar *buf; + tvbuff_t * tvb_out = NULL; /*add more translation UCS , IA5 , latin , latin \ hebrew ,gsm 7BIT*/ gchar *utf8_text = NULL; @@ -566,12 +567,30 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) return; } - bit = 3; + saved_offset = offset - 1; + i = num_fields * 7; + required_octs = (i / 8) + ((i % 8) ? 1 : 0); + buf = (gchar*)ep_alloc(required_octs); + for (i=0; i < required_octs; i++) + { + oct = tvb_get_guint8(tvb, saved_offset); + oct2 = tvb_get_guint8(tvb, saved_offset + 1); + buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3); + saved_offset++; + } + tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs); + add_new_data_source(g_pinfo, tvb_out, "Characters"); + offset = 0; + bit = 0; + if (g_pinfo->private_data && (GPOINTER_TO_UINT(g_pinfo->private_data) == TRUE)) { + dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, TRUE, &bit); + } + saved_offset = offset; - decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf); + decode_7_bits(tvb_out, &offset, num_fields, &oct, &bit, ansi_637_bigbuf); - proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, saved_offset, + proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, saved_offset, offset - saved_offset, ansi_637_bigbuf); switch (bit) @@ -607,12 +626,29 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) return; } - bit = 3; + saved_offset = offset - 1; + i = num_fields * 7; + required_octs = (i / 8) + ((i % 8) ? 1 : 0); + buf = (gchar*)ep_alloc(required_octs); + for (i=0; i < required_octs; i++) + { + oct = tvb_get_guint8(tvb, saved_offset); + oct2 = tvb_get_guint8(tvb, saved_offset + 1); + buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3); + saved_offset++; + } + tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs); + add_new_data_source(g_pinfo, tvb_out, "Characters"); + offset = 0; + bit = 0; + if (g_pinfo->private_data && (GPOINTER_TO_UINT(g_pinfo->private_data) == TRUE)) { + dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, TRUE, &bit); + } saved_offset = offset; - out_len = decode_7_bits(tvb, &offset, num_fields, &oct, &bit, ansi_637_bigbuf); + out_len = decode_7_bits(tvb_out, &offset, num_fields, &oct, &bit, ansi_637_bigbuf); IA5_7BIT_decode(ia5_637_bigbuf, ansi_637_bigbuf, out_len); - proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, saved_offset, + proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, saved_offset, offset - saved_offset, ia5_637_bigbuf); } @@ -622,25 +658,33 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) else if (encoding == 0x07)/* Latin/Hebrew */ { saved_offset = offset - 1; + buf = (gchar*)ep_alloc(num_fields); for (i=0; i < num_fields; i++) { oct = tvb_get_guint8(tvb, saved_offset); oct2 = tvb_get_guint8(tvb, saved_offset + 1); - ansi_637_bigbuf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3); + buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3); saved_offset++; } + tvb_out = tvb_new_child_real_data(tvb, buf, num_fields, num_fields); + add_new_data_source(g_pinfo, tvb_out, "Characters"); + offset = 0; + required_octs = len - used; + if (g_pinfo->private_data && (GPOINTER_TO_UINT(g_pinfo->private_data) == TRUE)) { + dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, FALSE, &bit); + } if ((cd = g_iconv_open("UTF-8","iso-8859-8")) != (GIConv)-1) { - utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb, offset, num_fields), num_fields , cd , NULL , NULL , &l_conv_error); + utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb_out, offset, num_fields), num_fields , cd , NULL , NULL , &l_conv_error); if(!l_conv_error) { - proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, offset, + proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset, num_fields, utf8_text); } else { - proto_tree_add_text(tree, tvb, offset, num_fields, "%s", "Failed on iso-8859-8 contact Wireshark developers"); + proto_tree_add_text(tree, tvb_out, offset, num_fields, "%s", "Failed on iso-8859-8 contact Wireshark developers"); } if(utf8_text) g_free(utf8_text); @@ -650,25 +694,33 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) else if (encoding == 0x08) /* Latin */ { saved_offset = offset - 1; + buf = (gchar*)ep_alloc(num_fields); for (i=0; i < num_fields; i++) { oct = tvb_get_guint8(tvb, saved_offset); oct2 = tvb_get_guint8(tvb, saved_offset + 1); - ansi_637_bigbuf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3); + buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3); saved_offset++; } + tvb_out = tvb_new_child_real_data(tvb, buf, num_fields, num_fields); + add_new_data_source(g_pinfo, tvb_out, "Characters"); + offset = 0; + required_octs = len - used; + if (g_pinfo->private_data && (GPOINTER_TO_UINT(g_pinfo->private_data) == TRUE)) { + dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, FALSE, &bit); + } if ((cd = g_iconv_open("UTF-8","iso-8859-1")) != (GIConv)-1) { - utf8_text = g_convert_with_iconv(ansi_637_bigbuf , num_fields , cd , NULL , NULL , &l_conv_error); + utf8_text = g_convert_with_iconv(tvb_get_ptr(tvb_out, offset, num_fields) , num_fields , cd , NULL , NULL , &l_conv_error); if(!l_conv_error) { - proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, offset, + proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset, num_fields, utf8_text); } else { - proto_tree_add_text(tree, tvb, offset, num_fields, "%s", "Failed on iso-8859-1 contact Wireshark developers"); + proto_tree_add_text(tree, tvb_out, offset, num_fields, "%s", "Failed on iso-8859-1 contact Wireshark developers"); } if(utf8_text) g_free(utf8_text); @@ -690,18 +742,29 @@ tele_param_user_data(tvbuff_t *tvb, proto_tree *tree, guint len, guint32 offset) } saved_offset = offset - 1; + i = num_fields * 7; + required_octs = (i / 8) + ((i % 8) ? 1 : 0); + buf = (gchar*)ep_alloc(required_octs); for (i=0; i < required_octs; i++) { oct = tvb_get_guint8(tvb, saved_offset); oct2 = tvb_get_guint8(tvb, saved_offset + 1); - ansi_637_bigbuf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3); + buf[i] = ((oct & 0x07) << 5) | ((oct2 & 0xf8) >> 3); saved_offset++; } + tvb_out = tvb_new_child_real_data(tvb, buf, required_octs, required_octs); + add_new_data_source(g_pinfo, tvb_out, "Characters"); + offset = 0; + bit = 0; + if (g_pinfo->private_data && (GPOINTER_TO_UINT(g_pinfo->private_data) == TRUE)) { + dis_field_udh(tvb_out, tree, &offset, &required_octs, &num_fields, TRUE, &bit); + } - out_len = gsm_sms_char_7bit_unpack(0, required_octs+1, num_fields, ansi_637_bigbuf, gsm_637_bigbuf); + out_len = gsm_sms_char_7bit_unpack(bit, required_octs, num_fields, + tvb_get_ptr(tvb_out, offset, required_octs), gsm_637_bigbuf); gsm_637_bigbuf[out_len] = '\0'; - proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb, offset, + proto_tree_add_unicode_string(tree, hf_ansi_637_tele_user_data_text, tvb_out, offset, required_octs, gsm_sms_chars_to_utf8(gsm_637_bigbuf, num_fields)); } else @@ -1855,6 +1918,7 @@ dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) proto_tree *ansi_637_tree = NULL; const gchar *str = NULL; guint32 value; + void* pd_save; col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short); @@ -1863,6 +1927,11 @@ dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) */ if (tree) { + pd_save = pinfo->private_data; + pinfo->private_data = NULL; + g_pinfo = pinfo; + g_tree = tree; + value = pinfo->match_uint; /* @@ -1947,6 +2016,7 @@ dissect_ansi_637_tele(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) proto_item_add_subtree(ansi_637_item, ett_ansi_637_tele); dissect_ansi_637_tele_message(tvb, ansi_637_tree); + pinfo->private_data = pd_save; } } @@ -2034,6 +2104,7 @@ dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) const gchar *str = NULL; guint8 oct; guint8 len; + void* pd_save; col_set_str(pinfo->cinfo, COL_PROTOCOL, ansi_proto_name_short); @@ -2042,6 +2113,8 @@ dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) */ if (tree) { + pd_save = pinfo->private_data; + pinfo->private_data = NULL; g_pinfo = pinfo; g_tree = tree; @@ -2104,6 +2177,7 @@ dissect_ansi_637_trans(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) break; } } + pinfo->private_data = pd_save; } } /* Dissect SMS embedded in SIP */ @@ -2160,10 +2234,15 @@ proto_register_ansi_637(void) "ansi_637_tele.msg_status", FT_UINT8, BASE_DEC, VALS(ansi_tele_msg_status_strings), 0, NULL, HFILL }}, + { &hf_ansi_637_tele_msg_ind, + { "Header Indicator", + "ansi_637_tele.msg_ind", + FT_UINT24, BASE_DEC, NULL, 0x000008, + NULL, HFILL }}, { &hf_ansi_637_tele_msg_rsvd, { "Reserved", "ansi_637_tele.msg_rsvd", - FT_UINT24, BASE_DEC, NULL, 0x00000f, + FT_UINT24, BASE_DEC, NULL, 0x000007, NULL, HFILL }}, { &hf_ansi_637_tele_length, { "Length", "ansi_637_tele.len", |