diff options
author | glores <gloria.pozuelo@bics.com> | 2016-02-23 15:34:07 +0100 |
---|---|---|
committer | Pascal Quantin <pascal.quantin@gmail.com> | 2016-03-02 19:46:36 +0000 |
commit | 2146c4632eb7aaab7ed1cfeb4e868bfea3ad473a (patch) | |
tree | f893c9ad9b267f1ff6cd4db6271f9e3858667315 /epan/dissectors | |
parent | a86a723d76ba0a283a93740b2d56ced006426d58 (diff) |
GTP session ID generated tree item for tracking GTPv2 sessions
Change-Id: I6d487c901838dcdb3550674e0a514a59d221806f
Reviewed-on: https://code.wireshark.org/review/14093
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-gtp.c | 391 | ||||
-rw-r--r-- | epan/dissectors/packet-gtp.h | 26 | ||||
-rw-r--r-- | epan/dissectors/packet-gtpv2.c | 532 | ||||
-rw-r--r-- | epan/dissectors/packet-gtpv2.h | 15 | ||||
-rw-r--r-- | epan/dissectors/packet-m3ap.c | 6 | ||||
-rw-r--r-- | epan/dissectors/packet-mip6.c | 6 |
6 files changed, 570 insertions, 406 deletions
diff --git a/epan/dissectors/packet-gtp.c b/epan/dissectors/packet-gtp.c index eb7a0538e8..41dca2176c 100644 --- a/epan/dissectors/packet-gtp.c +++ b/epan/dissectors/packet-gtp.c @@ -95,7 +95,7 @@ static dissector_table_t gtp_cdr_fmt_dissector_table; #define GTP_TPDU_AS_SYNC 2 static gboolean g_gtp_over_tcp = TRUE; -static gboolean g_gtp_session = FALSE; +gboolean g_gtp_session = FALSE; static guint g_gtpv0_port = GTPv0_PORT; static guint g_gtpv1c_port = GTPv1C_PORT; @@ -1838,26 +1838,191 @@ static dissector_handle_t data_handle; static dissector_handle_t gtpv2_handle; static dissector_handle_t bssgp_handle; static dissector_table_t bssap_pdu_type_table; -static guint32 gtp_session_count; +guint32 gtp_session_count; + +/* Relation between frame -> session */ +GHashTable* session_table; +/* Relation between <teid,ip> -> frame */ +wmem_tree_t* frame_tree; -/* Data structures to keep track of sessions */ typedef struct gtp_info { guint32 teid; guint32 frame; } gtp_info_t; -typedef struct session_args { - wmem_list_t *teid_list; - wmem_list_t *ip_list; - guint32 last_teid; - address last_ip; - guint8 last_cause; -} session_args_t; +/* GTP Session funcs*/ +guint32 +get_frame(address ip, guint32 teid, guint32 *frame) { + gboolean found = FALSE; + wmem_list_frame_t *elem; + gtp_info_t *info; + wmem_list_t *info_list; + gchar *ip_str; -/* Relation between frame -> session */ -GHashTable* session_table; -/* Relation between <teid,ip> -> frame */ -wmem_tree_t* frame_tree; + /* First we get the teid list*/ + ip_str = address_to_str(wmem_packet_scope(), &ip); + info_list = (wmem_list_t*)wmem_tree_lookup_string(frame_tree, ip_str, 0); + if (info_list != NULL) { + elem = wmem_list_head(info_list); + while (!found && elem) { + info = (gtp_info_t*)wmem_list_frame_data(elem); + if (teid == info->teid) { + *frame = info->frame; + return 1; + } + elem = wmem_list_frame_next(elem); + } + } + return 0; +} + +static void +call_foreach_ip(const void *key _U_, void *value, void *data){ + wmem_list_frame_t * elem; + wmem_list_t *info_list = (wmem_list_t *)value; + gtp_info_t *info; + guint32* frame = (guint32*)data; + + /* We loop over the <teid, frame> list */ + elem = wmem_list_head(info_list); + while (elem) { + info = (gtp_info_t*)wmem_list_frame_data(elem); + if (info->frame == *frame) { + wmem_list_frame_t * del = elem; + /* proceed to next request */ + elem = wmem_list_frame_next(elem); + /* If we find the frame we remove its information from the list */ + wmem_list_remove_frame(info_list, del); + wmem_free(wmem_file_scope(), info); + } + else { + elem = wmem_list_frame_next(elem); + } + } +} + +void +remove_frame_info(guint32 *f) { + /* For each ip node */ + wmem_tree_foreach(frame_tree, (wmem_foreach_func)call_foreach_ip, (void *)f); +} + +void +add_gtp_session(guint32 frame, guint32 session) { + guint32 *f, *session_count; + + f = wmem_new0(wmem_file_scope(), guint32); + session_count = wmem_new0(wmem_file_scope(), guint32); + *f = frame; + *session_count = session; + g_hash_table_insert(session_table, f, session_count); +} + +gboolean +teid_exists(guint32 teid, wmem_list_t *teid_list) { + wmem_list_frame_t *elem; + guint32 *info; + gboolean found; + found = FALSE; + elem = wmem_list_head(teid_list); + while (!found && elem) { + info = (guint32*)wmem_list_frame_data(elem); + found = *info == teid; + elem = wmem_list_frame_next(elem); + } + return found; +} + +gboolean +ip_exists(address ip, wmem_list_t *ip_list) { + wmem_list_frame_t *elem; + address *info; + gboolean found; + found = FALSE; + elem = wmem_list_head(ip_list); + while (!found && elem) { + info = (address*)wmem_list_frame_data(elem); + found = addresses_equal(info, &ip); + elem = wmem_list_frame_next(elem); + } + return found; +} + +static gboolean +info_exists(gtp_info_t *wanted, wmem_list_t *info_list) { + wmem_list_frame_t *elem; + gtp_info_t *info; + gboolean found; + found = FALSE; + elem = wmem_list_head(info_list); + while (!found && elem) { + info = (gtp_info_t*)wmem_list_frame_data(elem); + found = wanted->teid == info->teid; + elem = wmem_list_frame_next(elem); + } + return found; +} + +void +fill_map(wmem_list_t *teid_list, wmem_list_t *ip_list, guint32 frame) { + wmem_list_frame_t *elem_ip, *elem_teid; + gtp_info_t *gtp_info; + wmem_list_t * info_list; /* List of <teids,frames>*/ + guint32 *f, *session, *fr, *session_count; + GHashTableIter iter; + guint32 teid; + gchar *ip; + + elem_ip = wmem_list_head(ip_list); + while (elem_ip) { + ip = address_to_str(wmem_file_scope(), (address*)wmem_list_frame_data(elem_ip)); + /* We check if a teid list exists for this ip */ + info_list = (wmem_list_t*)wmem_tree_lookup_string(frame_tree, ip, 0); + if (info_list == NULL) { + info_list = wmem_list_new(wmem_file_scope()); + } + /* We loop over the teid list */ + elem_teid = wmem_list_head(teid_list); + while (elem_teid) { + teid = *(guint32*)wmem_list_frame_data(elem_teid); + f = wmem_new0(wmem_file_scope(), guint32); + *f = frame; + gtp_info = wmem_new0(wmem_file_scope(), gtp_info_t); + gtp_info->teid = teid; + gtp_info->frame = *f; + if (info_exists(gtp_info, info_list)) { + /* If the teid and ip already existed, that means that we need to remove old info about that session */ + /* We look for its session ID */ + session = (guint32 *)g_hash_table_lookup(session_table, f); + if (session) { + g_hash_table_iter_init(&iter, session_table); + while (g_hash_table_iter_next(&iter, (gpointer*)&fr, (gpointer*)&session_count)) { + /* If the msg has the same session ID and it's not the upd req we have to remove its info */ + if (*session_count == *session) { + /* If it's the session we are looking for, we remove all the frame information */ + remove_frame_info(fr); + } + } + } + } + wmem_list_prepend(info_list, gtp_info); + elem_teid = wmem_list_frame_next(elem_teid); + } + wmem_tree_insert_string(frame_tree, ip, info_list, 0); + elem_ip = wmem_list_frame_next(elem_ip); + } +} + +gboolean +is_cause_accepted(guint8 cause, guint32 version) { + if (version == 1) { + return cause == 128; + } + else if (version == 2) { + return cause == 16; + } + return FALSE; +} static int decode_gtp_cause(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, session_args_t * args); static int decode_gtp_imsi(tvbuff_t * tvb, int offset, packet_info * pinfo, proto_tree * tree, session_args_t * args _U_); @@ -2131,12 +2296,6 @@ static const gtp_opt_t gtpopt[] = { #define NUM_GTP_IES 255 static gint ett_gtp_ies[NUM_GTP_IES]; -/*struct _gtp_hdr { - guint8 flags; - guint8 message; - guint16 length; - };*/ - static guint8 gtp_version = 0; #define BCD2CHAR(d) ((d) | 0x30) @@ -3216,173 +3375,6 @@ gtp_sn_equal_unmatched(gconstpointer k1, gconstpointer k2) return key1->seq_nr == key2->seq_nr; } -/* GTP Session funcs*/ -static guint32 -get_frame(address ip, guint32 teid, guint32 *frame) { - gboolean found = FALSE; - wmem_list_frame_t *elem; - gtp_info_t *info; - wmem_list_t *info_list; - gchar *ip_str; - - /* First we get the teid list*/ - ip_str = address_to_str(wmem_packet_scope(), &ip); - info_list = (wmem_list_t*)wmem_tree_lookup_string(frame_tree, ip_str, 0); - if (info_list != NULL) { - elem = wmem_list_head(info_list); - while (!found && elem) { - info = (gtp_info_t*)wmem_list_frame_data(elem); - if (teid == info->teid) { - *frame = info->frame; - return 1; - } - elem = wmem_list_frame_next(elem); - } - } - return 0; -} - -static void -call_foreach_ip(const void *key _U_, void *value, void *data){ - wmem_list_frame_t * elem; - wmem_list_t *info_list = (wmem_list_t *)value; - gtp_info_t *info; - guint32* frame = (guint32*)data; - - /* We loop over the <teid, frame> list */ - elem = wmem_list_head(info_list); - while (elem) { - info = (gtp_info_t*)wmem_list_frame_data(elem); - if (info->frame == *frame) { - wmem_list_frame_t * del = elem; - /* proceed to next request */ - elem = wmem_list_frame_next(elem); - /* If we find the frame we remove its information from the list */ - wmem_list_remove_frame(info_list, del); - wmem_free(wmem_file_scope(), info); - } else { - elem = wmem_list_frame_next(elem); - } - } -} - -static void -remove_frame_info(guint32 *f) { - /* For each ip node */ - wmem_tree_foreach(frame_tree, (wmem_foreach_func)call_foreach_ip, (void *)f); -} - -static void -add_gtp_session(guint32 frame, guint32 session) { - guint32 *f, *session_count; - - f = wmem_new0(wmem_file_scope(), guint32); - session_count = wmem_new0(wmem_file_scope(), guint32); - *f = frame; - *session_count = session; - g_hash_table_insert(session_table, f, session_count); -} - -static gboolean -teid_exists(guint32 teid, wmem_list_t *teid_list) { - wmem_list_frame_t *elem; - guint32 *info; - gboolean found; - found = FALSE; - elem = wmem_list_head(teid_list); - while (!found && elem) { - info = (guint32*)wmem_list_frame_data(elem); - found = *info == teid; - elem = wmem_list_frame_next(elem); - } - return found; -} - -static gboolean -ip_exists(address ip, wmem_list_t *ip_list) { - wmem_list_frame_t *elem; - address *info; - gboolean found; - found = FALSE; - elem = wmem_list_head(ip_list); - while (!found && elem) { - info = (address*)wmem_list_frame_data(elem); - found = addresses_equal(info, &ip); - elem = wmem_list_frame_next(elem); - } - return found; -} - -static gboolean -info_exists(gtp_info_t *wanted, wmem_list_t *info_list) { - wmem_list_frame_t *elem; - gtp_info_t *info; - gboolean found; - found = FALSE; - elem = wmem_list_head(info_list); - while (!found && elem) { - info = (gtp_info_t*)wmem_list_frame_data(elem); - found = wanted->teid == info->teid; - elem = wmem_list_frame_next(elem); - } - return found; -} - -static void -fill_map(wmem_list_t *teid_list, wmem_list_t *ip_list, guint32 frame) { - wmem_list_frame_t *elem_ip, *elem_teid; - gtp_info_t *gtp_info; - wmem_list_t * info_list; /* List of <teids,frames>*/ - guint32 *f, *session, *fr, *session_count; - GHashTableIter iter; - guint32 teid; - gchar *ip; - - elem_ip = wmem_list_head(ip_list); - while (elem_ip) { - ip = address_to_str(wmem_file_scope(), (address*)wmem_list_frame_data(elem_ip)); - /* We check if a teid list exists for this ip */ - info_list = (wmem_list_t*)wmem_tree_lookup_string(frame_tree, ip, 0); - if (info_list == NULL) { - info_list = wmem_list_new(wmem_file_scope()); - } - /* We loop over the teid list */ - elem_teid = wmem_list_head(teid_list); - while (elem_teid) { - teid = *(guint32*)wmem_list_frame_data(elem_teid); - f = wmem_new0(wmem_file_scope(), guint32); - *f = frame; - gtp_info = wmem_new0(wmem_file_scope(), gtp_info_t); - gtp_info->teid = teid; - gtp_info->frame = *f; - if (info_exists(gtp_info, info_list)) { - /* If the teid and ip already existed, that means that we need to remove old info about that session */ - /* We look for its session ID */ - session = (guint32 *)g_hash_table_lookup(session_table, f); - if (session) { - g_hash_table_iter_init(&iter, session_table); - while (g_hash_table_iter_next(&iter, (gpointer*)&fr, (gpointer*)&session_count)) { - /* If the msg has the same session ID and it's not the upd req we have to remove its info */ - if (*session_count == *session) { - /* If it's the session we are looking for, we remove all the frame information */ - remove_frame_info(fr); - } - } - } - } - wmem_list_prepend(info_list, gtp_info); - elem_teid = wmem_list_frame_next(elem_teid); - } - wmem_tree_insert_string(frame_tree, ip, info_list, 0); - elem_ip = wmem_list_frame_next(elem_ip); - } -} - -static gboolean -is_cause_accepted(guint8 cause) { - return cause == 128; -} - static gtp_msg_hash_t * gtp_match_response(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gint seq_nr, guint msgtype, gtp_conv_info_t *gtp_info, guint8 last_cause) { @@ -3487,7 +3479,7 @@ gtp_match_response(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gint if (g_gtp_session) { if (!PINFO_FD_VISITED(pinfo) && gtp_version == 1) { /* GTP session */ - /* If it's not already in the list */ + /* If it does not have any session assigned yet */ session = (guint32 *)g_hash_table_lookup(session_table, &pinfo->num); if (!session) { session = (guint32 *)g_hash_table_lookup(session_table, &gcrp->req_frame); @@ -3496,7 +3488,7 @@ gtp_match_response(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gint } } - if (!is_cause_accepted(last_cause)){ + if (!is_cause_accepted(last_cause, gtp_version)){ /* 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); } @@ -8401,19 +8393,18 @@ track_gtp_session(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gtp_hd if (!PINFO_FD_VISITED(pinfo) && gtp_version == 1) { - /* If the message is not a CPDPCRES, CPDPCREQ, UPDPREQ, UPDPRES then we remove its information from teid_cp - and gsn_ipv4 lists */ - if ((gtp_hdr->message != GTP_MSG_CREATE_PDP_RESP && gtp_hdr->message != GTP_MSG_CREATE_PDP_REQ && gtp_hdr->message != GTP_MSG_UPDATE_PDP_RESP - && gtp_hdr->message != GTP_MSG_UPDATE_PDP_REQ)) { - /* If the lists are not empty*/ - if (wmem_list_count(teid_list) && wmem_list_count(ip_list)) { - remove_frame_info(&pinfo->num); - } - } - /* 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 CPDPCRES, CPDPCREQ, UPDPREQ, UPDPRES then we remove its information from teid and ip lists */ + if ((gtp_hdr->message != GTP_MSG_CREATE_PDP_RESP && gtp_hdr->message != GTP_MSG_CREATE_PDP_REQ && gtp_hdr->message != GTP_MSG_UPDATE_PDP_RESP + && gtp_hdr->message != GTP_MSG_UPDATE_PDP_REQ)) { + /* If the lists are not empty*/ + if (wmem_list_count(teid_list) && wmem_list_count(ip_list)) { + remove_frame_info(&pinfo->num); + } + } + if (gtp_hdr->message == GTP_MSG_CREATE_PDP_REQ) { /* If CPDPCREQ and not already in the list then we create a new session*/ add_gtp_session(pinfo->num, gtp_session_count++); @@ -8657,7 +8648,7 @@ dissect_gtp_common(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) offset += 2; /* If GTP' version is 0 and bit 1 is 0 20 bytes header is used, dissect it */ if( (gtp_version == 0) && ((gtp_hdr->flags & 0x01) == 0) ) { - proto_tree_add_item(gtp_tree, hf_gtp_dummy_octets, tvb, offset, 14, ENC_BIG_ENDIAN); + proto_tree_add_item(gtp_tree, hf_gtp_dummy_octets, tvb, offset, 14, ENC_NA); offset += 14; } diff --git a/epan/dissectors/packet-gtp.h b/epan/dissectors/packet-gtp.h index 33066feb9c..8b0af67831 100644 --- a/epan/dissectors/packet-gtp.h +++ b/epan/dissectors/packet-gtp.h @@ -146,4 +146,30 @@ typedef struct _gtp_hdr { extern value_string_ext cause_type_ext; +/* Data structures to keep track of sessions */ +extern guint32 gtp_session_count; +extern gboolean g_gtp_session; + +typedef struct session_args { + wmem_list_t *teid_list; + wmem_list_t *ip_list; + guint32 last_teid; + address last_ip; + guint8 last_cause; +} session_args_t; + +guint32 get_frame(address ip, guint32 teid, guint32 *frame); + +void remove_frame_info(guint32 *f); + +void add_gtp_session(guint32 frame, guint32 session); + +gboolean teid_exists(guint32 teid, wmem_list_t *teid_list); + +gboolean ip_exists(address ip, wmem_list_t *ip_list); + +void fill_map(wmem_list_t *teid_list, wmem_list_t *ip_list, guint32 frame); + +gboolean is_cause_accepted(guint8 cause, guint32 version); + #endif /* __PACKET_GTP_H*/ diff --git a/epan/dissectors/packet-gtpv2.c b/epan/dissectors/packet-gtpv2.c index b7fa4a4999..9fb5efe098 100644 --- a/epan/dissectors/packet-gtpv2.c +++ b/epan/dissectors/packet-gtpv2.c @@ -501,6 +501,7 @@ 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 gint ett_gtpv2 = -1; static gint ett_gtpv2_flags = -1; @@ -602,7 +603,7 @@ static expert_field ei_gtpv2_ie = EI_INIT; #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[] = { @@ -1029,6 +1030,19 @@ static const value_string gtpv2_element_type_vals[] = { {0, NULL} }; static value_string_ext gtpv2_element_type_vals_ext = VALUE_STRING_EXT_INIT(gtpv2_element_type_vals); + +/* Relation between frame -> session */ +GHashTable* session_table; +/* Relation between <teid,ip> -> frame */ +wmem_tree_t* frame_tree; + +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 */ @@ -1084,7 +1098,7 @@ gtpv2_sn_equal_unmatched(gconstpointer k1, gconstpointer k2) /* 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); } @@ -1099,7 +1113,7 @@ dissect_gtpv2_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto */ 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; @@ -1254,13 +1268,16 @@ static const true_false_string gtpv2_cause_cs = { }; 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 */ @@ -1307,7 +1324,7 @@ dissect_gtpv2_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pro * 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; @@ -1323,7 +1340,7 @@ dissect_gtpv2_recovery(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, /* 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; @@ -1346,7 +1363,7 @@ dissect_gtpv2_stn_sr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_ /* 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; @@ -1378,7 +1395,7 @@ dissect_gtpv2_src_tgt_trans_con(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre /* 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 _U_, guint8 instance _U_, session_args_t * args _U_) { int offset = 0; proto_tree_add_item(tree, hf_gtpv2_len_trans_con, tvb, offset, 1, ENC_BIG_ENDIAN); @@ -1392,7 +1409,7 @@ dissect_gtpv2_tgt_src_trans_con(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre /* 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; @@ -1435,7 +1452,7 @@ dissect_gtpv2_mm_con_eutran_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t /* 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; @@ -1500,7 +1517,7 @@ static const value_string gtpv2_srvcc_cause_vals[] = { 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; @@ -1516,7 +1533,7 @@ dissect_gtpv2_srvcc_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * 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; @@ -1577,7 +1594,7 @@ dissect_gtpv2_tgt_rnc_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pr * -- 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; @@ -1618,7 +1635,7 @@ dissect_gtpv2_tgt_global_cell_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree * /* 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; @@ -1632,7 +1649,7 @@ dissect_gtpv2_teid_c(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pr /* 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); @@ -1646,7 +1663,7 @@ dissect_gtpv2_sv_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, /* 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; @@ -1672,7 +1689,7 @@ dissect_gtpv2_sai(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_ite /* 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; @@ -1708,7 +1725,7 @@ dissect_gtpv2_mm_ctx_for_cs_to_ps_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, p * 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; @@ -1742,7 +1759,7 @@ dissect_gtpv2_apn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto */ 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; @@ -1755,7 +1772,7 @@ dissect_gtpv2_ambr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, prot * 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; @@ -1773,7 +1790,7 @@ dissect_gtpv2_ebi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto * 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; @@ -1800,7 +1817,7 @@ dissect_gtpv2_ip_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree */ 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; @@ -1822,7 +1839,7 @@ dissect_gtpv2_mei(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto * 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; @@ -1847,7 +1864,7 @@ dissect_gtpv2_msisdn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pr * 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 */ @@ -1937,7 +1954,7 @@ dissect_gtpv2_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_ite * 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: @@ -1976,7 +1993,7 @@ static const value_string gtpv2_pdn_type_vals[] = { }; 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; @@ -2026,7 +2043,7 @@ dissect_gtpv2_paa(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto */ 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); @@ -2049,7 +2066,7 @@ dissect_gtpv2_bearer_qos(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree */ 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); @@ -2081,7 +2098,7 @@ static value_string_ext gtpv2_rat_type_vals_ext = VALUE_STRING_EXT_INIT(gtpv2_ra 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; @@ -2095,7 +2112,7 @@ dissect_gtpv2_rat_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, * 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; @@ -2108,7 +2125,7 @@ dissect_gtpv2_serv_net(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, prot */ 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] , @@ -2121,7 +2138,7 @@ dissect_gtpv2_bearer_tft(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pr /* 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] , @@ -2364,7 +2381,7 @@ decode_gtpv2_uli(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item } 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; @@ -2527,10 +2544,12 @@ static const true_false_string gtpv2_f_teid_v6_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); @@ -2542,7 +2561,7 @@ dissect_gtpv2_f_teid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pr 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)); @@ -2550,21 +2569,46 @@ dissect_gtpv2_f_teid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pr 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); @@ -2583,7 +2627,7 @@ dissect_gtpv2_tmsi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, prot */ 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; @@ -2597,7 +2641,7 @@ dissect_gtpv2_g_cn_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto * 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; @@ -2653,7 +2697,7 @@ dissect_gtpv2_s103pdf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto * 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; @@ -2696,7 +2740,7 @@ dissect_gtpv2_s1udf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_i */ 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; @@ -2708,7 +2752,7 @@ dissect_gtpv2_delay_value(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre */ 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; @@ -2718,12 +2762,12 @@ dissect_gtpv2_bearer_ctx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_ 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; @@ -2738,7 +2782,7 @@ dissect_gtpv2_charging_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * 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; @@ -2755,7 +2799,7 @@ dissect_gtpv2_char_char(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, * 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; @@ -2769,7 +2813,7 @@ dissect_gtpv2_bearer_flag(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * 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; @@ -2792,7 +2836,7 @@ dissect_gtpv2_pdn_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, prot * 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; @@ -3060,7 +3104,7 @@ dissect_gtpv2_tra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, prot /* 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); } @@ -3068,7 +3112,7 @@ dissect_gtpv2_pti(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto * 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; @@ -3082,7 +3126,7 @@ dissect_gtpv2_drx_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, * 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); @@ -3358,7 +3402,7 @@ dissect_gtpv2_access_restriction_data(tvbuff_t *tvb, proto_tree *tree, int offse * 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; @@ -3420,7 +3464,7 @@ dissect_gtpv2_mm_context_gsm_t(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr * 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; @@ -3523,7 +3567,7 @@ dissect_gtpv2_mm_context_utms_cq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr * 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; @@ -3622,7 +3666,7 @@ dissect_gtpv2_mm_context_gsm_cq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre * 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; @@ -3728,7 +3772,7 @@ dissect_gtpv2_mm_context_utms_q(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre * 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; @@ -3863,7 +3907,7 @@ dissect_gtpv2_mm_context_eps_qq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre * 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; @@ -3959,7 +4003,7 @@ dissect_gtpv2_mm_context_utms_qq(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr * 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; @@ -3969,13 +4013,13 @@ dissect_gtpv2_PDN_conn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, 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; @@ -4006,7 +4050,7 @@ dissect_gtpv2_pdn_numbers(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * 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; @@ -4019,7 +4063,7 @@ dissect_gtpv2_p_tmsi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pr * 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; @@ -4033,7 +4077,7 @@ dissect_gtpv2_p_tmsi_sig(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree * 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; @@ -4056,7 +4100,7 @@ static const value_string gtpv2_ue_time_zone_dst_vals[] = { {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; @@ -4074,7 +4118,7 @@ dissect_gtpv2_ue_time_zone(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, * 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; @@ -4097,7 +4141,7 @@ static const value_string gtpv2_complete_req_msg_type_vals[] = { {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; @@ -4118,7 +4162,7 @@ dissect_complete_request_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree * 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; @@ -4149,7 +4193,7 @@ static const value_string gtpv2_container_type_vals[] = { 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; @@ -4312,7 +4356,7 @@ dissect_gtpv2_s1ap_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree } 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; @@ -4394,7 +4438,7 @@ dissect_gtpv2_F_cause(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto * +--+--+--+--+--+--+--+--+ */ 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; @@ -4466,7 +4510,7 @@ dissect_gtpv2_home_enodeb_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree } 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; @@ -4539,7 +4583,7 @@ dissect_gtpv2_target_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pro * 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; @@ -4556,7 +4600,7 @@ dissect_gtpv2_pkt_flow_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * 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; @@ -4586,7 +4630,7 @@ dissect_gtpv2_rab_context(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * 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); } @@ -4595,7 +4639,7 @@ dissect_gtpv2_s_rnc_pdcp_ctx_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t * 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)); @@ -4604,7 +4648,7 @@ dissect_udp_s_port_nr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, p * 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; @@ -4625,7 +4669,7 @@ static const value_string gtpv2_selec_mode_vals[] = { }; 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; @@ -4648,7 +4692,7 @@ static const value_string gtpv2_source_ident_types[] = { }; #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; @@ -4702,7 +4746,7 @@ static const value_string gtpv2_bearer_control_mode_short_vals[] = { }; 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; @@ -4727,7 +4771,7 @@ static const value_string gtpv2_cng_rep_act_vals[] = { }; 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; @@ -4750,7 +4794,7 @@ static const value_string gtpv2_fq_csid_type_vals[] = { #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; @@ -4808,7 +4852,7 @@ dissect_gtpv2_fq_csid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto * 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] @@ -4823,7 +4867,7 @@ dissect_gtpv2_channel_needed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree * 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); @@ -4839,7 +4883,7 @@ static const value_string gtpv2_node_type_vals[] = { }; 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; @@ -4854,7 +4898,7 @@ dissect_gtpv2_node_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, * 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; @@ -4887,7 +4931,7 @@ dissect_gtpv2_fqdn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, prot * 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; @@ -4912,7 +4956,7 @@ dissect_gtpv2_private_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * 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); @@ -4923,7 +4967,7 @@ dissect_gtpv2_ti(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_ * 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; @@ -4974,7 +5018,7 @@ dissect_gtpv2_mbms_session_duration(tvbuff_t *tvb, packet_info *pinfo _U_, proto * 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; @@ -5007,7 +5051,7 @@ dissect_gtpv2_mbms_service_area(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre * 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. */ @@ -5022,7 +5066,7 @@ dissect_gtpv2_mbms_session_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree * 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. */ @@ -5044,7 +5088,7 @@ static const value_string gtpv2_mbms_hc_indicator_vals[] = { }; 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; @@ -5101,7 +5145,7 @@ static const value_string gtpv2_mbms_dist_indication_vals[] = { }; 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; @@ -5136,7 +5180,7 @@ static const value_string gtpv2_uci_leave_csg[] = { }; 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; @@ -5161,14 +5205,14 @@ dissect_gtpv2_uci(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_ite /* 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; @@ -5181,42 +5225,42 @@ dissect_gtpv2_rfsp_index(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree /* 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, 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.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, 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.80 Service indicator */ 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, 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.81 Detach Type */ 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, 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.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, 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.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); @@ -5231,7 +5275,7 @@ dissect_gtpv2_node_features(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t * 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; @@ -5259,7 +5303,7 @@ static const value_string gtpv2_throttling_delay_unit_vals[] = { /* 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; @@ -5282,7 +5326,7 @@ dissect_gtpv2_throttling(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree /* 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; @@ -5309,7 +5353,7 @@ static const value_string gtpv2_timer_unit_vals[] = { }; 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); @@ -5318,14 +5362,14 @@ dissect_gtpv2_epc_timer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, /* 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; @@ -5349,7 +5393,7 @@ dissect_gtpv2_tmgi(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, prot * 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; @@ -5392,7 +5436,7 @@ dissect_gtpv2_add_mm_cont_for_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto /* 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; @@ -5406,7 +5450,7 @@ dissect_gtpv2_add_flags_for_srvcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t /* 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; @@ -5427,14 +5471,14 @@ dissect_gtpv2_mmbr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, prot /* 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: @@ -5463,7 +5507,7 @@ dissect_gtpv2_apco(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, prot /* 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; @@ -5484,7 +5528,7 @@ static const true_false_string gtpv2_henb_info_report_fti_vals = { }; 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; @@ -5497,7 +5541,7 @@ dissect_gtpv2_henb_info_report(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree /* 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; @@ -5512,7 +5556,7 @@ dissect_gtpv2_ip4cp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pro /* 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; @@ -5539,7 +5583,7 @@ static const value_string gtpv2_action_indication_vals[] = { 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; @@ -5554,7 +5598,7 @@ dissect_gtpv2_action_indication(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre * 8.100 TWAN Identifier */ 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); } @@ -5562,7 +5606,7 @@ dissect_gtpv2_twan_Identifier(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree * 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; @@ -5579,7 +5623,7 @@ dissect_gtpv2_uli_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t * 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); } @@ -5587,7 +5631,7 @@ dissect_gtpv2_mbms_flags(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree * 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); } @@ -5595,7 +5639,7 @@ dissect_gtpv2_ran_nas_cause(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t * 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); } @@ -5603,7 +5647,7 @@ dissect_gtpv2_cn_operator_selection_entity(tvbuff_t *tvb, packet_info *pinfo _U_ * 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); } @@ -5611,7 +5655,7 @@ dissect_gtpv2_trust_wlan_mode_ind(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t * 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); } @@ -5619,7 +5663,7 @@ dissect_gtpv2_node_number(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre * 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); } @@ -5778,7 +5822,7 @@ static const value_string gtpv2_pres_rep_area_action_vals[] = { }; 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; @@ -5805,7 +5849,7 @@ dissect_gtpv2_pres_rep_area_action(tvbuff_t *tvb, packet_info *pinfo, proto_tree * 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); } @@ -5813,7 +5857,7 @@ dissect_gtpv2_pres_rep_area_information(tvbuff_t *tvb, packet_info *pinfo _U_, p * 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); } @@ -5822,7 +5866,7 @@ dissect_gtpv2_twan_identifier_timestamp(tvbuff_t *tvb, packet_info *pinfo _U_, p */ 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; @@ -5833,13 +5877,13 @@ dissect_gtpv2_overload_control_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_ 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 _U_, proto_item *item, 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_) { int offset = 0; tvbuff_t *new_tvb; @@ -5849,13 +5893,13 @@ dissect_gtpv2_load_control_inf(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree 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); + 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_) { guint32 oct; @@ -5871,7 +5915,7 @@ dissect_gtpv2_metric(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pr * 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_) { guint32 seq; proto_tree_add_item_ret_uint(tree, hf_gtpv2_sequence_number, tvb, 0, 4, ENC_BIG_ENDIAN, &seq); @@ -5881,7 +5925,7 @@ dissect_gtpv2_seq_no(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, pr * 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; @@ -5925,7 +5969,7 @@ dissect_gtpv2_apn_and_relative_capacity(tvbuff_t *tvb, packet_info *pinfo _U_, p * 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_) +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; @@ -5954,7 +5998,7 @@ dissect_gtpv2_paging_and_service_inf(tvbuff_t *tvb, packet_info *pinfo _U_, prot 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[] = { @@ -6099,9 +6143,10 @@ static const gtpv2_ie_t gtpv2_ies[] = { }; 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) +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) { @@ -6206,13 +6251,82 @@ gtpv2_match_response(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, gin } else { it = proto_tree_add_uint(tree, hf_gtpv2_response_to, tvb, 0, 0, gcrp->req_frame); 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; @@ -6263,7 +6377,7 @@ dissect_gtpv2_ie_common(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, } /* 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; @@ -6275,13 +6389,20 @@ dissect_gtpv2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data { 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"); @@ -6296,6 +6417,14 @@ dissect_gtpv2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data msg_length = tvb_get_ntohs(tvb, offset + 2); proto_tree_add_item(tree, proto_gtpv2, tvb, offset, msg_length + 4, ENC_NA); + 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()); + } + /* * Do we have a conversation for this connection? */ @@ -6317,63 +6446,75 @@ dissect_gtpv2(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data conversation_add_proto_data(conversation, proto_gtpv2, gtpv2_info); } - 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); - - /* 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; + 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; - /* 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; + /* 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 */ - 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_ret_uint(gtpv2_tree, hf_gtpv2_seq, tvb, offset, 3, ENC_BIG_ENDIAN, &seq_no); - offset += 3; + 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; + /* 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); - } else { - dissect_gtpv2_ie_common(tvb, pinfo, gtpv2_tree, offset, message_type); - } - /*Use sequence number to track Req/Resp pairs*/ - gtpv2_match_response(tvb, pinfo, gtpv2_tree, seq_no, message_type, gtpv2_info); + 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 @@ -8271,6 +8412,11 @@ void proto_register_gtpv2(void) 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 }}, diff --git a/epan/dissectors/packet-gtpv2.h b/epan/dissectors/packet-gtpv2.h index 3253e2a8cc..09760b076b 100644 --- a/epan/dissectors/packet-gtpv2.h +++ b/epan/dissectors/packet-gtpv2.h @@ -18,13 +18,14 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <epan/dissectors/packet-gtp.h> -extern void dissect_gtpv2_mbms_service_area(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_); -extern 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_); -extern void dissect_gtpv2_mbms_time_to_data_xfer(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, guint16 length _U_, guint8 message_type _U_, guint8 instance _U_); -extern 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_); -extern 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_); -extern 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_); -extern 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_); +extern void dissect_gtpv2_mbms_service_area(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_); +extern 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_, session_args_t * args _U_); +extern void dissect_gtpv2_mbms_time_to_data_xfer(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_); +extern 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_, session_args_t * args _U_); +extern 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_, session_args_t * args _U_); +extern 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_, session_args_t * args _U_); +extern 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_, session_args_t * args _U_); extern value_string_ext gtpv2_cause_vals_ext; diff --git a/epan/dissectors/packet-m3ap.c b/epan/dissectors/packet-m3ap.c index 91e1ccb5d7..ed9cf518fd 100644 --- a/epan/dissectors/packet-m3ap.c +++ b/epan/dissectors/packet-m3ap.c @@ -1064,7 +1064,7 @@ dissect_m3ap_MBMS_Service_Area(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *ac tvb_len = tvb_reported_length(parameter_tvb); - dissect_gtpv2_mbms_service_area(parameter_tvb, actx->pinfo, tree, actx->created_item, tvb_len, 0, 0); + dissect_gtpv2_mbms_service_area(parameter_tvb, actx->pinfo, tree, actx->created_item, tvb_len, 0, 0, NULL); return offset; @@ -1087,7 +1087,7 @@ dissect_m3ap_MBMS_Session_Duration(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t tvb_len = tvb_reported_length(parameter_tvb); proto_item_append_text(actx->created_item, " "); - dissect_gtpv2_mbms_session_duration(parameter_tvb, actx->pinfo, tree, actx->created_item, tvb_len, 0, 0); + dissect_gtpv2_mbms_session_duration(parameter_tvb, actx->pinfo, tree, actx->created_item, tvb_len, 0, 0, NULL); return offset; @@ -1129,7 +1129,7 @@ dissect_m3ap_MinimumTimeToMBMSDataTransfer(tvbuff_t *tvb _U_, int offset _U_, as return offset; tvb_len = tvb_reported_length(parameter_tvb); - dissect_gtpv2_mbms_time_to_data_xfer(parameter_tvb, actx->pinfo, tree, actx->created_item, tvb_len, 0, 0); + dissect_gtpv2_mbms_time_to_data_xfer(parameter_tvb, actx->pinfo, tree, actx->created_item, tvb_len, 0, 0, NULL); return offset; diff --git a/epan/dissectors/packet-mip6.c b/epan/dissectors/packet-mip6.c index 98c292f1ed..c216b66e37 100644 --- a/epan/dissectors/packet-mip6.c +++ b/epan/dissectors/packet-mip6.c @@ -1965,7 +1965,7 @@ dissect_mip6_opt_vsm_3gpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v */ case 5: next_tvb = tvb_new_subset_length(tvb, offset, len); - dissect_gtpv2_fq_csid(next_tvb, pinfo, tree, hdr_item, len, 0, 0); + dissect_gtpv2_fq_csid(next_tvb, pinfo, tree, hdr_item, len, 0, 0, NULL); break; /* 6, PMIPv6 PDN type indication */ case 6: @@ -1983,7 +1983,7 @@ dissect_mip6_opt_vsm_3gpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v /* 8, Selection Mode */ case 8: next_tvb = tvb_new_subset_length(tvb, offset, len); - dissect_gtpv2_selec_mode(next_tvb, pinfo, tree, hdr_item, len, 0, 0); + dissect_gtpv2_selec_mode(next_tvb, pinfo, tree, hdr_item, len, 0, 0, NULL); break; /* 9, I-WLAN Mobility Access Point Name (APN) */ /* 10, Charging Characteristics */ @@ -2029,7 +2029,7 @@ dissect_mip6_opt_vsm_3gpp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v /* 18, PGW Back-Off Time */ case 18: next_tvb = tvb_new_subset_length(tvb, offset, len); - dissect_gtpv2_epc_timer(next_tvb, pinfo, tree, hdr_item, len, 0, 0); + dissect_gtpv2_epc_timer(next_tvb, pinfo, tree, hdr_item, len, 0, 0, NULL); break; /* 19, Signalling Priority Indication */ case 19: |