aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-e164.c
diff options
context:
space:
mode:
authorJeff Morriss <jeff.morriss.ws@gmail.com>2014-08-20 22:47:22 -0400
committerJeff Morriss <jeff.morriss.ws@gmail.com>2014-08-21 13:01:22 +0000
commita3d8f31ad0a48f72cd6d8fa2b0c3659c9ea84745 (patch)
tree48dfaefaf4298963c9a7c132d34e2f08da15ac4e /epan/dissectors/packet-e164.c
parentc7c4abaab00ce1a8bc35e326c80095e9cc47584e (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.c265
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));
}