/* packet-gtpv2.c
*
* Routines for GTPv2 dissection
- * Copyright 2009 - 2015, Anders Broman <anders.broman [at] ericsson.com>
+ * Copyright 2009 - 2016, Anders Broman <anders.broman [at] ericsson.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
#include "config.h"
#include <epan/packet.h>
+#include <epan/conversation.h>
#include <epan/to_str.h>
#include <epan/asn1.h>
#include <epan/expert.h>
#include "packet-e164.h"
#include "packet-e212.h"
#include "packet-s1ap.h"
+#include "packet-ranap.h"
#include "packet-bssgp.h"
#include "packet-ntp.h"
#include "packet-gtpv2.h"
#include "packet-diameter.h"
+#include "packet-ip.h"
void proto_register_gtpv2(void);
void proto_reg_handoff_gtpv2(void);
/*GTPv2 Message->GTP Header(SB)*/
static int proto_gtpv2 = -1;
+static int hf_gtpv2_response_in = -1;
+static int hf_gtpv2_response_to = -1;
+static int hf_gtpv2_response_time = -1;
static int hf_gtpv2_spare_half_octet = -1;
static int hf_gtpv2_spare_bits = -1;
static int hf_gtpv2_flags = -1;
static int hf_gtpv2_csfbi = -1;
static int hf_gtpv2_clii = -1;
static int hf_gtpv2_cpsr = -1;
+static int hf_gtpv2_nsi = -1;
+static int hf_gtpv2_uasi = -1;
+static int hf_gtpv2_dtci = -1;
+static int hf_gtpv2_bdwi = -1;
+static int hf_gtpv2_psci = -1;
static int hf_gtpv2_pcri = -1;
static int hf_gtpv2_aosi = -1;
static int hf_gtpv2_aopi = -1;
+static int hf_gtpv2_roaai = -1;
+static int hf_gtpv2_epcosi = -1;
+static int hf_gtpv2_cpopci = -1;
+static int hf_gtpv2_pmtsmi = -1;
+static int hf_gtpv2_s11tf = -1;
+static int hf_gtpv2_pnsi = -1;
+static int hf_gtpv2_unaccsi = -1;
+static int hf_gtpv2_wpmsi = -1;
+static int hf_gtpv2_enbcrsi = -1;
+static int hf_gtpv2_tspcmi = -1;
static int hf_gtpv2_pdn_type = -1;
static int hf_gtpv2_ti = -1;
-static int hf_gtpv2_bearer_qos_pvi= -1;
-static int hf_gtpv2_bearer_qos_pl= -1;
static int hf_gtpv2_bearer_qos_pci= -1;
+static int hf_gtpv2_bearer_qos_pl= -1;
+static int hf_gtpv2_bearer_qos_pvi= -1;
static int hf_gtpv2_bearer_qos_label_qci = -1;
static int hf_gtpv2_bearer_qos_mbr_up = -1;
static int hf_gtpv2_bearer_qos_mbr_down = -1;
static int hf_gtpv2_CauseMisc = -1;
static int hf_gtpv2_target_type = -1;
static int hf_gtpv2_macro_enodeb_id = -1;
+static int hf_gtpv2_enodebid = -1;
+static int hf_gtpv2_cellid = -1;
static int hf_gtpv2_node_type= -1;
static int hf_gtpv2_fqdn = -1;
static int hf_gtpv2_mm_context_ms_net_cap_len = -1;
static int hf_gtpv2_mm_context_mei_len = -1;
static int hf_gtpv2_mm_context_vdp_len = -1;
+static int hf_gtpv2_mm_contex_nhi_old = -1;
+static int hf_gtpv2_mm_context_old_ksiasme = -1;
+static int hf_gtpv2_mm_context_old_ncc = -1;
+static int hf_gtpv2_mm_context_old_kasme = -1;
+static int hf_gtpv2_mm_context_old_nh = -1;
static int hf_gtpv2_mm_context_higher_br_16mb_flg_len = -1;
static int hf_gtpv2_mm_context_higher_br_16mb_flg = -1;
static int hf_gtpv2_vdp_length = -1;
+static int hf_gtpv2_mm_context_paging_len = -1;
static int hf_gtpv2_uci_csg_id = -1;
static int hf_gtpv2_uci_csg_id_spare = -1;
static int hf_gtpv2_uci_access_mode = -1;
static int hf_gtpv2_ina = -1;
static int hf_gtpv2_ena = -1;
static int hf_gtpv2_hnna = -1;
+static int hf_gtpv2_hbna = -1;
static int hf_gtpv2_mm_context_ksi_a= -1;
static int hf_gtpv2_mm_context_ksi = -1;
static int hf_gtpv2_mm_context_nr_tri = -1;
static int hf_gtpv2_uli_timestamp = -1;
static int hf_gtpv2_mbms_session_duration_days = -1;
static int hf_gtpv2_mbms_session_duration_secs = -1;
+static int hf_gtpv2_csg_id = -1;
+static int hf_gtpv2_cmi = -1;
+static int hf_gtpv2_service_indicator = -1;
+static int hf_gtpv2_detach_type = -1;
+static int hf_gtpv2_ldn = -1;
static int hf_gtpv2_node_features_prn = -1;
static int hf_gtpv2_node_features_mabr =-1;
static int hf_gtpv2_node_features_ntsr = -1;
static int hf_gtpv2_kc_ps = -1;
static int hf_gtpv2_cksn_ps = -1;
+static int hf_gtpv2_pres_rep_area_info_id = -1;
+static int hf_gtpv2_pres_rep_area_info_opra = -1;
+static int hf_gtpv2_pres_rep_area_info_ipra = -1;
+
/* Generated from convert_proto_tree_add_text.pl */
static int hf_gtpv2_downlink_subscribed_ue_ambr = -1;
static int hf_gtpv2_mm_context_sres = -1;
static int hf_gtpv2_iksrvcc = -1;
static int hf_gtpv2_nsapi08 = -1;
static int hf_gtpv2_voice_domain_and_ue_usage_setting = -1;
+static int hf_gtpv2_ue_radio_capability_for_paging_information = -1;
static int hf_gtpv2_upd_source_port_number = -1;
static int hf_gtpv2_uplink_used_ue_ambr = -1;
static int hf_gtpv2_tmsi_bytes = -1;
static int hf_gtpv2_ul_pdcp_sequence_number = -1;
static int hf_gtpv2_fq_csid_node_id = -1;
static int hf_gtpv2_fq_csid_mcc_mnc = -1;
+static int hf_gtpv2_ppi_value = -1;
+static int hf_gtpv2_ppi_flag = -1;
+static int hf_gtpv2_session = -1;
+static int hf_gtpv2_twan_id_ts = -1;
+static int hf_gtpv2_twan_flags = -1;
+static int hf_gtpv2_twan_bssidi = -1;
+static int hf_gtpv2_twan_civai = -1;
+static int hf_gtpv2_twan_plmni = -1;
+static int hf_gtpv2_twan_opnai = -1;
+static int hf_gtpv2_twan_laii = -1;
+static int hf_gtpv2_twan_ssid_len = -1;
+static int hf_gtpv2_twan_ssid = -1;
+static int hf_gtpv2_twan_bssid = -1;
+static int hf_gtpv2_twan_civa_len = -1;
+static int hf_gtpv2_twan_civa = -1;
+static int hf_gtpv2_twan_plmnid = -1;
+static int hf_gtpv2_twan_op_name_len = -1;
+static int hf_gtpv2_twan_op_name = -1;
+static int hf_gtpv2_twan_relay_id_type = -1;
+static int hf_gtpv2_twan_relay_id_len = -1;
+static int hf_gtpv2_twan_relay_id = -1;
+static int hf_gtpv2_twan_relay_id_ipv4 = -1;
+static int hf_gtpv2_twan_relay_id_ipv6 = -1;
+static int hf_gtpv2_twan_circuit_id_len = -1;
+static int hf_gtpv2_twan_circuit_id = -1;
+static int hf_gtpv2_integer_number_val = -1;
static gint ett_gtpv2 = -1;
static gint ett_gtpv2_flags = -1;
static gint ett_gtpv2_stn_sr = -1;
static gint ett_gtpv2_supp_codec_list = -1;
static gint ett_gtpv2_bss_con = -1;
+static gint ett_gtpv2_utran_con = -1;
+static gint ett_gtpv2_eutran_con = -1;
static gint ett_gtpv2_mm_context_auth_qua = -1;
static gint ett_gtpv2_mm_context_auth_qui = -1;
static gint ett_gtpv2_mm_context_auth_tri = -1;
static gint ett_gtpv2_preaa_rais = -1;
static gint ett_gtpv2_preaa_sais = -1;
static gint ett_gtpv2_preaa_cgis = -1;
+static gint ett_gtpv2_load_control_inf = -1;
+static gint ett_gtpv2_eci = -1;
+static gint ett_gtpv2_twan_flags = -1;
static expert_field ei_gtpv2_ie_data_not_dissected = EI_INIT;
static expert_field ei_gtpv2_ie_len_invalid = EI_INIT;
static expert_field ei_gtpv2_mbms_session_duration_days = EI_INIT;
static expert_field ei_gtpv2_mbms_session_duration_secs = EI_INIT;
static expert_field ei_gtpv2_ie = EI_INIT;
+static expert_field ei_gtpv2_int_size_not_handled = EI_INIT;
/* Definition of User Location Info (AVP 22) masks */
#define GTPv2_ULI_ECGI_MASK 0x10
#define GTPv2_ULI_LAI_MASK 0x20
+#define GTPV2_PPI_VAL_MASK 0x3F
+
+#define GTPV2_SRVCC_PS_TO_CS_REQUEST 25
+#define GTPV2_SRVCC_PS_TO_CS_RESPONSE 26
#define GTPV2_CREATE_SESSION_REQUEST 32
#define GTPV2_CREATE_SESSION_RESPONSE 33
+#define GTPV2_MODIFY_BEARER_REQUEST 34
#define GTPV2_MODIFY_BEARER_RESPONSE 35
#define GTPV2_DELETE_SESSION_REQUEST 36
#define GTPV2_DELETE_SESSION_RESPONSE 37
+#define GTPV2_MODIFY_BEARER_COMMAND 64
+#define GTPV2_MODIFY_BEARER_FAILURE_INDICATION 65
+#define GTPV2_DELETE_BEARER_COMMAND 66
+#define GTPV2_DELETE_BEARER_FAILURE_INDICATION 67
#define GTPV2_BEARER_RESOURCE_COMMAND 68
+#define GTPV2_BEARER_RESOURCE_FAILURE_INDICATION 69
#define GTPV2_CREATE_BEARER_REQUEST 95
#define GTPV2_CREATE_BEARER_RESPONSE 96
#define GTPV2_UPDATE_BEARER_REQUEST 97
#define GTPV2_FORWARD_CTX_NOTIFICATION 137
#define GTPV2_RAN_INFORMATION_RELAY 152
-static void dissect_gtpv2_ie_common(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, gint offset, guint8 message_type);
+static void dissect_gtpv2_ie_common(tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, gint offset, guint8 message_type, session_args_t * args);
/*Message Types for GTPv2 (Refer Pg19 29.274) (SB)*/
static const value_string gtpv2_message_type_vals[] = {
{ 35, "Modify Bearer Response"},
{ 36, "Delete Session Request"},
{ 37, "Delete Session Response"},
- /* SGSN to PGW (S4, S5/S8) */
+ /* SGSN/MME to PGW (S4/S11, S5/S8) */
{ 38, "Change Notification Request"},
{ 39, "Change Notification Response"},
- /* 40-63 For future use */
+ /* MME to PGW (S11, S5/S8) */
+ { 40, "Remote UE Report Notification" },
+ { 41, "Remote UE Report Acknowledge" },
+ /* 42-63 For future use */
/* Messages without explicit response */
{ 64, "Modify Bearer Command"}, /* (MME/SGSN to PGW -S11/S4, S5/S8) */
{ 65, "Modify Bearer Failure Indication"}, /*(PGW to MME/SGSN -S5/S8, S11/S4) */
{ 72, "Trace Session Deactivation"},
{ 73, "Stop Paging Indication"},
/* 74-94 For future use */
- /* PDN-GW to SGSN/MME (S5/S8, S4/S11) */
+ /* PGW to SGSN/MME/ TWAN/ePDG (S5/S8, S4/S11, S2a, S2b) */
{ 95, "Create Bearer Request"},
{ 96, "Create Bearer Response"},
{ 97, "Update Bearer Request"},
/* PGW to MME, MME to PGW, SGW to PGW, SGW to MME (S5/S8, S11) */
{101, "Delete PDN Connection Set Request"},
{102, "Delete PDN Connection Set Response"},
- /* 103-127 For future use */
+ /* PGW to SGSN/MME(S5, S4/S11) */
+ {103, "PGW Downlink Triggering Notification" },
+ {104, "PGW Downlink Triggering Acknowledge" },
+ /* 105-127 For future use */
/* MME to MME, SGSN to MME, MME to SGSN, SGSN to SGSN (S3/10/S16) */
{128, "Identification Request"},
{129, "Identification Response"},
{153, "Alert MME Notification"},
{154, "Alert MME Acknowledge"},
{155, "UE Activity Notification"},
- {156, "UE Activity Acknowledge"},
- /* 157 to 159 For future use */
+ {156, "UE Activity Acknowledge" },
+ {157, "ISR Status Indication" },
+ {158, "UE Registration Query Request" },
+ {159, "UE Registration Query Response" },
/* MME to SGW (S11) */
{160, "Create Forwarding Tunnel Request"},
{161, "Create Forwarding Tunnel Response"},
{235, "MBMS Session Stop Request"},
{236, "MBMS Session Stop Response"},
/* 237 to 239 For future use */
+ /* Reserved for Sv interface (see also types 25 to 31) TS 29.280 */
{240, "SRVCC CS to PS Response"}, /* 5.2.9 3GPP TS 29.280 V11.5.0 (2013-09) */
{241, "SRVCC CS to PS Complete Notification"}, /* 5.2.10 3GPP TS 29.280 V11.5.0 (2013-09) */
{242, "SRVCC CS to PS Complete Acknowledge"}, /* 5.2.11 3GPP TS 29.280 V11.5.0 (2013-09) */
#define GTPV2_IE_TRUST_WLAN_MODE_IND 174
#define GTPV2_IE_NODE_NUMBER 175
#define GTPV2_IE_NODE_IDENTIFIER 176
-#define GTPV2_IE_PRES_REP_AREA_ACT 177
-#define GTPV2_IE_PRES_REP_AREA_INF 178
+#define GTPV2_IE_PRES_REP_AREA_ACT 177
+#define GTPV2_IE_PRES_REP_AREA_INF 178
#define GTPV2_IE_TWAN_ID_TS 179
#define GTPV2_IE_OVERLOAD_CONTROL_INF 180
#define GTPV2_IE_LOAD_CONTROL_INF 181
#define GTPV2_IE_METRIC 182
#define GTPV2_IE_SEQ_NO 183
#define GTPV2_IE_APN_AND_REL_CAP 184
-
+/* 185: WLAN Offloadability Indication*/
+#define GTPV2_IE_PAGING_AND_SERVICE_INF 186
+#define GTPV2_IE_INTEGER_NUMBER 187
+/*
+188 Millisecond Time Stamp
+189 Monitoring Event Information
+190 ECGI List
+191 Remote UE Context
+192 Remote User ID
+193 Remote UE IP information
+194 CIoT Optimizations Support Indication
+195 SCEF PDN Connection
+196 Header Compression Configuration
+197 Extended Protocol Configuration Options (ePCO)
+198 Serving PLMN Rate Control
+199 Counter
+200 to 253 Spare. For future use.
+254 Special IE type for IE Type Extension
+255 Private Extension
+256 to 65535 Spare. For future use.
+
+*/
/* 169 to 254 reserved for future use */
#define GTPV2_IE_PRIVATE_EXT 255
{ 1, "International Mobile Subscriber Identity (IMSI)"}, /* Variable Length / 8.3 */
{ 2, "Cause"}, /* Variable Length / 8.4 */
{ 3, "Recovery (Restart Counter)"}, /* Variable Length / 8.5 */
- /* 4-34 Reserved for S101 interface Extendable / See 3GPP TS 29.276 [14] */
/* 4-34 Reserved for S101 interface Extendable / See 3GPP TS 29.276 [14] */
/* 35-50 / See 3GPP TS 29.276 */
/*Start SRVCC Messages ETSI TS 129 280 V10.1.0 (2011-06) 6.1*/
{182, "Metric"}, /* Fixed Length / 8.113 */
{183, "Sequence Number"}, /* Fixed Length / 8.114 */
{184, "APN and Relative Capacity"}, /* Extendable / 8.115 */
-
- /* 185 to 254 Spare. For future use. */
-
+ {185, "WLAN Offloadability Indication"}, /* Extendable / 8.116 */
+ {186, "Paging and Service Information"}, /* Extendable / 8.117 */
+ {187, "Integer Number" }, /* Variable / 8.118 */
+ {188, "Millisecond Time Stamp" }, /* Extendable / 8.119 */
+ {189, "Monitoring Event Information"}, /* Extendable / 8.120 */
+ {190, "ECGI List"}, /* Extendable / 8.121 */
+ {191, "Remote UE Context"}, /* Extendable / 8.122 */
+ {192, "Remote User ID"}, /* Extendable / 8.123 */
+ {193, "Remote UE IP information"}, /* Variable Length / 8.124 */
+ {194, "CIoT Optimizations Support Indication"}, /* Extendable / 8.125 */
+ {195, "SCEF PDN Connection"}, /* Extendable / 8.126 */
+ {196, "Header Compression Configuration"}, /* Extendable / 8.127 */
+ {197, "Extended Protocol Configuration Options(ePCO)"}, /* Variable Length / 8.128 */
+ {198, "Serving PLMN Rate Control"}, /* Extendable / 8.129 */
+ {199, "Counter" }, /* Extendable / 8.130 */
+ /* 1200 to 254 Spare. For future use. */
{255, "Private Extension"}, /* Variable Length / 8.67 */
{0, NULL}
};
static value_string_ext gtpv2_element_type_vals_ext = VALUE_STRING_EXT_INIT(gtpv2_element_type_vals);
+typedef struct _gtpv2_hdr {
+ guint8 flags; /* GTP header flags */
+ guint8 message; /* Message type */
+ guint16 length; /* Length of header */
+ gint64 teid; /* Tunnel End-point ID */
+} gtpv2_hdr_t;
+
+/* Data structure attached to a conversation,
+to keep track of request/response-pairs
+*/
+typedef struct gtpv2_conv_info_t {
+ wmem_map_t *unmatched;
+ wmem_map_t *matched;
+} gtpv2_conv_info_t;
+
+/*structure used to track responses to requests using sequence number*/
+typedef struct gtpv2_msg_hash_entry {
+ gboolean is_request; /*TRUE/FALSE*/
+ guint32 req_frame; /*frame with request */
+ nstime_t req_time; /*req time */
+ guint32 rep_frame; /*frame with reply */
+ gint seq_nr; /*sequence number*/
+ guint msgtype; /*messagetype*/
+} gtpv2_msg_hash_t;
+
+static guint
+gtpv2_sn_hash(gconstpointer k)
+{
+ const gtpv2_msg_hash_t *key = (const gtpv2_msg_hash_t *)k;
+
+ return key->seq_nr;
+}
+
+static gint
+gtpv2_sn_equal_matched(gconstpointer k1, gconstpointer k2)
+{
+ const gtpv2_msg_hash_t *key1 = (const gtpv2_msg_hash_t *)k1;
+ const gtpv2_msg_hash_t *key2 = (const gtpv2_msg_hash_t *)k2;
+
+ if (key1->req_frame && key2->req_frame && (key1->req_frame != key2->req_frame)) {
+ return 0;
+ }
+
+ if (key1->rep_frame && key2->rep_frame && (key1->rep_frame != key2->rep_frame)) {
+ return 0;
+ }
+
+ return key1->seq_nr == key2->seq_nr;
+}
+
+static gint
+gtpv2_sn_equal_unmatched(gconstpointer k1, gconstpointer k2)
+{
+ const gtpv2_msg_hash_t *key1 = (const gtpv2_msg_hash_t *)k1;
+ const gtpv2_msg_hash_t *key2 = (const gtpv2_msg_hash_t *)k2;
+
+ return key1->seq_nr == key2->seq_nr;
+}
+
/* Code to dissect IE's */
static void
-dissect_gtpv2_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
*/
static void
-dissect_gtpv2_imsi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_imsi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
const gchar *imsi_str;
};
static void
-dissect_gtpv2_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args)
{
int offset = 0;
guint8 tmp;
/* Cause value octet 5 */
tmp = tvb_get_guint8(tvb, offset);
+ if (g_gtp_session) {
+ args->last_cause = tmp;
+ }
proto_tree_add_item(tree, hf_gtpv2_cause, tvb, offset, 1, ENC_BIG_ENDIAN);
/* Add Cause to ie_tree */
* 8.5 Recovery (Restart Counter)
*/
static void
-dissect_gtpv2_recovery(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_recovery(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 recovery;
/* 6.2 STN-SR */
static void
-dissect_gtpv2_stn_sr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_stn_sr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_item *stn_sr_item;
proto_tree *sub_tree;
/* 6.3 Source to Target Transparent Container */
static void
-dissect_gtpv2_src_tgt_trans_con(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_src_tgt_trans_con(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
+ tvbuff_t *new_tvb;
+ proto_tree *sub_tree;
int offset = 0;
+
proto_tree_add_item(tree, hf_gtpv2_len_trans_con, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/*ra_type_flag = 0;*/
*/
proto_tree_add_item(tree, hf_gtpv2_transparent_container, tvb, offset, length-1, ENC_NA);
/*
- * bssmap_old_bss_to_new_bss_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo);
- * dissect_ranap_SourceRNC_ToTargetRNC_TransparentContainer_PDU
- */
+ * bssmap_old_bss_to_new_bss_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo);
+ * dissect_ranap_SourceRNC_ToTargetRNC_TransparentContainer_PDU
+ */
+ if (message_type == GTPV2_SRVCC_PS_TO_CS_REQUEST) {
+ sub_tree = proto_tree_add_subtree(tree, tvb, offset, length-1, ett_gtpv2_utran_con, NULL, "Source RNC to Target RNC Transparent Container");
+ new_tvb = tvb_new_subset_remaining(tvb, offset);
+ dissect_ranap_SourceRNC_ToTargetRNC_TransparentContainer_PDU(new_tvb, pinfo, sub_tree, NULL);
+ }
}
/* 6.4 Target to Source Transparent Container */
static void
-dissect_gtpv2_tgt_src_trans_con(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_tgt_src_trans_con(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type, guint8 instance _U_, session_args_t * args _U_)
{
+ tvbuff_t *new_tvb;
+ proto_tree *sub_tree;
int offset = 0;
+
proto_tree_add_item(tree, hf_gtpv2_len_trans_con, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* Transparent Container */
proto_tree_add_item(tree, hf_gtpv2_transparent_container, tvb, offset, length-1, ENC_NA);
+ if (message_type == GTPV2_SRVCC_PS_TO_CS_RESPONSE) {
+ sub_tree = proto_tree_add_subtree(tree, tvb, offset, length-1, ett_gtpv2_utran_con, NULL, "Target RNC to Source RNC Transparent Container");
+ new_tvb = tvb_new_subset_remaining(tvb, offset);
+ dissect_ranap_TargetRNC_ToSourceRNC_TransparentContainer_PDU(new_tvb, pinfo, sub_tree, NULL);
+ }
}
/* 6.5 MM Context for E-UTRAN SRVCC */
static void
-dissect_gtpv2_mm_con_eutran_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_con_eutran_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 elm_len;
/* 6.6 MM Context for UTRAN SRVCC */
static void
-dissect_gtpv2_mm_con_utran_srvcc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_con_utran_srvcc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 elm_len;
static value_string_ext gtpv2_srvcc_cause_vals_ext = VALUE_STRING_EXT_INIT(gtpv2_srvcc_cause_vals);
static void
-dissect_gtpv2_srvcc_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_srvcc_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 srvcc_cause;
* 6.8 Target RNC ID
*/
static void
-dissect_gtpv2_tgt_rnc_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_tgt_rnc_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint16 rnc_id;
* -- octets 6 and 7 Cell Identity (CI) according to TS 3GPP TS 24.008 [35]
*/
static void
-dissect_gtpv2_tgt_global_cell_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_tgt_global_cell_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 tgt_cell_id;
/* 6.10 Tunnel Endpoint Identifier for Control Plane (TEID-C) */
static void
-dissect_gtpv2_teid_c(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_teid_c(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* 6.11 Sv Flags */
static void
-dissect_gtpv2_sv_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_sv_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
proto_tree_add_item(tree, hf_gtpv2_sv_sti, tvb, offset, 1, ENC_BIG_ENDIAN);
/* 6.12 Service Area Identifier */
static void
-dissect_gtpv2_sai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_sai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* 6.13 MM Context for CS to PS SRVCC */
static void
-dissect_gtpv2_mm_ctx_for_cs_to_ps_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_ctx_for_cs_to_ps_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* subclauses 9.1.1 and 9.1.2, 3GPP TS 23.060 [35] Annex A and 3GPP TS 23.401 [3] subclauses 4.3.8.1.
*/
static void
-dissect_gtpv2_apn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_apn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 *apn = NULL;
*/
static void
-dissect_gtpv2_ambr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ambr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.8 EPS Bearer ID (EBI)
*/
static void
-dissect_gtpv2_ebi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ebi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.9 IP Address
*/
static void
-dissect_gtpv2_ip_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ip_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
*/
static void
-dissect_gtpv2_mei(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mei(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
const gchar *mei_str;
* Editor's note: MSISDN coding will be defined in TS 24.301.
*/
static void
-dissect_gtpv2_msisdn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_msisdn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
const char *digit_str;
* 8.12 Indication
*/
static void
-dissect_gtpv2_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* Octet 5 DAF DTF HI DFI OI ISRSI ISRAI SGWCI */
return;
}
- /* Octet 9 Spare Spare Spare Spare Spare PCRI AOSI AOPI */
+ /* Octet 9 NSI UASI DTCI BDWI PSCI PCRI AOSI AOPI */
+ proto_tree_add_item(tree, hf_gtpv2_nsi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_uasi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_dtci, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_bdwi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_psci, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_gtpv2_pcri, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_gtpv2_aosi, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_gtpv2_aopi, tvb, offset, 1, ENC_BIG_ENDIAN);
return;
}
+ /* Octet 10 ROAAI EPCOSI CPOPCI PMTSMI S11TF PNSI UNACCSI WPMSI */
+ proto_tree_add_item(tree, hf_gtpv2_roaai, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_epcosi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_cpopci, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_pmtsmi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_s11tf, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_pnsi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_unaccsi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_wpmsi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ if (length == 6){
+ return;
+ }
+
+ /*Octet 11 Spare Spare Spare Spare Spare Spare ENBCRSI TSPCMI */
+ proto_tree_add_item(tree, hf_gtpv2_enbcrsi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_tspcmi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ if (length == 7){
+ return;
+ }
+
proto_tree_add_expert_format(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, offset, -1, "The rest of the IE not dissected yet");
* Dissected in packet-gsm_a_gm.c
*/
static void
-dissect_gtpv2_pco(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_pco(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
switch (message_type) {
case GTPV2_CREATE_SESSION_REQUEST:
{1, "IPv4"},
{2, "IPv6"},
{3, "IPv4/IPv6"},
+ {4, "Non-IP"},
{0, NULL}
};
static void
-dissect_gtpv2_paa(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_paa(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 pdn_type;
*/
static void
-dissect_gtpv2_bearer_qos(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_bearer_qos(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
- proto_tree_add_item(tree, hf_gtpv2_bearer_qos_pvi, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(tree, hf_gtpv2_bearer_qos_pl, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_gtpv2_bearer_qos_pci, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_bearer_qos_pl, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_bearer_qos_pvi, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(tree, hf_gtpv2_bearer_qos_label_qci, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
*/
static void
-dissect_gtpv2_flow_qos(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_flow_qos(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
proto_tree_add_item(tree, hf_gtpv2_flow_qos_label_qci, tvb, offset, 1, ENC_BIG_ENDIAN);
{5, "HSPA Evolution"},
{6, "EUTRAN"},
{7, "Virtual"},
+ {8, "EUTRAN-NB-IoT"},
{0, NULL}
};
static value_string_ext gtpv2_rat_type_vals_ext = VALUE_STRING_EXT_INIT(gtpv2_rat_type_vals);
static void
-dissect_gtpv2_rat_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_rat_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
guint8 rat_type;
* 8.18 Serving Network
*/
static void
-dissect_gtpv2_serv_net(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_serv_net(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
gchar *mcc_mnc_str;
*/
static void
-dissect_gtpv2_bearer_tft(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_bearer_tft(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
/* The detailed coding of Traffic Aggregate
* Description is specified in 3GPP TS 24.008 [5] ,
/* 8.20 Traffic Aggregate Description (TAD)
*/
static void
-dissect_gtpv2_tad(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_tad(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
/* The detailed coding of Traffic Aggregate
* Description is specified in 3GPP TS 24.008 [5] ,
* It can be found in 3GPP TS 36.413 v8.3.0, but it is expected that it will be moved
* to 23.003 in a future version.
*/
-static gchar*
+gchar*
dissect_gtpv2_tai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int *offset)
{
gchar *str = NULL;
gchar *mcc_mnc_str;
guint16 tac;
- mcc_mnc_str = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, *offset, E212_NONE, TRUE);
+ mcc_mnc_str = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, *offset, E212_TAI, TRUE);
*offset += 3;
tac = tvb_get_ntohs(tvb, *offset);
proto_tree_add_item(tree, hf_gtpv2_tai_tac, tvb, *offset, 2, ENC_BIG_ENDIAN);
guint32 octet4;
guint8 spare;
guint32 ECGI;
+ const int* ECGI_flags[] = {
+ &hf_gtpv2_enodebid,
+ &hf_gtpv2_cellid,
+ NULL
+ };
- mcc_mnc_str = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, *offset, E212_NONE, TRUE);
+ mcc_mnc_str = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, *offset, E212_ECGI, TRUE);
*offset += 3;
/* The bits 8 through 5, of octet e+3 (Fig 8.21.5-1 in TS 29.274 V8.2.0) are spare
* and hence they would not make any difference to the hex string following it,
/* The coding of the E-UTRAN cell identifier is the responsibility of each administration.
* Coding using full hexadecimal representation shall be used.
*/
- proto_tree_add_uint(tree, hf_gtpv2_ecgi_eci, tvb, *offset, 4, ECGI);
- /*proto_tree_add_item(tree, hf_gtpv2_ecgi_eci, tvb, offset, 4, ENC_BIG_ENDIAN);*/
+ proto_tree_add_bitmask(tree, tvb, *offset, hf_gtpv2_ecgi_eci, ett_gtpv2_eci, ECGI_flags, ENC_BIG_ENDIAN);
*offset += 4;
str = wmem_strdup_printf(wmem_packet_scope(), "%s, ECGI 0x%x",
mcc_mnc_str,
gchar *mcc_mnc_str;
guint16 lac, ci;
- mcc_mnc_str = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, *offset, E212_NONE, TRUE);
+ mcc_mnc_str = dissect_e212_mcc_mnc_wmem_packet_str(tvb, pinfo, tree, *offset, E212_CGI, TRUE);
*offset += 3;
lac = tvb_get_ntohs(tvb, *offset);
proto_tree_add_item(tree, hf_gtpv2_uli_cgi_lac, tvb, *offset, 2, ENC_BIG_ENDIAN);
}
static void
-dissect_gtpv2_uli(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_uli(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree *flag_tree;
int offset = 0;
{35, "S2a TWAN GTP-C interface"},
{36, "S2a PGW GTP-C interface"},
{37, "S2a PGW GTP-U interface"},
+ {38, "S11 MME GTP-U interface"},
+ {39, "S11 SGW GTP-U interface"},
{0, NULL}
};
static value_string_ext gtpv2_f_teid_interface_type_vals_ext = VALUE_STRING_EXT_INIT(gtpv2_f_teid_interface_type_vals);
};
static void
-dissect_gtpv2_f_teid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_f_teid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t *args)
{
int offset = 0;
guint8 flags;
+ address *ipv4 = NULL, *ipv6 = NULL;
+ guint32 teid_cp, *teid, *session;
flags = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_gtpv2_f_teid_v4, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_gtpv2_f_teid_interface_type, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
- proto_tree_add_item(tree, hf_gtpv2_f_teid_gre_key, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_f_teid_gre_key, tvb, offset, 4, ENC_BIG_ENDIAN, &teid_cp);
proto_item_append_text(item, "%s, TEID/GRE Key: 0x%s",
val_to_str_ext_const((flags & 0x3f), >pv2_f_teid_interface_type_vals_ext, "Unknown"),
tvb_bytes_to_str(wmem_packet_scope(), tvb, offset, 4));
offset += 4;
if (flags & 0x80)
{
+ ipv4 = wmem_new0(wmem_packet_scope(), address);
proto_tree_add_item(tree, hf_gtpv2_f_teid_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
proto_item_append_text(item, ", IPv4 %s", tvb_ip_to_str(tvb, offset));
+ set_address_tvb(ipv4, AT_IPv4, 4, tvb, offset);
offset += 4;
}
if (flags & 0x40)
{
+ ipv6 = wmem_new0(wmem_packet_scope(), address);
proto_tree_add_item(tree, hf_gtpv2_f_teid_ipv6, tvb, offset, 16, ENC_NA);
proto_item_append_text(item, ", IPv6 %s", tvb_ip6_to_str(tvb, offset));
+ set_address_tvb(ipv6, AT_IPv6, 16, tvb, offset);
+ }
+
+ if (g_gtp_session) {
+ session = (guint32 *)g_hash_table_lookup(session_table, &pinfo->num);
+ if (!session) {
+ /* We save the teid so that we could assignate its corresponding session ID later */
+ args->last_teid = teid_cp;
+ if (!teid_exists(teid_cp, args->teid_list)) {
+ teid = wmem_new(wmem_packet_scope(), guint32);
+ *teid = teid_cp;
+ wmem_list_prepend(args->teid_list, teid);
+ }
+ if (ipv4 != NULL && !ip_exists(*ipv4, args->ip_list)) {
+ copy_address(&args->last_ip, ipv4);
+ wmem_list_prepend(args->ip_list, ipv4);
+ }
+ if (ipv6 != NULL && !ip_exists(*ipv6, args->ip_list)) {
+ copy_address(&args->last_ip, ipv6);
+ wmem_list_prepend(args->ip_list, ipv6);
+ }
+ }
}
}
/*
* 8.23 TMSI
*/
static void
-dissect_gtpv2_tmsi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_tmsi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_item(tree, hf_gtpv2_tmsi, tvb, 0, 4, ENC_BIG_ENDIAN);
proto_tree_add_item(item, hf_gtpv2_tmsi_bytes, tvb, 0, length, ENC_NA);
*/
static void
-dissect_gtpv2_g_cn_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_g_cn_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.25 S103 PDN Data Forwarding Info (S103PDF)
*/
static void
-dissect_gtpv2_s103pdf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_s103pdf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 m, k, i;
* 8.26 S1-U Data Forwarding (S1UDF)
*/
static void
-dissect_gtpv2_s1udf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_s1udf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 m;
*/
static void
-dissect_gtpv2_delay_value(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_delay_value(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
*/
static void
-dissect_gtpv2_bearer_ctx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_bearer_ctx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
tvbuff_t *new_tvb;
grouped_tree = proto_item_add_subtree(item, ett_gtpv2_bearer_ctx);
new_tvb = tvb_new_subset_length(tvb, offset, length);
- dissect_gtpv2_ie_common(new_tvb, pinfo, grouped_tree, 0, message_type);
+ dissect_gtpv2_ie_common(new_tvb, pinfo, grouped_tree, 0, message_type, args);
}
/* 8.29 Charging ID */
static void
-dissect_gtpv2_charging_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_charging_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* information element see 3GPP TS 32.298 [9].
*/
static void
-dissect_gtpv2_char_char(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_char_char(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.30 Bearer Flag
*/
static void
-dissect_gtpv2_bearer_flag(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_bearer_flag(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.34 PDN Type
*/
static void
-dissect_gtpv2_pdn_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_pdn_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.31 Trace Information
*/
static void
-dissect_gtpv2_tra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_tra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree *trigg_tree, *msc_server_tree, *mgw_tree, *sgsn_tree, *ggsn_tree;
proto_tree *bm_sc_tree, *sgw_mme_tree, *sgw_tree, *pgw_tree, *ne_types_tree;
lenb_tree = proto_tree_add_subtree(interfaces_tree, tvb, offset + 11, 1, ett_gtpv2_tra_info_interfaces_lpdn_lenb, NULL, "eNB");
- /* MSC Server - 2 octests */
+ /* MSC Server - 2 octets */
proto_tree_add_item(imsc_server_tree, hf_gtpv2_tra_info_lmsc_a, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(imsc_server_tree, hf_gtpv2_tra_info_lmsc_lu, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(imsc_server_tree, hf_gtpv2_tra_info_lmsc_mc, tvb, offset, 1, ENC_BIG_ENDIAN);
/* 8.35 Procedure Transaction ID (PTI) */
static void
-dissect_gtpv2_pti(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_pti(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_item(tree, hf_gtpv2_pti, tvb, 0, 1, ENC_BIG_ENDIAN);
}
* 8.36 DRX Parameter
*/
static void
-dissect_gtpv2_drx_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_drx_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* defined in 3GPP TS 24.301
*/
static void
-dissect_gtpv2_ue_net_capability(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ue_net_capability(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
de_emm_ue_net_cap(tvb, tree, pinfo, 0, length, NULL, 0);
{
proto_tree *auth_qui_tree;
int i;
- guint8 xres_len, autn_len;
+ guint32 tmp;
for (i = 0; i < nr_qui; i++) {
auth_qui_tree = proto_tree_add_subtree_format(tree, tvb, offset, 0,
*/
proto_tree_add_item(auth_qui_tree, hf_gtpv2_mm_context_rand, tvb, offset, 16, ENC_NA);
offset += 16;
- xres_len = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(auth_qui_tree, hf_gtpv2_mm_context_xres_len, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(auth_qui_tree, hf_gtpv2_mm_context_xres_len, tvb, offset, 1, ENC_NA, &tmp);
offset += 1;
- proto_tree_add_item(auth_qui_tree, hf_gtpv2_mm_context_xres, tvb, offset, xres_len, ENC_NA);
- offset += xres_len;
+ proto_tree_add_item(auth_qui_tree, hf_gtpv2_mm_context_xres, tvb, offset, tmp, ENC_NA);
+ offset += tmp;
proto_tree_add_item(auth_qui_tree, hf_gtpv2_ck, tvb, offset, 16, ENC_NA);
offset += 16;
proto_tree_add_item(auth_qui_tree, hf_gtpv2_ik, tvb, offset, 16, ENC_NA);
offset += 16;
- autn_len = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(auth_qui_tree, hf_gtpv2_mm_context_autn_len, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(auth_qui_tree, hf_gtpv2_mm_context_autn_len, tvb, offset, 1, ENC_NA, &tmp);
offset += 1;
- proto_tree_add_item(auth_qui_tree, hf_gtpv2_mm_context_autn, tvb, offset, autn_len, ENC_NA);
- offset += autn_len;
+ proto_tree_add_item(auth_qui_tree, hf_gtpv2_mm_context_autn, tvb, offset, tmp, ENC_NA);
+ offset += tmp;
}
return offset;
dissect_gtpv2_authentication_quadruplets(tvbuff_t *tvb, proto_tree *tree, int offset, guint8 nr_qui)
{
proto_tree *auth_qua_tree;
- guint8 tmp;
+ guint32 tmp;
int i;
for (i = 0; i < nr_qui; i++) {
- auth_qua_tree = proto_tree_add_subtree(tree, tvb, offset, 0,
- ett_gtpv2_mm_context_auth_qua, NULL, "Authentication Quadruplet");
+ auth_qua_tree = proto_tree_add_subtree_format(tree, tvb, offset, 0,
+ ett_gtpv2_mm_context_auth_qua, NULL, "Authentication Quadruplet %u",i+1);
proto_tree_add_item(auth_qua_tree, hf_gtpv2_mm_context_rand, tvb, offset, 16, ENC_NA);
offset += 16;
- tmp = tvb_get_guint8(tvb, offset++);
+ proto_tree_add_item_ret_uint(auth_qua_tree, hf_gtpv2_mm_context_xres_len, tvb, offset, 1, ENC_NA, &tmp);
+ offset++;
proto_tree_add_item(auth_qua_tree, hf_gtpv2_mm_context_xres, tvb, offset, tmp, ENC_NA);
offset += tmp;
- tmp = tvb_get_guint8(tvb, offset++);
+ proto_tree_add_item_ret_uint(auth_qua_tree, hf_gtpv2_mm_context_autn_len, tvb, offset, 1, ENC_NA, &tmp);
+ offset++;
proto_tree_add_item(auth_qua_tree, hf_gtpv2_mm_context_autn, tvb, offset, tmp, ENC_NA);
offset += tmp;
{
proto_tree *net_cap_tree, *msnt_cap_tree;
guint8 ue_net_cap_len, ms_net_cap_len, mei_len;
- guint32 tmp;
/*
* If SAMBRI (Subscribed UE AMBR Indicator), bit 1 of octet 6, is set to "1",
*/
if (samb_ri) {
/* j to (j+3) Uplink Subscribed UE AMBR */
- tmp = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint_format_value(tree, hf_gtpv2_uplink_subscribed_ue_ambr, tvb, offset, 4, tmp, "%d Kbps", tmp);
+ proto_tree_add_item(tree, hf_gtpv2_uplink_subscribed_ue_ambr, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
/* (j+4) to (j+7) Downlink Subscribed UE AMBR */
- tmp = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint_format_value(tree, hf_gtpv2_downlink_subscribed_ue_ambr, tvb, offset, 4, tmp, "%d Kbps", tmp);
+ proto_tree_add_item(tree, hf_gtpv2_downlink_subscribed_ue_ambr, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
*/
if (uamb_ri) {
/* i to (i+3) Uplink Used UE AMBR */
- tmp = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint_format_value(tree, hf_gtpv2_uplink_used_ue_ambr, tvb, offset, 4, tmp, "%d Kbps", tmp);
+ proto_tree_add_item(tree, hf_gtpv2_uplink_used_ue_ambr, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
/* (i+4) to (i+7) Downlink Used UE AMBR */
- tmp = tvb_get_ntohl(tvb, offset);
- proto_tree_add_uint_format_value(tree, hf_gtpv2_downlink_used_ue_ambr, tvb, offset, 4, tmp, "%d Kbps", tmp);
+ proto_tree_add_item(tree, hf_gtpv2_downlink_used_ue_ambr, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
}
accrstdata_tree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_gtpv2_access_rest_data, NULL, "Access restriction data");
/* Spare HNNA ENA INA GANA GENA UNA */
- proto_tree_add_bits_item(accrstdata_tree, hf_gtpv2_spare_bits, tvb, (offset << 3), 2, ENC_BIG_ENDIAN);
+ proto_tree_add_bits_item(accrstdata_tree, hf_gtpv2_spare_bits, tvb, (offset << 3), 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(accrstdata_tree, hf_gtpv2_hbna, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(accrstdata_tree, hf_gtpv2_hnna, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(accrstdata_tree, hf_gtpv2_ena, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(accrstdata_tree, hf_gtpv2_ina, tvb, offset, 1, ENC_BIG_ENDIAN);
* Figure 8.38-1: GSM Key and Triplets
*/
static void
-dissect_gtpv2_mm_context_gsm_t(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_context_gsm_t(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree *flag_tree;
int offset;
* Figure 8.38-2: UMTS Key, Used Cipher and Quintuplets
*/
static void
-dissect_gtpv2_mm_context_utms_cq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_context_utms_cq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree *flag_tree;
int offset;
* Figure 8.38-3: GSM Key, Used Cipher and Quintuplets
*/
static void
-dissect_gtpv2_mm_context_gsm_cq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_context_gsm_cq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree *flag_tree;
int offset;
* Figure 8.38-4: UMTS Key and Quintuplets
*/
static void
-dissect_gtpv2_mm_context_utms_q(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_context_utms_q(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree *flag_tree;
int offset;
* Figure 8.38-5: EPS Security Context and Quadruplets
*/
static void
-dissect_gtpv2_mm_context_eps_qq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_context_eps_qq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_item *qua_item, *qui_item;
proto_tree *flag_tree, *qua_tree, *qui_tree;
gint offset;
- guint8 tmp, nhi, drxi, nr_qua, nr_qui, uamb_ri, samb_ri, vdp_len;
+ guint8 tmp, nhi, drxi, nr_qua, nr_qui, uamb_ri, osci, samb_ri, vdp_len;
+ guint32 dword, paging_len;
offset = 0;
nr_qua = tmp & 0x1c;
nr_qua >>= 2;
uamb_ri = (tmp & 0x2) >> 1;
+ osci = tmp & 1;
proto_tree_add_item(flag_tree, hf_gtpv2_mm_context_nr_qui, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(flag_tree, hf_gtpv2_mm_context_nr_qua, tvb, offset, 1, ENC_BIG_ENDIAN);
/* Dissect octet j to r */
offset = dissect_gtpv2_mm_context_common_data(tvb, pinfo, tree, offset, samb_ri, uamb_ri);
- /* r+1 Spare HNNA ENA INA GANA GENA UNA */
+ /* r+1 Spare HBNA HNNA ENA INA GANA GENA UNA */
if (offset < (gint)length) {
offset = dissect_gtpv2_access_restriction_data(tvb, tree, offset);
} else {
return;
}
- /* r+2 Length of Voice Domain Preference and UE's Usage Setting */
+ /* the fields for the Old EPS Security Context (i.e. octets from s to s+64)
+ * may be present only in S10 Forward Relocation Request message according to
+ * the Rules on Concurrent Running of Security Procedures, which are specified in 3GPP TS 33.401 [12].
+ * The octets for Old EPS Security Context shall be present if the OSCI (Old Security Context Indicator),
+ * bit 1 of octet 6) is set to "1"; otherwise they shall not be present.
+ */
+ if (osci == 1) {
+ /* s */
+ /* If NHI_old (Next Hop Indicator for old EPS Security Context), bit 1 of octet s, is set to "1",
+ * then the parameters old NH (Next Hop) and old NCC (Next Hop Chaining Count) shall be present;
+ * otherwise the octets for old NH parameter shall not be present and the value of old NCC parameter
+ * shall be ignored by the receiver
+ */
+ /* NHI_old Spare old KSIASME old NCC*/
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_mm_contex_nhi_old, tvb, offset, 1, ENC_BIG_ENDIAN, &dword);
+ proto_tree_add_item(tree, hf_gtpv2_mm_context_old_ksiasme, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_mm_context_old_ncc, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ /* (s+1) to (s+32) old KASME */
+ proto_tree_add_item(tree, hf_gtpv2_mm_context_old_kasme, tvb, offset, 32, ENC_NA);
+ offset += 32;
+ /* (s+33) to (s+64) old NH */
+ if (dword) {
+ proto_tree_add_item(tree, hf_gtpv2_mm_context_old_nh, tvb, offset, 32, ENC_NA);
+ offset += 32;
+ }
+ }
+
+ if (offset == (gint)length) {
+ return;
+ }
+
+ /* w Length of Voice Domain Preference and UE's Usage Setting */
vdp_len = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_gtpv2_mm_context_vdp_len, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/* (r+3) to s Voice Domain Preference and UE's Usage Setting */
if (vdp_len) {
proto_tree_add_item(tree, hf_gtpv2_voice_domain_and_ue_usage_setting, tvb, offset, vdp_len, ENC_NA);
- /*offset += vdp_len;*/
+ offset += vdp_len;
}
+ if (offset == (gint)length) {
+ return;
+ }
+
+ /* (t+1) to (t+2) Length of UE Radio Capability for Paging information*/
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_mm_context_paging_len, tvb, offset, 2, ENC_BIG_ENDIAN, &paging_len);
+ offset += 2;
+
+ if (paging_len) {
+ proto_tree_add_item(tree, hf_gtpv2_ue_radio_capability_for_paging_information, tvb, offset, paging_len, ENC_NA);
+ offset +=paging_len;
+ }
+
+ if (offset < (gint)length){
+ proto_tree_add_expert_format(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, offset, length - offset, "The rest of the IE not dissected yet");
+ }
}
/*
* Figure 8.38-6: UMTS Key, Quadruplets and Quintuplets
*/
static void
-dissect_gtpv2_mm_context_utms_qq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mm_context_utms_qq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree *flag_tree;
guint32 offset;
if (offset >= (guint32)length) {
return;
}
- /* r+1 Spare HNNA ENA INA GANA GENA UNA */
+ /* r+1 Spare HBNA HNNA ENA INA GANA GENA UNA */
offset = dissect_gtpv2_access_restriction_data(tvb, tree, offset);
if (offset >= (guint32)length) {
* Length of Voice Domain Preference and UE's Usage Setting is zero, then the Voice Domain Preference and UE's Usage
* Setting parameter shall not be present.
*/
+ /* r+2 */
vdp_length = tvb_get_guint8(tvb, offset);
proto_tree_add_item(tree, hf_gtpv2_vdp_length, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
* 8.39 PDN Connection (grouped IE)
*/
static void
-dissect_gtpv2_PDN_conn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_PDN_conn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
proto_tree *grouped_tree;
grouped_tree = proto_item_add_subtree(item, ett_gtpv2_PDN_conn);
new_tvb = tvb_new_subset_length(tvb, offset, length);
- dissect_gtpv2_ie_common(new_tvb, pinfo, grouped_tree, offset, message_type);
+ dissect_gtpv2_ie_common(new_tvb, pinfo, grouped_tree, offset, message_type, args);
}
/*
* 8.40 PDU Numbers
*/
static void
-dissect_gtpv2_pdn_numbers(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_pdn_numbers(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_item *nsapi_ti;
proto_tree *nsapi_tree;
* 8.41 Packet TMSI (P-TMSI)
*/
static void
-dissect_gtpv2_p_tmsi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_p_tmsi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.42 P-TMSI Signature
*/
static void
-dissect_gtpv2_p_tmsi_sig(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_p_tmsi_sig(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.43 Hop Counter
*/
static void
-dissect_gtpv2_hop_counter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_hop_counter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 hop_counter;
{0, NULL}
};
static void
-dissect_gtpv2_ue_time_zone(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ue_time_zone(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.45 Trace Reference
*/
static void
-dissect_gtpv2_trace_reference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_trace_reference(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint32 trace_id;
{0, NULL }
};
static void
-dissect_complete_request_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_complete_request_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
tvbuff_t *new_tvb;
int offset;
* 8.47 GUTI
*/
static void
-dissect_gtpv2_guti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_guti(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
static void
-dissect_gtpv2_F_container(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type, guint8 instance _U_)
+dissect_gtpv2_F_container(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type, guint8 instance _U_, session_args_t * args _U_)
{
tvbuff_t *new_tvb;
proto_tree *sub_tree;
|| (message_type == GTPV2_CONTEXT_RESPONSE)
|| (message_type == GTPV2_RAN_INFORMATION_RELAY)) {
switch (container_type) {
+ case 1:
+ /* UTRAN transparent container (1)
+ * Contains the "Source to Target
+ * Transparent Container", if the message is used for PS
+ * handover to UTRAN Iu mode procedures, SRNS relocation
+ * procedure and E-UTRAN to UTRAN inter RAT handover
+ * procedure.
+ */
+ sub_tree = proto_tree_add_subtree(tree, tvb, offset, length, ett_gtpv2_utran_con, NULL, "UTRAN transparent container");
+ new_tvb = tvb_new_subset_remaining(tvb, offset);
+ dissect_ranap_Source_ToTarget_TransparentContainer_PDU(new_tvb, pinfo, sub_tree, NULL);
+ return;
case 2:
/* BSS container */
sub_tree = proto_tree_add_subtree(tree, tvb, offset, length, ett_gtpv2_bss_con, NULL, "BSS container");
proto_tree_add_item(sub_tree, hf_gtpv2_bss_con_xid, tvb, offset, xid_len, ENC_NA);
}
return;
+ case 3:
+ /* E-UTRAN transparent container
+ * This IE shall be included to contain the "Source to Target
+ * Transparent Container", if the message is used for
+ * UTRAN/GERAN to E-UTRAN inter RAT handover
+ * procedure, E-UTRAN intra RAT handover procedure and
+ * 3G SGSN to MME combined hard handover and SRNS
+ * relocation procedure. The Container Type shall be set to 3.
+ */
+ sub_tree = proto_tree_add_subtree(tree, tvb, offset, length, ett_gtpv2_eutran_con, NULL, "E-UTRAN transparent container");
+ proto_tree_add_expert(sub_tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, offset, length - offset);
+ return;
default:
break;
}
}
static void
-dissect_gtpv2_F_cause(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type, guint8 instance)
+dissect_gtpv2_F_cause(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type, guint8 instance, session_args_t * args _U_)
{
int offset = 0;
guint8 cause_type;
* +--+--+--+--+--+--+--+--+
*/
static void
-dissect_gtpv2_sel_plmn_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_sel_plmn_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
gchar *mcc_mnc_str;
}
static void
-dissect_gtpv2_target_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_target_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
tvbuff_t *new_tvb;
int offset = 0;
* 8.53 Packet Flow ID
*/
static void
-dissect_gtpv2_pkt_flow_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_pkt_flow_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.54 RAB Context
*/
static void
-dissect_gtpv2_rab_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_rab_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
* 8.55 Source RNC PDCP context info
*/
static void
-dissect_gtpv2_s_rnc_pdcp_ctx_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_s_rnc_pdcp_ctx_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_item(tree, hf_gtpv2_rrc_container, tvb, 0, length, ENC_NA);
}
* 8.56 UDP Source Port Number
*/
static void
-dissect_udp_s_port_nr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_udp_s_port_nr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_item(tree, hf_gtpv2_upd_source_port_number, tvb, 0, 2, ENC_BIG_ENDIAN);
proto_item_append_text(item, "%u", tvb_get_ntohs(tvb, 0));
* 8.57 APN Restriction
*/
static void
-dissect_gtpv2_apn_rest(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_apn_rest(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
guint8 type_value;
};
void
-dissect_gtpv2_selec_mode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_selec_mode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 ss_mode;
};
#endif
static void
-dissect_gtpv2_source_ident(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_source_ident(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 source_type;
};
static void
-dissect_gtpv2_bearer_control_mode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_bearer_control_mode(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
guint8 bcm;
};
static void
-dissect_gtpv2_cng_rep_act(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_cng_rep_act(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
guint8 action;
#endif
void
-dissect_gtpv2_fq_csid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_fq_csid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 octet, node_id_type, csids;
* 8.63 Channel needed
*/
static void
-dissect_gtpv2_channel_needed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_channel_needed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
/* The Channel needed shall be coded as depicted in Figure 8.63-1. Channel needed is coded as the IEI part and the value
* part of the Channel Needed IE defined in 3GPP TS 44.018[28]
* length indicator).
*/
static void
-dissect_gtpv2_emlpp_pri(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_emlpp_pri(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
be_emlpp_prio(tvb, tree, pinfo, 0, length, NULL, 0);
};
static void
-dissect_gtpv2_node_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_node_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
guint8 node_type;
* 8.66 Fully Qualified Domain Name (FQDN)
*/
static void
-dissect_gtpv2_fqdn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_fqdn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0, name_len, tmp;
guint8 *fqdn = NULL;
* 8.67 Private Extension
*/
static void
-dissect_gtpv2_private_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance)
+dissect_gtpv2_private_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance, session_args_t * args _U_)
{
int offset = 0;
tvbuff_t *next_tvb;
* 8.68 Transaction Identifier (TI)
*/
static void
-dissect_gtpv2_ti(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ti(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
/* 5 to (n+4) Transaction Identifier */
proto_tree_add_item(tree, hf_gtpv2_ti, tvb, 0, length, ENC_NA);
* 8.69 MBMS Session Duration
*/
void
-dissect_gtpv2_mbms_session_duration(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mbms_session_duration(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
int bit_offset = 0;
* 8.70 MBMS Service Area
*/
void
-dissect_gtpv2_mbms_service_area(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mbms_service_area(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
proto_item *sai_item;
* 8.71 MBMS Session Identifier
*/
static void
-dissect_gtpv2_mbms_session_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, _U_ guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mbms_session_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, _U_ guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* One octet OctetString. */
* 8.72 MBMS Flow Identifier
*/
static void
-dissect_gtpv2_mbms_flow_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mbms_flow_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* Two octets OctetString. */
};
static void
-dissect_gtpv2_mbms_ip_mc_dist(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mbms_ip_mc_dist(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
};
static void
-dissect_gtpv2_mbms_dist_ack(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mbms_dist_ack(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
};
static void
-dissect_gtpv2_uci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_uci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* 8.76 CSG Information Reporting Action */
static void
-dissect_gtpv2_csg_info_rep_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_csg_info_rep_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
/* 8.77 RFSP Index */
static void
-dissect_gtpv2_rfsp_index(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_rfsp_index(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* 8.78 CSG ID */
static void
-dissect_gtpv2_csg_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_csg_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ proto_tree_add_bits_item(tree, hf_gtpv2_spare_bits, tvb, 0, 5, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_csg_id, tvb, 0, 4, ENC_BIG_ENDIAN);
+ if (length > 1) {
+ proto_tree_add_item(tree, hf_gtpv2_spare_bytes, tvb, 1, length-1, ENC_NA);
+ }
}
/* 8.79 CSG Membership Indication (CMI) */
static void
-dissect_gtpv2_cmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_cmi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ proto_tree_add_bits_item(tree, hf_gtpv2_spare_bits, tvb, 0, 7, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_cmi, tvb, 0, 1, ENC_BIG_ENDIAN);
+ if (length > 1) {
+ proto_tree_add_item(tree, hf_gtpv2_spare_bytes, tvb, 1, length-1, ENC_NA);
+ }
}
/* 8.80 Service indicator */
+static const value_string gtpv2_service_indicator_vals[] = {
+ { 1, "CS call indicator" },
+ { 2, "SMS indicator" },
+ { 0, NULL }
+};
+
static void
-dissect_gtpv2_service_indicator(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_service_indicator(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ proto_tree_add_item(tree, hf_gtpv2_service_indicator, tvb, 0, 1, ENC_BIG_ENDIAN);
}
/* 8.81 Detach Type */
+static const value_string gtpv2_detach_type_vals[] = {
+ { 1, "PS Detach" },
+ { 2, "Combined PS/CS Detach" },
+ { 0, NULL }
+};
+
static void
-dissect_gtpv2_detach_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_detach_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ proto_tree_add_item(tree, hf_gtpv2_detach_type, tvb, 0, 1, ENC_BIG_ENDIAN);
}
/* 8.82 Local Distinguished Name (LDN) */
static void
-dissect_gtpv2_ldn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ldn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ proto_tree_add_item(tree, hf_gtpv2_ldn, tvb, 0, length, ENC_ASCII|ENC_NA);
}
/* 8.83 Node Features */
static void
-dissect_gtpv2_node_features(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_node_features(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
proto_tree_add_item(tree, hf_gtpv2_node_features_prn, tvb, offset, 1, ENC_BIG_ENDIAN);
* MBMS Time to Data Transfer
*/
void
-dissect_gtpv2_mbms_time_to_data_xfer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mbms_time_to_data_xfer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 binary_secs;
/* 8.85 Throttling */
static void
-dissect_gtpv2_throttling(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_throttling(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 oct;
/* 8.86 Allocation/Retention Priority (ARP) */
void
-dissect_gtpv2_arp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_arp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
};
void
-dissect_gtpv2_epc_timer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_epc_timer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_item(tree, hf_gtpv2_timer_unit, tvb, 0, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(tree, hf_gtpv2_timer_value, tvb, 0, 1, ENC_BIG_ENDIAN);
/* 8.88 Signalling Priority Indication */
static void
-dissect_gtpv2_sig_prio_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_sig_prio_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_item(tree, hf_gtpv2_lapi, tvb, 0, 1, ENC_BIG_ENDIAN);
}
/* 8.89 Temporary Mobile Group Identity (TMGI) */
static void
-dissect_gtpv2_tmgi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_tmgi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint64 tmgi;
* 3GPP TS 29.274 Figure 8.90-1
*/
static void
-dissect_gtpv2_add_mm_cont_for_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_add_mm_cont_for_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
proto_item *ms_cm_item;
/* 8.91 Additional flags for SRVCC */
static void
-dissect_gtpv2_add_flags_for_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_add_flags_for_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* 8.92 Max MBR/APN-AMBR (MMBR) */
static void
-dissect_gtpv2_mmbr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mmbr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint32 max_ul;
/* 8.93 MDT Configuration */
static void
-dissect_gtpv2_mdt_config(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mdt_config(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
/* 8.94 Additional Protocol Configuration Options (APCO) */
static void
-dissect_gtpv2_apco(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_apco(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
switch (message_type) {
case GTPV2_CREATE_SESSION_REQUEST:
/* 8.95 Absolute Time of MBMS Data Transfer */
static void
-dissect_gtpv2_abs_mbms_data_tf_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_abs_mbms_data_tf_time(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
const gchar *time_str;
};
static void
-dissect_gtpv2_henb_info_report(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_henb_info_report(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* 8.97 IPv4 Configuration Parameters (IP4CP) */
static void
-dissect_gtpv2_ip4cp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ip4cp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/* 8.98 Change to Report Flags */
static void
-dissect_gtpv2_change_report_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_change_report_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
static value_string_ext gtpv2_action_indication_vals_ext = VALUE_STRING_EXT_INIT(gtpv2_action_indication_vals);
static void
-dissect_gtpv2_action_indication(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_action_indication(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
/*
* 8.100 TWAN Identifier
*/
+static const value_string gtpv2_twan_relay_id_type_vals[] = {
+ { 0, "IPv4 or IPv6 Address" },
+ { 1, "FQDN" },
+ { 0, NULL }
+};
static void
-dissect_gtpv2_twan_Identifier(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_twan_identifier(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ int offset = 0;
+ guint8 flags=0;
+ guint32 ssid_len, civa_len, op_name_len, relay_id_type, relay_id_len, circuit_id_id_len;
+ const int* twan_id_flags[] = {
+ &hf_gtpv2_twan_laii,
+ &hf_gtpv2_twan_opnai,
+ &hf_gtpv2_twan_plmni,
+ &hf_gtpv2_twan_civai,
+ &hf_gtpv2_twan_bssidi,
+ NULL
+ };
+
+ /* Octet 5 Spare LAII OPNAI PLMNI CIVAI BSSIDI */
+ flags = tvb_get_guint8(tvb, offset);
+ proto_tree_add_bitmask(tree, tvb, offset, hf_gtpv2_twan_flags, ett_gtpv2_twan_flags, twan_id_flags, ENC_BIG_ENDIAN);
+ offset++;
+ /* Octet 6 SSID Length */
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_twan_ssid_len, tvb, offset, 1, ENC_BIG_ENDIAN, &ssid_len);
+ offset += 1;
+ /* 7 to k SSID */
+ proto_tree_add_item(tree, hf_gtpv2_twan_ssid, tvb, offset, ssid_len, ENC_NA);
+ offset += ssid_len;
+ /* (k+1) to (k+6) BSSID The BSSIDI flag in octet 5 indicates whether the BSSID in octets 'k+1' to 'k+6' shall be present.*/
+ if (flags & 0x01) {
+ proto_tree_add_item(tree, hf_gtpv2_twan_bssid, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ }
+ /* q Civic Address Length The CIVAI flag in octet 5 indicates whether the Civic Address Length
+ * and Civic Address Information in octets 'q' and 'q+1' to 'q+r' shall be present.
+ */
+ if (flags & 0x02) {
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_twan_civa_len, tvb, offset, 1, ENC_BIG_ENDIAN, &civa_len);
+ offset += 1;
+ /* (q+1) to (q+r) Civic Address Information
+ * ...it shall be encoded as defined in subclause 3.1 of IETF RFC 4776 [59] excluding the first 3 octets.
+ * RFC 4776:
+ * 3.1. Overall Format for DHCPv4
+
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | GEOCONF_CIVIC | N | what | country |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | code | civic address elements ...
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ proto_tree_add_item(tree, hf_gtpv2_twan_civa, tvb, offset, civa_len, ENC_NA);
+ offset += civa_len;
+ }
+ /* s to (s+3) TWAN PLMN-ID The PLMNI flag in octet 5 indicates whether the TWAN PLMN-ID
+ * in octets 's' to 's+3' shall be present
+ */
+ if (flags & 0x04) {
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_twan_plmnid, tvb, offset, 3, ENC_BIG_ENDIAN, &civa_len);
+ offset += 3;
+ /* (q+1) to (q+r) Civic Address Information
+ * ...it shall be encoded as defined in subclause 3.1 of IETF RFC 4776 [59] excluding the first 3 octets.
+ */
+ }
+ /* t TWAN Operator Name Length, The OPNAI flag in octet 5 indicates whether the TWAN Operator Name Length and
+ * TWAN Operator Name in octets 't' and 't+1' to 't+u' shall be present.
+ */
+ if (flags & 0x08) {
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_twan_op_name_len, tvb, offset, 1, ENC_BIG_ENDIAN, &op_name_len);
+ offset += 1;
+ /* (t+1) to (t+u) TWAN Operator Name. The TWAN Operator Name shall be encoded as specified in subclause 19. 8 of 3GPP TS 23.003 */
+ proto_tree_add_item(tree, hf_gtpv2_twan_op_name, tvb, offset, op_name_len, ENC_NA);
+ offset += op_name_len;
+ }
+ /* The LAII flag in octet 5 indicates whether the Logical Access ID information is present in the TWAN Identifier */
+ if (flags & 0x10) {
+ /* v Relay Identity Type */
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_twan_relay_id_type, tvb, offset, 1, ENC_BIG_ENDIAN, &relay_id_type);
+ offset += 1;
+ /* (v+1) Relay Identity Length*/
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_twan_relay_id_len, tvb, offset, 1, ENC_BIG_ENDIAN, &relay_id_len);
+ offset += 1;
+ /* (v+2) to (v+w) Relay Identity */
+ switch (relay_id_type) {
+ case 0:
+ /* IPv4 or IPv6 Address */
+ if (relay_id_len == 4) {
+ /* IPv4 */
+ proto_tree_add_item(tree, hf_gtpv2_twan_relay_id_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ } else {
+ proto_tree_add_item(tree, hf_gtpv2_twan_relay_id_ipv6, tvb, offset, 16, ENC_NA);
+ offset += 16;
+ }
+ break;
+ case 1:
+ /* fall trough */
+ proto_tree_add_item(tree, hf_gtpv2_twan_relay_id, tvb, offset, relay_id_len, ENC_NA);
+ offset += relay_id_len;
+ default:
+ break;
+ }
+ /* X Circuit-ID Length */
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_twan_circuit_id_len, tvb, offset, 1, ENC_BIG_ENDIAN, &circuit_id_id_len);
+ offset += 1;
+ /* (x+1) to (x+y) Circuit-ID */
+ proto_tree_add_item(tree, hf_gtpv2_twan_circuit_id, tvb, offset, circuit_id_id_len, ENC_NA);
+ offset += circuit_id_id_len;
+ }
+
+ if (offset < (gint)length) {
+ proto_tree_add_expert_format(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, offset, -1, "The rest of the IE not dissected yet");
+ }
+
}
/*
* 8.101 ULI Timestamp
*/
static void
-dissect_gtpv2_uli_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_uli_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
const gchar *time_str;
*/
time_str = tvb_ntp_fmt_ts_sec(tvb, 0);
- proto_tree_add_string(tree, hf_gtpv2_uli_timestamp, tvb, 0, 8, time_str);
+ proto_tree_add_string(tree, hf_gtpv2_uli_timestamp, tvb, 0, 4, time_str);
proto_item_append_text(item, "%s", time_str);
}
* 8.102 MBMS Flags
*/
static void
-dissect_gtpv2_mbms_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_mbms_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
* 8.103 RAN/NAS Cause
*/
static void
-dissect_gtpv2_ran_nas_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_ran_nas_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
* 8.104 CN Operator Selection Entity
*/
static void
-dissect_gtpv2_cn_operator_selection_entity(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_cn_operator_selection_entity(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
* 8.105 Trusted WLAN Mode Indication
*/
static void
-dissect_gtpv2_trust_wlan_mode_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_trust_wlan_mode_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
* 8.106 Node Number
*/
static void
-dissect_gtpv2_node_number(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_node_number(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
* 8.107 Node Identifier
*/
static void
-dissect_gtpv2_node_identifier(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_node_identifier(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
}
};
static void
-dissect_gtpv2_pres_rep_area_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_pres_rep_area_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
tvbuff_t * new_tvb;
if (length == 1)
return;
/* Octet 6 to 8 Presence Reporting Area Identifier */
- proto_tree_add_item(tree, hf_gtpv2_pres_rep_area_id, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset+=2;
- if (length == 3)
+ proto_tree_add_item(tree, hf_gtpv2_pres_rep_area_id, tvb, offset, 3, ENC_BIG_ENDIAN);
+ offset+=3;
+ if (length == 4)
return;
- new_tvb = tvb_new_subset_length(tvb, offset, length-3);
+ new_tvb = tvb_new_subset_length(tvb, offset, length-4);
/* Share the rest of the dissection with the AVP dissector */
dissect_diameter_3gpp_presence_reporting_area_elements_list(new_tvb, pinfo, tree, NULL);
* 8.109 Presence Reporting Area Information
*/
static void
-dissect_gtpv2_pres_rep_area_information(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_pres_rep_area_information(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ int offset = 0;
+
+ /*Octet 5 to 7 Presence Reporting Area Identifier */
+ proto_tree_add_item(tree, hf_gtpv2_pres_rep_area_info_id, tvb, offset, 3 , ENC_BIG_ENDIAN);
+ offset+=3;
+
+ proto_tree_add_item(tree, hf_gtpv2_pres_rep_area_info_opra, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_gtpv2_pres_rep_area_info_ipra, tvb, offset, 1, ENC_BIG_ENDIAN);
}
/*
* 8.110 TWAN Identifier Timestamp
*/
static void
-dissect_gtpv2_twan_identifier_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_twan_identifier_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ const gchar *time_str;
+
+ /* TWAN Identifier Timestamp value */
+ /* Octets 5 to 8 are encoded in the same format as the first four octets of the 64-bit timestamp
+ * format as defined in section 6 of IETF RFC 5905
+ */
+
+ time_str = tvb_ntp_fmt_ts_sec(tvb, 0);
+ proto_tree_add_string(tree, hf_gtpv2_twan_id_ts, tvb, 0, 4, time_str);
+ proto_item_append_text(item, "%s", time_str);
+
}
/*
* 8.111 Overload Control Information
*/
static void
-dissect_gtpv2_overload_control_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_overload_control_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
grouped_tree = proto_item_add_subtree(item, ett_gtpv2_overload_control_information);
new_tvb = tvb_new_subset_length(tvb, offset, length);
- dissect_gtpv2_ie_common(new_tvb, pinfo, grouped_tree, offset, message_type);
+ dissect_gtpv2_ie_common(new_tvb, pinfo, grouped_tree, offset, message_type, args);
}
/*
* 8.112 Load Control Information
*/
static void
-dissect_gtpv2_load_control_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_load_control_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, proto_item *item, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_expert(tree, pinfo, &ei_gtpv2_ie_data_not_dissected, tvb, 0, length);
+ int offset = 0;
+ tvbuff_t *new_tvb;
+ proto_tree *grouped_tree;
+
+ proto_item_append_text(item, "[Grouped IE]");
+ grouped_tree = proto_item_add_subtree(item, ett_gtpv2_load_control_inf);
+
+ new_tvb = tvb_new_subset_length(tvb, offset, length);
+ dissect_gtpv2_ie_common(new_tvb, pinfo, grouped_tree, 0, message_type, args);
}
/*
* 8.113 Metric
*/
static void
-dissect_gtpv2_metric(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_metric(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- guint8 oct;
+ guint32 oct;
- oct = tvb_get_guint8(tvb, 0);
- proto_tree_add_item(tree, hf_gtpv2_metric, tvb, 0, 1, ENC_BIG_ENDIAN);
- if(oct > 0x64)
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_metric, tvb, 0, 1, ENC_BIG_ENDIAN, &oct);
+ if (oct > 0x64) {
proto_item_append_text(item, "Metric: value beyond 100 is considered as 0");
+ } else {
+ proto_item_append_text(item, "%u", oct);
+
+ }
}
/*
* 8.114 Sequence Number
*/
static void
-dissect_gtpv2_seq_no(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_seq_no(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
- proto_tree_add_item(tree, hf_gtpv2_sequence_number, tvb, 0, 4, ENC_BIG_ENDIAN);
+ guint32 seq;
+ proto_tree_add_item_ret_uint(tree, hf_gtpv2_sequence_number, tvb, 0, 4, ENC_BIG_ENDIAN, &seq);
+ proto_item_append_text(item, "%u", seq);
}
/*
* 8.115 APN and Relative Capacity
*/
static void
-dissect_gtpv2_apn_and_relative_capacity(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_)
+dissect_gtpv2_apn_and_relative_capacity(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
{
int offset = 0;
guint8 oct, apn_length;
proto_tree_add_string(tree, hf_gtpv2_apn, tvb, offset, apn_length, apn);
}
+}
+/*
+ * 8.117 Paging and Service Information
+ */
+static void
+dissect_gtpv2_paging_and_service_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
+{
+ int offset = 0;
+ guint8 ppi_flag;
+
+ /* Spare (all bits set to 0) B8 - B5 */
+ proto_tree_add_bits_item(tree, hf_gtpv2_spare_bits, tvb, offset, 4, ENC_BIG_ENDIAN);
+ /* EPS Bearer ID (EBI) B4 - B1 */
+ proto_tree_add_item(tree, hf_gtpv2_ebi, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ /* Spare B8 - B2 */
+ proto_tree_add_bits_item(tree, hf_gtpv2_spare_bits, tvb, offset << 3, 7, ENC_BIG_ENDIAN);
+ /* Paging Policy Indication flag (PPI) */
+ ppi_flag = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_gtpv2_ppi_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ if(ppi_flag & 1){
+ /* Spare B8 - B7 */
+ proto_tree_add_bits_item(tree, hf_gtpv2_spare_bits, tvb, offset << 3, 2, ENC_BIG_ENDIAN);
+ /* Paging Policy Indication Value */
+ proto_item_append_text(tree, " (PPI Value: %s)", val_to_str_ext_const(tvb_get_guint8(tvb, offset), &dscp_vals_ext, "Unknown"));
+ proto_tree_add_item(tree, hf_gtpv2_ppi_value, tvb, offset, 1, ENC_BIG_ENDIAN);
+ }
+}
+/*
+ * 8.118 Integer Number
+ */
+static void
+dissect_gtpv2_integer_number(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length, guint8 message_type _U_, guint8 instance _U_, session_args_t * args _U_)
+{
+ int offset = 0;
+ /* The Integer Number value shall be encoded as further described below for the following information elements:
+ * Maximum Wait Time IE: the length shall be set to 2, i.e. the integer number value shall be encoded as a 16 bit unsigned integer.
+ * DL Buffering Suggested Packet Count IE: the length shall be set to 1 or 2;
+ * UE Usage Type IE: the length shall be set to 1, i.e. the integer number value shall be encoded as a 8 bit unsigned integer as specified in subclause 7.3.202 of 3GPP TS 29.272 [70].
+ */
+ if (length <= 4) {
+ /* Only handle up to 32 bits for now */
+ proto_tree_add_item(tree, hf_gtpv2_integer_number_val, tvb, offset, length, ENC_BIG_ENDIAN);
+ } else {
+ /* value not handled, yet*/
+ proto_tree_add_expert(tree, pinfo, &ei_gtpv2_int_size_not_handled, tvb, offset, length);
+
+ }
+
}
typedef struct _gtpv2_ie {
int ie_type;
- void (*decode) (tvbuff_t *, packet_info *, proto_tree *, proto_item *, guint16, guint8, guint8);
+ void (*decode) (tvbuff_t *, packet_info *, proto_tree *, proto_item *, guint16, guint8, guint8, session_args_t *);
} gtpv2_ie_t;
static const gtpv2_ie_t gtpv2_ies[] = {
{GTPV2_IE_IP4CP, dissect_gtpv2_ip4cp}, /* 166, 8.97 IPv4 Configuration Parameters (IPv4CP) */
{GTPV2_IE_CHANGE_TO_REPORT_FLAGS, dissect_gtpv2_change_report_flags}, /* 167, 8.98 Change to Report Flags */
{GTPV2_IE_ACTION_INDICATION, dissect_gtpv2_action_indication}, /* 168, 8.99 Action Indication */
- {GTPV2_IE_TWAN_IDENTIFIER, dissect_gtpv2_twan_Identifier}, /* 169, 8.100 TWAN Identifier */
+ {GTPV2_IE_TWAN_IDENTIFIER, dissect_gtpv2_twan_identifier}, /* 169, 8.100 TWAN Identifier */
{GTPV2_IE_ULI_TIMESTAMP, dissect_gtpv2_uli_timestamp}, /* 170, 8.101 ULI Timestamp */
{GTPV2_IE_MBMS_FLAGS, dissect_gtpv2_mbms_flags}, /* 171, 8.102 MBMS Flags */
{GTPV2_IE_RAN_NAS_CAUSE, dissect_gtpv2_ran_nas_cause}, /* 172, 8.103 RAN/NAS Cause */
{GTPV2_IE_METRIC, dissect_gtpv2_metric}, /* 182, 8.113 Metric */
{GTPV2_IE_SEQ_NO, dissect_gtpv2_seq_no}, /* 183, 8.114 Sequence Number */
{GTPV2_IE_APN_AND_REL_CAP, dissect_gtpv2_apn_and_relative_capacity}, /* 184, 8.115 APN and Relative Capacity */
+ /* 185, 8.116 WLAN Offloadability Indication */
+
+ {GTPV2_IE_PAGING_AND_SERVICE_INF, dissect_gtpv2_paging_and_service_inf}, /* 186, 8.117 Paging and Service Information */
+ { GTPV2_IE_INTEGER_NUMBER, dissect_gtpv2_integer_number }, /* 187, 8.118 Integer Number */
+ /* 188, 8.119 Millisecond Time Stamp */
+ /* 189, 8.120 Monitoring Event Information */
+ /* 190, 8.121 ECGI List */
+ /* 191, 8.122 Remote UE Context */
+ /* 192, 8.123 Remote User ID */
+ /* 193, 8.124 Remote UE IP Information */
+ /* 194, 8.125 CIoT Optimizations Support Indication */
+ /* 195, 8.126 SCEF PDN Connection */
+ /* 196, 8.127 Header Compression Configuration */
+ /* 197, 8.128 Extended Protocol Configuration Options (ePCO) */
+ /* 198, 8.129 Serving PLMN Rate Control */
{GTPV2_IE_PRIVATE_EXT, dissect_gtpv2_private_ext},
{0, dissect_gtpv2_unknown}
};
+static gtpv2_msg_hash_t *
+gtpv2_match_response(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gint seq_nr, guint msgtype, gtpv2_conv_info_t *gtpv2_info, guint8 last_cause)
+{
+ gtpv2_msg_hash_t gcr, *gcrp = NULL;
+ guint32 *session;
+ gcr.seq_nr = seq_nr;
+
+ switch (msgtype) {
+ case GTPV2_CREATE_SESSION_REQUEST:
+ case GTPV2_CREATE_BEARER_REQUEST:
+ case GTPV2_UPDATE_BEARER_REQUEST:
+ case GTPV2_MODIFY_BEARER_REQUEST:
+ case GTPV2_DELETE_BEARER_REQUEST:
+ case GTPV2_DELETE_SESSION_REQUEST:
+ case GTPV2_MODIFY_BEARER_COMMAND:
+ case GTPV2_DELETE_BEARER_COMMAND:
+ case GTPV2_BEARER_RESOURCE_COMMAND:
+ gcr.is_request = TRUE;
+ gcr.req_frame = pinfo->num;
+ gcr.rep_frame = 0;
+ break;
+ case GTPV2_CREATE_SESSION_RESPONSE:
+ case GTPV2_CREATE_BEARER_RESPONSE:
+ case GTPV2_UPDATE_BEARER_RESPONSE:
+ case GTPV2_MODIFY_BEARER_RESPONSE:
+ case GTPV2_DELETE_BEARER_RESPONSE:
+ case GTPV2_DELETE_SESSION_RESPONSE:
+ case GTPV2_MODIFY_BEARER_FAILURE_INDICATION:
+ case GTPV2_DELETE_BEARER_FAILURE_INDICATION:
+ case GTPV2_BEARER_RESOURCE_FAILURE_INDICATION:
+ gcr.is_request = FALSE;
+ gcr.req_frame = 0;
+ gcr.rep_frame = pinfo->num;
+ break;
+ default:
+ gcr.is_request = FALSE;
+ gcr.req_frame = 0;
+ gcr.rep_frame = 0;
+ break;
+ }
+
+ gcrp = (gtpv2_msg_hash_t *)wmem_map_lookup(gtpv2_info->matched, &gcr);
+
+ if (gcrp) {
+ gcrp->is_request = gcr.is_request;
+ } else {
+ /*no match, let's try to make one*/
+ switch (msgtype) {
+ case GTPV2_CREATE_SESSION_REQUEST:
+ case GTPV2_CREATE_BEARER_REQUEST:
+ case GTPV2_UPDATE_BEARER_REQUEST:
+ case GTPV2_MODIFY_BEARER_REQUEST:
+ case GTPV2_DELETE_BEARER_REQUEST:
+ case GTPV2_DELETE_SESSION_REQUEST:
+ case GTPV2_MODIFY_BEARER_COMMAND:
+ case GTPV2_DELETE_BEARER_COMMAND:
+ case GTPV2_BEARER_RESOURCE_COMMAND:
+ gcr.seq_nr = seq_nr;
+
+ gcrp = (gtpv2_msg_hash_t *)wmem_map_lookup(gtpv2_info->unmatched, &gcr);
+ if (gcrp) {
+ wmem_map_remove(gtpv2_info->unmatched, gcrp);
+ }
+ /* if we can't reuse the old one, grab a new chunk */
+ if (!gcrp) {
+ gcrp = wmem_new(wmem_file_scope(), gtpv2_msg_hash_t);
+ }
+ gcrp->seq_nr = seq_nr;
+ gcrp->req_frame = pinfo->num;
+ gcrp->req_time = pinfo->abs_ts;
+ gcrp->rep_frame = 0;
+ gcrp->msgtype = msgtype;
+ gcrp->is_request = TRUE;
+ wmem_map_insert(gtpv2_info->unmatched, gcrp, gcrp);
+ return NULL;
+ break;
+ case GTPV2_CREATE_SESSION_RESPONSE:
+ case GTPV2_CREATE_BEARER_RESPONSE:
+ case GTPV2_UPDATE_BEARER_RESPONSE:
+ case GTPV2_MODIFY_BEARER_RESPONSE:
+ case GTPV2_DELETE_BEARER_RESPONSE:
+ case GTPV2_DELETE_SESSION_RESPONSE:
+ case GTPV2_MODIFY_BEARER_FAILURE_INDICATION:
+ case GTPV2_DELETE_BEARER_FAILURE_INDICATION:
+ case GTPV2_BEARER_RESOURCE_FAILURE_INDICATION:
+ gcr.seq_nr = seq_nr;
+ gcrp = (gtpv2_msg_hash_t *)wmem_map_lookup(gtpv2_info->unmatched, &gcr);
+
+ if (gcrp) {
+ if (!gcrp->rep_frame) {
+ wmem_map_remove(gtpv2_info->unmatched, gcrp);
+ gcrp->rep_frame = pinfo->num;
+ gcrp->is_request = FALSE;
+ wmem_map_insert(gtpv2_info->matched, gcrp, gcrp);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* we have found a match */
+ if (gcrp) {
+ proto_item *it;
+
+ if (gcrp->is_request) {
+ it = proto_tree_add_uint(tree, hf_gtpv2_response_in, tvb, 0, 0, gcrp->rep_frame);
+ PROTO_ITEM_SET_GENERATED(it);
+ } else {
+ nstime_t ns;
+
+ it = proto_tree_add_uint(tree, hf_gtpv2_response_to, tvb, 0, 0, gcrp->req_frame);
+ PROTO_ITEM_SET_GENERATED(it);
+ nstime_delta(&ns, &pinfo->abs_ts, &gcrp->req_time);
+ it = proto_tree_add_time(tree, hf_gtpv2_response_time, tvb, 0, 0, &ns);
+ PROTO_ITEM_SET_GENERATED(it);
+ if (g_gtp_session && !PINFO_FD_VISITED(pinfo)) {
+ /* GTP session */
+ /* If it's not already in the list */
+ session = (guint32 *)g_hash_table_lookup(session_table, &pinfo->num);
+ if (!session) {
+ session = (guint32 *)g_hash_table_lookup(session_table, &gcrp->req_frame);
+ if (session != NULL) {
+ add_gtp_session(pinfo->num, *session);
+ }
+ }
+
+ if (!is_cause_accepted(last_cause, 2)){
+ /* If the cause is not accepted then we have to remove all the session information about its corresponding request */
+ remove_frame_info(&gcrp->req_frame);
+ }
+ }
+ }
+ }
+ return gcrp;
+}
+
static void
-dissect_gtpv2_ie_common(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gint offset, guint8 message_type)
+track_gtpv2_session(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gtpv2_hdr_t * gtpv2_hdr, wmem_list_t *teid_list, wmem_list_t *ip_list, guint32 last_teid _U_, address last_ip _U_)
+{
+ guint32 *session, frame_teid_cp;
+ proto_item *it;
+
+ /* GTP session */
+ if (tree) {
+ session = (guint32*)g_hash_table_lookup(session_table, &pinfo->num);
+ if (session) {
+ it = proto_tree_add_uint(tree, hf_gtpv2_session, tvb, 0, 0, *session);
+ PROTO_ITEM_SET_GENERATED(it);
+ }
+ }
+
+ if (!PINFO_FD_VISITED(pinfo)) {
+ /* If the message does not have any session ID */
+ session = (guint32*)g_hash_table_lookup(session_table, &pinfo->num);
+ if (!session) {
+ /* If the message is not a CSESRES, CSESREQ, UBEAREQ, UBEARES, CBEAREQ, CBEARES, MBEAREQ or MBEARES then we remove its information from teid and ip lists */
+ if ((gtpv2_hdr->message != GTPV2_CREATE_SESSION_RESPONSE && gtpv2_hdr->message != GTPV2_CREATE_SESSION_REQUEST && gtpv2_hdr->message != GTPV2_UPDATE_BEARER_RESPONSE
+ && gtpv2_hdr->message != GTPV2_UPDATE_BEARER_REQUEST && gtpv2_hdr->message != GTPV2_CREATE_BEARER_REQUEST && gtpv2_hdr->message != GTPV2_CREATE_BEARER_RESPONSE
+ && gtpv2_hdr->message != GTPV2_MODIFY_BEARER_REQUEST && gtpv2_hdr->message != GTPV2_MODIFY_BEARER_RESPONSE)) {
+ /* If the lists are not empty*/
+ if (wmem_list_count(teid_list) && wmem_list_count(ip_list)) {
+ remove_frame_info(&pinfo->num);
+ }
+ }
+
+ if (gtpv2_hdr->message == GTPV2_CREATE_SESSION_REQUEST){
+ /* If CPDPCREQ and not already in the list then we create a new session*/
+ add_gtp_session(pinfo->num, gtp_session_count++);
+ }
+ else if (gtpv2_hdr->message != GTPV2_CREATE_SESSION_RESPONSE) {
+ /* We have to check if its teid == teid_cp and ip.dst == gsn_ipv4 from the lists, if that is the case then we have to assign
+ the corresponding session ID */
+ const address * dst_address;
+ address gsn_address;
+ dst_address = &pinfo->dst;
+ copy_address(&gsn_address, dst_address);
+ if ((get_frame(gsn_address, (guint32)gtpv2_hdr->teid, &frame_teid_cp) == 1)) {
+ /* Then we have to set its session ID */
+ session = (guint32*)g_hash_table_lookup(session_table, &frame_teid_cp);
+ if (session != NULL) {
+ /* We add the corresponding session to the list so that when a response came we can associate its session ID*/
+ add_gtp_session(pinfo->num, *session);
+ }
+ }
+ }
+ }
+ }
+}
+
+static void
+dissect_gtpv2_ie_common(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gint offset, guint8 message_type, session_args_t * args)
{
proto_tree *ie_tree;
proto_item *ti;
}
/* Just give the IE dissector the IE */
ie_tvb = tvb_new_subset_remaining(tvb, offset);
- (*gtpv2_ies[i].decode) (ie_tvb, pinfo , ie_tree, ti, length, message_type, instance);
+ (*gtpv2_ies[i].decode) (ie_tvb, pinfo , ie_tree, ti, length, message_type, instance, args);
}
offset += length;
}
}
-static void
-dissect_gtpv2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
+static int
+dissect_gtpv2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_)
{
proto_tree *gtpv2_tree, *flags_tree;
proto_item *tf;
- guint8 message_type, t_flag, p_flag;
+ guint8 message_type, t_flag, p_flag, cause_aux;
int offset = 0;
guint16 msg_length;
tvbuff_t *msg_tvb;
+ int seq_no = 0;
+ conversation_t *conversation;
+ gtpv2_conv_info_t *gtpv2_info;
+ session_args_t *args = NULL;
+ gtpv2_hdr_t * gtpv2_hdr = NULL;
+ gtpv2_hdr = wmem_new0(wmem_packet_scope(), gtpv2_hdr_t);
+
+ /* Setting the TEID to -1 to say that the TEID is not valid for this packet */
+ gtpv2_hdr->teid = -1;
/* Currently we get called from the GTP dissector no need to check the version */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "GTPv2");
msg_length = tvb_get_ntohs(tvb, offset + 2);
proto_tree_add_item(tree, proto_gtpv2, tvb, offset, msg_length + 4, ENC_NA);
- if (tree) {
- gtpv2_tree = proto_tree_add_subtree(tree, tvb, offset, msg_length + 4, ett_gtpv2, NULL,
- val_to_str_ext_const(message_type, >pv2_message_type_vals_ext, "Unknown"));
-
- /* Control Plane GTP uses a variable length header. Control Plane GTP header
- * length shall be a multiple of 4 octets.
- * Figure 5.1-1 illustrates the format of the GTPv2-C Header.
- * Bits 8 7 6 5 4 3 2 1
- * Octets 1 Version P T Spare Spare Spare
- * 2 Message Type
- * 3 Message Length (1st Octet)
- * 4 Message Length (2nd Octet)
- * m-k(m+3) If T flag is set to 1, then TEID shall be placed into octets 5-8.
- * Otherwise, TEID field is not present at all.
- * n-(n+2) Sequence Number
- * (n+3) Spare
- * Figure 5.1-1: General format of GTPv2 Header for Control Plane
- */
- tf = proto_tree_add_item(gtpv2_tree, hf_gtpv2_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
- flags_tree = proto_item_add_subtree(tf, ett_gtpv2_flags);
+ if (g_gtp_session) {
+ args = wmem_new0(wmem_packet_scope(), session_args_t);
+ args->last_cause = 16; /* It stores the last cause decoded. Cause accepted by default */
+ /* We create the auxiliary lists */
+ args->teid_list = wmem_list_new(wmem_packet_scope());
+ args->ip_list = wmem_list_new(wmem_packet_scope());
+ }
- /* Octet 1 */
- t_flag = (tvb_get_guint8(tvb, offset) & 0x08) >> 3;
- proto_tree_add_item(flags_tree, hf_gtpv2_version, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(flags_tree, hf_gtpv2_p, tvb, offset, 1, ENC_BIG_ENDIAN);
- proto_tree_add_item(flags_tree, hf_gtpv2_t, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
+ /*
+ * Do we have a conversation for this connection?
+ */
+ conversation = find_or_create_conversation(pinfo);
- /* Octet 2 */
- proto_tree_add_item(gtpv2_tree, hf_gtpv2_message_type, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
- /* Octet 3 - 4 */
- proto_tree_add_item(gtpv2_tree, hf_gtpv2_msg_length, tvb, offset, 2, ENC_BIG_ENDIAN);
- offset += 2;
+ /*
+ * Do we already know this conversation?
+ */
+ gtpv2_info = (gtpv2_conv_info_t *)conversation_get_proto_data(conversation, proto_gtpv2);
+ if (gtpv2_info == NULL) {
+ /* No. Attach that information to the conversation, and add
+ * it to the list of information structures.
+ */
+ gtpv2_info = wmem_new(wmem_file_scope(), gtpv2_conv_info_t);
+ /*Request/response matching tables*/
+ gtpv2_info->matched = wmem_map_new(wmem_file_scope(), gtpv2_sn_hash, gtpv2_sn_equal_matched);
+ gtpv2_info->unmatched = wmem_map_new(wmem_file_scope(), gtpv2_sn_hash, gtpv2_sn_equal_unmatched);
- if (t_flag) {
- /* Tunnel Endpoint Identifier 4 octets */
- proto_tree_add_item(gtpv2_tree, hf_gtpv2_teid, tvb, offset, 4, ENC_BIG_ENDIAN);
- offset += 4;
- }
- /* Sequence Number 3 octets */
- proto_tree_add_item(gtpv2_tree, hf_gtpv2_seq, tvb, offset, 3, ENC_BIG_ENDIAN);
- offset += 3;
+ conversation_add_proto_data(conversation, proto_gtpv2, gtpv2_info);
+ }
- /* Spare 1 octet */
- proto_tree_add_item(gtpv2_tree, hf_gtpv2_spare, tvb, offset, 1, ENC_BIG_ENDIAN);
- offset += 1;
+ gtpv2_tree = proto_tree_add_subtree(tree, tvb, offset, msg_length + 4, ett_gtpv2, NULL,
+ val_to_str_ext_const(message_type, >pv2_message_type_vals_ext, "Unknown"));
+
+ /* Control Plane GTP uses a variable length header. Control Plane GTP header
+ * length shall be a multiple of 4 octets.
+ * Figure 5.1-1 illustrates the format of the GTPv2-C Header.
+ * Bits 8 7 6 5 4 3 2 1
+ * Octets 1 Version P T Spare Spare Spare
+ * 2 Message Type
+ * 3 Message Length (1st Octet)
+ * 4 Message Length (2nd Octet)
+ * m-k(m+3) If T flag is set to 1, then TEID shall be placed into octets 5-8.
+ * Otherwise, TEID field is not present at all.
+ * n-(n+2) Sequence Number
+ * (n+3) Spare
+ * Figure 5.1-1: General format of GTPv2 Header for Control Plane
+ */
+ gtpv2_hdr->flags = tvb_get_guint8(tvb, offset);
+ tf = proto_tree_add_uint(gtpv2_tree, hf_gtpv2_flags, tvb, offset, 1, gtpv2_hdr->flags);
+ flags_tree = proto_item_add_subtree(tf, ett_gtpv2_flags);
+
+ /* Octet 1 */
+ t_flag = (tvb_get_guint8(tvb, offset) & 0x08) >> 3;
+ proto_tree_add_item(flags_tree, hf_gtpv2_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_gtpv2_p, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(flags_tree, hf_gtpv2_t, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
- if (p_flag) {
- msg_tvb = tvb_new_subset_length(tvb, 0, msg_length + 4);
- dissect_gtpv2_ie_common(msg_tvb, pinfo, gtpv2_tree, offset, message_type);
- } else {
- dissect_gtpv2_ie_common(tvb, pinfo, gtpv2_tree, offset, message_type);
- }
+ /* Octet 2 */
+ gtpv2_hdr->message = tvb_get_guint8(tvb, offset);
+ proto_tree_add_uint(gtpv2_tree, hf_gtpv2_message_type, tvb, offset, 1, gtpv2_hdr->message);
+ offset += 1;
+ /* Octet 3 - 4 */
+ gtpv2_hdr->length = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_uint(gtpv2_tree, hf_gtpv2_msg_length, tvb, offset, 2, gtpv2_hdr->length);
+ offset += 2;
+
+ if (t_flag) {
+ /* Tunnel Endpoint Identifier 4 octets */
+ gtpv2_hdr->teid = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_uint(gtpv2_tree, hf_gtpv2_teid, tvb, offset, 4, (guint32)gtpv2_hdr->teid);
+ offset += 4;
+ }
+ /* Sequence Number 3 octets */
+ proto_tree_add_item_ret_uint(gtpv2_tree, hf_gtpv2_seq, tvb, offset, 3, ENC_BIG_ENDIAN, &seq_no);
+ offset += 3;
+
+ /* Spare 1 octet */
+ proto_tree_add_item(gtpv2_tree, hf_gtpv2_spare, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ if (p_flag) {
+ msg_tvb = tvb_new_subset_length(tvb, 0, msg_length + 4);
+ dissect_gtpv2_ie_common(msg_tvb, pinfo, gtpv2_tree, offset, message_type, args);
+ } else {
+ dissect_gtpv2_ie_common(tvb, pinfo, gtpv2_tree, offset, message_type, args);
+ }
+ /*Use sequence number to track Req/Resp pairs*/
+ cause_aux = 16; /* Cause accepted by default. Only used when args is NULL */
+ if (args && !PINFO_FD_VISITED(pinfo)) {
+ /* We insert the lists inside the table*/
+ fill_map(args->teid_list, args->ip_list, pinfo->num);
+ cause_aux = args->last_cause;
}
+ gtpv2_match_response(tvb, pinfo, gtpv2_tree, seq_no, message_type, gtpv2_info, cause_aux);
+ if (args) {
+ track_gtpv2_session(tvb, pinfo, gtpv2_tree, gtpv2_hdr, args->teid_list, args->ip_list, args->last_teid, args->last_ip);
+ }
+
/* Bit 5 represents a "P" flag. If the "P" flag is set to "0",
* no piggybacked message shall be present. If the "P" flag is set to "1",
* then another GTPv2-C message with its own header and body shall be present
new_p_tvb = tvb_new_subset_remaining(tvb, msg_length + 4);
col_append_str(pinfo->cinfo, COL_INFO, " / ");
col_set_fence(pinfo->cinfo, COL_INFO);
- dissect_gtpv2(new_p_tvb, pinfo, tree);
+ dissect_gtpv2(new_p_tvb, pinfo, tree, NULL);
}
-
+ return tvb_captured_length(tvb);
}
void proto_register_gtpv2(void)
{
static hf_register_info hf_gtpv2[] = {
+ { &hf_gtpv2_response_in,
+ { "Response In", "gtpv2.response_in",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "The response to this GTP request is in this frame", HFILL }
+ },
+ { &hf_gtpv2_response_to,
+ { "Response To", "gtpv2.response_to",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "This is a response to the GTP request in this frame", HFILL }
+ },
+ { &hf_gtpv2_response_time,
+ { "Response Time", "gtpv2.response_time",
+ FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
+ "The time between the Request and the Response", HFILL }
+ },
{ &hf_gtpv2_spare_half_octet,
{"Spare half octet", "gtpv2.spare_half_octet",
FT_UINT8, BASE_DEC, NULL, 0x0,
FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}
},
{&hf_gtpv2_cpsr,
- {"CPSR (CS to PS SRVCC indication)", "gtpv2.cpsr",
+ {"CPSR (CS to PS SRVCC Indication)", "gtpv2.cpsr",
FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}
},
+ {&hf_gtpv2_nsi,
+ {"NSI (NBIFOM Support Indication)", "gtpv2.nsi",
+ FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}
+ },
+ {&hf_gtpv2_uasi,
+ {"UASI (UE Available for Signalling Indication)", "gtpv2.uasi",
+ FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}
+ },
+ {&hf_gtpv2_dtci,
+ {"DTCI (Delay Tolerant Connection Indication)", "gtpv2.dtci",
+ FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}
+ },
+ {&hf_gtpv2_bdwi,
+ {"BDWI (Buffered DL Data Waiting Indication)", "gtpv2.bdwi",
+ FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL}
+ },
+ {&hf_gtpv2_psci,
+ {"PSCI (Pending Subscription Change Indication)", "gtpv2.psci",
+ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}
+ },
{&hf_gtpv2_pcri,
{"PCRI (P-CSCF Restoration Indication)", "gtpv2.pcri",
FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL}
{"AOPI (Associate OCI with PGW node's Identity)", "gtpv2.aopi",
FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}
},
+ {&hf_gtpv2_roaai,
+ {"ROAAI (Release Over Any Access Indication)", "gtpv2.roaai",
+ FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}
+ },
+ {&hf_gtpv2_epcosi,
+ {"EPCOSI (Extended PCO Support Indication)", "gtpv2.epcosi",
+ FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}
+ },
+ {&hf_gtpv2_cpopci,
+ {"CPOPCI (Control Plane Only PDN Connection Indication)", "gtpv2.cpopci",
+ FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}
+ },
+ {&hf_gtpv2_pmtsmi,
+ {"PMTSMI (Pending MT Short Message Indication)", "gtpv2.pmtsmi",
+ FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL}
+ },
+ {&hf_gtpv2_s11tf,
+ {"S11TF (S11-U Tunnel Flag)", "gtpv2.s11tf",
+ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}
+ },
+ {&hf_gtpv2_pnsi,
+ {"PNSI (Pending Network Initiated PDN Connection Signalling Indication)", "gtpv2.pnsi",
+ FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL}
+ },
+ {&hf_gtpv2_unaccsi,
+ {"UNACCSI (UE Not Authorized Cause Code Support Indication)", "gtpv2.unaccsi",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}
+ },
+ {&hf_gtpv2_wpmsi,
+ {"WPMSI (WLCP PDN Connection Modification Support Indication)", "gtpv2.wpmsi",
+ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}
+ },
+ {&hf_gtpv2_enbcrsi,
+ {"ENBCRSI (eNB Change Reporting Support Indication)", "gtpv2.enbcrsi",
+ FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL}
+ },
+ {&hf_gtpv2_tspcmi,
+ {"TSPCMI (Triggering SGSN Initiated PDP Context Creation/Modification Indication)", "gtpv2.tspcmi",
+ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL}
+ },
{ &hf_gtpv2_pdn_type,
{"PDN Type", "gtpv2.pdn_type",
FT_UINT8, BASE_DEC, VALS(gtpv2_pdn_type_vals), 0x07,
FT_BYTES, BASE_NONE, NULL, 0x0,
NULL, HFILL}
},
- /* Bit 1 - PVI (Pre-emption Vulnerability): See 3GPP TS 29.212[29],
- * clause 5.3.47 Pre-emption-Vulnerability AVP.
- * 5.3.47 Pre-emption-Vulnerability AVP
+ /* Bit 7 - PCI (Pre-emption Capability): See 3GPP TS 29.212[29], clause 5.3.46 Pre-emption-Capability AVP.
+ * clause 5.3.46 Pre-emption-Capability AVP.
+ * 5.3.46 Pre-emption-Capability AVP
* The following values are defined:
- * PRE-EMPTION_VULNERABILITY_ENABLED (0)
- * PRE-EMPTION_VULNERABILITY_DISABLED (1)
+ * PRE-EMPTION_CAPABILITY_ENABLED (0)
+ * PRE-EMPTION_CAPABILITY_DISABLED (1)
*/
- {&hf_gtpv2_bearer_qos_pvi,
- {"PVI (Pre-emption Vulnerability)", "gtpv2.bearer_qos_pvi",
- FT_BOOLEAN, 8, TFS(&tfs_disabled_enabled), 0x01,
+ {&hf_gtpv2_bearer_qos_pci,
+ {"PCI (Pre-emption Capability)", "gtpv2.bearer_qos_pci",
+ FT_BOOLEAN, 8, TFS(&tfs_disabled_enabled), 0x40,
NULL, HFILL}
},
{&hf_gtpv2_bearer_qos_pl,
FT_UINT8, BASE_DEC, NULL, 0x3c,
NULL, HFILL}
},
- /* Bit 7 - PCI (Pre-emption Capability): See 3GPP TS 29.212[29], clause 5.3.46 Pre-emption-Capability AVP.
- * clause 5.3.46 Pre-emption-Capability AVP.
- * 5.3.46 Pre-emption-Capability AVP
+ /* Bit 1 - PVI (Pre-emption Vulnerability): See 3GPP TS 29.212[29],
+ * clause 5.3.47 Pre-emption-Vulnerability AVP.
+ * 5.3.47 Pre-emption-Vulnerability AVP
* The following values are defined:
- * PRE-EMPTION_CAPABILITY_ENABLED (0)
- * PRE-EMPTION_CAPABILITY_DISABLED (1)
+ * PRE-EMPTION_VULNERABILITY_ENABLED (0)
+ * PRE-EMPTION_VULNERABILITY_DISABLED (1)
*/
- {&hf_gtpv2_bearer_qos_pci,
- {"PCI (Pre-emption Capability)", "gtpv2.bearer_qos_pci",
- FT_BOOLEAN, 8, TFS(&tfs_disabled_enabled), 0x40,
+ {&hf_gtpv2_bearer_qos_pvi,
+ {"PVI (Pre-emption Vulnerability)", "gtpv2.bearer_qos_pvi",
+ FT_BOOLEAN, 8, TFS(&tfs_disabled_enabled), 0x01,
NULL, HFILL}
},
{&hf_gtpv2_bearer_qos_label_qci,
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL}
},
+ { &hf_gtpv2_mm_contex_nhi_old,
+ { "Next Hop Indicator for old EPS Security Context", "gtpv2.mm_context_nhi_old",
+ FT_UINT8, BASE_DEC, NULL, 0x80,
+ NULL, HFILL }
+ },
+ { &hf_gtpv2_mm_context_old_ksiasme,
+ { "old KSIASME", "gtpv2.old_ksiasme",
+ FT_UINT8, BASE_DEC, NULL, 0x38,
+ NULL, HFILL }
+ },
+ { &hf_gtpv2_mm_context_old_ncc,
+ { "old NCC", "gtpv2.old_ncc",
+ FT_UINT8, BASE_DEC, NULL, 0x07,
+ NULL, HFILL }
+ },
+ { &hf_gtpv2_mm_context_old_kasme,
+ { "Old Kasme", "gtpv2.mm_context_old_kasme",
+ FT_BYTES, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_gtpv2_mm_context_old_nh,{ "Old NH (Old Next Hop)", "gtpv2.mm_context_old_nh", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
{ &hf_gtpv2_mm_context_vdp_len,
- {"Length of Voice Domain Preference and UE's Usage Setting", "gtpv2.mm_context_vdp_len",
- FT_UINT8, BASE_DEC, NULL, 0x0,
- NULL, HFILL}
+ { "Length of Voice Domain Preference and UE's Usage Setting", "gtpv2.mm_context_vdp_len",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_gtpv2_mm_context_paging_len,
+ { "Length of UE Radio Capability for Paging information", "gtpv2.mm_context_paging_len",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
},
{ &hf_gtpv2_una,
{ "UTRAN", "gtpv2.mm_context.una",
FT_BOOLEAN, 8, TFS(&tfs_not_allowed_allowed), 0x20,
NULL, HFILL }
},
+ { &hf_gtpv2_hbna,
+ { "NB-IoT Not Allowed", "gtpv2.mm_context.hbna",
+ FT_BOOLEAN, 8, TFS(&tfs_not_allowed_allowed), 0x40,
+ NULL, HFILL }
+ },
{ &hf_gtpv2_mm_context_ksi,
{"KSI", "gtpv2.mm_context_ksi",
FT_UINT8, BASE_DEC, NULL, 0x07,
},
{ &hf_gtpv2_mm_context_osci,
{"OSCI", "gtpv2.mm_context_osci",
- FT_BOOLEAN, 8, NULL, 0x02,
- NULL, HFILL}
+ FT_BOOLEAN, 8, NULL, 0x01,
+ "Old Security Context Indicator", HFILL}
},
{ &hf_gtpv2_mm_context_samb_ri,
{"SAMB RI", "gtpv2.mm_context_samb_ri",
},
{&hf_gtpv2_macro_enodeb_id,
{"Macro eNodeB ID", "gtpv2.macro_enodeb_id",
- FT_UINT24, BASE_HEX, NULL, 0x0fffff,
+ FT_UINT32, BASE_HEX, NULL, 0x0fffff,
+ NULL, HFILL}
+ },
+ {&hf_gtpv2_cellid,
+ {"CellId", "gtpv2.cellid",
+ FT_UINT32, BASE_DEC, NULL, 0xFF,
NULL, HFILL}
},
+ { &hf_gtpv2_enodebid,
+ { "eNodeB Id", "gtpv2.enodebid",
+ FT_UINT32, BASE_DEC, NULL, 0x0FFFFF00,
+ NULL, HFILL }
+ },
{ &hf_gtpv2_CauseProtocol,
{"Protocol Cause", "gtpv2.CauseProtocol",
FT_UINT8, BASE_DEC, VALS(s1ap_CauseProtocol_vals), 0x0,
FT_UINT24, BASE_DEC, NULL, 0xFFFF80,
NULL, HFILL}
},
+ { &hf_gtpv2_csg_id,
+ {"CSG ID", "gtpv2.csg_id",
+ FT_UINT32, BASE_HEX, NULL, 0x07ffffff,
+ NULL, HFILL}
+ },
+ { &hf_gtpv2_cmi,
+ {"CSG Membership Indication (CMI)", "gtpv2.cmi",
+ FT_BOOLEAN, 8, TFS(&tfs_no_yes), 0x01,
+ NULL, HFILL}
+ },
+ { &hf_gtpv2_service_indicator,
+ {"Service Indicator", "gtpv2.service_indicator",
+ FT_UINT8, BASE_DEC, VALS(gtpv2_service_indicator_vals), 0,
+ NULL, HFILL}
+ },
+ { &hf_gtpv2_detach_type,
+ {"Detach Type", "gtpv2.detach_type",
+ FT_UINT8, BASE_DEC, VALS(gtpv2_detach_type_vals), 0,
+ NULL, HFILL}
+ },
+ { &hf_gtpv2_ldn,
+ {"Local Distinguished Name (LDN)", "gtpv2.ldn",
+ FT_STRING, BASE_NONE, NULL, 0,
+ NULL, HFILL}
+ },
{ &hf_gtpv2_node_features_prn,
{"PGW Restart Notification (PRN)", "gtpv2.node_features_prn",
FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x01,
},
{ &hf_gtpv2_pres_rep_area_id,
{"Presence Reporting Area Identifier", "gtpv2.pres_rep_area_action.pres_rep_area_id",
- FT_UINT16, BASE_HEX, NULL, 0x0,
+ FT_UINT24, BASE_HEX, NULL, 0x0,
NULL, HFILL}
},
{ &hf_gtpv2_pres_rep_area_act_no_tai,
FT_UINT8, BASE_HEX, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_gtpv2_pres_rep_area_info_id,
+ {"Presence Reporting Area Identifier", "gtpv2.pres_rep_area_info_id",
+ FT_UINT24, BASE_HEX, NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_gtpv2_pres_rep_area_info_opra,
+ {"Outside Presence Reporting Area(OPRA) Flag", "gtpv2.pres_rep_area_info_opra",
+ FT_BOOLEAN, 8, NULL, 0x2,
+ NULL, HFILL}
+ },
+ { &hf_gtpv2_pres_rep_area_info_ipra,
+ {"Inside Presence Reporting Area(IPRA) Flag", "gtpv2.pres_rep_area_info_ipra",
+ FT_BOOLEAN, 8, NULL, 0x1,
+ NULL, HFILL}
+ },
+ { &hf_gtpv2_ppi_value,
+ {"Paging and Policy Information Value", "gtpv2.ppi_value",
+ FT_UINT8, BASE_DEC | BASE_EXT_STRING,
+ &dscp_vals_ext, GTPV2_PPI_VAL_MASK, NULL, HFILL}
+ },
+ { &hf_gtpv2_ppi_flag,
+ {"Paging Policy Indication", "gtpv2.ppi_flag",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_gtpv2_session,
+ { "Session", "gtpv2.session",
+ FT_UINT32, BASE_DEC, NULL, 0,
+ NULL, HFILL }
+ },
/* Generated from convert_proto_tree_add_text.pl */
{ &hf_gtpv2_transparent_container, { "Transparent Container", "gtpv2.transparent_container", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_gtpv2_drx_parameter, { "DRX parameter", "gtpv2.drx_parameter", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_gtpv2_mm_context_sres, { "SRES'", "gtpv2.mm_context_sres", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_gtpv2_mm_context_kc, { "Kc'", "gtpv2.mm_context_kc", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
- { &hf_gtpv2_uplink_subscribed_ue_ambr, { "Uplink Subscribed UE AMBR", "gtpv2.uplink_subscribed_ue_ambr", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_gtpv2_downlink_subscribed_ue_ambr, { "Downlink Subscribed UE AMBR", "gtpv2.downlink_subscribed_ue_ambr", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_gtpv2_uplink_used_ue_ambr, { "Uplink Used UE AMBR", "gtpv2.uplink_used_ue_ambr", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
- { &hf_gtpv2_downlink_used_ue_ambr, { "Downlink Used UE AMBR", "gtpv2.downlink_used_ue_ambr", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+ { &hf_gtpv2_uplink_subscribed_ue_ambr, { "Uplink Subscribed UE AMBR", "gtpv2.uplink_subscribed_ue_ambr", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, &units_kbps, 0x0, NULL, HFILL }},
+ { &hf_gtpv2_downlink_subscribed_ue_ambr, { "Downlink Subscribed UE AMBR", "gtpv2.downlink_subscribed_ue_ambr", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, &units_kbps, 0x0, NULL, HFILL }},
+ { &hf_gtpv2_uplink_used_ue_ambr, { "Uplink Used UE AMBR", "gtpv2.uplink_used_ue_ambr", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, &units_kbps, 0x0, NULL, HFILL }},
+ { &hf_gtpv2_downlink_used_ue_ambr, { "Downlink Used UE AMBR", "gtpv2.downlink_used_ue_ambr", FT_UINT32, BASE_DEC|BASE_UNIT_STRING, &units_kbps, 0x0, NULL, HFILL }},
{ &hf_gtpv2_voice_domain_and_ue_usage_setting, { "Voice Domain Preference and UE's Usage Setting", "gtpv2.voice_domain_and_ue_usage_setting", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+ { &hf_gtpv2_ue_radio_capability_for_paging_information,{ "UE Radio Capability for Paging information", "gtpv2.UE_Radio_Capability_for_Paging_information", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
{ &hf_gtpv2_authentication_quadruplets, { "Authentication Quadruplets", "gtpv2.authentication_quadruplets", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_gtpv2_authentication_quintuplets, { "Authentication Quintuplets", "gtpv2.authentication_quintuplets", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_gtpv2_mm_context_nh, { "NH (Next Hop)", "gtpv2.mm_context_nh", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_gtpv2_ul_pdcp_sequence_number, { "UL PDCP Sequence Number", "gtpv2.ul_pdcp_sequence_number", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_gtpv2_fq_csid_node_id, { "Node-ID", "gtpv2.fq_csid_node_id", FT_UINT32, BASE_DEC, NULL, 0x00000FFF, NULL, HFILL }},
{ &hf_gtpv2_fq_csid_mcc_mnc, { "MCC+MNC", "gtpv2.fq_csid_mcc_mnc", FT_UINT32, BASE_DEC, NULL, 0xFFFFF000, NULL, HFILL }},
+
+ { &hf_gtpv2_twan_id_ts, { "TWAN Identifier Timestamp", "gtpv2.twan.id_ts", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
+ { &hf_gtpv2_twan_flags,{ "Flags", "gtpv2.twan_id.flags", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_bssidi,{ "BSSIDI", "gtpv2.twan_id.bssidi", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x01, NULL, HFILL } },
+ { &hf_gtpv2_twan_civai,{ "CIVAI", "gtpv2.twan_id.civai", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x02, NULL, HFILL } },
+ { &hf_gtpv2_twan_plmni,{ "PLMNI", "gtpv2.twan_id.plmni", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x04, NULL, HFILL } },
+ { &hf_gtpv2_twan_opnai,{ "OPNAI", "gtpv2.twan_id.opnai", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x08, NULL, HFILL } },
+ { &hf_gtpv2_twan_laii,{ "LAII", "gtpv2.twan_id.laii", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x10, NULL, HFILL } },
+ { &hf_gtpv2_twan_ssid_len,{ "SSID Length", "gtpv2.twan_id.ssid_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_ssid,{ "SSID", "gtpv2.twan_id.ssid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_bssid,{ "BSSID", "gtpv2.twan_id.bssid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_civa_len,{ "Civic Address Length", "gtpv2.twan_id.civa_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_civa,{ "Civic Address Information", "gtpv2.twan_id.civa", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_plmnid,{ "TWAN PLMN-ID", "gtpv2.twan_id.plmnid", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_op_name_len,{ "TWAN Operator Name Length", "gtpv2.twan_id.op_name_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_op_name,{ "TWAN Operator Name", "gtpv2.twan_id.op_name", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_relay_id_type,{ "Relay Identity Type", "gtpv2.twan_id.relay_id_type", FT_UINT8, BASE_DEC, VALS(gtpv2_twan_relay_id_type_vals), 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_relay_id_len,{ "Relay Identity Type Length", "gtpv2.twan_id.relay_id_type_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_relay_id,{ "Relay Identity", "gtpv2.twan_id.relay_id", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_relay_id_ipv4,{ "Relay Identity", "gtpv2.twan_id.relay_id_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_relay_id_ipv6,{ "Relay Identity", "gtpv2.twan_id.relay_id_ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_circuit_id_len,{ "Relay Identity Type Length", "gtpv2.twan_id.relay_id_type_len", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_twan_circuit_id,{ "Circuit-ID", "gtpv2.twan_id.circuit_id", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
+ { &hf_gtpv2_integer_number_val,{ "Value", "gtpv2.integer_number_val", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
};
static gint *ett_gtpv2_array[] = {
&ett_gtpv2_ms_mark,
&ett_gtpv2_supp_codec_list,
&ett_gtpv2_bss_con,
+ &ett_gtpv2_utran_con,
+ &ett_gtpv2_eutran_con,
&ett_gtpv2_mm_context_auth_qua,
&ett_gtpv2_mm_context_auth_qui,
&ett_gtpv2_mm_context_auth_tri,
&ett_gtpv2_preaa_rais,
&ett_gtpv2_preaa_sais,
&ett_gtpv2_preaa_cgis,
+ &ett_gtpv2_load_control_inf,
+ &ett_gtpv2_eci,
+ &ett_gtpv2_twan_flags,
};
static ei_register_info ei[] = {
{ &ei_gtpv2_mbms_session_duration_days, { "gtpv2.mbms_session_duration_days.invalid", PI_PROTOCOL, PI_WARN, "Days out of allowed range", EXPFILL }},
{ &ei_gtpv2_mbms_session_duration_secs, { "gtpv2.mbms_session_duration_secs.unknown", PI_PROTOCOL, PI_WARN, "Seconds out of allowed range", EXPFILL }},
{ &ei_gtpv2_ie, { "gtpv2.ie_type.reserved", PI_PROTOCOL, PI_WARN, "IE type Zero is Reserved and should not be used", EXPFILL }},
+ { &ei_gtpv2_int_size_not_handled,{ "gtpv2.ie_type.int_size_not_handled", PI_PROTOCOL, PI_WARN, "Integer size not handled yet", EXPFILL } },
};
expert_module_t* expert_gtpv2;
expert_register_field_array(expert_gtpv2, ei, array_length(ei));
/* AVP Code: 22 3GPP-User-Location-Info */
- dissector_add_uint("diameter.3gpp", 22, new_create_dissector_handle(dissect_diameter_3gpp_uli, proto_gtpv2));
+ dissector_add_uint("diameter.3gpp", 22, create_dissector_handle(dissect_diameter_3gpp_uli, proto_gtpv2));
/* AVP Code: 2820 Presence-Reporting-Area-Elements-List */
- dissector_add_uint("diameter.3gpp", 2820, new_create_dissector_handle(dissect_diameter_3gpp_presence_reporting_area_elements_list, proto_gtpv2));
+ dissector_add_uint("diameter.3gpp", 2820, create_dissector_handle(dissect_diameter_3gpp_presence_reporting_area_elements_list, proto_gtpv2));
register_dissector("gtpv2", dissect_gtpv2, proto_gtpv2);
/* Dissector table for private extensions */
- gtpv2_priv_ext_dissector_table = register_dissector_table("gtpv2.priv_ext", "GTPv2 PRIVATE EXT", FT_UINT16, BASE_DEC);
+ gtpv2_priv_ext_dissector_table = register_dissector_table("gtpv2.priv_ext", "GTPv2 PRIVATE EXT", proto_gtpv2, FT_UINT16, BASE_DEC);
}
void
proto_reg_handoff_gtpv2(void)
{
- nas_eps_handle = find_dissector("nas-eps");
+ nas_eps_handle = find_dissector_add_dependency("nas-eps", proto_gtpv2);
}
/*