aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-nas_5gs.c
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2019-01-08 14:37:59 +0100
committerAnders Broman <a.broman58@gmail.com>2019-01-08 15:58:02 +0000
commitea001cd6c16b21a993fe7358cef65715dc015e90 (patch)
tree4d3dc47f11b74575d066d052cafb5b4b849a3d47 /epan/dissectors/packet-nas_5gs.c
parente0d6041bcfa35297db9ff91c3a5fce4bd3418715 (diff)
mas5gs: Fix dissection of QoS flow descriptions and QoS rules.
Change-Id: Ie4b9fcf0afdea19ba6f2fb531e84096ac103c99b Reviewed-on: https://code.wireshark.org/review/31443 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-nas_5gs.c')
-rw-r--r--epan/dissectors/packet-nas_5gs.c260
1 files changed, 152 insertions, 108 deletions
diff --git a/epan/dissectors/packet-nas_5gs.c b/epan/dissectors/packet-nas_5gs.c
index 1424e0fb10..89193a9299 100644
--- a/epan/dissectors/packet-nas_5gs.c
+++ b/epan/dissectors/packet-nas_5gs.c
@@ -222,6 +222,9 @@ static int hf_nas_5gs_sm_session_ambr_ul = -1;
static int hf_nas_5gs_sm_all_ssc_mode_b0 = -1;
static int hf_nas_5gs_sm_all_ssc_mode_b1 = -1;
static int hf_nas_5gs_sm_all_ssc_mode_b2 = -1;
+static int hf_nas_5gs_addr_mask_ipv4 = -1;
+static int hf_nas_5gs_protocol_identifier_or_next_hd = -1;
+static int hf_nas_5gs_protocol_identifier_or_next_hd_val = -1;
static int ett_nas_5gs = -1;
static int ett_nas_5gs_mm_nssai = -1;
@@ -322,6 +325,40 @@ nas5gs_get_private_data(packet_info *pinfo)
return nas5gs_data;
}
+static guint32
+get_ext_ambr_unit(guint32 unit, const char **unit_str)
+{
+ guint32 mult;
+
+ if (unit == 0) {
+ mult = 1;
+ *unit_str = "Unit value 0, Illegal";
+ return mult;
+ }
+ unit = unit - 1;
+
+ if (unit <= 0x05) {
+ mult = pow4(guint32, unit);
+ *unit_str = "Kbps";
+ } else if (unit <= 0x0a) {
+ mult = pow4(guint32, unit - 0x05);
+ *unit_str = "Mbps";
+ } else if (unit <= 0x0e) {
+ mult = pow4(guint32, unit - 0x07);
+ *unit_str = "Gbps";
+ } else if (unit <= 0x14) {
+ mult = pow4(guint32, unit - 0x0c);
+ *unit_str = "Tbps";
+ } else if (unit <= 0x19) {
+ mult = pow4(guint32, unit - 0x11);
+ *unit_str = "Pbps";
+ } else {
+ mult = 256;
+ *unit_str = "Pbps";
+ }
+ return mult;
+}
+
/*
* 9.11.3 5GS mobility management (5GMM) information elements
*/
@@ -2092,12 +2129,24 @@ de_nas_5gs_sm_pdu_session_type(tvbuff_t *tvb, proto_tree *tree, packet_info *pin
*/
static const value_string nas_5gs_sm_qos_des_flow_opt_code_vals[] = {
+ { 0x00, "Reserved" },
{ 0x01, "Create new QoS flow description" },
{ 0x02, "Delete existing QoS flow description" },
{ 0x03, "Modify existing QoS flow description" },
{ 0, NULL }
};
+static const value_string nas_5gs_sm_param_id_values[] = {
+ { 0x01, "5QI" },
+ { 0x02, "GFBR uplink" },
+ { 0x03, "GFBR downlink" },
+ { 0x04, "MFBR uplink" },
+ { 0x05, "MFBR downlink" },
+ { 0x06, "Averaging window" },
+ { 0x07, "EPS bearer identity" },
+ { 0, NULL }
+};
+
static guint16
de_nas_5gs_sm_qos_flow_des(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
guint32 offset, guint len,
@@ -2107,9 +2156,11 @@ de_nas_5gs_sm_qos_flow_des(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _
proto_tree *sub_tree, *sub_tree2;
proto_item *item;
int i = 1, j = 1;
- guint32 param_len;
+ guint32 param_len, param_id;
guint32 curr_offset, start_offset;
guint8 num_param;
+ guint32 unit, mult, ambr_val;
+ const char *unit_str;
static const int * param_flags[] = {
&hf_nas_5gs_sm_e,
@@ -2147,16 +2198,51 @@ de_nas_5gs_sm_qos_flow_des(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _
start_offset = curr_offset;
/* Parameter identifier */
- proto_tree_add_item(sub_tree2, hf_nas_5gs_sm_param_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item_ret_uint(sub_tree2, hf_nas_5gs_sm_param_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN, &param_id);
+ proto_item_append_text(item, " - %s", val_to_str_const(param_id, nas_5gs_sm_param_id_values, "Unknown"));
curr_offset++;
/* Length of parameter contents */
proto_tree_add_item_ret_uint(sub_tree2, hf_nas_5gs_sm_param_len, tvb, curr_offset, 1, ENC_BIG_ENDIAN, &param_len);
curr_offset++;
/*parameter content*/
- proto_tree_add_item(sub_tree2, hf_nas_5gs_sm_pal_cont, tvb, curr_offset, param_len, ENC_BIG_ENDIAN);
- curr_offset += param_len;
-
+ switch (param_id) {
+ /* 01H (5QI)*/
+ case 0x01:
+ proto_tree_add_item(sub_tree2, hf_nas_5gs_sm_pal_cont, tvb, curr_offset, param_len, ENC_BIG_ENDIAN);
+ curr_offset += param_len;
+ break;
+ /* 02H (GFBR uplink); 04H (MFBR uplink);*/
+ case 0x02:
+ case 0x04:
+ /* Unit for Session-AMBR for uplink */
+ proto_tree_add_item_ret_uint(sub_tree2, hf_nas_5gs_sm_unit_for_session_ambr_ul, tvb, curr_offset, 1, ENC_BIG_ENDIAN, &unit);
+ curr_offset++;
+ /* Session-AMBR for downlink */
+ mult = get_ext_ambr_unit(unit, &unit_str);
+ ambr_val = tvb_get_ntohs(tvb, curr_offset);
+ proto_tree_add_uint_format_value(sub_tree2, hf_nas_5gs_sm_session_ambr_ul, tvb, curr_offset, param_len - 1,
+ ambr_val, "%u %s (%u)", ambr_val * mult, unit_str, ambr_val);
+ curr_offset += (param_len - 1);
+ break;
+ /* 03H (GFBR downlink); 05H (MFBR downlink);*/
+ case 0x03:
+ case 0x05:
+ /* Unit for Session-AMBR for uplink */
+ proto_tree_add_item_ret_uint(sub_tree2, hf_nas_5gs_sm_unit_for_session_ambr_dl, tvb, curr_offset, 1, ENC_BIG_ENDIAN, &unit);
+ curr_offset++;
+ /* Session-AMBR for downlink*/
+ mult = get_ext_ambr_unit(unit, &unit_str);
+ ambr_val = tvb_get_ntohs(tvb, curr_offset);
+ proto_tree_add_uint_format_value(sub_tree2, hf_nas_5gs_sm_session_ambr_dl, tvb, curr_offset, param_len - 1,
+ ambr_val, "%u %s (%u)", ambr_val * mult, unit_str, ambr_val);
+ curr_offset += (param_len - 1);
+ break;
+ default:
+ proto_tree_add_item(sub_tree2, hf_nas_5gs_sm_pal_cont, tvb, curr_offset, param_len, ENC_BIG_ENDIAN);
+ curr_offset += param_len;
+ break;
+ }
num_param--;
j++;
proto_item_set_len(item, curr_offset - start_offset);
@@ -2168,7 +2254,7 @@ de_nas_5gs_sm_qos_flow_des(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _
return len;
}
/*
- * 9.12.4.13 QoS rules
+ * 9.11.4.13 QoS rules
*/
static true_false_string tfs_nas_5gs_sm_dqr = {
@@ -2220,17 +2306,6 @@ static const value_string nas_5gs_sm_pkt_flt_dir_values[] = {
{ 0, NULL }
};
-static const value_string nas_5gs_sm_param_id_values[] = {
- { 0x01, "5QI" },
- { 0x02, "GFBR uplink" },
- { 0x03, "GFBR downlink" },
- { 0x04, "MFBR uplink" },
- { 0x05, "MFBR downlink" },
- { 0x06, "Averaging window" },
- { 0x07, "EPS bearer identity" },
- { 0, NULL }
- };
-
static const value_string nas_5gs_rule_param_cont[] = {
{ 0x0, "Reserved" },
{ 0x01, "5QI 1" },
@@ -2251,12 +2326,12 @@ de_nas_5gs_sm_qos_rules(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
gchar *add_string _U_, int string_len _U_)
{
- proto_tree *sub_tree, *sub_tree2, *sub_tree3;
+ proto_tree *sub_tree, *sub_tree2;
proto_item *item;
int i = 1, j = 1;
- guint32 pf_len, pf_type, param_len;
- guint32 length, curr_offset, start_offset, rule_start_offset;
- guint8 num_pkt_flt, rop, num_param;
+ guint32 qos_rule_id, pf_len, pf_type;
+ guint32 length, curr_offset, start_offset;
+ guint8 num_pkt_flt, rop;
static const int * pkt_flt_flags[] = {
&hf_nas_5gs_sm_rop,
@@ -2265,24 +2340,17 @@ de_nas_5gs_sm_qos_rules(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
NULL
};
- static const int * param_flags[] = {
- &hf_nas_5gs_sm_e,
- &hf_nas_5gs_sm_nof_params,
- NULL
- };
-
curr_offset = offset;
while ((curr_offset - offset) < len) {
/* QoS Rule */
- rule_start_offset = curr_offset;
sub_tree = proto_tree_add_subtree_format(tree, tvb, curr_offset, -1, ett_nas_5gs_sm_qos_rules, &item, "QoS rule %u", i);
- /* QoS rule identifier */
- proto_tree_add_item(sub_tree, hf_nas_5gs_sm_qos_rule_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+ /* QoS rule identifier Octet 4*/
+ proto_tree_add_item_ret_uint(sub_tree, hf_nas_5gs_sm_qos_rule_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN, &qos_rule_id);
curr_offset += 1;
- /* Length of QoS rule */
+ /* Length of QoS rule Octet 5 - 6*/
proto_tree_add_item_ret_uint(sub_tree, hf_nas_5gs_sm_length, tvb, curr_offset, 2, ENC_BIG_ENDIAN, &length);
curr_offset += 2;
@@ -2314,8 +2382,8 @@ de_nas_5gs_sm_qos_rules(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
}
}
+ /* Packet filter list */
while (num_pkt_flt > 0) {
- /* Packet filter list */
sub_tree2 = proto_tree_add_subtree_format(sub_tree, tvb, curr_offset, -1, ett_nas_5gs_sm_qos_rules, &item, "Packet filter %u", j);
start_offset = curr_offset;
if (rop == 5) {
@@ -2327,7 +2395,7 @@ de_nas_5gs_sm_qos_rules(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
/* "create new QoS rule", or "modify existing QoS rule and add packet filters"
* or "modify existing QoS rule and replace packet filters"
*/
- /* 0 0 Packet filter direction 1 Packet filter identifier 1*/
+ /* 0 0 Packet filter direction 1 Packet filter identifier 1*/
proto_tree_add_item(sub_tree2, hf_nas_5gs_sm_pkt_flt_dir, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(sub_tree2, hf_nas_5gs_sm_pkt_flt_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
curr_offset++;
@@ -2342,59 +2410,58 @@ de_nas_5gs_sm_qos_rules(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
proto_tree_add_item_ret_uint(sub_tree2, hf_nas_5gs_sm_pf_type, tvb, curr_offset, 1, ENC_BIG_ENDIAN, &pf_type);
curr_offset++;
switch (pf_type) {
+ case 1:
+ /* Match-all type
+ * . If the "match-all type" packet filter component is present in the packet filter, no other packet filter
+ * component shall be present in the packet filter and the length of the packet filter contents field shall
+ * be set to one.
+ */
+ curr_offset += pf_len;
+ break;
+ case 16:
+ /* For "IPv4 remote address type", the packet filter component value field shall be encoded as a sequence
+ * of a four octet IPv4 address field and a four octet IPv4 address mask field.
+ * The IPv4 address field shall be transmitted first.
+ */
+ proto_tree_add_item(sub_tree2, hf_nas_5gs_sm_pdu_addr_inf_ipv4, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
+ curr_offset += 4;
+ proto_tree_add_item(sub_tree2, hf_nas_5gs_addr_mask_ipv4, tvb, curr_offset, 4, ENC_BIG_ENDIAN);
+ curr_offset += 4;
+ proto_tree_add_item(sub_tree2, hf_nas_5gs_protocol_identifier_or_next_hd, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+ curr_offset += 1;
+ proto_tree_add_item(sub_tree2, hf_nas_5gs_protocol_identifier_or_next_hd_val, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
+ curr_offset++;
+ break;
default:
- proto_tree_add_expert(sub_tree2, pinfo, &ei_nas_5gs_not_diss, tvb, curr_offset, pf_len - 1);
+ proto_tree_add_expert(sub_tree2, pinfo, &ei_nas_5gs_not_diss, tvb, curr_offset, pf_len);
+ curr_offset += pf_len;
break;
}
- curr_offset += (pf_len - 1);
}
num_pkt_flt--;
j++;
proto_item_set_len(item, curr_offset - start_offset);
}
-
- /* 0 Spare E Number of parameters */
- j = 1;
- num_param = tvb_get_guint8(tvb, curr_offset);
- num_param = num_param & 0x3f;
- proto_tree_add_bitmask_list(sub_tree, tvb, curr_offset, 1, param_flags, ENC_BIG_ENDIAN);
- curr_offset++;
-
- while (num_param > 0) {
- /* Parameter list */
- sub_tree3 = proto_tree_add_subtree_format(sub_tree, tvb, curr_offset, -1, ett_nas_5gs_sm_qos_rules, &item, "Parameter %u", j);
-
- start_offset = curr_offset;
-
- /* Parameter identifier */
- proto_tree_add_item(sub_tree3, hf_nas_5gs_sm_param_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
- curr_offset++;
- /* Length of parameter contents */
- proto_tree_add_item_ret_uint(sub_tree3, hf_nas_5gs_sm_param_len, tvb, curr_offset, 1, ENC_BIG_ENDIAN, &param_len);
+ /* QoS rule precedence (octet z+1)
+ * For the "delete existing QoS rule" operation, the QoS rule precedence value field shall not be included.
+ * For the "create new QoS rule" operation, the QoS rule precedence value field shall be included.
+ */
+ if (qos_rule_id != 2) { /* Delete existing QoS rule */
+ proto_tree_add_item(sub_tree, hf_nas_5gs_sm_qos_rule_precedence, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
curr_offset++;
-
- proto_tree_add_item(sub_tree3, hf_nas_5gs_sm_pal_cont, tvb, curr_offset, param_len, ENC_BIG_ENDIAN);
- curr_offset += param_len;
-
- num_param--;
- j++;
- proto_item_set_len(item, curr_offset - start_offset);
}
-
- /* Qos rule precedence */
- proto_tree_add_item(sub_tree, hf_nas_5gs_sm_qos_rule_precedence, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
- curr_offset++;
-
- /* 0 spare 0 spare QFI */
+ /* QoS flow identifier (QFI) (bits 6 to 1 of octet z+2)
+ * For the "delete existing QoS rule" operation, the QoS flow identifier value field shall not be included.
+ * For the "create new QoS rule" operation, the QoS flow identifier value field shall be included.
+ */
+ /* Segregation bit (bit 7 of octet z+2) */
proto_tree_add_item(sub_tree, hf_nas_5gs_sm_qfi, tvb, curr_offset, 1, ENC_BIG_ENDIAN);
- curr_offset++;
+ curr_offset += 1;
i++;
- curr_offset = rule_start_offset + length + 3;
}
-
return len;
}
@@ -2432,44 +2499,6 @@ static const value_string nas_5gs_sm_unit_for_session_ambr_values[] = {
{ 0, NULL }
};
-static guint32
-get_ext_ambr_unit(guint32 unit, const char **unit_str)
-{
- guint32 mult;
-
- if (unit == 0) {
- mult = 1;
- *unit_str = "Unit value 0, Illegal";
- return mult;
- }
- unit = unit - 1;
-
- if (unit <= 0x05) {
- mult = pow4(guint32, unit);
- *unit_str = "Kbps";
- }
- else if (unit <= 0x0a) {
- mult = pow4(guint32, unit - 0x05);
- *unit_str = "Mbps";
- }
- else if (unit <= 0x0e) {
- mult = pow4(guint32, unit - 0x07);
- *unit_str = "Gbps";
- }
- else if (unit <= 0x14) {
- mult = pow4(guint32, unit - 0x0c);
- *unit_str = "Tbps";
- }
- else if (unit <= 0x19) {
- mult = pow4(guint32, unit - 0x11);
- *unit_str = "Pbps";
- }
- else {
- mult = 256;
- *unit_str = "Pbps";
- }
- return mult;
-}
guint16
de_nas_5gs_sm_session_ambr(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_,
@@ -5377,6 +5406,21 @@ proto_register_nas_5gs(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_nas_5gs_addr_mask_ipv4,
+ { "IPv4 address mask", "nas_5gs.ipv4_address_mask",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_nas_5gs_protocol_identifier_or_next_hd,
+ { "packet filter component type", "nas_5gs.protocol_identifier_or_next_hd",
+ FT_UINT8, BASE_DEC, VALS(nas_5gs_sm_pf_type_values), 0x0,
+ NULL, HFILL }
+ },
+ { &hf_nas_5gs_protocol_identifier_or_next_hd_val,
+ { "packet filter component value", "nas_5gs.protocol_identifier_or_next_hd_val",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_nas_5gs_sm_qos_rule_precedence,
{ "QoS rule precedence", "nas_5gs.sm.qos_rule_precedence",
FT_UINT8, BASE_DEC, NULL, 0x0,