summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/asn1/e2ap
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:33 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:33 +0000
commit9f153fbfec0fb9c9ce38e749a7c6f4a5e115d4e9 (patch)
tree2784370cda9bbf2da9114d70f05399c0b229d28c /epan/dissectors/asn1/e2ap
parentAdding debian version 4.2.6-1. (diff)
downloadwireshark-9f153fbfec0fb9c9ce38e749a7c6f4a5e115d4e9.tar.xz
wireshark-9f153fbfec0fb9c9ce38e749a7c6f4a5e115d4e9.zip
Merging upstream version 4.4.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/asn1/e2ap')
-rw-r--r--epan/dissectors/asn1/e2ap/e2ap.cnf130
-rw-r--r--epan/dissectors/asn1/e2ap/packet-e2ap-template.c450
2 files changed, 450 insertions, 130 deletions
diff --git a/epan/dissectors/asn1/e2ap/e2ap.cnf b/epan/dissectors/asn1/e2ap/e2ap.cnf
index dc37391d..205bdefd 100644
--- a/epan/dissectors/asn1/e2ap/e2ap.cnf
+++ b/epan/dissectors/asn1/e2ap/e2ap.cnf
@@ -111,7 +111,7 @@ SuccessfulOutcome/value successfulOutcome_value
# TODO: probably not worth it
# #.FN_BODY E2AP-PDU VAL_PTR=&value
-# guint32 value;
+# uint32_t value;
# %(DEFAULT_BODY)s
# col_append_fstr(actx->pinfo->cinfo, COL_INFO, " (%%s)", val_to_str(value, e2ap_E2AP_PDU_vals, "Unknown"));
@@ -259,25 +259,36 @@ SuccessfulOutcome/value successfulOutcome_value
%(DEFAULT_BODY)s
/* Looking for shortName string near beginning of tvb */
- gboolean found = FALSE;
+ bool found = false;
/* For each RAN function name.. */
- for (int n=KPM_RANFUNCTIONS; n<MAX_RANFUNCTIONS && !found; n++) {
- guint32 tvb_len = tvb_captured_length(parameter_tvb);
- guint name_len = (gint)strlen(g_ran_function_name_table[n]);
+ int n, found_index;
+ for (n=KPM_RANFUNCTIONS; n<MAX_RANFUNCTIONS && !found; n++) {
+ uint32_t tvb_len = tvb_captured_length(parameter_tvb);
+ unsigned name_len = (int)strlen(g_ran_function_name_table[n]);
/* For each of several byte positions.. */
for (int m=0; (m<30) && ((m+name_len+1))<tvb_len; m++) {
/* Have we found a match on the name? */
if (tvb_strneql(parameter_tvb, m, g_ran_function_name_table[n], name_len) == 0) {
- /* TODO: we don't yet know the OID (hopefully won't make a difference for this message though...),
+ /* We don't yet know the OID (should be OK),
so for now just call with the first/only available dissector for this RAN Function name */
if (g_ran_functions_available_dissectors[n].num_available_dissectors) {
g_ran_functions_available_dissectors[n].ran_function_dissectors[0]->functions.ran_function_definition_dissector(parameter_tvb, actx->pinfo, tree, NULL);
- found = TRUE;
+ found = true;
+ found_index = n;
break;
}
}
}
}
+
+ if (found && (found_index==CCC_RANFUNCTIONS)) {
+ // ranFunctionName, for this ranFunction, is inside the JSON. Rather than try to retrive it,
+ // just use this proxy that ought to appear at the start... OID should get set in the normal way.
+ if (!actx->pinfo->fd->visited) {
+ e2ap_store_ran_function_mapping(actx->pinfo, tree, parameter_tvb, "{" /*"ORAN-E2SM-CCC"*/);
+ }
+ }
+
if (!found) {
proto_item *ti = proto_tree_add_item(tree, hf_e2ap_ran_function_name_not_recognised, tvb, 0, 0, ENC_NA);
expert_add_info_format(actx->pinfo, ti, &ei_e2ap_ran_function_names_no_match,
@@ -290,18 +301,21 @@ SuccessfulOutcome/value successfulOutcome_value
if (!actx->pinfo->fd->visited) {
/* N.B. too early to work out exact dissector, as don't have OID yet */
e2ap_store_ran_function_mapping(actx->pinfo, tree, value_tvb,
- tvb_get_string_enc(wmem_packet_scope(), value_tvb, 0, tvb_captured_length(value_tvb), ENC_ASCII));
+ tvb_get_string_enc(actx->pinfo->pool, value_tvb, 0, tvb_captured_length(value_tvb), ENC_ASCII));
}
-
-#.FN_BODY RANfunction-Name/ranFunction-E2SM-OID VAL_PTR = &parameter_tvb
+#.FN_BODY RANfunctionOID VAL_PTR = &parameter_tvb
tvbuff_t *parameter_tvb;
%(DEFAULT_BODY)s
+ /* Now complete mapping with OID string */
e2ap_update_ran_function_mapping(actx->pinfo, tree, parameter_tvb,
tvb_get_string_enc(actx->pinfo->pool, parameter_tvb, 0,
tvb_captured_length(parameter_tvb), ENC_ASCII));
+
+# TODO: for these IEs, report as expert info if have RAN Function dissector, but it lacks that IE!
+
#.FN_BODY RICcontrolHeader VAL_PTR = &parameter_tvb
tvbuff_t *parameter_tvb;
%(DEFAULT_BODY)s
@@ -712,7 +726,7 @@ RICQueryResponse N e2ap.proc.sout id-RICquery
#.FN_BODY RANfunctionID VAL_PTR=&value
- guint32 value;
+ uint32_t value;
%(DEFAULT_BODY)s
/* Store value in packet-private data */
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(actx->pinfo);
@@ -753,9 +767,9 @@ RICQueryResponse N e2ap.proc.sout id-RICquery
if (e2ap_data->component_configuration_dissector) {
col_append_str(actx->pinfo->cinfo, COL_PROTOCOL, "|");
col_set_fence(actx->pinfo->cinfo, COL_PROTOCOL);
- col_set_writable(actx->pinfo->cinfo, COL_INFO, FALSE);
+ col_set_writable(actx->pinfo->cinfo, COL_INFO, false);
call_dissector(e2ap_data->component_configuration_dissector, value_tvb, actx->pinfo, tree);
- col_set_writable(actx->pinfo->cinfo, COL_INFO, TRUE);
+ col_set_writable(actx->pinfo->cinfo, COL_INFO, true);
}
#.FN_BODY E2nodeComponentConfiguration/e2nodeComponentResponsePart VAL_PTR=&value_tvb
@@ -763,9 +777,9 @@ RICQueryResponse N e2ap.proc.sout id-RICquery
%(DEFAULT_BODY)s
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(actx->pinfo);
if (e2ap_data->component_configuration_dissector) {
- col_set_writable(actx->pinfo->cinfo, COL_INFO, FALSE);
+ col_set_writable(actx->pinfo->cinfo, COL_INFO, false);
call_dissector(e2ap_data->component_configuration_dissector, value_tvb, actx->pinfo, tree);
- col_set_writable(actx->pinfo->cinfo, COL_INFO, TRUE);
+ col_set_writable(actx->pinfo->cinfo, COL_INFO, true);
}
@@ -809,98 +823,130 @@ RICQueryResponse N e2ap.proc.sout id-RICquery
+# Set labels and update stats for the various message types
+
#.FN_HDR E2connectionUpdate
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2connectionUpdate");
+ set_message_label(actx, MTYPE_E2_CONNECTION_UPDATE);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_CONNECTION_UPDATE);
+
#.FN_HDR E2connectionUpdateAcknowledge
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2connectionUpdateAcknowledge");
+ set_message_label(actx, MTYPE_E2_CONNECTION_UPDATE_ACK);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_CONNECTION_UPDATE_ACK);
#.FN_HDR E2connectionUpdateFailure
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2connectionUpdateFailure");
+ set_message_label(actx, MTYPE_E2_CONNECTION_UPDATE_FAIL);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_CONNECTION_UPDATE_FAIL);
#.FN_HDR E2nodeConfigurationUpdate
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2nodeConfigurationUpdate");
+ set_message_label(actx, MTYPE_E2_CONFIGURATION_UPDATE_FAIL);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_CONFIGURATION_UPDATE_FAIL);
+
#.FN_HDR E2nodeConfigurationUpdateAcknowledge
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2nodeConfigurationUpdateAcknowledge");
+ set_message_label(actx, MTYPE_E2_CONFIGURATION_UPDATE_ACK);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_CONFIGURATION_UPDATE_ACK);
#.FN_HDR E2nodeConfigurationUpdateFailure
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2nodeConfigurationUpdateFailure");
+ set_message_label(actx, MTYPE_E2_CONFIGURATION_UPDATE_FAIL);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_CONFIGURATION_UPDATE_FAIL);
#.FN_HDR E2setupFailure
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2setupFailure");
+ set_message_label(actx, MTYPE_E2_SETUP_FAIL);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_SETUP_FAIL);
#.FN_HDR E2setupRequest
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2setupRequest");
+ set_message_label(actx, MTYPE_E2_SETUP_REQUEST);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_SETUP_REQUEST);
#.FN_HDR E2setupResponse
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "E2setupResponse");
+ set_message_label(actx, MTYPE_E2_SETUP_RESPONSE);
+ set_stats_message_type(actx->pinfo, MTYPE_E2_SETUP_RESPONSE);
+
#.FN_HDR ErrorIndication
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "ErrorIndication");
+ set_message_label(actx, MTYPE_ERROR_INDICATION);
+ set_stats_message_type(actx->pinfo, MTYPE_ERROR_INDICATION);
#.FN_HDR ResetRequest
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "ResetRequest");
+ set_message_label(actx, MTYPE_RESET_REQUEST);
+ set_stats_message_type(actx->pinfo, MTYPE_RESET_REQUEST);
#.FN_HDR ResetResponse
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "ResetResponse");
+ set_message_label(actx, MTYPE_RESET_RESPONSE);
+ set_stats_message_type(actx->pinfo, MTYPE_RESET_RESPONSE);
#.FN_HDR RICcontrolAcknowledge
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICcontrolAcknowledge");
+ set_message_label(actx, MTYPE_RIC_CONTROL_ACK);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_CONTROL_ACK);
#.FN_HDR RICcontrolFailure
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICcontrolFailure");
+ set_message_label(actx, MTYPE_RIC_CONTROL_FAIL);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_CONTROL_FAIL);
#.FN_HDR RICcontrolRequest
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICcontrolRequest");
+ set_message_label(actx, MTYPE_RIC_CONTROL_REQUEST);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_CONTROL_REQUEST);
#.FN_HDR RICindication
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICindication");
+ set_message_label(actx, MTYPE_RIC_IND);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_IND);
#.FN_HDR RICserviceQuery
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICserviceQuery");
+ set_message_label(actx, MTYPE_RIC_SERVICE_QUERY);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SERVICE_QUERY);
#.FN_HDR RICserviceUpdate
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICserviceUpdate");
+ set_message_label(actx, MTYPE_RIC_SERVICE_UPDATE);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SERVICE_UPDATE);
#.FN_HDR RICserviceUpdateAcknowledge
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICserviceUpdateAcknowledge");
+ set_message_label(actx, MTYPE_RIC_SERVICE_UPDATE_ACK);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SERVICE_UPDATE_ACK);
#.FN_HDR RICserviceUpdateFailure
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICserviceUpdateFailure");
+ set_message_label(actx, MTYPE_RIC_SERVICE_UPDATE_FAIL);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SERVICE_UPDATE_FAIL);
#.FN_HDR RICsubscriptionFailure
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICsubscriptionFailure");
+ set_message_label(actx, MTYPE_RIC_SUBSCRIPTION_FAIL);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SUBSCRIPTION_FAIL);
#.FN_HDR RICsubscriptionRequest
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICsubscriptionRequest");
+ set_message_label(actx, MTYPE_RIC_SUBSCRIPTION_REQUEST);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SUBSCRIPTION_REQUEST);
#.FN_HDR RICsubscriptionResponse
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICsubscriptionResponse");
+ set_message_label(actx, MTYPE_RIC_SUBSCRIPTION_RESPONSE);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SUBSCRIPTION_RESPONSE);
#.FN_HDR RICsubscriptionDeleteFailure
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICsubscriptionDeleteFailure");
+ set_message_label(actx, MTYPE_RIC_SUBSCRIPTION_DELETE_FAIL);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SUBSCRIPTION_DELETE_FAIL);
#.FN_HDR RICsubscriptionDeleteRequest
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICsubscriptionDeleteRequest");
+ set_message_label(actx, MTYPE_RIC_SUBSCRIPTION_DELETE_REQUEST);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SUBSCRIPTION_DELETE_REQUEST);
#.FN_HDR RICsubscriptionDeleteResponse
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICsubscriptionDeleteResponse");
+ set_message_label(actx, MTYPE_RIC_SUBSCRIPTION_DELETE_RESPONSE);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SUBSCRIPTION_DELETE_RESPONSE);
#.FN_HDR RICsubscriptionDeleteRequired
- col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, "RICsubscriptionDeleteRequired");
+ set_message_label(actx, MTYPE_RIC_SUBSCRIPTION_DELETE_REQUIRED);
+ set_stats_message_type(actx->pinfo, MTYPE_RIC_SUBSCRIPTION_DELETE_REQUIRED);
#
diff --git a/epan/dissectors/asn1/e2ap/packet-e2ap-template.c b/epan/dissectors/asn1/e2ap/packet-e2ap-template.c
index 709469f6..644d6a64 100644
--- a/epan/dissectors/asn1/e2ap/packet-e2ap-template.c
+++ b/epan/dissectors/asn1/e2ap/packet-e2ap-template.c
@@ -23,6 +23,9 @@
#include <epan/conversation.h>
#include <epan/to_str.h>
#include <epan/oids.h>
+#include <epan/tap.h>
+#include <epan/stats_tree.h>
+#include <wsutil/array.h>
#include "packet-e2ap.h"
#include "packet-per.h"
@@ -43,26 +46,27 @@ static dissector_handle_t e2ap_handle;
#include "packet-e2ap-val.h"
/* Initialize the protocol and registered fields */
-static int proto_e2ap = -1;
+static int proto_e2ap;
#include "packet-e2ap-hf.c"
-static int hf_e2ap_unmapped_ran_function_id = -1;
-static int hf_e2ap_ran_function_name_not_recognised = -1;
-static int hf_e2ap_ran_function_setup_frame = -1;
+static int hf_e2ap_unmapped_ran_function_id;
+static int hf_e2ap_ran_function_name_not_recognised;
+static int hf_e2ap_ran_function_setup_frame;
+/* TODO: for each RAN Function, also link forward to where setup is referenced (if at all?). Maybe just first usage? */
-static int hf_e2ap_dissector_version= -1;
-static int hf_e2ap_frame_version = -1;
+static int hf_e2ap_dissector_version;
+static int hf_e2ap_frame_version;
-static int hf_e2ap_timestamp_string = -1;
+static int hf_e2ap_timestamp_string;
/* Initialize the subtree pointers */
-static gint ett_e2ap = -1;
+static int ett_e2ap;
-static expert_field ei_e2ap_ran_function_names_no_match = EI_INIT;
-static expert_field ei_e2ap_ran_function_id_not_mapped = EI_INIT;
-static expert_field ei_e2ap_ran_function_dissector_mismatch = EI_INIT;
-static expert_field ei_e2ap_ran_function_max_dissectors_registered = EI_INIT;
+static expert_field ei_e2ap_ran_function_names_no_match;
+static expert_field ei_e2ap_ran_function_id_not_mapped;
+static expert_field ei_e2ap_ran_function_dissector_mismatch;
+static expert_field ei_e2ap_ran_function_max_dissectors_registered;
#include "packet-e2ap-ett.c"
@@ -86,9 +90,6 @@ static int dissect_E2SM_RC_CallProcessID_PDU(tvbuff_t *tvb _U_, packet_info *pin
static int dissect_E2SM_RC_ControlHeader_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
static int dissect_E2SM_RC_ControlMessage_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
static int dissect_E2SM_RC_ControlOutcome_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
-//static int dissect_E2SM_RC_QueryOutcome_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
-//static int dissect_E2SM_RC_QueryDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
-//static int dissect_E2SM_RC_QueryHeader_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
static int dissect_E2SM_NI_EventTriggerDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
static int dissect_E2SM_NI_ActionDefinition_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_, void *data _U_);
@@ -106,27 +107,106 @@ enum {
UNSUCCESSFUL_OUTCOME
};
-typedef struct _e2ap_ctx_t {
- guint32 message_type;
- guint32 ProcedureCode;
- guint32 ProtocolIE_ID;
- guint32 ProtocolExtensionID;
-} e2ap_ctx_t;
+
+/* E2AP stats - Tap interface */
+
+static void set_stats_message_type(packet_info *pinfo, int type);
+
+static const uint8_t *st_str_packets = "Total Packets";
+static const uint8_t *st_str_packet_types = "E2AP Packet Types";
+
+static int st_node_packets = -1;
+static int st_node_packet_types = -1;
+static int e2ap_tap;
+
+struct e2ap_tap_t {
+ int e2ap_mtype;
+};
+
+#define MTYPE_E2_CONNECTION_UPDATE 1
+#define MTYPE_E2_CONNECTION_UPDATE_ACK 2
+#define MTYPE_E2_CONNECTION_UPDATE_FAIL 3
+#define MTYPE_E2_CONFIGURATION_UPDATE 4
+#define MTYPE_E2_CONFIGURATION_UPDATE_ACK 5
+#define MTYPE_E2_CONFIGURATION_UPDATE_FAIL 6
+#define MTYPE_E2_SETUP_FAIL 7
+#define MTYPE_E2_SETUP_REQUEST 8
+#define MTYPE_E2_SETUP_RESPONSE 9
+#define MTYPE_ERROR_INDICATION 10
+#define MTYPE_RESET_REQUEST 11
+#define MTYPE_RESET_RESPONSE 12
+#define MTYPE_RIC_CONTROL_ACK 13
+#define MTYPE_RIC_CONTROL_FAIL 14
+#define MTYPE_RIC_CONTROL_REQUEST 15
+#define MTYPE_RIC_IND 16
+#define MTYPE_RIC_SERVICE_QUERY 17
+#define MTYPE_RIC_SERVICE_UPDATE 18
+#define MTYPE_RIC_SERVICE_UPDATE_ACK 19
+#define MTYPE_RIC_SERVICE_UPDATE_FAIL 20
+#define MTYPE_RIC_SUBSCRIPTION_FAIL 21
+#define MTYPE_RIC_SUBSCRIPTION_REQUEST 22
+#define MTYPE_RIC_SUBSCRIPTION_RESPONSE 23
+#define MTYPE_RIC_SUBSCRIPTION_DELETE_FAIL 24
+#define MTYPE_RIC_SUBSCRIPTION_DELETE_REQUEST 25
+#define MTYPE_RIC_SUBSCRIPTION_DELETE_RESPONSE 26
+#define MTYPE_RIC_SUBSCRIPTION_DELETE_REQUIRED 27
+
+/* Value Strings. TODO: ext? */
+static const value_string mtype_names[] = {
+ { MTYPE_E2_CONNECTION_UPDATE, "E2connectionUpdate"},
+ { MTYPE_E2_CONNECTION_UPDATE_ACK, "E2connectionUpdateAcknowledge"},
+ { MTYPE_E2_CONNECTION_UPDATE_FAIL, "E2connectionUpdateFailure"},
+ { MTYPE_E2_CONFIGURATION_UPDATE, "E2nodeConfigurationUpdate"},
+ { MTYPE_E2_CONFIGURATION_UPDATE_ACK, "E2nodeConfigurationUpdateAcknowledge"},
+ { MTYPE_E2_CONFIGURATION_UPDATE_FAIL, "E2nodeConfigurationUpdateFailure"},
+ { MTYPE_E2_SETUP_FAIL, "E2setupFailure"},
+ { MTYPE_E2_SETUP_REQUEST, "E2setupRequest"},
+ { MTYPE_E2_SETUP_RESPONSE, "E2setupResponse"},
+ { MTYPE_ERROR_INDICATION, "ErrorIndication"},
+ { MTYPE_RESET_REQUEST, "ResetRequest"},
+ { MTYPE_RESET_RESPONSE, "ResetResponse"},
+ { MTYPE_RIC_CONTROL_ACK, "RICcontrolAcknowledge"},
+ { MTYPE_RIC_CONTROL_FAIL, "RICcontrolFailure"},
+ { MTYPE_RIC_CONTROL_REQUEST, "RICcontrolRequest"},
+ { MTYPE_RIC_IND, "RICindication"},
+ { MTYPE_RIC_SERVICE_QUERY, "RICserviceQuery"},
+ { MTYPE_RIC_SERVICE_UPDATE, "RICserviceUpdate"},
+ { MTYPE_RIC_SERVICE_UPDATE_ACK, "RICserviceUpdateAcknowledge"},
+ { MTYPE_RIC_SERVICE_UPDATE_FAIL, "RICserviceUpdateFailure"},
+ { MTYPE_RIC_SUBSCRIPTION_FAIL, "RICsubscriptionFailure"},
+ { MTYPE_RIC_SUBSCRIPTION_REQUEST, "RICsubscriptionRequest"},
+ { MTYPE_RIC_SUBSCRIPTION_RESPONSE, "RICsubscriptionResponse"},
+ { MTYPE_RIC_SUBSCRIPTION_DELETE_FAIL, "RICsubscriptionDeleteFailure"},
+ { MTYPE_RIC_SUBSCRIPTION_DELETE_REQUEST, "RICsubscriptionDeleteRequest"},
+ { MTYPE_RIC_SUBSCRIPTION_DELETE_RESPONSE, "RICsubscriptionDeleteResponse"},
+ { MTYPE_RIC_SUBSCRIPTION_DELETE_REQUIRED, "RICsubscriptionDeleteRequired"},
+ { 0, NULL }
+};
+
+static proto_tree *top_tree;
+
+static void set_message_label(asn1_ctx_t *actx, int type)
+{
+ const char *label = val_to_str_const(type, mtype_names, "Unknown");
+ col_append_sep_str(actx->pinfo->cinfo, COL_INFO, NULL, label);
+ proto_item_append_text(top_tree, " (%s)", label);
+}
+
+
/* Temporary private info to remember while dissecting frame */
struct e2ap_private_data {
- guint32 procedure_code;
- guint32 protocol_ie_id;
- guint32 protocol_extension_id;
- guint32 message_type;
- guint32 ran_ue_e2ap_id;
-
- guint32 ran_function_id;
- guint32 gnb_id_len;
+ uint32_t procedure_code;
+ uint32_t protocol_ie_id;
+ uint32_t message_type;
+
+ uint32_t ran_function_id;
+ uint32_t gnb_id_len;
#define MAX_GNB_ID_BYTES 6
- guint8 gnb_id_bytes[MAX_GNB_ID_BYTES];
+ uint8_t gnb_id_bytes[MAX_GNB_ID_BYTES];
dissector_handle_t component_configuration_dissector;
+ struct e2ap_tap_t *stats_tap;
};
/* Lookup temporary private info */
@@ -142,25 +222,22 @@ e2ap_get_private_data(packet_info *pinfo)
}
/****************************************************************************************************************/
-/* We learn which set of RAN functions pointers corresponds to a given ranFunctionID when we see E2SetupRequest */
-/* TODO: unfortunately, it seems that different versions of these protocols are not backward-compatible, so */
-/* it would be good to show where (going by OID) the dissector isn't at the same version as the message.. */
-/* An alternative would be to have multiple versions of each protocol and have them register in tables... */
-
+/* These are the strings that we look for at the beginning of RAN Function Description to identify RAN Function */
/* Static table mapping from string -> ran_function */
static const char* g_ran_function_name_table[MAX_RANFUNCTIONS] =
{
"ORAN-E2SM-KPM",
"ORAN-E2SM-RC",
- "ORAN-E2SM-NI"
+ "ORAN-E2SM-NI",
+ "{" /* For now, CCC is the only JSON-based RAN Function, so just match opening */
};
/* Per-conversation mapping: ranFunctionId -> ran_function+dissector */
typedef struct {
- guint32 setup_frame;
- guint32 ran_function_id;
+ uint32_t setup_frame;
+ uint32_t ran_function_id;
ran_function_t ran_function;
char oid[MAX_OID_LEN]; // i.e., OID from setupRequest
ran_function_dissector_t *dissector;
@@ -168,7 +245,7 @@ typedef struct {
typedef struct {
#define MAX_RANFUNCTION_ENTRIES 8
- guint32 num_entries;
+ uint32_t num_entries;
ran_function_id_mapping_t entries[MAX_RANFUNCTION_ENTRIES];
} ran_functionid_table_t;
@@ -181,6 +258,9 @@ static const char *ran_function_to_str(ran_function_t ran_function)
return "RC";
case NI_RANFUNCTIONS:
return "NI";
+ case CCC_RANFUNCTIONS:
+ return "CCC";
+
default:
return "Unknown";
}
@@ -189,10 +269,10 @@ static const char *ran_function_to_str(ran_function_t ran_function)
/* Table of RAN Function tables, indexed by gnbId (bytes) */
typedef struct {
#define MAX_GNBS 6
- guint32 num_gnbs;
+ uint32_t num_gnbs;
struct {
- guint8 id_value[MAX_GNB_ID_BYTES];
- guint32 id_len;
+ uint8_t id_value[MAX_GNB_ID_BYTES];
+ uint32_t id_len;
ran_functionid_table_t *ran_function_table;
} gnb[MAX_GNBS];
} gnb_ran_functions_t;
@@ -202,8 +282,8 @@ static gnb_ran_functions_t s_gnb_ran_functions_table;
/* Table of available dissectors for each RAN function */
typedef struct {
- guint32 num_available_dissectors;
-#define MAX_DISSECTORS_PER_RAN_FUNCTION 3
+ uint32_t num_available_dissectors;
+#define MAX_DISSECTORS_PER_RAN_FUNCTION 8
ran_function_dissector_t* ran_function_dissectors[MAX_DISSECTORS_PER_RAN_FUNCTION];
} ran_function_available_dissectors_t;
@@ -213,7 +293,7 @@ static ran_function_available_dissectors_t g_ran_functions_available_dissectors[
/* Will be called from outside this file by separate dissectors */
void register_e2ap_ran_function_dissector(ran_function_t ran_function, ran_function_dissector_t *dissector)
{
- if ((ran_function >= MIN_RANFUNCTIONS) && (ran_function <= MAX_RANFUNCTIONS)) {
+ if ((ran_function >= MIN_RANFUNCTIONS) && (ran_function < MAX_RANFUNCTIONS)) {
ran_function_available_dissectors_t *available_dissectors = &g_ran_functions_available_dissectors[ran_function];
if (available_dissectors->num_available_dissectors < MAX_DISSECTORS_PER_RAN_FUNCTION) {
available_dissectors->ran_function_dissectors[available_dissectors->num_available_dissectors++] = dissector;
@@ -255,9 +335,11 @@ void e2ap_store_ran_function_mapping(packet_info *pinfo, proto_tree *tree, tvbuf
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
- if (!name) {
+ /* Need these pointers not to be NULL */
+ if (!name || !table) {
return;
}
+
/* Stop if already reached table limit */
if (table->num_entries == MAX_RANFUNCTION_ENTRIES) {
proto_tree_add_expert_format(tree, pinfo, &ei_e2ap_ran_function_max_dissectors_registered,
@@ -267,7 +349,7 @@ void e2ap_store_ran_function_mapping(packet_info *pinfo, proto_tree *tree, tvbuf
return;
}
- guint32 ran_function_id = e2ap_data->ran_function_id;
+ uint32_t ran_function_id = e2ap_data->ran_function_id;
ran_function_t ran_function = MAX_RANFUNCTIONS; /* i.e. invalid */
ran_function_dissector_t *ran_function_dissector = NULL;
@@ -292,14 +374,14 @@ void e2ap_store_ran_function_mapping(packet_info *pinfo, proto_tree *tree, tvbuf
}
/* If ID already mapped, can stop here */
- for (guint n=0; n < table->num_entries; n++) {
+ for (unsigned n=0; n < table->num_entries; n++) {
if (table->entries[n].ran_function_id == ran_function_id) {
return;
}
}
/* OK, store this new entry */
- guint idx = table->num_entries++;
+ unsigned idx = table->num_entries++;
table->entries[idx].setup_frame = pinfo->num;
table->entries[idx].ran_function_id = ran_function_id;
table->entries[idx].ran_function = ran_function;
@@ -307,22 +389,22 @@ void e2ap_store_ran_function_mapping(packet_info *pinfo, proto_tree *tree, tvbuf
/* When add first entry, also want to set up table from gnbId -> table */
if (idx == 0) {
- guint id_len = e2ap_data->gnb_id_len;
- guint8 *id_value = &e2ap_data->gnb_id_bytes[0];
+ unsigned id_len = e2ap_data->gnb_id_len;
+ uint8_t *id_value = &e2ap_data->gnb_id_bytes[0];
- gboolean found = FALSE;
- for (guint n=0; n<s_gnb_ran_functions_table.num_gnbs; n++) {
+ bool found = false;
+ for (unsigned n=0; n<s_gnb_ran_functions_table.num_gnbs; n++) {
if ((s_gnb_ran_functions_table.gnb[n].id_len = id_len) &&
(memcmp(s_gnb_ran_functions_table.gnb[n].id_value, id_value, id_len) == 0)) {
/* Already have an entry for this gnb. */
- found = TRUE;
+ found = true;
break;
}
}
if (!found) {
/* Add entry (if room for 1 more) */
- guint32 new_idx = s_gnb_ran_functions_table.num_gnbs;
+ uint32_t new_idx = s_gnb_ran_functions_table.num_gnbs;
if (new_idx < MAX_GNBS-1) {
s_gnb_ran_functions_table.gnb[new_idx].id_len = id_len;
memcpy(s_gnb_ran_functions_table.gnb[new_idx].id_value, id_value, id_len);
@@ -339,7 +421,7 @@ static ran_function_dissector_t* lookup_ranfunction_dissector(packet_info *pinfo
{
/* Get ranFunctionID from this frame */
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
- guint ran_function_id = e2ap_data->ran_function_id;
+ unsigned ran_function_id = e2ap_data->ran_function_id;
/* Get ranFunction table corresponding to this frame's conversation */
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
@@ -349,7 +431,7 @@ static ran_function_dissector_t* lookup_ranfunction_dissector(packet_info *pinfo
}
/* Find the entry in this table corresponding to ran_function_id */
- for (guint n=0; n < table->num_entries; n++) {
+ for (unsigned n=0; n < table->num_entries; n++) {
if (ran_function_id == table->entries[n].ran_function_id) {
if (tree) {
/* Point back at the setup frame where this ranfunction was mapped */
@@ -396,7 +478,7 @@ static char* lookup_ranfunction_oid(packet_info *pinfo)
{
/* Get ranFunctionID from this frame */
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
- guint ran_function_id = e2ap_data->ran_function_id;
+ unsigned ran_function_id = e2ap_data->ran_function_id;
/* Get ranFunction table corresponding to this frame's conversation */
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
@@ -406,7 +488,7 @@ static char* lookup_ranfunction_oid(packet_info *pinfo)
}
/* Find the entry in this table corresponding to ran_function_id */
- for (guint n=0; n < table->num_entries; n++) {
+ for (unsigned n=0; n < table->num_entries; n++) {
if (ran_function_id == table->entries[n].ran_function_id) {
return (char*)(table->entries[n].oid);
}
@@ -426,7 +508,7 @@ static void update_dissector_using_oid(packet_info *pinfo, ran_function_t ran_fu
return;
}
- gboolean found = FALSE;
+ bool found = false;
/* Look at available dissectors for this RAN function */
ran_function_available_dissectors_t *available = &g_ran_functions_available_dissectors[ran_function];
@@ -437,11 +519,15 @@ static void update_dissector_using_oid(packet_info *pinfo, ran_function_t ran_fu
// Get mapping in use
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
- guint ran_function_id = e2ap_data->ran_function_id;
+ unsigned ran_function_id = e2ap_data->ran_function_id;
ran_function_id_mapping_t *mapping = NULL;
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
+ if (!table) {
+ return;
+ }
+
/* Find the entry in this table corresponding to ran_function_id */
- for (guint n=0; n < table->num_entries; n++) {
+ for (unsigned n=0; n < table->num_entries; n++) {
if (ran_function_id == table->entries[n].ran_function_id) {
mapping = &(table->entries[n]);
}
@@ -452,11 +538,11 @@ static void update_dissector_using_oid(packet_info *pinfo, ran_function_t ran_fu
}
/* Set dissector pointer in ran_function_id_mapping_t */
- for (guint32 n=0; n < available->num_available_dissectors; n++) {
+ for (uint32_t n=0; n < available->num_available_dissectors; n++) {
/* If exact match, set it */
if (strcmp(frame_oid, available->ran_function_dissectors[n]->oid) == 0) {
mapping->dissector = available->ran_function_dissectors[n];
- found = TRUE;
+ found = true;
break;
}
}
@@ -474,8 +560,12 @@ void e2ap_update_ran_function_mapping(packet_info *pinfo, proto_tree *tree, tvbu
/* Copy OID into table entry (so may be used to choose and be compared with chosen available dissector */
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
ran_functionid_table_t *table = get_ran_functionid_table(pinfo);
+ /* Make sure we have private and table data to compare */
+ if (!e2ap_data || !table) {
+ return;
+ }
ran_function_t ran_function = MAX_RANFUNCTIONS;
- for (guint n=0; n < table->num_entries; n++) {
+ for (unsigned n=0; n < table->num_entries; n++) {
if (e2ap_data->ran_function_id == table->entries[n].ran_function_id) {
ran_function = table->entries[n].ran_function;
g_strlcpy(table->entries[n].oid, oid, MAX_OID_LEN);
@@ -519,10 +609,10 @@ static void update_conversation_from_gnb_id(asn1_ctx_t *actx)
conversation_add_proto_data(p_conv, proto_e2ap, p_conv_data);
/* Look to see if we already know about the mappings in effect on this gNB */
- guint id_len = e2ap_data->gnb_id_len;
- guint8 *id_value = &e2ap_data->gnb_id_bytes[0];
+ unsigned id_len = e2ap_data->gnb_id_len;
+ uint8_t *id_value = &e2ap_data->gnb_id_bytes[0];
- for (guint n=0; n<s_gnb_ran_functions_table.num_gnbs; n++) {
+ for (unsigned n=0; n<s_gnb_ran_functions_table.num_gnbs; n++) {
if ((s_gnb_ran_functions_table.gnb[n].id_len = id_len) &&
(memcmp(s_gnb_ran_functions_table.gnb[n].id_value, id_value, id_len) == 0)) {
@@ -538,6 +628,14 @@ static void update_conversation_from_gnb_id(asn1_ctx_t *actx)
}
}
+static dissector_handle_t json_handle;
+
+static int dissect_E2SM_NI_JSON_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ /* Send to JSON dissector */
+ return call_dissector_only(json_handle, tvb, pinfo, tree, NULL);
+}
+
/* Dissector tables */
static dissector_table_t e2ap_ies_dissector_table;
@@ -567,15 +665,8 @@ static int dissect_UnsuccessfulOutcomeValue(tvbuff_t *tvb, packet_info *pinfo, p
static int dissect_ProtocolIEFieldValue(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
- e2ap_ctx_t e2ap_ctx;
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
-
- e2ap_ctx.message_type = e2ap_data->message_type;
- e2ap_ctx.ProcedureCode = e2ap_data->procedure_code;
- e2ap_ctx.ProtocolIE_ID = e2ap_data->protocol_ie_id;
- e2ap_ctx.ProtocolExtensionID = e2ap_data->protocol_extension_id;
-
- return (dissector_try_uint_new(e2ap_ies_dissector_table, e2ap_data->protocol_ie_id, tvb, pinfo, tree, FALSE, &e2ap_ctx)) ? tvb_captured_length(tvb) : 0;
+ return (dissector_try_uint_new(e2ap_ies_dissector_table, e2ap_data->protocol_ie_id, tvb, pinfo, tree, false, NULL)) ? tvb_captured_length(tvb) : 0;
}
@@ -601,39 +692,82 @@ static int dissect_InitiatingMessageValue(tvbuff_t *tvb, packet_info *pinfo, pro
{
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
- return (dissector_try_uint_new(e2ap_proc_imsg_dissector_table, e2ap_data->procedure_code, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
+ return (dissector_try_uint_new(e2ap_proc_imsg_dissector_table, e2ap_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)
{
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
- return (dissector_try_uint_new(e2ap_proc_sout_dissector_table, e2ap_data->procedure_code, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
+ return (dissector_try_uint_new(e2ap_proc_sout_dissector_table, e2ap_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)
{
struct e2ap_private_data *e2ap_data = e2ap_get_private_data(pinfo);
- return (dissector_try_uint_new(e2ap_proc_uout_dissector_table, e2ap_data->procedure_code, tvb, pinfo, tree, TRUE, data)) ? tvb_captured_length(tvb) : 0;
+ return (dissector_try_uint_new(e2ap_proc_uout_dissector_table, e2ap_data->procedure_code, tvb, pinfo, tree, true, data)) ? tvb_captured_length(tvb) : 0;
}
+static void set_stats_message_type(packet_info *pinfo, int type)
+{
+ struct e2ap_private_data* priv_data = e2ap_get_private_data(pinfo);
+ priv_data->stats_tap->e2ap_mtype = type;
+}
+
+static void
+e2ap_stats_tree_init(stats_tree *st)
+{
+ st_node_packets = stats_tree_create_node(st, st_str_packets, 0, STAT_DT_INT, true);
+ st_node_packet_types = stats_tree_create_pivot(st, st_str_packet_types, st_node_packets);
+}
+
+static tap_packet_status
+e2ap_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_,
+ epan_dissect_t* edt _U_ , const void* p, tap_flags_t flags _U_)
+{
+ const struct e2ap_tap_t *pi = (const struct e2ap_tap_t *)p;
+
+ tick_stat_node(st, st_str_packets, 0, false);
+ stats_tree_tick_pivot(st, st_node_packet_types,
+ val_to_str(pi->e2ap_mtype, mtype_names,
+ "Unknown packet type (%d)"));
+ return TAP_PACKET_REDRAW;
+}
+
+
+/* Main dissection function */
static int
dissect_e2ap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
proto_item *e2ap_item = NULL;
proto_tree *e2ap_tree = NULL;
+ struct e2ap_tap_t *tap_info;
+
/* make entry in the Protocol column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "E2AP");
col_clear(pinfo->cinfo, COL_INFO);
+ tap_info = wmem_new(pinfo->pool, struct e2ap_tap_t);
+ tap_info->e2ap_mtype = 0; /* unknown/invalid */
+
+ /* Add stats tap to private struct */
+ struct e2ap_private_data *priv_data = e2ap_get_private_data(pinfo);
+ priv_data->stats_tap = tap_info;
+
+ /* Store top-level tree */
+ top_tree = e2ap_tree;
+
/* create the e2ap protocol tree */
e2ap_item = proto_tree_add_item(tree, proto_e2ap, tvb, 0, -1, ENC_NA);
e2ap_tree = proto_item_add_subtree(e2ap_item, ett_e2ap);
- return dissect_E2AP_PDU_PDU(tvb, pinfo, e2ap_tree, NULL);
+ dissect_E2AP_PDU_PDU(tvb, pinfo, e2ap_tree, NULL);
+
+ tap_queue_packet(e2ap_tap, pinfo, tap_info);
+ return tvb_captured_length(tvb);
}
@@ -656,11 +790,18 @@ proto_reg_handoff_e2ap(void)
/********************************/
/* Known OIDs for RAN providers */
+ /* N.B. These appear in the RAN Function ASN.1 definitions (except for CCC, which is based on JSON).
+ * There is a registry of known OIDs though in the E2SM specification
+ */
/* KPM */
oid_add_from_string("KPM v1", "1.3.6.1.4.1.53148.1.1.2.2");
oid_add_from_string("KPM v2", "1.3.6.1.4.1.53148.1.2.2.2");
oid_add_from_string("KPM v3", "1.2.6.1.4.1.53148.1.3.2.2");
+ oid_add_from_string("KPM v4", "1.2.6.1.4.1.53148.1.4.2.2");
+ oid_add_from_string("KPM v5", "1.2.6.1.4.1.53148.1.5.2.2");
+ oid_add_from_string("KPM v6", "1.2.6.1.4.1.53148.1.6.2.2");
+
/* RC */
// TODO: appears to be the same??? Asking for clarification from ORAN..
@@ -670,9 +811,24 @@ proto_reg_handoff_e2ap(void)
/* NI */
oid_add_from_string("NI v1", "1.3.6.1.4.1.53148.1.1.2.1");
+ oid_add_from_string("NI v2", "1.3.6.1.4.1.53148.1.2.2.1");
+ oid_add_from_string("NI v3", "1.3.6.1.4.1.53148.1.3.2.1");
+ oid_add_from_string("NI v4", "1.3.6.1.4.1.53148.1.4.2.1");
+ oid_add_from_string("NI v5", "1.3.6.1.4.1.53148.1.5.2.1");
+ oid_add_from_string("NI v6", "1.3.6.1.4.1.53148.1.6.2.1");
- /********************************/
- /* Register 'built-in' dissectors */
+
+ /* CCC */
+ oid_add_from_string("CCC v1", "1.3.6.1.4.1.53148.1.1.2.4");
+ oid_add_from_string("CCC v2", "1.3.6.1.4.1.53148.1.2.2.4");
+ oid_add_from_string("CCC v3", "1.3.6.1.4.1.53148.1.3.2.4");
+ oid_add_from_string("CCC v4", "1.3.6.1.4.1.53148.1.4.2.4");
+ oid_add_from_string("CCC v5", "1.3.6.1.4.1.53148.1.5.2.4");
+ oid_add_from_string("CCC v6", "1.3.6.1.4.1.53148.1.6.2.4");
+
+
+ /*********************************************************/
+ /* Register 'built-in' dissectors (i.e., from asn1/e2ap) */
static ran_function_dissector_t kpm_v3 =
{ "ORAN-E2SM-KPM", "1.2.6.1.4.1.53148.1.3.2.2", 3, 0,
@@ -701,9 +857,9 @@ proto_reg_handoff_e2ap(void)
dissect_E2SM_RC_ControlMessage_PDU,
dissect_E2SM_RC_ControlOutcome_PDU,
/* new for v3 */
- NULL, //dissect_E2SM_RC_QueryOutcome_PDU,
- NULL, //dissect_E2SM_RC_QueryDefinition_PDU,
- NULL, //dissect_E2SM_RC_QueryHeader_PDU,
+ NULL,
+ NULL,
+ NULL,
dissect_E2SM_RC_ActionDefinition_PDU,
dissect_E2SM_RC_IndicationMessage_PDU,
@@ -732,11 +888,127 @@ proto_reg_handoff_e2ap(void)
}
};
- /* Register available dissectors. TODO: break these out into separate
- * ASN.1 protocols that register themselves, or leave one of each here? */
+ static ran_function_dissector_t ccc_v1 =
+ { "{", /*"ORAN-E2SM-CCC",*/ "1.3.6.1.4.1.53148.1.1.2.4", 1, 0,
+ /* See table 5.1 */
+ { dissect_E2SM_NI_JSON_PDU,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ NULL,
+ NULL,
+ NULL,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU
+ }
+ };
+
+ static ran_function_dissector_t ccc_v2 =
+ { "{", /*"ORAN-E2SM-CCC",*/ "1.3.6.1.4.1.53148.1.2.2.4", 2, 0,
+ /* See table 5.1 */
+ { dissect_E2SM_NI_JSON_PDU,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ NULL,
+ NULL,
+ NULL,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU
+ }
+ };
+
+ static ran_function_dissector_t ccc_v3 =
+ { "{", /*"ORAN-E2SM-CCC",*/ "1.3.6.1.4.1.53148.1.3.2.4", 3, 0,
+ /* See table 5.1 */
+ { dissect_E2SM_NI_JSON_PDU,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ NULL,
+ NULL,
+ NULL,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU
+ }
+ };
+
+ static ran_function_dissector_t ccc_v4 =
+ { "{", /*"ORAN-E2SM-CCC",*/ "1.3.6.1.4.1.53148.1.4.2.4", 4, 0,
+ /* See table 5.1 */
+ { dissect_E2SM_NI_JSON_PDU,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ NULL,
+ NULL,
+ NULL,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU
+ }
+ };
+
+ static ran_function_dissector_t ccc_v5 =
+ { "{", /*"ORAN-E2SM-CCC",*/ "1.3.6.1.4.1.53148.1.5.2.4", 5, 0,
+ /* See table 5.1 */
+ { dissect_E2SM_NI_JSON_PDU,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ NULL,
+ NULL,
+ NULL,
+
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU,
+ dissect_E2SM_NI_JSON_PDU
+ }
+ };
+
+
+ /* Register available dissectors.
+ * Registering one version of each RAN Function here - others will need to be
+ * registered in sepparate dissectors (e.g. kpm_v2) */
register_e2ap_ran_function_dissector(KPM_RANFUNCTIONS, &kpm_v3);
register_e2ap_ran_function_dissector(RC_RANFUNCTIONS, &rc_v1);
register_e2ap_ran_function_dissector(NI_RANFUNCTIONS, &ni_v1);
+
+ register_e2ap_ran_function_dissector(CCC_RANFUNCTIONS, &ccc_v1);
+ register_e2ap_ran_function_dissector(CCC_RANFUNCTIONS, &ccc_v2);
+ register_e2ap_ran_function_dissector(CCC_RANFUNCTIONS, &ccc_v3);
+ register_e2ap_ran_function_dissector(CCC_RANFUNCTIONS, &ccc_v4);
+ register_e2ap_ran_function_dissector(CCC_RANFUNCTIONS, &ccc_v5);
+
+
+ /* Cache JSON dissector */
+ json_handle = find_dissector("json");
+
+ stats_tree_register("e2ap", "e2ap", "E2AP", 0,
+ e2ap_stats_tree_packet, e2ap_stats_tree_init, NULL);
+
}
@@ -777,7 +1049,7 @@ void proto_register_e2ap(void) {
};
/* List of subtrees */
- static gint *ett[] = {
+ static int *ett[] = {
&ett_e2ap,
#include "packet-e2ap-ettarr.c"
};
@@ -817,6 +1089,8 @@ void proto_register_e2ap(void) {
e2ap_n2_ie_type_dissector_table = register_dissector_table("e2ap.n2_ie_type", "E2AP N2 IE Type", proto_e2ap, FT_STRING, STRING_CASE_SENSITIVE);
register_init_routine(&e2ap_init_protocol);
+
+ e2ap_tap = register_tap("e2ap");
}
/*