From a85be06c72dcb8647e490dfa074e056a3a6820f6 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 30 Sep 2024 16:32:55 +0200 Subject: [PATCH 1/5] Add defines for IPv4 and IPv6 PDU address header fields --- .../NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c | 8 ++++---- .../NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c index f5d053ae58..86aa3eaf7f 100644 --- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c @@ -128,14 +128,14 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ 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 < 4; ++i) + 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"); } else if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV6) { - for (int i = 0; i < 8; ++i) + for (int i = 0; i < IPv6_INTERFACE_ID_LENGTH; ++i) addr[i] = *curPtr++; char ipv6[40]; capture_ipv6_addr(addr, ipv6, sizeof(ipv6)); @@ -145,12 +145,12 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ // 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 < 12; ++i) + 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[8], ipv4, sizeof(ipv4)); + 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 { diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h index a254debfbe..e655607d9c 100644 --- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h @@ -42,6 +42,8 @@ #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 /* Rule operation codes - TS 24.501 Table 9.11.4.13.1 */ @@ -114,7 +116,8 @@ typedef struct pdu_address_s { uint8_t pdu_iei; /* PDU Address IEI (0x29) */ uint8_t pdu_length; /* Length of PDU address contents */ uint8_t pdu_type; /* PDU session type value */ - uint8_t pdu_addr_oct[12]; /* PDU address information (depending on type, up to 12 bytes)*/ + /// PDU address information (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 { From 66231badaf52abc31e258a8f49c19baf01a0de99 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Thu, 3 Oct 2024 12:35:08 +0200 Subject: [PATCH 2/5] Refactor PDU address IE in PDU Session Establishment Accept * take 3 bits for PDU session type value * add define for SMF's IPv6 link local address --- .../COMMON/ESM/MSG/PduSessionEstablishmentAccept.c | 12 +++++++++++- .../COMMON/ESM/MSG/PduSessionEstablishmentAccept.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c index 86aa3eaf7f..aee6d0e63d 100644 --- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c @@ -124,8 +124,18 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ case IEI_PDU_ADDRESS: LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received PDU Address IE\n"); psea_msg.pdu_addr_ie.pdu_length = *curPtr++; - psea_msg.pdu_addr_ie.pdu_type = *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) diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h index e655607d9c..c283079998 100644 --- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h @@ -44,6 +44,7 @@ #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 */ From b5f4c55d88060cc85b79be7bd1013867ca253fed Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 25 Oct 2024 11:48:11 +0200 Subject: [PATCH 3/5] Use capture_pdu_session_establishment_accept_msg with NAS_DOWNLINK_DATA_IND:FGS_PDU_SESSION_ESTABLISHMENT_ACC * the capture_pdu_session_establishment_accept_msg function is already handling the code in the case FGS_PDU_SESSION_ESTABLISHMENT_ACC of NAS_DOWNLINK_DATA_IND Closes: #841 --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 29 +++-------------------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index c942e079cd..d5652c4f07 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -1423,32 +1423,9 @@ void *nas_nrue(void *args_p) case FGS_DEREGISTRATION_ACCEPT: LOG_I(NAS, "received deregistration accept\n"); break; - case FGS_PDU_SESSION_ESTABLISHMENT_ACC: { - uint8_t offset = 0; - uint8_t *payload_container = pdu_buffer; - offset += SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH; - uint32_t payload_container_length = htons(((dl_nas_transport_t *)(pdu_buffer + offset))->payload_container_length); - if ((payload_container_length >= PAYLOAD_CONTAINER_LENGTH_MIN) - && (payload_container_length <= PAYLOAD_CONTAINER_LENGTH_MAX)) - offset += (PLAIN_5GS_NAS_MESSAGE_HEADER_LENGTH + 3); - if (offset < NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length) - payload_container = pdu_buffer + offset; - - while (offset < payload_container_length) { - if (*(payload_container + offset) == 0x29) { // PDU address IEI - if ((*(payload_container + offset + 1) == 0x05) && (*(payload_container + offset + 2) == 0x01)) { // IPV4 - uint8_t *ip_p = payload_container + offset + 3; - char ip[20]; - snprintf(ip, sizeof(ip), "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3)); - LOG_I(NAS, "Received PDU Session Establishment Accept, UE IP: %s\n", ip); - tun_config(1, ip, NULL, "oaitun_ue"); - setup_ue_ipv4_route(1, ip, "oaitun_ue"); - break; - } - } - offset++; - } - } break; + case FGS_PDU_SESSION_ESTABLISHMENT_ACC: + capture_pdu_session_establishment_accept_msg(pdu_buffer, pdu_length); + break; case FGS_PDU_SESSION_ESTABLISHMENT_REJ: LOG_E(NAS, "Received PDU Session Establishment reject\n"); break; From 9a67c5e5b50451f19acf3cc493d3f53f0b0e145d Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Mon, 23 Sep 2024 10:40:52 +0200 Subject: [PATCH 4/5] Fix scoping issues for variable declarations in switch-case blocks (capture_pdu_session_establishment_accept_msg) --- .../ESM/MSG/PduSessionEstablishmentAccept.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c index aee6d0e63d..a3c6039752 100644 --- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c @@ -174,42 +174,47 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ curPtr++; /* TS 24.008 10.5.7.3 */ break; - case IEI_SNSSAI: /* Ommited */ + case IEI_SNSSAI: { LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received S-NSSAI IE\n"); uint8_t snssai_length = *curPtr; curPtr += (snssai_length + sizeof(snssai_length)); break; + } case IEI_ALWAYSON_PDU: /* Ommited */ LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Always-on PDU Session indication IE\n"); curPtr++; break; - case IEI_MAPPED_EPS: /* Ommited */ + case IEI_MAPPED_EPS: { LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Mapped EPS bearer context IE\n"); uint16_t mapped_eps_length = getShort(curPtr); curPtr += mapped_eps_length; break; + } - case IEI_EAP_MSG: /* Ommited */ + case IEI_EAP_MSG: { LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received EAP message IE\n"); uint16_t eap_length = getShort(curPtr); curPtr += (eap_length + sizeof(eap_length)); break; + } - case IEI_AUTH_QOS_DESC: /* Ommited */ + case IEI_AUTH_QOS_DESC: { LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Authorized QoS flow descriptions IE\n"); 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: /* Ommited */ + case IEI_EXT_CONF_OPT: { LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Extended protocol configuration options IE\n"); 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: + case IEI_DNN: { LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received DNN IE\n"); psea_msg.dnn_ie.dnn_length = *curPtr++; char apn[APN_MAX_LEN]; @@ -223,6 +228,7 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ curPtr = buffer + msg_length; // we force stop processing break; + } default: LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Not known IE\n"); From c3f1824f0b818605f8019ed02418e6da81dda33b Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 25 Oct 2024 12:35:49 +0200 Subject: [PATCH 5/5] Use capture_pdu_session_establishment_accept_msg in handleDownlinkNASTransport * DL NAS Transport messages can piggy-back 5GSM messages * the relevant decoding functions can be called in the handler (e.g. capture_pdu_session_establishment_accept_msg) --- openair3/NAS/NR_UE/nr_nas_msg_sim.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index d5652c4f07..64f3d2b9a9 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -848,16 +848,15 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, } } -void decodeDownlinkNASTransport(as_nas_info_t *initialNasMsg, uint8_t *pdu_buffer) +/** + * @brief Handle DL NAS Transport and process piggybacked 5GSM messages + */ +static void handleDownlinkNASTransport(uint8_t *pdu_buffer, uint32_t msg_length) { uint8_t msg_type = *(pdu_buffer + 16); if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { - uint8_t *ip_p = pdu_buffer + 39; - char ip[20]; - sprintf(ip, "%d.%d.%d.%d", *(ip_p), *(ip_p + 1), *(ip_p + 2), *(ip_p + 3)); - LOG_A(NAS, "Received PDU Session Establishment Accept\n"); - tun_config(1, ip, NULL, "oaitun_ue"); - setup_ue_ipv4_route(1, ip, "oaitun_ue"); + LOG_A(NAS, "Received PDU Session Establishment Accept in DL NAS Transport\n"); + capture_pdu_session_establishment_accept_msg(pdu_buffer, msg_length); } else { LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type); } @@ -1415,7 +1414,7 @@ void *nas_nrue(void *args_p) handle_security_mode_command(nas, &initialNasMsg, pdu_buffer, pdu_length); break; case FGS_DOWNLINK_NAS_TRANSPORT: - decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer); + handleDownlinkNASTransport(pdu_buffer, pdu_length); break; case REGISTRATION_ACCEPT: handle_registration_accept(nas, pdu_buffer, pdu_length);