Commit 7b2e4a8c authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/nr-nas-issue-841' into integration_2024_w43 (!2980)

Refactor NAS 5GS PDU Session Establishment Accept handling

- Closes #841
- address minor code issues
parents 5b733192 c3f1824f
...@@ -124,18 +124,28 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ ...@@ -124,18 +124,28 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_
case IEI_PDU_ADDRESS: case IEI_PDU_ADDRESS:
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received PDU Address IE\n"); 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_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; uint8_t *addr = psea_msg.pdu_addr_ie.pdu_addr_oct;
if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV4) { 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++; addr[i] = *curPtr++;
char ip[20]; char ip[20];
capture_ipv4_addr(&addr[0], ip, sizeof(ip)); capture_ipv4_addr(&addr[0], ip, sizeof(ip));
tun_config(1, ip, NULL, "oaitun_ue"); tun_config(1, ip, NULL, "oaitun_ue");
setup_ue_ipv4_route(1, ip, "oaitun_ue"); setup_ue_ipv4_route(1, ip, "oaitun_ue");
} else if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV6) { } 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++; addr[i] = *curPtr++;
char ipv6[40]; char ipv6[40];
capture_ipv6_addr(addr, ipv6, sizeof(ipv6)); capture_ipv6_addr(addr, ipv6, sizeof(ipv6));
...@@ -145,12 +155,12 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ ...@@ -145,12 +155,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 // IPv4v6, the PDU address information in octet 4 to octet 11
// contains an interface identifier for the IPv6 link local address // contains an interface identifier for the IPv6 link local address
// and in octet 12 to octet 15 contains an IPv4 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++; addr[i] = *curPtr++;
char ipv6[40]; char ipv6[40];
capture_ipv6_addr(addr, ipv6, sizeof(ipv6)); capture_ipv6_addr(addr, ipv6, sizeof(ipv6));
char ipv4[20]; 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"); tun_config(1, ipv4, ipv6, "oaitun_ue");
setup_ue_ipv4_route(1, ipv4, "oaitun_ue"); setup_ue_ipv4_route(1, ipv4, "oaitun_ue");
} else { } else {
...@@ -164,42 +174,47 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ ...@@ -164,42 +174,47 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_
curPtr++; /* TS 24.008 10.5.7.3 */ curPtr++; /* TS 24.008 10.5.7.3 */
break; break;
case IEI_SNSSAI: /* Ommited */ case IEI_SNSSAI: {
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received S-NSSAI IE\n"); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received S-NSSAI IE\n");
uint8_t snssai_length = *curPtr; uint8_t snssai_length = *curPtr;
curPtr += (snssai_length + sizeof(snssai_length)); curPtr += (snssai_length + sizeof(snssai_length));
break; break;
}
case IEI_ALWAYSON_PDU: /* Ommited */ case IEI_ALWAYSON_PDU: /* Ommited */
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Always-on PDU Session indication IE\n"); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Always-on PDU Session indication IE\n");
curPtr++; curPtr++;
break; break;
case IEI_MAPPED_EPS: /* Ommited */ case IEI_MAPPED_EPS: {
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Mapped EPS bearer context IE\n"); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Mapped EPS bearer context IE\n");
uint16_t mapped_eps_length = getShort(curPtr); uint16_t mapped_eps_length = getShort(curPtr);
curPtr += mapped_eps_length; curPtr += mapped_eps_length;
break; break;
}
case IEI_EAP_MSG: /* Ommited */ case IEI_EAP_MSG: {
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received EAP message IE\n"); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received EAP message IE\n");
uint16_t eap_length = getShort(curPtr); uint16_t eap_length = getShort(curPtr);
curPtr += (eap_length + sizeof(eap_length)); curPtr += (eap_length + sizeof(eap_length));
break; 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"); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Authorized QoS flow descriptions IE\n");
psea_msg.qos_fd_ie.length = getShort(curPtr); psea_msg.qos_fd_ie.length = getShort(curPtr);
curPtr += (psea_msg.qos_fd_ie.length + sizeof(psea_msg.qos_fd_ie.length)); curPtr += (psea_msg.qos_fd_ie.length + sizeof(psea_msg.qos_fd_ie.length));
break; 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"); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received Extended protocol configuration options IE\n");
psea_msg.ext_pp_ie.length = getShort(curPtr); psea_msg.ext_pp_ie.length = getShort(curPtr);
curPtr += (psea_msg.ext_pp_ie.length + sizeof(psea_msg.ext_pp_ie.length)); curPtr += (psea_msg.ext_pp_ie.length + sizeof(psea_msg.ext_pp_ie.length));
break; break;
}
case IEI_DNN: case IEI_DNN: {
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received DNN IE\n"); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received DNN IE\n");
psea_msg.dnn_ie.dnn_length = *curPtr++; psea_msg.dnn_ie.dnn_length = *curPtr++;
char apn[APN_MAX_LEN]; char apn[APN_MAX_LEN];
...@@ -213,6 +228,7 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ ...@@ -213,6 +228,7 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_
curPtr = buffer + msg_length; // we force stop processing curPtr = buffer + msg_length; // we force stop processing
break; break;
}
default: default:
LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Not known IE\n"); LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Not known IE\n");
......
...@@ -42,6 +42,9 @@ ...@@ -42,6 +42,9 @@
#define PDU_SESSION_TYPE_IPV4 0b001 #define PDU_SESSION_TYPE_IPV4 0b001
#define PDU_SESSION_TYPE_IPV6 0b010 #define PDU_SESSION_TYPE_IPV6 0b010
#define PDU_SESSION_TYPE_IPV4V6 0b011 #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 */ /* Rule operation codes - TS 24.501 Table 9.11.4.13.1 */
...@@ -114,7 +117,8 @@ typedef struct pdu_address_s { ...@@ -114,7 +117,8 @@ typedef struct pdu_address_s {
uint8_t pdu_iei; /* PDU Address IEI (0x29) */ uint8_t pdu_iei; /* PDU Address IEI (0x29) */
uint8_t pdu_length; /* Length of PDU address contents */ uint8_t pdu_length; /* Length of PDU address contents */
uint8_t pdu_type; /* PDU session type value */ 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 */ } pdu_address_t; /* TS 24.501 9.11.4.10 */
typedef struct dnn_s { typedef struct dnn_s {
......
...@@ -848,16 +848,15 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, ...@@ -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); uint8_t msg_type = *(pdu_buffer + 16);
if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) { if (msg_type == FGS_PDU_SESSION_ESTABLISHMENT_ACC) {
uint8_t *ip_p = pdu_buffer + 39; LOG_A(NAS, "Received PDU Session Establishment Accept in DL NAS Transport\n");
char ip[20]; capture_pdu_session_establishment_accept_msg(pdu_buffer, msg_length);
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");
} else { } else {
LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type); LOG_E(NAS, "Received unexpected message in DLinformationTransfer %d\n", msg_type);
} }
...@@ -1415,7 +1414,7 @@ void *nas_nrue(void *args_p) ...@@ -1415,7 +1414,7 @@ void *nas_nrue(void *args_p)
handle_security_mode_command(nas, &initialNasMsg, pdu_buffer, pdu_length); handle_security_mode_command(nas, &initialNasMsg, pdu_buffer, pdu_length);
break; break;
case FGS_DOWNLINK_NAS_TRANSPORT: case FGS_DOWNLINK_NAS_TRANSPORT:
decodeDownlinkNASTransport(&initialNasMsg, pdu_buffer); handleDownlinkNASTransport(pdu_buffer, pdu_length);
break; break;
case REGISTRATION_ACCEPT: case REGISTRATION_ACCEPT:
handle_registration_accept(nas, pdu_buffer, pdu_length); handle_registration_accept(nas, pdu_buffer, pdu_length);
...@@ -1423,32 +1422,9 @@ void *nas_nrue(void *args_p) ...@@ -1423,32 +1422,9 @@ void *nas_nrue(void *args_p)
case FGS_DEREGISTRATION_ACCEPT_UE_ORIGINATING: case FGS_DEREGISTRATION_ACCEPT_UE_ORIGINATING:
LOG_I(NAS, "received deregistration accept\n"); LOG_I(NAS, "received deregistration accept\n");
break; break;
case FGS_PDU_SESSION_ESTABLISHMENT_ACC: { case FGS_PDU_SESSION_ESTABLISHMENT_ACC:
uint8_t offset = 0; capture_pdu_session_establishment_accept_msg(pdu_buffer, pdu_length);
uint8_t *payload_container = pdu_buffer; break;
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_REJ: case FGS_PDU_SESSION_ESTABLISHMENT_REJ:
LOG_E(NAS, "Received PDU Session Establishment reject\n"); LOG_E(NAS, "Received PDU Session Establishment reject\n");
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment