Migrated NAS 5GS (5GMM & 5GSM) to NR folders and refactor CMakeLists.txt files

This commit is introducing the following macro changes:

(1) Migrate NAS 5GS lib files to a new 5GS subfolder in NR_UE
    and organize NAS 5GS lib messages into 5GMM and 5GSM subfolders.
    A nested CMake structure was implemented and CMakeLists.txt were
    added whenever necessary. This is effectively separating 5GS
    libraries from LTE libraries.

(2) In order to simplify the separation of 5GS libs from LTE libs,
    remaining dependencies from NAS LTE (e.g. nas_ue_task.c, ue-idx-standalone)
    were removed in the process

(3) ExtendedProtocolDiscriminator.c/.h and SpareHalfOctet.c/.h were deleted
    and affected types were replaced with simple integer types

(4) Cleanup: unused definitions and libs (e.g. LIB_5GNAS_GNB)
    were removed

(5) Update doc/Doxyfile

(6) clang-formatted the migrated files in the process

(7) Update includes of headers in affected files
This commit is contained in:
Guido Casati
2025-01-30 15:17:30 +01:00
parent 0fd0a4fcae
commit c0583be24e
63 changed files with 475 additions and 865 deletions
@@ -1,63 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PduSessionEstablishRequest.c
\brief pdu session establishment request procedures
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "TLVEncoder.h"
#include "TLVDecoder.h"
#include "PduSessionEstablishRequest.h"
int encode_pdu_session_establishment_request(pdu_session_establishment_request_msg *pdusessionestablishrequest, uint8_t *buffer)
{
int encoded = 0;
*(buffer + encoded) = pdusessionestablishrequest->protocoldiscriminator;
encoded++;
*(buffer + encoded) = pdusessionestablishrequest->pdusessionid;
encoded++;
*(buffer + encoded) = pdusessionestablishrequest->pti;
encoded++;
*(buffer + encoded) = pdusessionestablishrequest->pdusessionestblishmsgtype;
encoded++;
IES_ENCODE_U16(buffer, encoded, pdusessionestablishrequest->maxdatarate);
*(buffer + encoded) = pdusessionestablishrequest->pdusessiontype;
encoded++;
return encoded;
}
@@ -1,65 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PduSessionEstablishRequest.h
\brief pdu session establishment request procedures
\author Yoshio INOUE, Masayuki HARADA
\email: yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com
\date 2020
\version 0.1
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "ExtendedProtocolDiscriminator.h"
#include "MessageType.h"
#ifndef PDU_SESSION_ESTABLISHMENT_REQUEST_H_
#define PDU_SESSION_ESTABLISHMENT_REQUEST_H_
/*
* Message name: pdu session establishment request
* Description: The PDU SESSION ESTABLISHMENT REQUEST message is sent by the UE to the SMF to initiate establishment of a PDU session. See table 8.3.1.1.1.
* Significance: dual
* Direction: UE to network
*/
typedef struct pdu_session_establishment_request_msg_tag {
/* Mandatory fields */
ExtendedProtocolDiscriminator protocoldiscriminator;
uint8_t pdusessionid;
uint8_t pti;
MessageType pdusessionestblishmsgtype;
uint16_t maxdatarate;
uint8_t pdusessiontype;
/* Optional fields */
} pdu_session_establishment_request_msg;
int encode_pdu_session_establishment_request(pdu_session_establishment_request_msg *pdusessionestablishrequest, uint8_t *buffer);
#endif /* ! defined(PDU_SESSION_ESTABLISHMENT_REQUEST_H_) */
@@ -1,241 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include <netinet/in.h>
#include "PduSessionEstablishmentAccept.h"
#include "common/utils/LOG/log.h"
#include "nr_nas_msg.h"
#include "common/utils/tun_if.h"
#include "openair2/SDAP/nr_sdap/nr_sdap.h"
static uint16_t getShort(uint8_t *input)
{
uint16_t tmp16;
memcpy(&tmp16, input, sizeof(tmp16));
return htons(tmp16);
}
static int capture_ipv4_addr(const uint8_t *addr, char *ip, size_t len)
{
return snprintf(ip, len, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
}
static int capture_ipv6_addr(const uint8_t *addr, char *ip, size_t len)
{
// 24.501 Sec 9.11.4.10: "an interface identifier for the IPv6 link local
// address": link local starts with fe80::, and only the last 64bits are
// given (middle is zero)
return snprintf(ip,
len,
"fe80::%02x%02x:%02x%02x:%02x%02x:%02x%02x",
addr[0],
addr[1],
addr[2],
addr[3],
addr[4],
addr[5],
addr[6],
addr[7]);
}
/**
* @brief PDU session establishment accept (8.3.2 of 3GPP TS 24.501)
* network to UE
*/
void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_length)
{
security_protected_nas_5gs_msg_t sec_nas_hdr;
security_protected_plain_nas_5gs_msg_t sec_nas_msg;
pdu_session_establishment_accept_msg_t psea_msg;
uint8_t *curPtr = buffer;
// Security protected NAS header (7 bytes)
sec_nas_hdr.epd = *curPtr++;
sec_nas_hdr.sht = *curPtr++;
uint32_t tmp;
memcpy(&tmp, buffer, sizeof(tmp));
sec_nas_hdr.mac = htonl(tmp);
curPtr += sizeof(sec_nas_hdr.mac);
sec_nas_hdr.sqn = *curPtr++;
// Security protected plain NAS message
sec_nas_msg.epd = *curPtr++;
sec_nas_msg.sht = *curPtr++;
sec_nas_msg.msg_type = *curPtr++;
sec_nas_msg.payload_type = *curPtr++;
sec_nas_msg.payload_len = getShort(curPtr);
curPtr += sizeof(sec_nas_msg.payload_len);
/* Mandatory Presence IEs */
psea_msg.epd = *curPtr++;
psea_msg.pdu_id = *curPtr++;
psea_msg.pti = *curPtr++;
psea_msg.msg_type = *curPtr++;
psea_msg.pdu_type = *curPtr & 0x0f;
psea_msg.ssc_mode = (*curPtr++ & 0xf0) >> 4;
psea_msg.qos_rules.length = getShort(curPtr);
curPtr += sizeof(psea_msg.qos_rules.length);
/* Supports the capture of only one QoS Rule, it should be changed for multiple QoS Rules */
qos_rule_t qos_rule;
qos_rule.id = *curPtr++;
qos_rule.length = getShort(curPtr);
curPtr += sizeof(qos_rule.length);
qos_rule.oc = (*(curPtr)&0xE0) >> 5;
qos_rule.dqr = (*(curPtr)&0x10) >> 4;
qos_rule.nb_pf = *curPtr++ & 0x0F;
if(qos_rule.nb_pf) {
packet_filter_t pf;
if(qos_rule.oc == ROC_CREATE_NEW_QOS_RULE ||
qos_rule.oc == ROC_MODIFY_QOS_RULE_ADD_PF ||
qos_rule.oc == ROC_MODIFY_QOS_RULE_REPLACE_PF) {
pf.pf_type.type_1.pf_dir = (*curPtr & 0x30) >> 4;
pf.pf_type.type_1.pf_id = *curPtr++ & 0x0F;
pf.pf_type.type_1.length = *curPtr++;
curPtr += (qos_rule.nb_pf * pf.pf_type.type_1.length); /* Ommit the Packet filter List */
} else if (qos_rule.oc == ROC_MODIFY_QOS_RULE_DELETE_PF) {
curPtr += qos_rule.nb_pf;
}
}
qos_rule.prcd = *curPtr++;
qos_rule.qfi = *curPtr++;
psea_msg.sess_ambr.length = *curPtr++;
curPtr += psea_msg.sess_ambr.length; /* Ommit the Seassion-AMBR */
/* Optional Presence IEs */
while (curPtr < buffer + msg_length) {
uint8_t psea_iei = *curPtr++;
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received %s IEI\n", iei_text_desc[psea_iei].text);
switch (psea_iei) {
case IEI_5GSM_CAUSE: /* Ommited */
curPtr++;
break;
case IEI_PDU_ADDRESS:
psea_msg.pdu_addr_ie.pdu_length = *curPtr++;
/* Octet 3 */
// PDU type (3 bits)
psea_msg.pdu_addr_ie.pdu_type = *curPtr & 0x07;
// SMF's IPv6 link local address (1 bit)
uint8_t si6lla = (*curPtr >> 3) & 0x01;
if (si6lla)
LOG_E(NAS, "SMF's IPv6 link local address is not handled\n");
curPtr++;
/* Octet 4 to n */
// PDU address information
uint8_t *addr = psea_msg.pdu_addr_ie.pdu_addr_oct;
if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV4) {
for (int i = 0; i < IPv4_ADDRESS_LENGTH; ++i)
addr[i] = *curPtr++;
char ip[20];
capture_ipv4_addr(&addr[0], ip, sizeof(ip));
tun_config(1, ip, NULL, "oaitun_ue");
setup_ue_ipv4_route(1, ip, "oaitun_ue");
LOG_I(NAS, "Received PDU Session Establishment Accept, UE IP: %u.%u.%u.%u\n",
addr[0], addr[1], addr[2], addr[3]);
} else if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV6) {
for (int i = 0; i < IPv6_INTERFACE_ID_LENGTH; ++i)
addr[i] = *curPtr++;
char ipv6[40];
capture_ipv6_addr(addr, ipv6, sizeof(ipv6));
tun_config(1, NULL, ipv6, "oaitun_ue");
} else if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV4V6) {
// 24.501 Sec 9.11.4.10: "If the PDU session type value indicates
// IPv4v6, the PDU address information in octet 4 to octet 11
// contains an interface identifier for the IPv6 link local address
// and in octet 12 to octet 15 contains an IPv4 address."
for (int i = 0; i < IPv4_ADDRESS_LENGTH + IPv6_INTERFACE_ID_LENGTH; ++i)
addr[i] = *curPtr++;
char ipv6[40];
capture_ipv6_addr(addr, ipv6, sizeof(ipv6));
char ipv4[20];
capture_ipv4_addr(&addr[IPv6_INTERFACE_ID_LENGTH], ipv4, sizeof(ipv4));
tun_config(1, ipv4, ipv6, "oaitun_ue");
setup_ue_ipv4_route(1, ipv4, "oaitun_ue");
} else {
LOG_E(NAS, "unknown/unhandled PDU session establishment accept PDU type %d\n", psea_msg.pdu_addr_ie.pdu_type);
curPtr += psea_msg.pdu_addr_ie.pdu_length;
}
break;
case IEI_RQ_TIMER_VALUE: /* Ommited */
curPtr++; /* TS 24.008 10.5.7.3 */
break;
case IEI_SNSSAI: {
uint8_t snssai_length = *curPtr;
curPtr += (snssai_length + sizeof(snssai_length));
break;
}
case IEI_ALWAYSON_PDU: /* Ommited */
curPtr++;
break;
case IEI_MAPPED_EPS: {
uint16_t mapped_eps_length = getShort(curPtr);
curPtr += mapped_eps_length;
break;
}
case IEI_EAP_MSG: {
uint16_t eap_length = getShort(curPtr);
curPtr += (eap_length + sizeof(eap_length));
break;
}
case IEI_AUTH_QOS_DESC: {
psea_msg.qos_fd_ie.length = getShort(curPtr);
curPtr += (psea_msg.qos_fd_ie.length + sizeof(psea_msg.qos_fd_ie.length));
break;
}
case IEI_EXT_CONF_OPT: {
psea_msg.ext_pp_ie.length = getShort(curPtr);
curPtr += (psea_msg.ext_pp_ie.length + sizeof(psea_msg.ext_pp_ie.length));
break;
}
case IEI_DNN: {
psea_msg.dnn_ie.dnn_length = *curPtr++;
char apn[APN_MAX_LEN];
if(psea_msg.dnn_ie.dnn_length <= APN_MAX_LEN &&
psea_msg.dnn_ie.dnn_length >= APN_MIN_LEN) {
memcpy(apn, curPtr, psea_msg.dnn_ie.dnn_length);
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - APN: %s\n", apn);
} else
LOG_E(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - DNN IE has invalid length\n");
curPtr = buffer + msg_length; // we force stop processing
break;
}
default:
curPtr = buffer + msg_length; // we force stop processing
break;
}
}
set_qfi_pduid(qos_rule.qfi, psea_msg.pdu_id);
return;
}
@@ -1,181 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef PDU_SESSION_ESTABLISHMENT_ACCEPT_H_
#define PDU_SESSION_ESTABLISHMENT_ACCEPT_H_
#include <stdint.h>
#include "NR_NAS_defs.h"
/* PDU Session Establish Accept Optional IE Identifiers - TS 24.501 Table 8.3.2.1.1 */
#define FOREACH_IEI(IEI_DEF) \
IEI_DEF(IEI_5GSM_CAUSE, 0x59) /* 5GSM cause 9.11.4.2 */ \
IEI_DEF(IEI_PDU_ADDRESS, 0x29) /* PDU address 9.11.4.10 */ \
IEI_DEF(IEI_RQ_TIMER_VALUE, 0x56) /* GPRS timer 9.11.2.3 */ \
IEI_DEF(IEI_SNSSAI, 0x22) /* S-NSSAI 9.11.2.8 */ \
IEI_DEF(IEI_ALWAYSON_PDU, 0x80) /* Always-on PDU session indication 9.11.4.3 */ \
IEI_DEF(IEI_MAPPED_EPS, 0x75) /* Mapped EPS bearer contexts 9.11.4.8 */ \
IEI_DEF(IEI_EAP_MSG, 0x78) /* EAP message 9.11.2.2 */ \
IEI_DEF(IEI_AUTH_QOS_DESC, 0x79) /* QoS flow descriptions 9.11.4.12 */ \
IEI_DEF(IEI_EXT_CONF_OPT, 0x7b) /* Extended protocol configuration options 9.11.4.6 */ \
IEI_DEF(IEI_DNN, 0x25) /* DNN 9.11.2.1B */
static const text_info_t iei_text_desc[] = {FOREACH_IEI(TO_TEXT)};
typedef enum { FOREACH_IEI(TO_ENUM) } pduSessionEstablishment_IEI_t;
/* PDU Session type value - TS 24.501 Table 9.11.4.10.1*/
#define PDU_SESSION_TYPE_IPV4 0b001
#define PDU_SESSION_TYPE_IPV6 0b010
#define PDU_SESSION_TYPE_IPV4V6 0b011
#define IPv4_ADDRESS_LENGTH 4 // length of the IPv4 address associated with a PDU session
#define IPv6_INTERFACE_ID_LENGTH 8 // interface identifier for the IPv6 link local address
#define SMF_IPv6_LLA_LENGTH 16
/* Rule operation codes - TS 24.501 Table 9.11.4.13.1 */
#define ROC_RESERVED_0 0b000 /* Reserved */
#define ROC_CREATE_NEW_QOS_RULE 0b001 /* Create new QoS rule */
#define ROC_DELETE_QOS_RULE 0b010 /* Delete existing QoS rule */
#define ROC_MODIFY_QOS_RULE_ADD_PF 0b011 /* Modify existing QoS rule and add packet filters */
#define ROC_MODIFY_QOS_RULE_REPLACE_PF 0b100 /* Modify existing QoS rule and replace all packet filters */
#define ROC_MODIFY_QOS_RULE_DELETE_PF 0b101 /* Modify existing QoS rule and delete packet filters */
#define ROC_MODIFY_QOS_RULE_WITHOUT_PF 0b110 /* Modify existing QoS rule without modifying packet filters */
#define ROC_RESERVED_1 0b111 /* Reserved */
/* DNN - APN
* TS 23.003 9.1
* The APN is composed of two parts, the APN Network Identifier (9.1.1) & The APN Operator Identifier (9.1.2).
*
* The DNN information element has a length in the range of 3 to 102 octets.
* The Header is consisted of two octets, the DNN IEI and the Length of the DNN contents fields, each is 1 octet.
* The DNN value payload starts from the 3rd octet.
* The accumulated max length of APN payload is 100 octets.
* The min length of the APN payload is 1 octet.
*/
#define APN_MAX_LEN 100
#define APN_MIN_LEN 1
/* Mandatory Presence IE - TS 24.501 Table 8.3.2.1.1 */
typedef struct packet_filter_create_qos_rule_s {
uint8_t pf_dir; /* Packet filter direction */
uint8_t pf_id; /* Packet filter identifier */
uint8_t length; /* Length of packet filter contents */
} packet_filter_type1_t; /* TS 24.501 Figure 9.11.4.13.3 */
typedef struct packet_filter_modify_qos_rule_s {
uint8_t pf_id; /* Packet filter identifier */
} packet_filter_type2_t; /* TS 24.501 Figure 9.11.4.13.4 */
typedef struct packet_filter_s {
union pf_type {
packet_filter_type1_t type_1;
packet_filter_type2_t type_2;
} pf_type;
} packet_filter_t;
typedef struct qos_rule_s {
uint8_t id; /* QoS rule identifier */
uint16_t length; /* Length of QoS Rule */
uint8_t oc; /* Rule operation code (3bits) */
uint8_t dqr; /* DQR bit (1 bit) */
uint8_t nb_pf; /* Number of packet filters (4 bits) */
uint8_t prcd; /* QoS rule precedence */
uint8_t qfi; /* QoS Flow Identifier */
} qos_rule_t;
typedef struct auth_qos_rules_s {
uint16_t length; /* Length of QoS rules IE */
} auth_qos_rule_t; /* QoS Rule as defined in 24.501 Figure 9.11.4.13.2 */
typedef struct session_ambr_s {
uint8_t length; /* Length of Session-AMBR contents */
uint8_t unit_dl; /* Unit for Session-AMBR for downlink */
uint16_t sess_dl; /* Session-AMBR for downlink */
uint8_t unit_ul; /* Unit for Session-AMBR for uplink */
uint16_t sess_ul; /* Session-AMBR for uplink */
} session_ambr_t; /* TS 24.501 Figure 9.11.4.14.1 */
/* Optional Presence IE - TS 24.501 Table 8.3.2.1.1 */
typedef struct pdu_address_s {
// PDU address IEI (0x29) (octet 1)
uint8_t pdu_iei;
// Length of PDU address contents (octet 2)
uint8_t pdu_length;
// PDU session type value (9.11.4.11 of TS 24.501)
uint8_t pdu_type;
// PDU address IE (depending on type, up to 12 bytes)
uint8_t pdu_addr_oct[IPv4_ADDRESS_LENGTH + IPv6_INTERFACE_ID_LENGTH];
} pdu_address_t; /* TS 24.501 9.11.4.10 */
typedef struct dnn_s {
uint8_t dnn_iei; /* DNN IEI (0x25) */
uint8_t dnn_length; /* Length of DNN contents */
} dnn_t; /* TS 24.501 9.11.2.1A */
typedef struct ext_pP_t {
uint16_t length;
} ext_pP_t; /* TS 24.008 10.5.6.3A - Ommited, only length is processed*/
typedef struct qos_fd_s {
uint16_t length;
} qos_fd_t; /* TS 24.501 9.11.4.12 - Ommited, only length is processed*/
typedef struct pdu_session_establishment_accept_msg_s {
/* Mandatory presence */
uint8_t epd; /* Extended Protocol Discriminator */
uint8_t pdu_id; /* PDU Session ID */
uint8_t pti; /* Procedure Transaction Identity */
uint8_t msg_type; /* Message Type */
uint8_t pdu_type; /* PDU Session Type */
uint8_t ssc_mode; /* SSC mode */
auth_qos_rule_t qos_rules; /* Authorized QoS rules */
session_ambr_t sess_ambr; /* Session-AMBR */
/* Optional presence */
dnn_t dnn_ie; /* Data Network Name */
pdu_address_t pdu_addr_ie; /* PDU Address */
ext_pP_t ext_pp_ie; /* Extended Protocol Configuration Options */
qos_fd_t qos_fd_ie; /* QoS flow descriptions */
} pdu_session_establishment_accept_msg_t; /* 24.501 Table 8.3.2.1.1 */
typedef struct security_protected_plain_nas_5gs_msg_s {
uint8_t epd; /* Extended Protocol Discriminator */
uint8_t sht; /* Security Header Type */
uint8_t msg_type; /* Message Type */
uint8_t payload_type; /* Payload Container Type */
uint16_t payload_len; /* Payload Container Length */
} security_protected_plain_nas_5gs_msg_t;
typedef struct security_protected_nas_5gs_msg_s {
uint8_t epd; /* Extended Protocol Discriminator */
uint8_t sht; /* Security Header Type */
uint32_t mac; /* Message Authentication Code */
uint8_t sqn; /* Sequence Number */
} security_protected_nas_5gs_msg_t; /* 24.501 Figure 9.1.1.2 */
void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_length);
#endif