aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-ansi_637.c
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2013-06-12 16:59:59 +0000
committerPascal Quantin <pascal.quantin@gmail.com>2013-06-12 16:59:59 +0000
commit0975d03e8df9b1dd24215ccec50fbb93d6f18a1f (patch)
treecf12d5d45948d43612123fbff35080adf945db08 /epan/dissectors/packet-ansi_637.c
parent855870768130ba53bcaaa61b243b4ba79cf5edc1 (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.c133
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",