S1AP: add dissection of NB-IoT transparent containers

To do so, memorize whether a given eNB UE S1AP ID belongs to a NB-IoT
TAI or not.
Also add a preference allowing to force dissection as legacy LTE or
NB-IoT if automatic mode fails.
While we are at it, let's remove the global variables and introduce
a S1AP private data info stored in pinfo.

Change-Id: I7e30b3d59d909684e5cfe13510293ed38ad52574
Reviewed-on: https://code.wireshark.org/review/17709
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>
This commit is contained in:
Pascal Quantin 2016-09-15 11:37:07 +02:00
parent f2e79776a7
commit c5a477e72a
6 changed files with 1906 additions and 1107 deletions

View File

@ -28,11 +28,13 @@ HandoverPreparationInformation-NB_PDU
RLF-Report-r9_PDU
RLF-Report-v9e0_PDU
SCG-ConfigInfo-r12_PDU
UEPagingCoverageInformation_PDU
UEPagingCoverageInformation-NB_PDU
UERadioAccessCapabilityInformation_PDU
UERadioAccessCapabilityInformation-NB_PDU
UE-EUTRA-Capability_PDU
UEPagingCoverageInformation_PDU
UERadioPagingInformation_PDU
UERadioPagingInformation-NB_PDU
VisitedCellInfoList-r12_PDU
#.END
@ -44,9 +46,11 @@ RLF-Report-r9
RLF-Report-v9e0
SCG-ConfigInfo-r12
UEPagingCoverageInformation
UEPagingCoverageInformation-NB
UERadioAccessCapabilityInformation
UERadioAccessCapabilityInformation-NB
UERadioPagingInformation
UERadioPagingInformation-NB
VisitedCellInfoList-r12
BCCH-BCH-Message @bcch.bch
BCCH-DL-SCH-Message @bcch.dl.sch
@ -88,10 +92,6 @@ SL-PreconfigRelay-r13
SL-PreconfigSync-r12
SL-Preconfiguration-r12
SL-TxPoolIdentity-r13
UEPagingCoverageInformation-NB
UEPagingCoverageInformation-NB-IEs
UERadioPagingInformation-NB
UERadioPagingInformation-NB-IEs
VarConnEstFailReport-r11
VarLogMeasConfig-r10
VarLogMeasConfig-r11

View File

