diff options
-rw-r--r-- | epan/dissectors/packet-gtp.c | 116 |
1 files changed, 101 insertions, 15 deletions
diff --git a/epan/dissectors/packet-gtp.c b/epan/dissectors/packet-gtp.c index 26d56317bf..9dbfb019b2 100644 --- a/epan/dissectors/packet-gtp.c +++ b/epan/dissectors/packet-gtp.c @@ -62,6 +62,7 @@ #include "packet-gsm_a_common.h" #include "packet-gsm_map.h" #include "packet-per.h" +#include "packet-ber.h" #include "packet-ranap.h" #include "packet-bssgp.h" #include "packet-gtp.h" @@ -225,6 +226,9 @@ static int hf_gtp_xid_par_len = -1; static int hf_gtp_earp_pvi = -1; static int hf_gtp_earp_pl = -1; static int hf_gtp_earp_pci = -1; +static int hf_gtp_cdr_app = -1; +static int hf_gtp_cdr_rel = -1; +static int hf_gtp_cdr_ver = -1; static int hf_gtp_spare = -1; static int hf_gtp_cmn_flg_ppc = -1; static int hf_gtp_cmn_flg_mbs_srv_type = -1; @@ -316,6 +320,8 @@ static gint ett_gtp_ext_ps_handover_xid = -1; static gint ett_gtp_target_id = -1; static gint ett_gtp_utran_cont = -1; static gint ett_gtp_bcm = -1; +static gint ett_gtp_cdr_ver = -1; +static gint ett_gtp_cdr_dr = -1; static gboolean g_gtp_tpdu = TRUE; @@ -6374,34 +6380,100 @@ static int decode_gtp_can_pack(tvbuff_t * tvb, int offset, packet_info * pinfo _ return 3 + length; } -/* CDRs dissector */ +/* CDRs dissector + * 3GPP TS 32.295 version 9.0.0 Release 9 + */ +static const value_string gtp_cdr_fmt_vals[] = { + {1, "Basic Encoding Rules (BER)"}, + {2, "Unaligned basic Packed Encoding Rules (PER)"}, + {3, "Aligned basic Packed Encoding Rules (PER)"}, + {0, NULL} +}; static int decode_gtp_data_req(tvbuff_t * tvb, int offset, packet_info * pinfo _U_, proto_tree * tree) { - guint16 length, format_ver; - guint8 no, format; - proto_tree *ext_tree; - proto_item *te; + guint16 length, cdr_length; + guint8 no, format, app_id, rel_id, ver_id, i; + proto_tree *ext_tree, *ver_tree, *cdr_dr_tree; + proto_item *te, *fmt_item, *ver_item; tvbuff_t *next_tvb; + gint8 tmp_cls; + gint32 tmp_tag; + guint32 tmp_len; te = proto_tree_add_text(tree, tvb, offset, 1, "%s", val_to_str_ext_const(GTP_EXT_DATA_REQ, >p_val_ext, "Unknown message")); ext_tree = proto_item_add_subtree(te, ett_gtp_ext); + offset++; - length = tvb_get_ntohs(tvb, offset + 1); - no = tvb_get_guint8(tvb, offset + 3); - format = tvb_get_guint8(tvb, offset + 4); - format_ver = tvb_get_ntohs(tvb, offset + 5); + length = tvb_get_ntohs(tvb, offset); + proto_tree_add_text(ext_tree, tvb, offset, 2, "Length: %u", length); + offset+=2; + + /* Octet 4 Number of Data Records */ + no = tvb_get_guint8(tvb, offset); + proto_tree_add_text(ext_tree, tvb, offset, 1, "Number of data records: %u", no); + offset++; + + /* Octet 5 Data Record Format */ + format = tvb_get_guint8(tvb, offset); + fmt_item = proto_tree_add_text(ext_tree, tvb, offset, 1, "Data record format: %u", format); + offset++; + /* The value range is 1-255 in decimal. The value '0' should not be used. + * Only the values 1-10 and 51-255 can be used for standards purposes. + * Values in the range of 11-50 are to be configured only by operators, and are not subject to standardization. + */ + if(format<4){ + proto_item_append_text(fmt_item, " %s", val_to_str_const(format, gtp_cdr_fmt_vals, "Unknown")); + /* Octet 6 -7 Data Record Format Version + * 8 7 6 5 4 3 2 1 + * 6 Application Identifier Release Identifier + * 7 Version Identifier + */ + app_id = tvb_get_guint8(tvb,offset); + rel_id = app_id & 0x0f; + app_id = app_id >>4; + ver_id =tvb_get_guint8(tvb,offset+1); + /* The second octet (#7 in Data Record Packet IE) identifies the version of the TS used to encode the CDR, + * i.e. its value corresponds to the second digit of the version number of the document [51] + * (as shown on the cover sheet), plus '1'. + * E.g. for version 3.4.0, the Version Identifier would be "5". + * In circumstances where the second digit is an alphabetical character, (e.g. 3.b.0), the corresponding ASCII value shall + * be taken, e.g. the Version Identifier would be "66" (ASCII(b)). + */ + if(ver_id<0x65) + ver_id = ver_id -1; + /* XXX We don't handle ASCCI version */ + + ver_item = proto_tree_add_text(ext_tree, tvb, offset, 2, "Data record format version: AppId %u Rel %u.%u.0", app_id,rel_id,ver_id); + ver_tree = proto_item_add_subtree(ver_item, ett_gtp_cdr_ver); + proto_tree_add_item(ver_tree, hf_gtp_cdr_app, tvb, offset, 1, FALSE); + proto_tree_add_item(ver_tree, hf_gtp_cdr_rel, tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(ver_tree, hf_gtp_cdr_ver, tvb, offset, 1, FALSE); + offset++; + for(i = 0; i < no; ++i) { + cdr_length = tvb_get_ntohs(tvb, offset); + te = proto_tree_add_text(ext_tree, tvb, offset, cdr_length+2, "Data record %d", i + 1); + cdr_dr_tree = proto_item_add_subtree(te, ett_gtp_cdr_dr); + proto_tree_add_text(cdr_dr_tree, tvb, offset, 2, "Length: %u", cdr_length); + offset+=2; + proto_tree_add_text(cdr_dr_tree, tvb, offset, cdr_length, "Content"); +#if 0 + dissect_ber_identifier(pinfo, cdr_dr_tree, tvb, offset, &tmp_cls, NULL, &tmp_tag); + dissect_ber_length(pinfo, cdr_dr_tree, tvb, offset+1, &tmp_len, NULL); +#endif + offset = offset + cdr_length; + } - proto_tree_add_text(ext_tree, tvb, offset + 1, 2, "Length: %u", length); - proto_tree_add_text(ext_tree, tvb, offset + 3, 1, "Number of data records: %u", no); - proto_tree_add_text(ext_tree, tvb, offset + 4, 1, "Data record format: %u", format); - proto_tree_add_text(ext_tree, tvb, offset + 5, 2, "Data record format version: %u", format_ver); + }else{ + /* Proprietary CDR format */ + proto_item_append_text(fmt_item, " Proprietary or un documented format"); + } if (gtpcdr_handle) { next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(gtpcdr_handle, next_tvb, pinfo, tree); - } else - proto_tree_add_text(tree, tvb, offset, 0, "Data"); + } return 3 + length; } @@ -7143,6 +7215,18 @@ void proto_register_gtp(void) {"PCI Pre-emption Capability", "gtp.EARP_pre_emption_Capability", FT_UINT8, BASE_DEC, NULL, 0x40, NULL, HFILL}}, + {&hf_gtp_cdr_app, + {"Application Identifier", "gtp.cdr_app", + FT_UINT8, BASE_DEC, NULL, 0xf0, + NULL, HFILL}}, + { &hf_gtp_cdr_rel, + {"Release Identifier", "gtp.cdr_rel", + FT_UINT8, BASE_DEC, NULL, 0x0f, + NULL, HFILL}}, + { &hf_gtp_cdr_ver, + {"Version Identifier", "gtp.cdr_ver", + FT_UINT8, BASE_DEC, NULL, 0x0, + NULL, HFILL}}, {&hf_gtp_spare, {"Spare", "gtp.spare", FT_UINT8, BASE_DEC, NULL, 0x02, @@ -7306,6 +7390,8 @@ void proto_register_gtp(void) &ett_gtp_ext_ps_handover_xid, &ett_gtp_target_id, &ett_gtp_utran_cont, + &ett_gtp_cdr_ver, + &ett_gtp_cdr_dr, }; module_t *gtp_module; |