diff options
author | Pascal Quantin <pascal.quantin@gmail.com> | 2016-04-22 15:50:55 +0200 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2016-04-23 15:57:33 +0000 |
commit | f7691b13c71ed22373424de482af2d44311ae55b (patch) | |
tree | 08205cc8cffda75a5982cb5e08e42a95185edead /epan | |
parent | 6f5991750be4c5e211105aa88714834f724cc973 (diff) |
ETSI CAT: add dissection of Information Elements coded as EFadn
While we are at it, fix decoding of STK packed SMS
Change-Id: I2de757f1720381c75f23f3ee6043ac56813db658
Reviewed-on: https://code.wireshark.org/review/15054
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-etsi_card_app_toolkit.c | 191 | ||||
-rw-r--r-- | epan/dissectors/packet-gsm_sms.c | 19 |
2 files changed, 199 insertions, 11 deletions
diff --git a/epan/dissectors/packet-etsi_card_app_toolkit.c b/epan/dissectors/packet-etsi_card_app_toolkit.c index f6b24b738a..f7831dd51b 100644 --- a/epan/dissectors/packet-etsi_card_app_toolkit.c +++ b/epan/dissectors/packet-etsi_card_app_toolkit.c @@ -27,6 +27,7 @@ #include "config.h" #include <epan/packet.h> +#include <epan/charsets.h> #include "packet-e212.h" #include "packet-gsm_a_common.h" @@ -51,8 +52,13 @@ static int hf_ctlv_cmd_qual_loci = -1; static int hf_ctlv_cmd_qual_timer_mgmt = -1; static int hf_ctlv_cmd_qual_send_data = -1; static int hf_ctlv_cmd_qual = -1; -static int hf_ctlv_dur_time_intv = -1; static int hf_ctlv_dur_time_unit = -1; +static int hf_ctlv_dur_time_intv = -1; +static int hf_ctlv_alpha_id_string = -1; +static int hf_ctlv_address_ton = -1; +static int hf_ctlv_address_npi = -1; +static int hf_ctlv_address_string = -1; +static int hf_ctlv_subaddress_string = -1; static int hf_ctlv_result_gen = -1; static int hf_ctlv_result_term = -1; static int hf_ctlv_result_launch_browser = -1; @@ -64,6 +70,8 @@ static int hf_ctlv_text_string_enc = -1; static int hf_ctlv_text_string = -1; static int hf_ctlv_event = -1; static int hf_ctlv_tone = -1; +static int hf_ctlv_item_id = -1; +static int hf_ctlv_item_string = -1; static int hf_ctlv_loc_status = -1; static int hf_ctlv_timer_val_hr = -1; static int hf_ctlv_timer_val_min = -1; @@ -77,6 +85,7 @@ static int hf_ctlv_date_time_sec = -1; static int hf_ctlv_date_time_tz = -1; static int hf_ctlv_at_cmd = -1; static int hf_ctlv_at_rsp = -1; +static int hf_ctlv_dtmf_string = -1; static int hf_ctlv_language = -1; static int hf_ctlv_me_status = -1; static int hf_ctlv_timing_adv = -1; @@ -431,6 +440,26 @@ static const value_string time_unit_vals[] = { { 0, NULL } }; +/* TS 102 223 Chapter 8.1 */ +static const value_string ton_vals[] = { + { 0x00, "Unknown" }, + { 0x01, "International Number" }, + { 0x02, "National Number" }, + { 0x03, "Network Specific Number" }, + { 0, NULL } +}; + +/* TS 102 223 Chapter 8.1 */ +static const value_string npi_vals[] = { + { 0x00, "Unknown" }, + { 0x01, "ISDN/telephony numbering plan (Recommendation ITU-Ts E.164 and E.163" }, + { 0x03, "Data numbering plan (Recommendation ITU-T X.121)" }, + { 0x04, "Telex numbering plan (Recommendation ITU-T F.69)" }, + { 0x09, "Private numbering plan" }, + { 0x0f, "Reserved for extension" }, + { 0, NULL } +}; + /* TS 102 223 Chapter 8.12 */ static const value_string result_vals[] = { { 0x00, "Command performed successfully" }, @@ -956,6 +985,93 @@ static const value_string aid_pix_app_code_3gpp2_vals[] = { { 0, NULL} }; +static void +dissect_cat_efadn_coding(tvbuff_t *tvb, proto_tree *tree, guint32 pos, guint32 len, int hf_entry) +{ + if (len) { + guint32 i; + + guint8 first_byte = tvb_get_guint8(tvb, pos); + if ((first_byte & 0x80) == 0) { + wmem_strbuf_t *strbuf = wmem_strbuf_sized_new(wmem_packet_scope(), len+1, 0); + for (i = 0; i < len; i++) { + guint8 gsm_chars[2]; + gsm_chars[0] = tvb_get_guint8(tvb, pos+i); + if (gsm_chars[0] == 0x1b) { + /* Escape character */ + guint8 second_byte; + i++; + second_byte = tvb_get_guint8(tvb, pos+i); + gsm_chars[0] |= second_byte << 7; + gsm_chars[1] = second_byte >> 1; + wmem_strbuf_append(strbuf, get_ts_23_038_7bits_string(wmem_packet_scope(), gsm_chars, 0, 2)); + } else { + wmem_strbuf_append(strbuf, get_ts_23_038_7bits_string(wmem_packet_scope(), gsm_chars, 0, 1)); + } + } + proto_tree_add_string(tree, hf_entry, tvb, pos, len, wmem_strbuf_finalize(strbuf)); + } else if (first_byte == 0x80) { + proto_tree_add_item(tree, hf_entry, tvb, pos+1, len-1, ENC_UCS_2|ENC_BIG_ENDIAN); + } else if (first_byte == 0x81) { + guint8 string_len = tvb_get_guint8(tvb, pos+1); + guint16 ucs2_base = tvb_get_guint8(tvb, pos+2) << 7; + wmem_strbuf_t *strbuf = wmem_strbuf_sized_new(wmem_packet_scope(), 2*string_len+1, 0); + for (i = 0; i < string_len; i++) { + guint8 byte = tvb_get_guint8(tvb, pos+3+i); + if ((byte & 0x80) == 0) { + guint8 gsm_chars[2]; + gsm_chars[0] = byte; + if (gsm_chars[0] == 0x1b) { + /* Escape character */ + guint8 second_byte; + i++; + second_byte = tvb_get_guint8(tvb, pos+3+i); + gsm_chars[0] |= second_byte << 7; + gsm_chars[1] = second_byte >> 1; + wmem_strbuf_append(strbuf, get_ts_23_038_7bits_string(wmem_packet_scope(), gsm_chars, 0, 2)); + } else { + wmem_strbuf_append(strbuf, get_ts_23_038_7bits_string(wmem_packet_scope(), gsm_chars, 0, 1)); + } + } else { + guint8 ucs2_char[2]; + ucs2_char[0] = ucs2_base >> 8; + ucs2_char[1] = (ucs2_base & 0xff) + (byte & 0x7f); + wmem_strbuf_append(strbuf, get_ucs_2_string(wmem_packet_scope(), ucs2_char, 2, ENC_BIG_ENDIAN)); + } + } + proto_tree_add_string(tree, hf_entry, tvb, pos, len, wmem_strbuf_finalize(strbuf)); + } else if (first_byte == 0x82) { + guint8 string_len = tvb_get_guint8(tvb, pos+1); + guint16 ucs2_base = tvb_get_ntohs(tvb, pos+2); + wmem_strbuf_t *strbuf = wmem_strbuf_sized_new(wmem_packet_scope(), 2*string_len+1, 0); + for (i = 0; i < string_len; i++) { + guint8 byte = tvb_get_guint8(tvb, pos+4+i); + if ((byte & 0x80) == 0) { + guint8 gsm_chars[2]; + gsm_chars[0] = byte; + if (gsm_chars[0] == 0x1b) { + /* Escape character */ + guint8 second_byte; + i++; + second_byte = tvb_get_guint8(tvb, pos+4+i); + gsm_chars[0] |= second_byte << 7; + gsm_chars[1] = second_byte >> 1; + wmem_strbuf_append(strbuf, get_ts_23_038_7bits_string(wmem_packet_scope(), gsm_chars, 0, 2)); + } else { + wmem_strbuf_append(strbuf, get_ts_23_038_7bits_string(wmem_packet_scope(), gsm_chars, 0, 1)); + } + } else { + guint8 ucs2_char[2]; + ucs2_char[0] = ucs2_base >> 8; + ucs2_char[1] = (ucs2_base & 0xff) + (byte & 0x7f); + wmem_strbuf_append(strbuf, get_ucs_2_string(wmem_packet_scope(), ucs2_char, 2, ENC_BIG_ENDIAN)); + } + } + proto_tree_add_string(tree, hf_entry, tvb, pos, len, wmem_strbuf_finalize(strbuf)); + } + } +} + static int dissect_cat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { @@ -1081,13 +1197,19 @@ dissect_cat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) case 0x04: /* Duration */ if (len < 2) break; - proto_tree_add_item(elem_tree, hf_ctlv_dur_time_intv, tvb, pos+1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(elem_tree, hf_ctlv_dur_time_unit, tvb, pos, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(elem_tree, hf_ctlv_dur_time_intv, tvb, pos+1, 1, ENC_BIG_ENDIAN); break; case 0x05: /* alpha identifier */ + dissect_cat_efadn_coding(tvb, elem_tree, pos, len, hf_ctlv_alpha_id_string); break; case 0x06: /* address */ - de_cld_party_bcd_num(tvb, elem_tree, pinfo, pos, len, NULL, 0); + proto_tree_add_item(elem_tree, hf_ctlv_address_ton, tvb, pos, 1, ENC_BIG_ENDIAN); + proto_tree_add_item(elem_tree, hf_ctlv_address_npi, tvb, pos, 1, ENC_BIG_ENDIAN); + dissect_cat_efadn_coding(tvb, elem_tree, pos+1, len-1, hf_ctlv_address_string); + break; + case 0x08: /* subaddress */ + dissect_cat_efadn_coding(tvb, elem_tree, pos, len, hf_ctlv_subaddress_string); break; case 0x0b: /* sms tpdu */ new_tvb = tvb_new_subset_length(tvb, pos, len); @@ -1141,6 +1263,12 @@ dissect_cat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) break; proto_tree_add_item(elem_tree, hf_ctlv_tone, tvb, pos, 1, ENC_BIG_ENDIAN); break; + case 0x0f: /* item */ + if (len) { + proto_tree_add_item(elem_tree, hf_ctlv_item_id, tvb, pos, 1, ENC_BIG_ENDIAN); + dissect_cat_efadn_coding(tvb, elem_tree, pos+1, len-1, hf_ctlv_item_string); + } + break; case 0x13: /* location information */ if (len == 0) break; @@ -1215,6 +1343,9 @@ dissect_cat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) case 0x29: /* AT Response */ proto_tree_add_item(elem_tree, hf_ctlv_at_rsp, tvb, pos, len, ENC_ASCII|ENC_NA); break; + case 0x2c: /* DTMF string */ + dissect_cat_efadn_coding(tvb, elem_tree, pos, len, hf_ctlv_dtmf_string); + break; case 0x2d: /* language */ proto_tree_add_item(elem_tree, hf_ctlv_language, tvb, pos, len, ENC_ASCII|ENC_NA); break; @@ -1455,14 +1586,39 @@ proto_register_card_app_toolkit(void) FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }, }, + { &hf_ctlv_dur_time_unit, + { "Time Unit", "etsi_cat.comp_tlv.time_unit", + FT_UINT8, BASE_HEX, VALS(time_unit_vals), 0, + NULL, HFILL }, + }, { &hf_ctlv_dur_time_intv, { "Time Interval", "etsi_cat.comp_tlv.time_interval", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }, }, - { &hf_ctlv_dur_time_unit, - { "Time Unit", "etsi_cat.comp_tlv.time_unit", - FT_UINT8, BASE_HEX, VALS(time_unit_vals), 0, + { &hf_ctlv_alpha_id_string, + { "Alpha Identifier String", "etsi_cat.comp_tlv.alpha_id.string", + FT_STRING, STR_UNICODE, NULL, 0, + NULL, HFILL }, + }, + { &hf_ctlv_address_ton, + { "TON", "etsi_cat.comp_tlv.address.ton", + FT_UINT8, BASE_HEX, VALS(ton_vals), 0x70, + NULL, HFILL }, + }, + { &hf_ctlv_address_npi, + { "NPI", "etsi_cat.comp_tlv.address.npi", + FT_UINT8, BASE_HEX, VALS(npi_vals), 0x0f, + NULL, HFILL }, + }, + { &hf_ctlv_address_string, + { "Address String", "etsi_cat.comp_tlv.address.string", + FT_STRING, STR_UNICODE, NULL, 0, + NULL, HFILL }, + }, + { &hf_ctlv_subaddress_string, + { "Subaddress String", "etsi_cat.comp_tlv.subaddress.string", + FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }, }, { &hf_ctlv_result_gen, @@ -1520,6 +1676,16 @@ proto_register_card_app_toolkit(void) FT_UINT8, BASE_HEX | BASE_EXT_STRING, &tone_vals_ext, 0, NULL, HFILL }, }, + { &hf_ctlv_item_id, + { "Item Identifier", "etsi_cat.comp_tlv.item.id", + FT_UINT8, BASE_DEC, NULL, 0, + NULL, HFILL }, + }, + { &hf_ctlv_item_string, + { "Item String", "etsi_cat.comp_tlv.item.string", + FT_STRING, STR_UNICODE, NULL, 0, + NULL, HFILL }, + }, { &hf_ctlv_loc_status, { "Location Status", "etsi_cat.comp_tlv.loc_status", FT_UINT8, BASE_HEX, VALS(loc_status_vals), 0, @@ -1577,17 +1743,22 @@ proto_register_card_app_toolkit(void) }, { &hf_ctlv_at_cmd, { "AT Command", "etsi_cat.comp_tlv.at_cmd", - FT_STRING, BASE_NONE, NULL, 0, + FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }, }, { &hf_ctlv_at_rsp, { "AT Response", "etsi_cat.comp_tlv.at_rsp", - FT_STRING, BASE_NONE, NULL, 0, + FT_STRING, STR_UNICODE, NULL, 0, + NULL, HFILL }, + }, + { &hf_ctlv_dtmf_string, + { "DMTF String", "etsi_cat.comp_tlv.dtmf.string", + FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }, }, { &hf_ctlv_language, { "Language", "etsi_cat.comp_tlv.language", - FT_STRING, BASE_NONE, NULL, 0, + FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }, }, { &hf_ctlv_me_status, @@ -1852,7 +2023,7 @@ proto_register_card_app_toolkit(void) }, { &hf_ctlv_ims_status_code, { "IMS Status-Code", "etsi_cat.comp_tlv.ims_status_code", - FT_STRING, BASE_NONE, NULL, 0, + FT_STRING, STR_UNICODE, NULL, 0, NULL, HFILL }, }, { &hf_ctlv_broadcast_nw_tech, diff --git a/epan/dissectors/packet-gsm_sms.c b/epan/dissectors/packet-gsm_sms.c index cfccec95b7..09ff280ce5 100644 --- a/epan/dissectors/packet-gsm_sms.c +++ b/epan/dissectors/packet-gsm_sms.c @@ -40,6 +40,7 @@ #include <epan/expert.h> #include <epan/prefs.h> #include <epan/reassemble.h> +#include <epan/charsets.h> #include "packet-gsm_sms.h" void proto_register_gsm_sms(void); @@ -1929,7 +1930,23 @@ dis_field_ud(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset /* as defined in TS 23.038 with bit 8 set to 0 */ if(!(reassembled && pinfo->num == reassembled_in)) { - proto_tree_add_item(subtree, hf_gsm_sms_text, tvb, offset, length, ENC_ASCII|ENC_NA); + wmem_strbuf_t *strbuf = wmem_strbuf_sized_new(wmem_packet_scope(), length+1, 0); + for (i = 0; i < length; i++) { + guint8 gsm_chars[2]; + gsm_chars[0] = tvb_get_guint8(tvb, offset+i); + if (gsm_chars[0] == 0x1b) { + /* Escape character */ + guint8 second_byte; + i++; + second_byte = tvb_get_guint8(tvb, offset+i); + gsm_chars[0] |= second_byte << 7; + gsm_chars[1] = second_byte >> 1; + wmem_strbuf_append(strbuf, get_ts_23_038_7bits_string(wmem_packet_scope(), gsm_chars, 0, 2)); + } else { + wmem_strbuf_append(strbuf, get_ts_23_038_7bits_string(wmem_packet_scope(), gsm_chars, 0, 1)); + } + } + proto_tree_add_string(subtree, hf_gsm_sms_text, tvb, offset, length, wmem_strbuf_finalize(strbuf)); } else { |