diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index e8050f2e5d..a98853af28 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -310,7 +310,6 @@ static int decodePDUSessionResourceSetup(pdusession_t *session) /* mandatory PDUSessionType */ case NGAP_ProtocolIE_ID_id_PDUSessionType: session->pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType; - AssertFatal(session->pdu_session_type == PDUSessionType_ipv4 || session->pdu_session_type == PDUSessionType_ipv4v6, "To be developped: support not IPv4 sessions\n"); break; /* optional SecurityIndication */ diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c index 4a307039c9..decb80d7e3 100644 --- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.c @@ -32,6 +32,29 @@ static uint16_t getShort(uint8_t *input) 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]); +} + void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_length) { security_protected_nas_5gs_msg_t sec_nas_hdr; @@ -103,25 +126,35 @@ void capture_pdu_session_establishment_accept_msg(uint8_t *buffer, uint32_t msg_ psea_msg.pdu_addr_ie.pdu_length = *curPtr++; psea_msg.pdu_addr_ie.pdu_type = *curPtr++; - DevAssert(psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV4); + uint8_t *addr = psea_msg.pdu_addr_ie.pdu_addr_oct; if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV4) { - pdu_address_t *addr = &psea_msg.pdu_addr_ie; - addr->pdu_addr_oct1 = *curPtr++; - addr->pdu_addr_oct2 = *curPtr++; - addr->pdu_addr_oct3 = *curPtr++; - addr->pdu_addr_oct4 = *curPtr++; + for (int i = 0; i < 4; ++i) + addr[i] = *curPtr++; char ip[20]; - snprintf(ip, - sizeof(ip), - "%d.%d.%d.%d", - addr->pdu_addr_oct1, - addr->pdu_addr_oct2, - addr->pdu_addr_oct3, - addr->pdu_addr_oct4); + capture_ipv4_addr(&addr[0], ip, sizeof(ip)); nas_config(1, ip, NULL, "oaitun_ue"); setup_ue_ipv4_route(1, ip, "oaitun_ue"); - LOG_T(NAS, "PDU SESSION ESTABLISHMENT ACCEPT - Received UE IP: %s\n", ip); + } else if (psea_msg.pdu_addr_ie.pdu_type == PDU_SESSION_TYPE_IPV6) { + for (int i = 0; i < 8; ++i) + addr[i] = *curPtr++; + char ipv6[40]; + capture_ipv6_addr(addr, ipv6, sizeof(ipv6)); + nas_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 < 12; ++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)); + nas_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; diff --git a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h index 95ca942339..a254debfbe 100644 --- a/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h +++ b/openair3/NAS/COMMON/ESM/MSG/PduSessionEstablishmentAccept.h @@ -114,10 +114,7 @@ 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)*/ + uint8_t pdu_addr_oct[12]; /* PDU address information (depending on type, up to 12 bytes)*/ } pdu_address_t; /* TS 24.501 9.11.4.10 */ typedef struct dnn_s { diff --git a/openair3/NAS/NR_UE/nr_nas_msg_sim.c b/openair3/NAS/NR_UE/nr_nas_msg_sim.c index 53575244fd..5b8edeab7e 100644 --- a/openair3/NAS/NR_UE/nr_nas_msg_sim.c +++ b/openair3/NAS/NR_UE/nr_nas_msg_sim.c @@ -1176,7 +1176,7 @@ static void request_default_pdusession(int instance, int nssai_idx) { MessageDef *message_p = itti_alloc_new_message(TASK_NAS_NRUE, 0, NAS_PDU_SESSION_REQ); NAS_PDU_SESSION_REQ(message_p).pdusession_id = 10; /* first or default pdu session */ - NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91; + NAS_PDU_SESSION_REQ(message_p).pdusession_type = 0x91; // 0x91 = IPv4, 0x92 = IPv6, 0x93 = IPv4v6 NAS_PDU_SESSION_REQ(message_p).sst = nas_allowed_nssai[nssai_idx].sst; NAS_PDU_SESSION_REQ(message_p).sd = nas_allowed_nssai[nssai_idx].sd; itti_send_msg_to_task(TASK_NAS_NRUE, instance, message_p);