NAS 5GS: Framwork for dissecting UPDP messages.

Change-Id: Id08fe25cdf118e6912fa3f201dfd07bde5ebdaf9
Reviewed-on: https://code.wireshark.org/review/33679
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Anders Broman 2019-06-20 13:56:36 +02:00 committed by Anders Broman
parent 088b3d63a0
commit 57a9a500b9
3 changed files with 275 additions and 3 deletions

View File

@ -1197,6 +1197,9 @@ const char* get_gsm_a_msg_string(int pdu_type, int idx)
case NAS_5GS_PDU_TYPE_SM:
msg_string = val_to_str_ext(idx, &nas_5gs_sm_elem_strings_ext, "NAS_5GS_PDU_TYPE_SM (%u)");
break;
case NAS_5GS_PDU_TYPE_UPDP:
msg_string = val_to_str_ext(idx, &nas_5gs_updp_elem_strings_ext, "NAS_5GS_PDU_TYPE_UPDP (%u)");
break;
default:
DISSECTOR_ASSERT_NOT_REACHED();
}
@ -1261,6 +1264,9 @@ static int get_hf_elem_id(int pdu_type)
case NAS_5GS_PDU_TYPE_SM:
hf_elem_id = hf_nas_5gs_sm_elem_id;
break;
case NAS_5GS_PDU_TYPE_UPDP:
hf_elem_id = hf_nas_5gs_updp_elem_id;
break;
default:
DISSECTOR_ASSERT_NOT_REACHED();
}

View File

