forked from osmocom/wireshark
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:
parent
f2e79776a7
commit
c5a477e72a
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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, ¶meter_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 = ¶meter_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 = ¶meter_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 = ¶meter_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 = ¶meter_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 = ¶meter_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 = ¶meter_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
|
@ -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
Loading…
Reference in New Issue