@ -34,6 +34,8 @@
#include <epan/prefs.h>
#include <epan/sctpppids.h>
#include <epan/expert.h>
#include <epan/conversation.h>
#include <epan/proto_data.h>
#include "packet-ber.h"
#include "packet-per.h"
@ -144,21 +146,56 @@ enum{
UNSUCCESSFUL_OUTCOME
};
struct s1ap_conv_info {
wmem_map_t *nbiot_ta;
wmem_tree_t *nbiot_enb_ue_s1ap_id;
};
struct s1ap_supported_ta {
guint16 tac;
wmem_array_t *plmn;
};
struct s1ap_tai {
guint32 plmn;
guint16 tac;
};
struct s1ap_private_data {
struct s1ap_conv_info *s1ap_conv;
guint32 procedure_code;
guint32 protocol_ie_id;
guint32 protocol_extension_id;
guint32 handover_type_value;
guint32 message_type;
guint8 data_coding_scheme;
struct s1ap_supported_ta *supported_ta;
const char *obj_id;
struct s1ap_tai *tai;
guint16 enb_ue_s1ap_id;
};
enum {
S1AP_LTE_CONTAINER_AUTOMATIC,
S1AP_LTE_CONTAINER_LEGACY,
S1AP_LTE_CONTAINER_NBIOT
};
static const enum_val_t s1ap_lte_container_vals[] = {
{"automatic", "Automatic", S1AP_LTE_CONTAINER_AUTOMATIC},
{"legacy", "Legacy LTE", S1AP_LTE_CONTAINER_LEGACY},
{"nb-iot","NB-IoT", S1AP_LTE_CONTAINER_NBIOT},
{NULL, NULL, -1}
};
/* Global variables */
static guint32 ProcedureCode;
static guint32 ProtocolIE_ID;
static guint32 ProtocolExtensionID;
static guint gbl_s1apSctpPort=SCTP_PORT_S1AP;
static guint32 handover_type_value;
static guint32 message_type;
static gboolean g_s1ap_dissect_container = TRUE;
static const char *obj_id = NULL;
static guint8 dataCodingScheme = SMS_ENCODING_NOT_SET;
static gint g_s1ap_dissect_lte_container_as = S1AP_LTE_CONTAINER_AUTOMATIC;
static dissector_handle_t gcsna_handle = NULL;
static dissector_handle_t s1ap_handle;
/* Dissector tables */
static dissector_table_t s1ap_ies_dissector_table;
static dissector_table_t s1ap_ies_p1_dissector_table;
@ -268,56 +305,103 @@ static const true_false_string s1ap_tfs_activate_do_not_activate = {
"Do not activate"
};
static struct s1ap_private_data*
s1ap_get_private_data(packet_info *pinfo)
{
struct s1ap_private_data *s1ap_data = (struct s1ap_private_data*)p_get_proto_data(pinfo->pool, pinfo, proto_s1ap, 0);
if (!s1ap_data) {
s1ap_data = wmem_new0(pinfo->pool, struct s1ap_private_data);
p_add_proto_data(pinfo->pool, pinfo, proto_s1ap, 0, s1ap_data);
}
return s1ap_data;
}
static gboolean
s1ap_is_nbiot_ue(packet_info *pinfo)
{
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(pinfo);
if (s1ap_data->s1ap_conv) {
wmem_tree_key_t tree_key[3];
guint32 *id;
guint32 enb_ue_s1ap_id = s1ap_data->enb_ue_s1ap_id;
tree_key[0].length = 1;
tree_key[0].key = &enb_ue_s1ap_id;
tree_key[1].length = 1;
tree_key[1].key = &pinfo->num;
tree_key[2].length = 0;
tree_key[2].key = NULL;
id = (guint32*)wmem_tree_lookup32_array_le(s1ap_data->s1ap_conv->nbiot_enb_ue_s1ap_id, tree_key);
if (id && (*id == enb_ue_s1ap_id)) {
return TRUE;
}
}
return FALSE;
}
#include "packet-s1ap-fn.c"
static int dissect_ProtocolIEFieldValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
s1ap_ctx_t s1ap_ctx;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(pinfo);
s1ap_ctx.message_type = message_type;
s1ap_ctx.ProcedureCode = ProcedureCode;
s1ap_ctx.ProtocolIE_ID = ProtocolIE_ID;
s1ap_ctx.ProtocolExtensionID = ProtocolExtensionID;
s1ap_ctx.message_type = s1ap_data->message_type;
s1ap_ctx.ProcedureCode = s1ap_data->procedure_code;
s1ap_ctx.ProtocolIE_ID = s1ap_data->protocol_ie_id;
s1ap_ctx.ProtocolExtensionID = s1ap_data->protocol_extension_id;
return (dissector_try_uint_new(s1ap_ies_dissector_table, ProtocolIE_ID, tvb, pinfo, tree, TRUE, &s1ap_ctx)) ? tvb_captured_length(tvb) : 0;
return (dissector_try_uint_new(s1ap_ies_dissector_table, s1ap_data->protocol_ie_id, tvb, pinfo, tree, TRUE, &s1ap_ctx)) ? tvb_captured_length(tvb) : 0;
}
/* Currently not used
static int dissect_ProtocolIEFieldPairFirstValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
return (dissector_try_uint(s1ap_ies_p1_dissector_table, ProtocolIE_ID, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(pinfo);
return (dissector_try_uint(s1ap_ies_p1_dissector_table, s1ap_data->protocol_ie_id, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
}
static int dissect_ProtocolIEFieldPairSecondValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
return (dissector_try_uint(s1ap_ies_p2_dissector_table, ProtocolIE_ID, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(pinfo);
return (dissector_try_uint(s1ap_ies_p2_dissector_table, s1ap_data->protocol_ie_id, tvb, pinfo, tree)) ? tvb_captured_length(tvb) : 0;
}
*/
static int dissect_ProtocolExtensionFieldExtensionValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
s1ap_ctx_t s1ap_ctx;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(pinfo);
s1ap_ctx.message_type = message_type;
s1ap_ctx.ProcedureCode = ProcedureCode;
s1ap_ctx.ProtocolIE_ID = ProtocolIE_ID;
s1ap_ctx.ProtocolExtensionID = ProtocolExtensionID;
s1ap_ctx.message_type = s1ap_data->message_type;
s1ap_ctx.ProcedureCode = s1ap_data->procedure_code;
s1ap_ctx.ProtocolIE_ID = s1ap_data->protocol_ie_id;
s1ap_ctx.ProtocolExtensionID = s1ap_data->protocol_extension_id;
return (dissector_try_uint_new(s1ap_extension_dissector_table, ProtocolExtensionID, tvb, pinfo, tree, TRUE, &s1ap_ctx)) ? tvb_captured_length(tvb) : 0;
return (dissector_try_uint_new(s1ap_extension_dissector_table, s1ap_data->protocol_extension_id, tvb, pinfo, tree, TRUE, &s1ap_ctx)) ? tvb_captured_length(tvb) : 0;
}
static int dissect_InitiatingMessageValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
return (dissector_try_uint_new(s1ap_proc_imsg_dissector_table, ProcedureCode, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(pinfo);
return (dissector_try_uint_new(s1ap_proc_imsg_dissector_table, s1ap_data->procedure_code, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
}
static int dissect_SuccessfulOutcomeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
return (dissector_try_uint_new(s1ap_proc_sout_dissector_table, ProcedureCode, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(pinfo);
return (dissector_try_uint_new(s1ap_proc_sout_dissector_table, s1ap_data->procedure_code, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
}
static int dissect_UnsuccessfulOutcomeValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
return (dissector_try_uint_new(s1ap_proc_uout_dissector_table, ProcedureCode, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(pinfo);
return (dissector_try_uint_new(s1ap_proc_uout_dissector_table, s1ap_data->procedure_code, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
}
@ -326,6 +410,8 @@ dissect_s1ap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
{
proto_item *s1ap_item = NULL;
proto_tree *s1ap_tree = NULL;
conversation_t *conversation;
struct s1ap_private_data* s1ap_data;
/* make entry in the Protocol column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "S1AP");
@ -336,6 +422,16 @@ dissect_s1ap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
s1ap_item = proto_tree_add_item(tree, proto_s1ap, tvb, 0, -1, ENC_NA);
s1ap_tree = proto_item_add_subtree(s1ap_item, ett_s1ap);
s1ap_data = s1ap_get_private_data(pinfo);
conversation = find_or_create_conversation(pinfo);
s1ap_data->s1ap_conv = (struct s1ap_conv_info *)conversation_get_proto_data(conversation, proto_s1ap);
if (!s1ap_data->s1ap_conv) {
s1ap_data->s1ap_conv = wmem_new(wmem_file_scope(), struct s1ap_conv_info);
s1ap_data->s1ap_conv->nbiot_ta = wmem_map_new(wmem_file_scope(), wmem_int64_hash, g_int64_equal);
s1ap_data->s1ap_conv->nbiot_enb_ue_s1ap_id = wmem_tree_new(wmem_file_scope());
conversation_add_proto_data(conversation, proto_s1ap, s1ap_data->s1ap_conv);
}
dissect_S1AP_PDU_PDU(tvb, pinfo, s1ap_tree, NULL);
return tvb_captured_length(tvb);
}
@ -588,7 +684,9 @@ void proto_register_s1ap(void) {
10,
&gbl_s1apSctpPort);
prefs_register_bool_preference(s1ap_module, "dissect_container", "Dissect TransparentContainer", "Dissect TransparentContainers that are opaque to S1AP", &g_s1ap_dissect_container);
prefs_register_enum_preference(s1ap_module, "dissect_lte_container_as", "Dissect LTE TransparentContainer as",
"Select whether LTE TransparentContainer should be dissected as NB-IOT or legacy LTE",
&g_s1ap_dissect_lte_container_as, s1ap_lte_container_vals, FALSE);
}
/*

View File

@ -44,6 +44,7 @@ UE-HistoryInformation
#.MAKE_ENUM
ProcedureCode
ProtocolIE-ID
RAT-Type
#.NO_EMIT
TBCD-STRING
@ -86,10 +87,14 @@ ProtocolExtensionField/id ext_id
#PrivateIE-Field/value private_value
ProtocolIE-Field/value ie_field_value
#.FN_PARS ProtocolIE-ID VAL_PTR=&ProtocolIE_ID
#.FN_BODY ProtocolIE-ID VAL_PTR=&s1ap_data->protocol_ie_id
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
%(DEFAULT_BODY)s
#.FN_FTR ProtocolIE-ID
if (tree) {
proto_item_append_text(proto_item_get_parent_nth(actx->created_item, 2), ": %s", val_to_str_ext(ProtocolIE_ID, &s1ap_ProtocolIE_ID_vals_ext, "unknown (%d)"));
proto_item_append_text(proto_item_get_parent_nth(actx->created_item, 2), ": %s",
val_to_str_ext(s1ap_data->protocol_ie_id, &s1ap_ProtocolIE_ID_vals_ext, "unknown (%d)"));
}
#.END
@ -100,21 +105,29 @@ ProtocolIE-Field/value ie_field_value
# FN_PARS ProtocolIE-FieldPair/firstValue FN_VARIANT=_pdu_new TYPE_REF_FN=dissect_ProtocolIEFieldPairFirstValue
# FN_PARS ProtocolIE-FieldPair/secondValue FN_VARIANT=_pdu_new TYPE_REF_FN=dissect_ProtocolIEFieldPairSecondValue
#.FN_PARS ProtocolExtensionID VAL_PTR=&ProtocolExtensionID
#.FN_BODY ProtocolExtensionID VAL_PTR=&s1ap_data->protocol_extension_id
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
%(DEFAULT_BODY)s
#.FN_PARS ProtocolExtensionField/extensionValue FN_VARIANT=_pdu_new TYPE_REF_FN=dissect_ProtocolExtensionFieldExtensionValue
#.FN_PARS ProcedureCode VAL_PTR = &ProcedureCode
#.FN_BODY ProcedureCode VAL_PTR = &s1ap_data->procedure_code
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
%(DEFAULT_BODY)s
#.END
#.FN_PARS InitiatingMessage/value FN_VARIANT=_pdu_new TYPE_REF_FN=dissect_InitiatingMessageValue
#.FN_HDR InitiatingMessage/value
message_type = INITIATING_MESSAGE;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->message_type = INITIATING_MESSAGE;
#.FN_PARS SuccessfulOutcome/value FN_VARIANT=_pdu_new TYPE_REF_FN=dissect_SuccessfulOutcomeValue
#.FN_HDR SuccessfulOutcome/value
message_type = SUCCESSFUL_OUTCOME;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->message_type = SUCCESSFUL_OUTCOME;
#.FN_PARS UnsuccessfulOutcome/value FN_VARIANT=_pdu_new TYPE_REF_FN=dissect_UnsuccessfulOutcomeValue
#.FN_HDR UnsuccessfulOutcome/value
message_type = UNSUCCESSFUL_OUTCOME;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->message_type = UNSUCCESSFUL_OUTCOME;
#--- Parameterization is not supported in asn2wrs ---
@ -181,15 +194,18 @@ MAX_VAL = asn1_param_get_integer(%(ACTX)s,"upperBound")
# END
#.FN_HDR PrivateIE-ID
obj_id = NULL;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->obj_id = NULL;
#.FN_PARS PrivateIE-ID/global FN_VARIANT = _str VAL_PTR = &obj_id
#.FN_BODY PrivateIE-ID/global FN_VARIANT = _str VAL_PTR = &s1ap_data->obj_id
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
%(DEFAULT_BODY)s
#.FN_BODY PrivateIE-Field/value
if (obj_id){
offset=call_per_oid_callback(obj_id, tvb, actx->pinfo, tree, offset, actx, hf_index);
}else{
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
if (s1ap_data->obj_id) {
offset = call_per_oid_callback(s1ap_data->obj_id, tvb, actx->pinfo, tree, offset, actx, hf_index);
} else {
%(DEFAULT_BODY)s
}
@ -200,6 +216,7 @@ obj_id = NULL;
#.FN_BODY PLMNidentity VAL_PTR = parameter_tvb
tvbuff_t *parameter_tvb=NULL;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
3, 3, FALSE, &parameter_tvb);
@ -209,6 +226,12 @@ obj_id = NULL;
if (!parameter_tvb)
return offset;
dissect_e212_mcc_mnc(parameter_tvb, actx->pinfo, tree, 0, E212_NONE, FALSE);
if (s1ap_data->supported_ta) {
guint32 plmn = tvb_get_ntoh24(parameter_tvb, 0);
wmem_array_append_one(s1ap_data->supported_ta->plmn, plmn);
} else if (s1ap_data->tai) {
s1ap_data->tai->plmn = tvb_get_ntoh24(parameter_tvb, 0);
}
#.END
#.FN_BODY ENBname VAL_PTR = parameter_tvb
@ -328,19 +351,23 @@ Port-Number TYPE = FT_UINT16 DISPLAY = BASE_DEC
/* Set the direction of the message */
actx->pinfo->link_dir=P2P_DIR_UL;
#.FN_BODY HandoverType VAL_PTR = &handover_type_value
#.FN_BODY HandoverType VAL_PTR = &s1ap_data->handover_type_value
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
%(DEFAULT_BODY)s
#Zero the value before use
#.FN_HDR HandoverRequired
handover_type_value = 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->handover_type_value = 0;
#.FN_HDR HandoverCommand
handover_type_value = 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->handover_type_value = 0;
#.FN_HDR HandoverRequest
handover_type_value = 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->handover_type_value = 0;
#.FN_HDR HandoverRequestAcknowledge
handover_type_value = 0;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->handover_type_value = 0;
#.FN_BODY Source-ToTarget-TransparentContainer VAL_PTR = &parameter_tvb
# I think the message is "directly encoded" into the octet string(no "double encoding")
@ -356,11 +383,12 @@ Port-Number TYPE = FT_UINT16 DISPLAY = BASE_DEC
%(DEFAULT_BODY)s
if (g_s1ap_dissect_container) {
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
/* Don't want elements inside container to write to info column */
col_set_writable(actx->pinfo->cinfo, COL_INFO, FALSE);
subtree = proto_item_add_subtree(actx->created_item, ett_s1ap_ToTargetTransparentContainer);
switch(handover_type_value){
switch(s1ap_data->handover_type_value){
/*
HandoverType ::= ENUMERATED {
intralte,
@ -414,9 +442,10 @@ Port-Number TYPE = FT_UINT16 DISPLAY = BASE_DEC
%(DEFAULT_BODY)s
if (g_s1ap_dissect_container) {
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
subtree = proto_item_add_subtree(actx->created_item, ett_s1ap_ToSourceTransparentContainer);
switch(handover_type_value){
switch(s1ap_data->handover_type_value){
/*
HandoverType ::= ENUMERATED {
intralte,
@ -505,12 +534,18 @@ Port-Number TYPE = FT_UINT16 DISPLAY = BASE_DEC
return offset;
if (g_s1ap_dissect_container) {
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
subtree = proto_item_add_subtree(actx->created_item, ett_s1ap_RRCContainer);
switch(message_type){
switch(s1ap_data->message_type){
case INITIATING_MESSAGE:
/* 9.2.1.7 Source eNB to Target eNB Transparent Container */
dissect_lte_rrc_HandoverPreparationInformation_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
if ((s1ap_is_nbiot_ue(actx->pinfo) && (g_s1ap_dissect_lte_container_as == S1AP_LTE_CONTAINER_AUTOMATIC)) ||
(g_s1ap_dissect_lte_container_as == S1AP_LTE_CONTAINER_NBIOT)) {
dissect_lte_rrc_HandoverPreparationInformation_NB_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
} else {
dissect_lte_rrc_HandoverPreparationInformation_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
}
break;
case SUCCESSFUL_OUTCOME:
/* 9.2.1.8 Target eNB to Source eNB Transparent Container */
@ -544,7 +579,12 @@ Port-Number TYPE = FT_UINT16 DISPLAY = BASE_DEC
if (g_s1ap_dissect_container) {
subtree = proto_item_add_subtree(actx->created_item, ett_s1ap_UERadioCapability);
dissect_lte_rrc_UERadioAccessCapabilityInformation_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
if ((s1ap_is_nbiot_ue(actx->pinfo) && (g_s1ap_dissect_lte_container_as == S1AP_LTE_CONTAINER_AUTOMATIC)) ||
(g_s1ap_dissect_lte_container_as == S1AP_LTE_CONTAINER_NBIOT)) {
dissect_lte_rrc_UERadioAccessCapabilityInformation_NB_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
} else {
dissect_lte_rrc_UERadioAccessCapabilityInformation_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
}
}
#.TYPE_ATTR
@ -617,7 +657,12 @@ if (gcsna_handle) {
if (g_s1ap_dissect_container) {
subtree = proto_item_add_subtree(actx->created_item, ett_s1ap_UERadioPagingInformation);
dissect_lte_rrc_UERadioPagingInformation_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
if ((s1ap_is_nbiot_ue(actx->pinfo) && (g_s1ap_dissect_lte_container_as == S1AP_LTE_CONTAINER_AUTOMATIC)) ||
(g_s1ap_dissect_lte_container_as == S1AP_LTE_CONTAINER_NBIOT)) {
dissect_lte_rrc_UERadioPagingInformation_NB_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
} else {
dissect_lte_rrc_UERadioPagingInformation_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
}
}
#.FN_BODY CELevel VAL_PTR = &parameter_tvb
@ -631,7 +676,12 @@ if (gcsna_handle) {
if (g_s1ap_dissect_container) {
subtree = proto_item_add_subtree(actx->created_item, ett_s1ap_CELevel);
dissect_lte_rrc_UEPagingCoverageInformation_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
if ((s1ap_is_nbiot_ue(actx->pinfo) && (g_s1ap_dissect_lte_container_as == S1AP_LTE_CONTAINER_AUTOMATIC)) ||
(g_s1ap_dissect_lte_container_as == S1AP_LTE_CONTAINER_NBIOT)) {
dissect_lte_rrc_UEPagingCoverageInformation_NB_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
} else {
dissect_lte_rrc_UEPagingCoverageInformation_PDU(parameter_tvb, actx->pinfo, subtree, NULL);
}
}
#.FN_BODY UE-RLF-Report-Container VAL_PTR = &parameter_tvb
@ -821,18 +871,20 @@ MessageIdentifier TYPE = FT_UINT16 DISPLAY = BASE_DEC|BASE_EXT_STRING STRINGS =
tvbuff_t *parameter_tvb = NULL;
%(DEFAULT_BODY)s
if (parameter_tvb) {
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
proto_tree *subtree;
subtree = proto_item_add_subtree(actx->created_item, ett_s1ap_DataCodingScheme);
dataCodingScheme = dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree, 0);
s1ap_data->data_coding_scheme = dissect_cbs_data_coding_scheme(parameter_tvb, actx->pinfo, subtree, 0);
}
#.FN_BODY WarningMessageContents VAL_PTR = &parameter_tvb
tvbuff_t *parameter_tvb = NULL;
%(DEFAULT_BODY)s
if (parameter_tvb) {
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
proto_tree *subtree = proto_item_add_subtree(actx->created_item, ett_s1ap_WarningMessageContents);
dissect_s1ap_warningMessageContents(parameter_tvb, subtree, actx->pinfo, dataCodingScheme);
dissect_s1ap_warningMessageContents(parameter_tvb, subtree, actx->pinfo, s1ap_data->data_coding_scheme);
}
#.FN_BODY MSClassmark2 VAL_PTR = &parameter_tvb
@ -911,9 +963,15 @@ proto_item_append_text(actx->created_item, "s");
TAC TYPE = FT_UINT16 DISPLAY = BASE_DEC_HEX
#.FN_BODY TAC VAL_PTR = &parameter_tvb HF_INDEX = -1
tvbuff_t *parameter_tvb = NULL;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
%(DEFAULT_BODY)s
if (parameter_tvb) {
actx->created_item = proto_tree_add_item(tree, hf_index, parameter_tvb, 0, 2, ENC_BIG_ENDIAN);
if (s1ap_data->supported_ta) {
s1ap_data->supported_ta->tac = tvb_get_ntohs(parameter_tvb, 0);
} else if (s1ap_data->tai) {
s1ap_data->tai->tac = tvb_get_ntohs(parameter_tvb, 0);
}
}
#.TYPE_ATTR
@ -967,6 +1025,66 @@ M-TMSI TYPE = FT_UINT32 DISPLAY = BASE_DEC_HEX
de_emm_sec_par_to_eutra(parameter_tvb, subtree, actx->pinfo, 0, tvb_reported_length(parameter_tvb), NULL, 0);
}
#.FN_HDR SupportedTAs-Item
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
if (!PINFO_FD_VISITED(actx->pinfo) &&
(s1ap_data->message_type == INITIATING_MESSAGE) &&
((s1ap_data->procedure_code == id_S1Setup) ||
(s1ap_data->procedure_code == id_ENBConfigurationUpdate))) {
s1ap_data->supported_ta = wmem_new0(wmem_packet_scope(), struct s1ap_supported_ta);
s1ap_data->supported_ta->plmn = wmem_array_new(wmem_packet_scope(), sizeof(guint32));
}
#.FN_FTR SupportedTAs-Item
s1ap_data->supported_ta = NULL;
#.FN_BODY RAT-Type VAL_PTR = &rat_type
guint32 rat_type = 0xffffffff;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
%(DEFAULT_BODY)s
if (s1ap_data->s1ap_conv && s1ap_data->supported_ta && (rat_type == nbiot)) {
guint64 *key;
guint i;
for (i = 0; i < wmem_array_get_count(s1ap_data->supported_ta->plmn); i++) {
key = wmem_new(wmem_file_scope(), guint64);
*key = ((*(guint32*)wmem_array_index(s1ap_data->supported_ta->plmn, i)) << 16) | s1ap_data->supported_ta->tac;
wmem_map_insert(s1ap_data->s1ap_conv->nbiot_ta, key, GUINT_TO_POINTER(1));
}
}
#.FN_BODY ENB-UE-S1AP-ID VAL_PTR = &enb_ue_s1ap_id
guint32 enb_ue_s1ap_id;
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
%(DEFAULT_BODY)s
s1ap_data->enb_ue_s1ap_id = (guint16)enb_ue_s1ap_id;
#.FN_BODY TAI
struct s1ap_private_data *s1ap_data = s1ap_get_private_data(actx->pinfo);
s1ap_data->tai = wmem_new0(wmem_packet_scope(), struct s1ap_tai);
%(DEFAULT_BODY)s
if (!PINFO_FD_VISITED(actx->pinfo) && s1ap_data->s1ap_conv &&
(s1ap_data->message_type == INITIATING_MESSAGE) &&
(s1ap_data->procedure_code == id_initialUEMessage)) {
guint64 key = (s1ap_data->tai->plmn << 16) | s1ap_data->tai->tac;
if (wmem_map_lookup(s1ap_data->s1ap_conv->nbiot_ta, &key)) {
wmem_tree_key_t tree_key[3];
guint32 *id = wmem_new(wmem_file_scope(), guint32);
*id = s1ap_data->enb_ue_s1ap_id;
tree_key[0].length = 1;
tree_key[0].key = id;
tree_key[1].length = 1;
tree_key[1].key = &actx->pinfo->num;
tree_key[2].length = 0;
tree_key[2].key = NULL;
wmem_tree_insert32_array(s1ap_data->s1ap_conv->nbiot_enb_ue_s1ap_id, tree_key, id);
}
}
#.ASSIGN_VALUE_TO_TYPE # S1AP does not have constants assigned to types, they are pure INTEGER
# ProcedureCode
@ -1759,7 +1877,6 @@ col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "OverloadStart");
col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "OverloadStop");
#.FN_HDR WriteReplaceWarningRequest
col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "WriteReplaceWarningRequest");
dataCodingScheme = SMS_ENCODING_NOT_SET;
#.FN_HDR WriteReplaceWarningResponse
col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "WriteReplaceWarningResponse");
#.FN_HDR ENBDirectInformationTransfer

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,9 @@ int dissect_lte_rrc_RLF_Report_v9e0_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U
int dissect_lte_rrc_UE_EUTRA_Capability_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
int dissect_lte_rrc_VisitedCellInfoList_r12_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
int dissect_lte_rrc_HandoverPreparationInformation_NB_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
int dissect_lte_rrc_UEPagingCoverageInformation_NB_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
int dissect_lte_rrc_UERadioAccessCapabilityInformation_NB_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
int dissect_lte_rrc_UERadioPagingInformation_NB_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
/*--- End of included file: packet-lte-rrc-exp.h ---*/
#line 29 "./asn1/lte-rrc/packet-lte-rrc-template.h"

File diff suppressed because it is too large Load Diff