@ -181,6 +181,11 @@ extern gint ett_nas_5gs_sm_elem[];
extern elem_fcn nas_5gs_sm_elem_fcn[];
extern int hf_nas_5gs_sm_elem_id;
extern value_string_ext nas_5gs_updp_elem_strings_ext;
extern gint ett_nas_5gs_updp_elem[];
extern elem_fcn nas_5gs_updp_elem_fcn[];
extern int hf_nas_5gs_updp_elem_id;
extern sccp_assoc_info_t* sccp_assoc;
extern int gsm_a_tap;
@ -224,6 +229,7 @@ extern int hf_gsm_a_lac;
#define NAS_5GS_PDU_TYPE_COMMON 16
#define NAS_5GS_PDU_TYPE_MM 17
#define NAS_5GS_PDU_TYPE_SM 18
#define NAS_5GS_PDU_TYPE_UPDP 19
extern const char* get_gsm_a_msg_string(int pdu_type, int idx);
@ -347,6 +353,11 @@ extern const char* get_gsm_a_msg_string(int pdu_type, int idx);
SEV_elem_ett = ett_nas_5gs_sm_elem; \
SEV_elem_funcs = nas_5gs_sm_elem_fcn; \
break; \
case NAS_5GS_PDU_TYPE_UPDP: \
SEV_elem_names_ext = nas_5gs_updp_elem_strings_ext; \
SEV_elem_ett = ett_nas_5gs_updp_elem; \
SEV_elem_funcs = nas_5gs_updp_elem_fcn; \
break; \
default: \
proto_tree_add_expert_format(tree, pinfo, ei_unknown, \
tvb, curr_offset, -1, \

View File

@ -51,6 +51,7 @@ static int proto_nas_5gs = -1;
int hf_nas_5gs_common_elem_id = -1;
int hf_nas_5gs_mm_elem_id = -1;
int hf_nas_5gs_sm_elem_id = -1;
int hf_nas_5gs_updp_elem_id = -1;
static int hf_nas_5gs_epd = -1;
static int hf_nas_5gs_spare_b7 = -1;
@ -68,6 +69,7 @@ static int hf_nas_5gs_msg_auth_code = -1;
static int hf_nas_5gs_seq_no = -1;
static int hf_nas_5gs_mm_msg_type = -1;
static int hf_nas_5gs_sm_msg_type = -1;
static int hf_nas_5gs_updp_msg_type = -1;
static int hf_nas_5gs_proc_trans_id = -1;
static int hf_nas_5gs_spare_half_octet = -1;
static int hf_nas_5gs_pdu_session_id = -1;
@ -345,6 +347,7 @@ static expert_field ei_nas_5gs_extraneous_data = EI_INIT;
static expert_field ei_nas_5gs_unknown_pd = EI_INIT;
static expert_field ei_nas_5gs_mm_unknown_msg_type = EI_INIT;
static expert_field ei_nas_5gs_sm_unknown_msg_type = EI_INIT;
static expert_field ei_nas_5gs_updp_unknown_msg_type = EI_INIT;
static expert_field ei_nas_5gs_msg_not_dis = EI_INIT;
static expert_field ei_nas_5gs_ie_not_dis = EI_INIT;
static expert_field ei_nas_5gs_missing_mandatory_elemen = EI_INIT;
@ -5064,6 +5067,87 @@ nas_5gs_sm_5gsm_status(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
}
/* D.5.1 Manage UE policy command */
/*
Direction: network to UE
UE policy section management list UE policy section management list D.6.2 M LV-E 11-65537
*/
/* D.5.2 Manage UE policy complete */
/*
Direction: UE to network
No data
*/
/* D.5.3 Manage UE policy command reject*/
/*
Direction: UE to network
UE policy section management result UE policy section management result D.6.3 M LV-E 11-65537
*/
/* D.5.4 UE state indication */
/*
Direction: UE to network
UPSI list UPSI list D.6.4 M LV-E 9-65537
UE policy classmark UE policy classmark D.6.5 M LV 2-4
UE OS Id OS Id D.6.6 O TLV 18-242
*/
/* D.6.2 UE policy section management list */
static guint16
de_nas_5gs_updp_ue_policy_section_mgm_lst(tvbuff_t* tvb, proto_tree* tree, packet_info* pinfo,
guint32 offset, guint len,
gchar* add_string _U_, int string_len _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_nas_5gs_ie_not_dis, tvb, offset, len);
return len;
}
/* D.6.3 UE policy section management result */
static guint16
de_nas_5gs_updp_ue_policy_section_mgm_res(tvbuff_t* tvb, proto_tree* tree, packet_info* pinfo,
guint32 offset, guint len,
gchar* add_string _U_, int string_len _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_nas_5gs_ie_not_dis, tvb, offset, len);
return len;
}
/* D.6.4 UPSI list */
static guint16
de_nas_5gs_updp_upsi_list(tvbuff_t* tvb, proto_tree* tree, packet_info* pinfo,
guint32 offset, guint len,
gchar* add_string _U_, int string_len _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_nas_5gs_ie_not_dis, tvb, offset, len);
return len;
}
/* D.6.5 UE policy classmark */
static guint16
de_nas_5gs_updp_ue_policy_cm(tvbuff_t* tvb, proto_tree* tree, packet_info* pinfo,
guint32 offset, guint len,
gchar* add_string _U_, int string_len _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_nas_5gs_ie_not_dis, tvb, offset, len);
return len;
}
/* D.6.6 UE OS Id */
static guint16
de_nas_5gs_updp_ue_os_id(tvbuff_t* tvb, proto_tree* tree, packet_info* pinfo,
guint32 offset, guint len,
gchar* add_string _U_, int string_len _U_)
{
proto_tree_add_expert(tree, pinfo, &ei_nas_5gs_ie_not_dis, tvb, offset, len);
return len;
}
/* 9.7 Message type */
@ -5247,7 +5331,69 @@ static void(*nas_5gs_sm_msg_fcn[])(tvbuff_t *tvb, proto_tree *tree, packet_info
};
/* D.6 Information elements coding */
typedef enum
{
DE_NAS_5GS_UPDP_UE_POLICY_SECTION_MGM_LST, /* D.6.2 UE policy section management list */
DE_NAS_5GS_UPDP_UE_POLICY_SECTION_MGM_RES, /* D.6.3 UE policy section management result */
DE_NAS_5GS_UPDP_UPSI_LIST, /* D.6.4 UPSI list */
DE_NAS_5GS_UPDP_UE_policy_CM, /* D.6.5 UE policy classmark */
DE_NAS_5GS_UPDP_UE_OS_Id, /* D.6.6 UE OS Id */
DE_NAS_5GS_UPDP_NONE /* NONE */
}
nas_5gs_updp_elem_idx_t;
static const value_string nas_5gs_updp_elem_strings[] = {
{ DE_NAS_5GS_UPDP_UE_POLICY_SECTION_MGM_LST, "UE policy section management list" }, /* D.6.2 UE policy section management list */
{ DE_NAS_5GS_UPDP_UE_POLICY_SECTION_MGM_RES, "UE policy section management result" }, /* D.6.3 UE policy section management result */
{ DE_NAS_5GS_UPDP_UPSI_LIST, "UPSI list" }, /* D.6.4 UPSI list */
{ DE_NAS_5GS_UPDP_UE_policy_CM, "UE policy classmark" }, /* D.6.5 UE policy classmark */
{ DE_NAS_5GS_UPDP_UE_OS_Id, "UE OS Id" }, /* D.6.6 UE OS Id */
{ 0, NULL }
};
value_string_ext nas_5gs_updp_elem_strings_ext = VALUE_STRING_EXT_INIT(nas_5gs_updp_elem_strings);
#define NUM_NAS_5GS_UPDP_ELEM (sizeof(nas_5gs_updp_elem_strings)/sizeof(value_string))
gint ett_nas_5gs_updp_elem[NUM_NAS_5GS_UPDP_ELEM];
guint16(*nas_5gs_updp_elem_fcn[])(tvbuff_t* tvb, proto_tree* tree, packet_info* pinfo,
guint32 offset, guint len,
gchar* add_string, int string_len) = {
/* 5GS session management (5GSM) information elements */
de_nas_5gs_updp_ue_policy_section_mgm_lst, /* D.6.2 UE policy section management list */
de_nas_5gs_updp_ue_policy_section_mgm_res, /* D.6.3 UE policy section management result */
de_nas_5gs_updp_upsi_list, /* D.6.4 UPSI list */
de_nas_5gs_updp_ue_policy_cm, /* D.6.5 UE policy classmark */
de_nas_5gs_updp_ue_os_id, /* D.6.6 UE OS Id */
NULL, /* NONE */
};
/* Table D.6.1.1: UE policy delivery service message type */
static const value_string nas_5gs_updp_msg_strings[] = {
{ 0x0, "Reserved"},
{ 0x1, "MANAGE UE POLICY COMMAND"},
{ 0x2, "MANAGE UE POLICY COMPLETE"},
{ 0x3, "MANAGE UE POLICY COMMAND REJECT"},
{ 0x4, "UE STATE INDICATION"},
{ 0, NULL }
};
static value_string_ext nas_5gs_updp_msg_strings_ext = VALUE_STRING_EXT_INIT(nas_5gs_updp_msg_strings);
#define NUM_NAS_5GS_UPDP_MSG (sizeof(nas_5gs_updp_msg_strings)/sizeof(value_string))
static gint ett_nas_5gs_updp_msg[NUM_NAS_5GS_UPDP_MSG];
static void(*nas_5gs_updp_msg_fcn[])(tvbuff_t* tvb, proto_tree* tree, packet_info* pinfo, guint32 offset, guint len) = {
nas_5gs_exp_not_dissected_yet, /* 0x0 Reserved */
nas_5gs_exp_not_dissected_yet, /* 0x1 MANAGE UE POLICY COMMAND */
nas_5gs_exp_not_dissected_yet, /* 0x2 MANAGE UE POLICY COMPLETE */
nas_5gs_exp_not_dissected_yet, /* 0x3 MANAGE UE POLICY COMMAND REJECT */
nas_5gs_exp_not_dissected_yet, /* 0x4 UE STATE INDICATION */
NULL, /* NONE */
};
static void
get_nas_5gsmm_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *hf_idx, msg_fcn *msg_fcn_p)
@ -5278,6 +5424,22 @@ get_nas_5gssm_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *
return;
}
static void
get_nas_5gs_updp_msg_params(guint8 oct, const gchar** msg_str, int* ett_tree, int* hf_idx, msg_fcn* msg_fcn_p)
{
gint idx;
*msg_str = try_val_to_str_idx_ext((guint32)(oct & 0xff), &nas_5gs_updp_msg_strings_ext, &idx);
*hf_idx = hf_nas_5gs_updp_msg_type;
if (*msg_str != NULL) {
*ett_tree = ett_nas_5gs_updp_msg[idx];
*msg_fcn_p = nas_5gs_updp_msg_fcn[idx];
}
return;
}
static void
dissect_nas_5gs_sm_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
{
@ -5381,6 +5543,74 @@ disect_nas_5gs_mm_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int o
}
/* UPDP */
/* D.6.1 UE policy delivery service message type */
static void
disect_nas_5gs_updp(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, int offset)
{
const gchar* msg_str;
guint32 len;
gint ett_tree;
int hf_idx;
void(*msg_fcn_p)(tvbuff_t * tvb, proto_tree * tree, packet_info * pinfo, guint32 offset, guint len);
guint8 oct;
len = tvb_reported_length(tvb);
/* PTI Procedure transaction identity 9.6 M V 1 */
/* MANAGE UE POLICY COMMAND message identity UE policy delivery service message type D.6.1 M V 1*/
/* ... IEs*/
/* 9.6 Procedure transaction identity
* Bits 1 to 8 of the third octet of every 5GSM message contain the procedure transaction identity.
* The procedure transaction identity and its use are defined in 3GPP TS 24.007
* XXX Only 5GSM ?
*/
proto_tree_add_item(tree, hf_nas_5gs_proc_trans_id, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/* Message type IE*/
oct = tvb_get_guint8(tvb, offset);
msg_fcn_p = NULL;
ett_tree = -1;
hf_idx = -1;
msg_str = NULL;
get_nas_5gs_updp_msg_params(oct, &msg_str, &ett_tree, &hf_idx, &msg_fcn_p);
if (msg_str) {
col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, msg_str);
}
else {
proto_tree_add_expert_format(tree, pinfo, &ei_nas_5gs_updp_unknown_msg_type, tvb, offset, 1, "Unknown Message Type 0x%02x", oct);
return;
}
/*
* Add PDCP message name
*/
proto_tree_add_item(tree, hf_idx, tvb, offset, 1, ENC_BIG_ENDIAN);
offset++;
/*
* decode elements
*/
if (msg_fcn_p == NULL)
{
if (tvb_reported_length_remaining(tvb, offset)) {
proto_tree_add_item(tree, hf_nas_5gs_msg_elems, tvb, offset, len - offset, ENC_NA);
}
}
else
{
(*msg_fcn_p)(tvb, tree, pinfo, offset, len - offset);
}
}
const value_string nas_5gs_pdu_session_id_vals[] = {
{ 0x00, "No PDU session identity assigned" },
{ 0x01, "Reserved" },
@ -5674,8 +5904,9 @@ dissect_nas_5gs_media_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
/* how to know the direction? */
subdissector = NULL;
} else if (!strcmp(n1_msg_class, "UPDP")) {
/* UD policy delivery service not dissected yet */
subdissector = NULL;
/* UD policy delivery service */
disect_nas_5gs_updp(tvb, pinfo, tree, 0);
return tvb_captured_length(tvb);;
} else {
subdissector = NULL;
}
@ -5776,6 +6007,11 @@ proto_register_nas_5gs(void)
FT_UINT8, BASE_HEX | BASE_EXT_STRING, &nas_5gs_sm_msg_strings_ext, 0x0,
NULL, HFILL }
},
{ &hf_nas_5gs_updp_msg_type,
{ "Message type", "nas_5gs.updp.message_type",
FT_UINT8, BASE_HEX | BASE_EXT_STRING, &nas_5gs_updp_msg_strings_ext, 0x0,
NULL, HFILL }
},
{ &hf_nas_5gs_common_elem_id,
{ "Element ID", "nas_5gs.common.elem_id",
FT_UINT8, BASE_HEX, NULL, 0,
@ -5791,6 +6027,11 @@ proto_register_nas_5gs(void)
FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL }
},
{ &hf_nas_5gs_updp_elem_id,
{ "Element ID", "nas_5gs.updp.elem_id",
FT_UINT8, BASE_HEX, NULL, 0,
NULL, HFILL }
},
{ &hf_nas_5gs_proc_trans_id,
{ "Procedure transaction identity", "nas_5gs.proc_trans_id",
FT_UINT8, BASE_DEC, NULL, 0x0,
@ -6981,7 +7222,8 @@ proto_register_nas_5gs(void)
gint *ett[NUM_INDIVIDUAL_ELEMS +
NUM_NAS_5GS_COMMON_ELEM +
NUM_NAS_5GS_MM_MSG + NUM_NAS_5GS_MM_ELEM +
NUM_NAS_5GS_SM_MSG + NUM_NAS_5GS_SM_ELEM
NUM_NAS_5GS_SM_MSG + NUM_NAS_5GS_SM_ELEM +
NUM_NAS_5GS_UPDP_MSG + NUM_NAS_5GS_UPDP_ELEM
];
ett[0] = &ett_nas_5gs;
@ -7033,11 +7275,24 @@ proto_register_nas_5gs(void)
ett[last_offset] = &ett_nas_5gs_sm_elem[i];
}
for (i = 0; i < NUM_NAS_5GS_UPDP_MSG; i++, last_offset++)
{
ett_nas_5gs_updp_msg[i] = -1;
ett[last_offset] = &ett_nas_5gs_updp_msg[i];
}
for (i = 0; i < NUM_NAS_5GS_UPDP_ELEM; i++, last_offset++)
{
ett_nas_5gs_updp_elem[i] = -1;
ett[last_offset] = &ett_nas_5gs_updp_elem[i];
}
static ei_register_info ei[] = {
{ &ei_nas_5gs_extraneous_data, { "nas_5gs.extraneous_data", PI_PROTOCOL, PI_NOTE, "Extraneous Data, dissector bug or later version spec(report to wireshark.org)", EXPFILL }},
{ &ei_nas_5gs_unknown_pd,{ "nas_5gs.unknown_pd", PI_PROTOCOL, PI_ERROR, "Unknown protocol discriminator", EXPFILL } },
{ &ei_nas_5gs_mm_unknown_msg_type,{ "nas_5gs.mm.unknown_msg_type", PI_PROTOCOL, PI_WARN, "Unknown Message Type", EXPFILL } },
{ &ei_nas_5gs_sm_unknown_msg_type,{ "nas_5gs.sm.unknown_msg_type", PI_PROTOCOL, PI_WARN, "Unknown Message Type", EXPFILL } },
{ &ei_nas_5gs_updp_unknown_msg_type,{ "nas_5gs.updp.unknown_msg_type", PI_PROTOCOL, PI_WARN, "Unknown Message Type", EXPFILL } },
{ &ei_nas_5gs_msg_not_dis,{ "nas_5gs.msg_not_dis", PI_PROTOCOL, PI_WARN, "MSG IEs not dissected yet", EXPFILL } },
{ &ei_nas_5gs_ie_not_dis,{ "nas_5gs.ie_not_dis", PI_PROTOCOL, PI_WARN, "IE not dissected yet", EXPFILL } },
{ &ei_nas_5gs_missing_mandatory_elemen,{ "nas_5gs.missing_mandatory_element", PI_PROTOCOL, PI_ERROR, "Missing Mandatory element, rest of dissection is suspect", EXPFILL } },