diff --git a/CMakeLists.txt b/CMakeLists.txt index 06184ac619..d3fd4b4a2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2383,6 +2383,7 @@ set(libnrnas_emm_msg_OBJS ${NAS_SRC}COMMON/EMM/MSG/RegistrationComplete.c ${NAS_SRC}COMMON/EMM/MSG/FGSUplinkNasTransport.c ${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishRequest.c + ${NAS_SRC}COMMON/ESM/MSG/PduSessionEstablishmentAccept.c ) set(libnrnas_ies_OBJS diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c new file mode 100644 index 0000000000..cbcd767c11 --- /dev/null +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c @@ -0,0 +1,192 @@ +/* + * 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 "PduSessionEstablishmentAccept.h" +#include "common/utils/LOG/log.h" +#include "nr_nas_msg_sim.h" +#include "openair2/RRC/NAS/nas_config.h" +#include "openair2/SDAP/nr_sdap/nr_sdap.h" + +extern char *baseNetAddress; + +void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_length) +{ + uint8_t offset = 0; + 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; + sec_nas_hdr.epd = *(buffer + (offset++)); + sec_nas_hdr.sht = *(buffer + (offset++)); + sec_nas_hdr.mac = htonl(*(uint32_t *)(buffer + offset)); + offset+=sizeof(sec_nas_hdr.mac); + sec_nas_hdr.sqn = *(buffer + (offset++)); + sec_nas_msg.epd = *(buffer + (offset++)); + sec_nas_msg.sht = *(buffer + (offset++)); + sec_nas_msg.msg_type = *(buffer + (offset++)); + sec_nas_msg.payload_type = *(buffer + (offset++)); + sec_nas_msg.payload_len = htons(*(uint16_t *)(buffer + offset)); + offset+=sizeof(sec_nas_msg.payload_len); + /* Mandatory Presence IEs */ + psea_msg.epd = *(buffer + (offset++)); + psea_msg.pdu_id = *(buffer + (offset++)); + psea_msg.pti = *(buffer + (offset++)); + psea_msg.msg_type = *(buffer + (offset++)); + psea_msg.pdu_type = *(buffer + offset) & 0x0f; + psea_msg.ssc_mode = (*(buffer + (offset++)) & 0xf0) >> 4; + psea_msg.qos_rules.length = htons(*(uint16_t *)(buffer + offset)); + offset+=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 = *(buffer + (offset++)); + qos_rule.length = htons(*(uint16_t *)(buffer + offset)); + offset+=sizeof(qos_rule.length); + qos_rule.oc = (*(buffer + offset) & 0xE0) >> 5; + qos_rule.dqr = (*(buffer + offset) & 0x10) >> 4; + qos_rule.nb_pf = *(buffer + (offset++)) & 0x0F; + + if(qos_rule.nb_pf) { + packet_filter_t pf; + + if(qos_rule.oc == ROC_CREATE_NEW_QOS_RULE || + ROC_MODIFY_QOS_RULE_ADD_PF || + ROC_MODIFY_QOS_RULE_REPLACE_PF) { + pf.pf_type.type_1.pf_dir = (*(buffer + offset) & 0x30) >> 4; + pf.pf_type.type_1.pf_id = *(buffer + offset++) & 0x0F; + pf.pf_type.type_1.length = *(buffer + offset++); + offset += (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) { + offset += qos_rule.nb_pf; + } + } + + qos_rule.prcd = *(buffer + offset++); + qos_rule.qfi = *(buffer + offset++); + psea_msg.sess_ambr.length = *(buffer + offset++); + offset += psea_msg.sess_ambr.length; /* Ommit the Seassion-AMBR */ + + /* Optional Presence IEs */ + uint8_t psea_iei = *(buffer + offset++); + + while(offset < msg_length) { + switch (psea_iei) { + case IEI_5GSM_CAUSE: /* Ommited */ + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received 5GSM Cause IEI\n"); + offset++; + break; + + case IEI_PDU_ADDRESS: + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received PDU Address IE\n"); + psea_msg.pdu_addr_ie.pdu_length = *(buffer + offset++); + psea_msg.pdu_addr_ie.pdu_type = *(buffer + offset++); + + if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV4) { + psea_msg.pdu_addr_ie.pdu_addr_oct1 = *(buffer + offset++); + psea_msg.pdu_addr_ie.pdu_addr_oct2 = *(buffer + offset++); + psea_msg.pdu_addr_ie.pdu_addr_oct3 = *(buffer + offset++); + psea_msg.pdu_addr_ie.pdu_addr_oct4 = *(buffer + offset++); + nas_getparams(); + sprintf(baseNetAddress, "%d.%d", psea_msg.pdu_addr_ie.pdu_addr_oct1, psea_msg.pdu_addr_ie.pdu_addr_oct2); + nas_config(1, psea_msg.pdu_addr_ie.pdu_addr_oct3, psea_msg.pdu_addr_ie.pdu_addr_oct4, "oaitun_ue"); + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received UE IP: %d.%d.%d.%d\n", + psea_msg.pdu_addr_ie.pdu_addr_oct1, + psea_msg.pdu_addr_ie.pdu_addr_oct2, + psea_msg.pdu_addr_ie.pdu_addr_oct3, + psea_msg.pdu_addr_ie.pdu_addr_oct4); + } else { + offset += psea_msg.pdu_addr_ie.pdu_length; + } + + psea_iei = *(buffer + offset++); + break; + + case IEI_RQ_TIMER_VALUE: /* Ommited */ + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received RQ timer value IE\n"); + offset++; /* TS 24.008 10.5.7.3 */ + psea_iei = *(buffer + offset++); + break; + + case IEI_SNSSAI: /* Ommited */ + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received S-NSSAI IE\n"); + uint8_t snssai_length = *(buffer + offset); + offset += (snssai_length + sizeof(snssai_length)); + psea_iei = *(buffer + offset++); + break; + + case IEI_ALWAYSON_PDU: /* Ommited */ + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Always-on PDU Session indication IE\n"); + offset++; + psea_iei = *(buffer + offset++); + break; + + case IEI_MAPPED_EPS: /* Ommited */ + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Mapped EPS bearer context IE\n"); + uint16_t mapped_eps_length = htons(*(uint16_t *)(buffer + offset)); + offset += mapped_eps_length; + psea_iei = *(buffer + offset++); + break; + + case IEI_EAP_MSG: /* Ommited */ + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received EAP message IE\n"); + uint16_t eap_length = htons(*(uint16_t *)(buffer + offset)); + offset += (eap_length + sizeof(eap_length)); + psea_iei = *(buffer + offset++); + break; + + case IEI_AUTH_QOS_DESC: /* Ommited */ + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Authorized QoS flow descriptions IE\n"); + psea_msg.qos_fd_ie.length = htons(*(uint16_t *)(buffer + offset)); + offset += (psea_msg.qos_fd_ie.length + sizeof(psea_msg.qos_fd_ie.length)); + psea_iei = *(buffer + offset++); + break; + + case IEI_EXT_CONF_OPT: /* Ommited */ + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Extended protocol configuration options IE\n"); + psea_msg.ext_pp_ie.length = htons(*(uint16_t *)(buffer + offset)); + offset += (psea_msg.ext_pp_ie.length + sizeof(psea_msg.ext_pp_ie.length )); + psea_iei = *(buffer + offset++); + break; + + case IEI_DNN: + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received DNN IE\n"); + psea_msg.dnn_ie.dnn_length = *(buffer + offset++); + uint8_t i=0; + char apn[20]; + + while (*(buffer + offset + i) != ASCII_ACK) { + apn[i] = *(buffer + offset + i); + ++i; + } + + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - APN: %s\n", apn); + offset += psea_msg.dnn_ie.dnn_length; + psea_iei = *(buffer + offset++); + break; + + default: + LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Not known IE\n"); + offset = msg_length; + break; + } + } + + set_qfi_pduid(qos_rule.qfi, psea_msg.pdu_id); + return; +} \ No newline at end of file diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h new file mode 100644 index 0000000000..ca92e54418 --- /dev/null +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h @@ -0,0 +1,162 @@ +/* + * 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 + +/* PDU Session Establish Accept Optional IE Identifiers - TS 24.501 Table 8.3.2.1.1 */ + +#define IEI_5GSM_CAUSE 0x59 /* 5GSM cause 9.11.4.2 */ +#define IEI_PDU_ADDRESS 0x29 /* PDU address 9.11.4.10 */ +#define IEI_RQ_TIMER_VALUE 0x56 /* GPRS timer 9.11.2.3 */ +#define IEI_SNSSAI 0x22 /* S-NSSAI 9.11.2.8 */ +#define IEI_ALWAYSON_PDU 0x80 /* Always-on PDU session indication 9.11.4.3 */ +#define IEI_MAPPED_EPS 0x75 /* Mapped EPS bearer contexts 9.11.4.8 */ +#define IEI_EAP_MSG 0x78 /* EAP message 9.11.2.2 */ +#define IEI_AUTH_QOS_DESC 0x79 /* QoS flow descriptions 9.11.4.12 */ +#define IEI_EXT_CONF_OPT 0x7b /* Extended protocol configuration options 9.11.4.6 */ +#define IEI_DNN 0x25 /* DNN 9.11.2.1B */ + +/* 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 + +/* 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 - ASCII Codes */ + +#define ASCII_ACK 0x06 /* Delimiter in the DNN IEI */ + +/* 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 { + 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_oct1; /* PDU address information (1st Octet)*/ + uint8_t pdu_addr_oct2; /* PDU address information (2nd Octet)*/ + uint8_t pdu_addr_oct3; /* PDU address information (3rd Octet)*/ + uint8_t pdu_addr_oct4; /* PDU address information (4th Octet)*/ +} 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 \ No newline at end of file diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 2b2d9b08a5..890af23d1f 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -38,6 +38,7 @@ #include "aka_functions.h" #include "secu_defs.h" #include "PduSessionEstablishRequest.h" +#include "PduSessionEstablishmentAccept.h" #include "intertask_interface.h" #include "openair2/RRC/NAS/nas_config.h" #include @@ -908,42 +909,8 @@ void *nas_nrue_task(void *args_p) LOG_I(NAS, "Send NAS_UPLINK_DATA_REQ message(PduSessionEstablishRequest)\n"); } } else if(msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC){ - uint8_t offset = 0; - uint8_t *payload_container = NULL; - offset += SECURITY_PROTECTED_5GS_NAS_MESSAGE_HEADER_LENGTH; - uint16_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; - } - offset = 0; - uint8_t pdu_id = *(pdu_buffer+14); - while(offset < payload_container_length) { - // Fixme: this is not good 'type' 0x29 searching in TLV like structure - // AND fix dirsty code copy hereafter of the same!!! - if (*(payload_container + offset) == 0x29) { // PDU address IEI - if ((*(payload_container+offset+1) == 0x05) && (*(payload_container +offset+2) == 0x01)) { // IPV4 - nas_getparams(); - sprintf(baseNetAddress, "%d.%d", *(payload_container+offset+3), *(payload_container+offset+4)); - int third_octet = *(payload_container+offset+5); - int fourth_octet = *(payload_container+offset+6); - LOG_I(NAS, "Received PDU Session Establishment Accept, UE IP: %d.%d.%d.%d\n", - *(payload_container+offset+3), *(payload_container+offset+4), - *(payload_container+offset+5), *(payload_container+offset+6)); - nas_config(1,third_octet,fourth_octet,"oaitun_ue"); - } - } - if (*(payload_container + offset) == 0x79) { - uint8_t qfi = *(payload_container+offset+3); - set_qfi_pduid(qfi, pdu_id); - break; - } - offset++; - } - } + capture_pdu_session_establishment_accept_msg(pdu_buffer, NAS_CONN_ESTABLI_CNF (msg_p).nasMsg.length); + } break; }