diff options
author | Jeff Morriss <jeff.morriss.ws@gmail.com> | 2014-08-20 22:47:22 -0400 |
---|---|---|
committer | Jeff Morriss <jeff.morriss.ws@gmail.com> | 2014-08-21 13:01:22 +0000 |
commit | a3d8f31ad0a48f72cd6d8fa2b0c3659c9ea84745 (patch) | |
tree | 48dfaefaf4298963c9a7c132d34e2f08da15ac4e /epan/dissectors/packet-e164.c | |
parent | c7c4abaab00ce1a8bc35e326c80095e9cc47584e (diff) |
Add a function to dissect an E.164 (MSISDN) number in UTF8 format and use it
in the Diameter dissector.
This new API adds a filter for the MSISDN as well as a subtree and filter for
the Country Code.
Change-Id: Ibcbf4b5f72178b7e4af63efa7496188d608a9de7
Reviewed-on: https://code.wireshark.org/review/3760
Petri-Dish: Jeff Morriss <jeff.morriss.ws@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Reviewed-by: Jeff Morriss <jeff.morriss.ws@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-e164.c')
-rw-r--r-- | epan/dissectors/packet-e164.c | 265 |
1 files changed, 163 insertions, 102 deletions
diff --git a/epan/dissectors/packet-e164.c b/epan/dissectors/packet-e164.c index 93118e30dd..155408430f 100644 --- a/epan/dissectors/packet-e164.c +++ b/epan/dissectors/packet-e164.c @@ -345,6 +345,7 @@ const value_string E164_country_code_value[] = { { 0, NULL } }; static value_string_ext E164_country_code_value_ext = VALUE_STRING_EXT_INIT(E164_country_code_value); + const value_string E164_GMSS_vals[] = { { 0x6, "Iridium Satellite LLC"}, { 0x7, "Iridium Satellite LLC"}, @@ -352,6 +353,7 @@ const value_string E164_GMSS_vals[] = { { 0x9, "Globalstar"}, { 0, NULL } }; + const value_string E164_International_Networks_882_vals[] = { { 0x10, "Global Office Application"}, { 0x12, "HyperStream International (HSI) Data Network"}, @@ -384,6 +386,7 @@ const value_string E164_International_Networks_882_vals[] = { { 0, NULL } }; static value_string_ext E164_International_Networks_882_vals_ext = VALUE_STRING_EXT_INIT(E164_International_Networks_882_vals); + const value_string E164_International_Networks_883_vals[] = { { 0x100, "MediaLincc Ltd"}, { 0x110, "Aicent Inc"}, @@ -397,24 +400,25 @@ const value_string E164_International_Networks_883_vals[] = { { 0, NULL } }; -static int proto_e164 = -1; +static int proto_e164 = -1; static int hf_E164_calling_party_number = -1; static int hf_E164_called_party_number = -1; +static int hf_E164_number = -1; static int hf_E164_identification_code = -1; -static int hf_E164_country_code = -1; - +static int hf_E164_country_code = -1; +static int ett_e164_msisdn = -1; void dissect_e164_number(tvbuff_t *tvb, proto_tree *tree, int offset, int length,e164_info_t e164_info) { - switch (e164_info.e164_number_type){ - case CALLING_PARTY_NUMBER : + switch (e164_info.e164_number_type) { + case CALLING_PARTY_NUMBER: proto_tree_add_string(tree, hf_E164_calling_party_number, tvb, offset, length, e164_info.E164_number_str); break; - case CALLED_PARTY_NUMBER : + case CALLED_PARTY_NUMBER: proto_tree_add_string(tree, hf_E164_called_party_number, tvb, offset, length, e164_info.E164_number_str); break; @@ -424,206 +428,247 @@ dissect_e164_number(tvbuff_t *tvb, proto_tree *tree, int offset, int length,e164 } } -void -dissect_e164_cc(tvbuff_t *tvb, proto_tree *tree, int offset, gboolean bcd_coded){ +void +dissect_e164_cc(tvbuff_t *tvb, proto_tree *tree, int offset, e164_encoding_t encoding) +{ int cc_offset; guint8 address_digit_pair; - guint16 id_code; + guint16 id_code = 0; guint8 cc_length; guint8 length; - guint16 cc; + guint16 cc = 0; cc_offset = offset; address_digit_pair = tvb_get_guint8(tvb, cc_offset); - if(!bcd_coded){ + /* Get the first 3 digits of the MSISDN */ + switch (encoding) { + case E164_ENC_BINARY: /* Dissect country code after removing non significant zeros */ - while ( address_digit_pair == 0 ) { + while (address_digit_pair == 0) { cc_offset = cc_offset + 1; address_digit_pair = tvb_get_guint8(tvb, cc_offset); } cc = tvb_get_ntohs(tvb, cc_offset); - if (( address_digit_pair & 0xf0 ) != 0 ){ + if ((address_digit_pair & 0xf0) != 0) { cc = cc >> 4; } - }else{ + break; + case E164_ENC_BCD: cc = address_digit_pair &0x0f; cc = cc << 4; cc = cc | (address_digit_pair &0xf0)>>4; cc = cc << 4; - if (tvb_bytes_exist(tvb, cc_offset+1, 1)){ + if (tvb_bytes_exist(tvb, cc_offset+1, 1)) { address_digit_pair = tvb_get_guint8(tvb, cc_offset+1); cc = cc | (address_digit_pair &0x0f); } - + break; + case E164_ENC_UTF8: + /* XXX - do we need to worry about leading 0s? */ + cc = (tvb_get_guint8(tvb, cc_offset) - '0') << 8; + cc |= (tvb_get_guint8(tvb, cc_offset+1) - '0') << 4; + cc |= (tvb_get_guint8(tvb, cc_offset+2) - '0'); + break; } - switch ( cc & 0x0f00 ) { - + /* Determine how many of those digits are the Country Code */ + switch (cc & 0x0f00) { case 0x0: cc_length = 1; break; - case 0x0100: cc_length = 1; break; - case 0x0200: - switch ( cc & 0x00f0 ) { + switch (cc & 0x00f0) { case 0: - case 0x70 : + case 0x70: cc_length = 2; break; - default : + default: cc_length = 3; break; } break; - - case 0x0300 : - switch ( cc & 0x00f0 ) { - case 0 : - case 0x10 : - case 0x20 : - case 0x30 : - case 0x40 : - case 0x60 : - case 0x90 : + case 0x0300: + switch (cc & 0x00f0) { + case 0: + case 0x10: + case 0x20: + case 0x30: + case 0x40: + case 0x60: + case 0x90: cc_length = 2; break; - default : + default: cc_length = 3; break; } break; - case 0x0400 : - switch ( cc & 0x00f0 ) { - case 0x20 : + case 0x0400: + switch (cc & 0x00f0) { + case 0x20: cc_length = 3; break; - default : + default: cc_length = 2; break; } break; - - case 0x0500 : - switch ( cc & 0x00f0 ) { - case 0 : - case 0x90 : + case 0x0500: + switch (cc & 0x00f0) { + case 0: + case 0x90: cc_length = 3; break; - default : + default: cc_length = 2; break; } break; - - case 0x0600 : - switch ( cc & 0x00f0 ) { - case 0x70 : - case 0x80 : - case 0x90 : + case 0x0600: + switch (cc & 0x00f0) { + case 0x70: + case 0x80: + case 0x90: cc_length = 3; break; - default : + default: cc_length = 2; break; } break; - - case 0x0700 : + case 0x0700: cc_length = 1; break; - - case 0x0800 : - switch ( cc & 0x00f0 ) { + case 0x0800: + switch (cc & 0x00f0) { case 0x10: case 0x20: case 0x40: case 0x60: cc_length = 2; break; - default : + default: cc_length = 3; break; } break; - - case 0x0900 : - switch ( cc & 0x00f0 ) { - case 0 : - case 0x10 : - case 0x20 : - case 0x30 : - case 0x40 : - case 0x50 : - case 0x80 : + case 0x0900: + switch (cc & 0x00f0) { + case 0: + case 0x10: + case 0x20: + case 0x30: + case 0x40: + case 0x50: + case 0x80: cc_length = 2; break; - default : + default: cc_length = 3; break; } break; - default : + default: cc_length = 0; break; - }/* End switch cc */ + } /* End switch cc */ - switch ( cc_length ) { - case 1 : + /* (Now that we know how long the CC is,) + * shift off any extra digits we got. + */ + switch (cc_length) { + case 1: cc = cc >> 8; length = 1; break; - case 2 : + case 2: cc = cc >> 4; length = 1; break; default: length = 2; break; - }/* end switch cc_length */ - - proto_tree_add_uint(tree, hf_E164_country_code, tvb, cc_offset, length, cc); - - switch ( cc ) { - case 0x881 : - if (!bcd_coded) { + } /* end switch cc_length */ + + /* Display the CC */ + if (encoding == E164_ENC_UTF8) + proto_tree_add_uint(tree, hf_E164_country_code, tvb, cc_offset, cc_length, cc); + else + proto_tree_add_uint(tree, hf_E164_country_code, tvb, cc_offset, length, cc); + + /* Handle special Country Codes */ + switch (cc) { + case 0x881: + /* Get the 1-digit ID code */ + switch (encoding) { + case E164_ENC_BINARY: id_code = tvb_get_guint8(tvb, cc_offset + 1) & 0x0f; - } else { + break; + case E164_ENC_BCD: id_code = (tvb_get_guint8(tvb, cc_offset + 1) & 0xf0) >> 4; + break; + case E164_ENC_UTF8: + id_code = tvb_get_guint8(tvb, cc_offset + cc_length) - '0'; + break; } proto_tree_add_uint_format_value(tree, hf_E164_identification_code, tvb, (cc_offset + 1), 1, id_code, "%x %s", id_code, val_to_str_const(id_code, E164_GMSS_vals, "Unknown")); break; - case 0x882 : - if (!bcd_coded) { + case 0x882: + /* Get the 2-digit ID code */ + switch (encoding) { + case E164_ENC_BINARY: id_code = tvb_get_ntohs(tvb, cc_offset + 1); id_code = (id_code & 0x0ff0) >> 4; - } else { + break; + case E164_ENC_BCD: id_code = tvb_get_guint8(tvb, cc_offset + 1) & 0xf0; id_code |= tvb_get_guint8(tvb, cc_offset + 2) & 0x0f; + break; + case E164_ENC_UTF8: + id_code = (tvb_get_guint8(tvb, cc_offset+cc_length) - '0') << 4; + id_code |= (tvb_get_guint8(tvb, cc_offset+cc_length+1) - '0'); + break; } proto_tree_add_uint_format_value(tree, hf_E164_identification_code, tvb, (cc_offset + 1), 2, id_code, "%x %s", id_code, val_to_str_ext_const(id_code, &E164_International_Networks_882_vals_ext, "Unknown")); break; - case 0x883 : - if (!bcd_coded) { + case 0x883: + /* Get the 3-digit ID code */ + switch (encoding) { + case E164_ENC_BINARY: id_code = tvb_get_ntohs(tvb, cc_offset + 1); id_code = id_code & 0x0fff; - } else { + break; + case E164_ENC_BCD: id_code = (tvb_get_guint8(tvb, cc_offset + 1) & 0xf0) << 4; id_code |= (tvb_get_guint8(tvb, cc_offset + 2) & 0x0f) << 4; id_code |= (tvb_get_guint8(tvb, cc_offset + 2) & 0xf0) >> 4; + break; + case E164_ENC_UTF8: + id_code = (tvb_get_guint8(tvb, cc_offset+cc_length) - '0') << 8; + id_code |= (tvb_get_guint8(tvb, cc_offset+cc_length+1) - '0') << 4; + id_code |= (tvb_get_guint8(tvb, cc_offset+cc_length+2) - '0'); + break; } if ((id_code & 0x0ff0) == 0x510) { - if (!bcd_coded) { + /* Get the 4th digit of the ID code */ + switch (encoding) { + case E164_ENC_BINARY: id_code = (id_code << 4) | ((tvb_get_guint8(tvb, cc_offset + 3) & 0xf0) >> 4); - } else { + break; + case E164_ENC_BCD: id_code = (id_code << 4) | (tvb_get_guint8(tvb, cc_offset + 3) & 0x0f); + break; + case E164_ENC_UTF8: + id_code = (id_code << 4) | (tvb_get_guint8(tvb, cc_offset + cc_length + 3) - '0'); + break; } proto_tree_add_uint_format_value(tree, hf_E164_identification_code, tvb, (cc_offset + 1), 3, id_code, "%x %s", id_code, val_to_str_const(id_code, E164_International_Networks_883_vals, "Unknown")); @@ -638,6 +683,23 @@ dissect_e164_cc(tvbuff_t *tvb, proto_tree *tree, int offset, gboolean bcd_coded) } +const gchar * +dissect_e164_utf8_number(tvbuff_t *tvb, proto_tree *tree, int offset, int length) +{ + proto_item *pi; + proto_tree *subtree; + gchar *msisdn_str; + + msisdn_str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, length, ENC_UTF_8); + pi = proto_tree_add_string(tree, hf_E164_number, tvb, offset, length, msisdn_str); + + subtree = proto_item_add_subtree(pi, ett_e164_msisdn); + + dissect_e164_cc(tvb, subtree, offset, E164_ENC_UTF8); + + return msisdn_str; +} + /* * Register the protocol with Wireshark. * @@ -661,6 +723,11 @@ proto_register_e164(void) FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, + { &hf_E164_number, + { "E.164 number (MSISDN)", "e164.msisdn", + FT_STRING, BASE_NONE, NULL, 0x0, + NULL, HFILL }}, + { &hf_E164_identification_code, { "Identification Code", "e164.identification_code", FT_UINT32, BASE_HEX, NULL, 0x0, @@ -672,18 +739,12 @@ proto_register_e164(void) NULL, HFILL }}, }; - /* - * Register the protocol name and description - */ - proto_e164 = proto_register_protocol( - "ITU-T E.164 number", - "E.164", - "e164"); - - /* - * Required function calls to register - * the header fields and subtrees used. - */ - proto_register_field_array(proto_e164, hf, array_length(hf)); + static gint *ett_e164_array[] = { + &ett_e164_msisdn, + }; + + proto_e164 = proto_register_protocol("ITU-T E.164 number", "E.164", "e164"); + proto_register_field_array(proto_e164, hf, array_length(hf)); + proto_register_subtree_array(ett_e164_array, array_length(ett_e164_array)); } |