mirror of
https://github.com/open5gs/open5gs.git
synced 2025-10-23 07:41:57 +00:00
[AMF/MME] Add size validation for NGAP/S1AP IE fields to prevent crashes (#4087)
- Added explicit size checks for critical IE fields (PLMNIdentity, TAC, GTP-TEID, Cell-ID, UE security capability algorithms, etc.) before memcpy() operations. - When size mismatch is detected, log an error and return an Error Indication (or Setup Failure) with appropriate protocol cause (semantic_error or message_not_compatible_with_receiver_state). - Introduced s1ap_send_error_indication1(enb_ue_t *enb_ue, ...) as a helper for cases where ENB UE context is available directly. s1ap_send_error_indication2(mme_ue_t *mme_ue, ...) now delegates to the new function, reducing code duplication. - Replaced ogs_assert() checks with graceful error handling paths to avoid abnormal process termination. This improves robustness against malformed or non-compliant NGAP/S1AP messages and prevents potential AMF/MME crashes.
This commit is contained in:
@@ -2944,6 +2944,56 @@ void ngap_handle_path_switch_request(
|
|||||||
eUTRAintegrityProtectionAlgorithms =
|
eUTRAintegrityProtectionAlgorithms =
|
||||||
&UESecurityCapabilities->eUTRAintegrityProtectionAlgorithms;
|
&UESecurityCapabilities->eUTRAintegrityProtectionAlgorithms;
|
||||||
|
|
||||||
|
if (nRencryptionAlgorithms->size != sizeof(nr_ea)) {
|
||||||
|
ogs_error("Invalid nRencryptionAlgorithms->size = %d (expected %d)",
|
||||||
|
(int)nRencryptionAlgorithms->size,
|
||||||
|
(int)sizeof(nr_ea));
|
||||||
|
r = ngap_send_error_indication(
|
||||||
|
gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id,
|
||||||
|
NGAP_Cause_PR_protocol,
|
||||||
|
NGAP_CauseProtocol_message_not_compatible_with_receiver_state);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (nRintegrityProtectionAlgorithms->size != sizeof(nr_ia)) {
|
||||||
|
ogs_error("Invalid nRintegrityProtectionAlgorithms->size = %d "
|
||||||
|
"(expected %d)",
|
||||||
|
(int)nRintegrityProtectionAlgorithms->size,
|
||||||
|
(int)sizeof(nr_ia));
|
||||||
|
r = ngap_send_error_indication(
|
||||||
|
gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id,
|
||||||
|
NGAP_Cause_PR_protocol,
|
||||||
|
NGAP_CauseProtocol_message_not_compatible_with_receiver_state);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (eUTRAencryptionAlgorithms->size != sizeof(eutra_ea)) {
|
||||||
|
ogs_error("Invalid eUTRAencryptionAlgorithms->size = %d (expected %d)",
|
||||||
|
(int)eUTRAencryptionAlgorithms->size,
|
||||||
|
(int)sizeof(eutra_ea));
|
||||||
|
r = ngap_send_error_indication(
|
||||||
|
gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id,
|
||||||
|
NGAP_Cause_PR_protocol,
|
||||||
|
NGAP_CauseProtocol_message_not_compatible_with_receiver_state);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (eUTRAintegrityProtectionAlgorithms->size != sizeof(eutra_ia)) {
|
||||||
|
ogs_error("Invalid eUTRAintegrityProtectionAlgorithms->size = %d "
|
||||||
|
"(expected %d)",
|
||||||
|
(int)eUTRAintegrityProtectionAlgorithms->size,
|
||||||
|
(int)sizeof(eutra_ia));
|
||||||
|
r = ngap_send_error_indication(
|
||||||
|
gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id,
|
||||||
|
NGAP_Cause_PR_protocol,
|
||||||
|
NGAP_CauseProtocol_message_not_compatible_with_receiver_state);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&nr_ea, nRencryptionAlgorithms->buf, sizeof(nr_ea));
|
memcpy(&nr_ea, nRencryptionAlgorithms->buf, sizeof(nr_ea));
|
||||||
nr_ea = be16toh(nr_ea);
|
nr_ea = be16toh(nr_ea);
|
||||||
nr_ea0 = amf_ue->ue_security_capability.nr_ea0;
|
nr_ea0 = amf_ue->ue_security_capability.nr_ea0;
|
||||||
@@ -4412,6 +4462,19 @@ void ngap_handle_ran_configuration_update(
|
|||||||
&BroadcastPLMNItem->pLMNIdentity;
|
&BroadcastPLMNItem->pLMNIdentity;
|
||||||
ogs_assert(pLMNIdentity);
|
ogs_assert(pLMNIdentity);
|
||||||
|
|
||||||
|
if (pLMNIdentity->size != sizeof(ogs_plmn_id_t)) {
|
||||||
|
ogs_error("Invalid PLMNIdentity size = %d (expected %d)",
|
||||||
|
(int)pLMNIdentity->size,
|
||||||
|
(int)sizeof(ogs_plmn_id_t));
|
||||||
|
group = NGAP_Cause_PR_protocol;
|
||||||
|
cause = NGAP_CauseProtocol_semantic_error;
|
||||||
|
r = ngap_send_ran_configuration_update_failure(
|
||||||
|
gnb, group, cause);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&gnb->supported_ta_list[i].bplmn_list[j].plmn_id,
|
memcpy(&gnb->supported_ta_list[i].bplmn_list[j].plmn_id,
|
||||||
pLMNIdentity->buf, sizeof(ogs_plmn_id_t));
|
pLMNIdentity->buf, sizeof(ogs_plmn_id_t));
|
||||||
ogs_debug(" PLMN_ID[MCC:%d MNC:%d]",
|
ogs_debug(" PLMN_ID[MCC:%d MNC:%d]",
|
||||||
|
@@ -139,6 +139,19 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Global_ENB_ID->pLMNidentity.size != sizeof(enb->plmn_id)) {
|
||||||
|
ogs_error("Invalid PLMNIdentity size = %d (expected %d)",
|
||||||
|
(int)Global_ENB_ID->pLMNidentity.size,
|
||||||
|
(int)sizeof(enb->plmn_id));
|
||||||
|
group = S1AP_Cause_PR_misc;
|
||||||
|
cause = S1AP_CauseProtocol_semantic_error;
|
||||||
|
|
||||||
|
r = s1ap_send_s1_setup_failure(enb, group, cause);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SupportedTAs) {
|
if (!SupportedTAs) {
|
||||||
ogs_error("No SupportedTAs");
|
ogs_error("No SupportedTAs");
|
||||||
group = S1AP_Cause_PR_misc;
|
group = S1AP_Cause_PR_misc;
|
||||||
@@ -193,6 +206,30 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tAC->size != sizeof(uint16_t)) {
|
||||||
|
ogs_error("Invalid tAC size = %d (expected %d)",
|
||||||
|
(int)tAC->size, (int)sizeof(uint16_t));
|
||||||
|
group = S1AP_Cause_PR_misc;
|
||||||
|
cause = S1AP_CauseProtocol_semantic_error;
|
||||||
|
|
||||||
|
r = s1ap_send_s1_setup_failure(enb, group, cause);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLMNidentity->size != sizeof(ogs_plmn_id_t)) {
|
||||||
|
ogs_error("Invalid pLMNidentity size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size, (int)sizeof(ogs_plmn_id_t));
|
||||||
|
group = S1AP_Cause_PR_misc;
|
||||||
|
cause = S1AP_CauseProtocol_semantic_error;
|
||||||
|
|
||||||
|
r = s1ap_send_s1_setup_failure(enb, group, cause);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&enb->supported_ta_list[enb->num_of_supported_ta_list].tac,
|
memcpy(&enb->supported_ta_list[enb->num_of_supported_ta_list].tac,
|
||||||
tAC->buf, sizeof(uint16_t));
|
tAC->buf, sizeof(uint16_t));
|
||||||
enb->supported_ta_list[enb->num_of_supported_ta_list].tac =
|
enb->supported_ta_list[enb->num_of_supported_ta_list].tac =
|
||||||
@@ -335,6 +372,31 @@ void s1ap_handle_enb_configuration_update(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tAC->size != sizeof(uint16_t)) {
|
||||||
|
ogs_error("Invalid tAC size = %d (expected %d)",
|
||||||
|
(int)tAC->size, (int)sizeof(uint16_t));
|
||||||
|
group = S1AP_Cause_PR_misc;
|
||||||
|
cause = S1AP_CauseProtocol_semantic_error;
|
||||||
|
|
||||||
|
r = s1ap_send_s1_setup_failure(enb, group, cause);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLMNidentity->size != sizeof(ogs_plmn_id_t)) {
|
||||||
|
ogs_error("Invalid pLMNidentity size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(ogs_plmn_id_t));
|
||||||
|
group = S1AP_Cause_PR_misc;
|
||||||
|
cause = S1AP_CauseProtocol_semantic_error;
|
||||||
|
|
||||||
|
r = s1ap_send_s1_setup_failure(enb, group, cause);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&enb->supported_ta_list[
|
memcpy(&enb->supported_ta_list[
|
||||||
enb->num_of_supported_ta_list].tac,
|
enb->num_of_supported_ta_list].tac,
|
||||||
tAC->buf, sizeof(uint16_t));
|
tAC->buf, sizeof(uint16_t));
|
||||||
@@ -500,8 +562,30 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
|||||||
nas_guti.mme_gid = served_gummei->mme_gid[0];
|
nas_guti.mme_gid = served_gummei->mme_gid[0];
|
||||||
|
|
||||||
/* size must be 1 */
|
/* size must be 1 */
|
||||||
|
if (S_TMSI->mMEC.size != 1) {
|
||||||
|
ogs_error("Invalid S_TMSI->mMEC.size = %d (expected 1)",
|
||||||
|
(int)S_TMSI->mMEC.size);
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&nas_guti.mme_code, S_TMSI->mMEC.buf, S_TMSI->mMEC.size);
|
memcpy(&nas_guti.mme_code, S_TMSI->mMEC.buf, S_TMSI->mMEC.size);
|
||||||
/* size must be 4 */
|
/* size must be 4 */
|
||||||
|
if (S_TMSI->m_TMSI.size != 4) {
|
||||||
|
ogs_error("Invalid S_TMSI->m_TMSI.size = %d (expected 4)",
|
||||||
|
(int)S_TMSI->m_TMSI.size);
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&nas_guti.m_tmsi, S_TMSI->m_TMSI.buf, S_TMSI->m_TMSI.size);
|
memcpy(&nas_guti.m_tmsi, S_TMSI->m_TMSI.buf, S_TMSI->m_TMSI.size);
|
||||||
nas_guti.m_tmsi = be32toh(nas_guti.m_tmsi);
|
nas_guti.m_tmsi = be32toh(nas_guti.m_tmsi);
|
||||||
|
|
||||||
@@ -586,18 +670,61 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pLMNidentity = &TAI->pLMNidentity;
|
pLMNidentity = &TAI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(enb_ue->saved.tai.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(enb_ue->saved.tai.plmn_id));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tAC = &TAI->tAC;
|
tAC = &TAI->tAC;
|
||||||
ogs_assert(tAC && tAC->size == sizeof(uint16_t));
|
if (tAC->size != sizeof(enb_ue->saved.tai.tac)) {
|
||||||
|
ogs_error("Invalid tAC->size = %d (expected %d)",
|
||||||
|
(int)tAC->size, (int)sizeof(enb_ue->saved.tai.tac));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&enb_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
memcpy(&enb_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
||||||
sizeof(enb_ue->saved.tai.plmn_id));
|
sizeof(enb_ue->saved.tai.plmn_id));
|
||||||
memcpy(&enb_ue->saved.tai.tac, tAC->buf, sizeof(enb_ue->saved.tai.tac));
|
memcpy(&enb_ue->saved.tai.tac, tAC->buf, sizeof(enb_ue->saved.tai.tac));
|
||||||
enb_ue->saved.tai.tac = be16toh(enb_ue->saved.tai.tac);
|
enb_ue->saved.tai.tac = be16toh(enb_ue->saved.tai.tac);
|
||||||
|
|
||||||
pLMNidentity = &EUTRAN_CGI->pLMNidentity;
|
pLMNidentity = &EUTRAN_CGI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(enb_ue->saved.e_cgi.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(enb_ue->saved.e_cgi.plmn_id));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
cell_ID = &EUTRAN_CGI->cell_ID;
|
cell_ID = &EUTRAN_CGI->cell_ID;
|
||||||
ogs_assert(cell_ID);
|
if (cell_ID->size != sizeof(enb_ue->saved.e_cgi.cell_id)) {
|
||||||
|
ogs_error("Invalid cell_ID->size = %d (expected %d)",
|
||||||
|
(int)cell_ID->size,
|
||||||
|
(int)sizeof(enb_ue->saved.e_cgi.cell_id));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&enb_ue->saved.e_cgi.plmn_id, pLMNidentity->buf,
|
memcpy(&enb_ue->saved.e_cgi.plmn_id, pLMNidentity->buf,
|
||||||
sizeof(enb_ue->saved.e_cgi.plmn_id));
|
sizeof(enb_ue->saved.e_cgi.plmn_id));
|
||||||
memcpy(&enb_ue->saved.e_cgi.cell_id, cell_ID->buf,
|
memcpy(&enb_ue->saved.e_cgi.cell_id, cell_ID->buf,
|
||||||
@@ -745,9 +872,26 @@ void s1ap_handle_uplink_nas_transport(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pLMNidentity = &TAI->pLMNidentity;
|
pLMNidentity = &TAI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(tai.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(tai.plmn_id));
|
||||||
|
r = s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tAC = &TAI->tAC;
|
tAC = &TAI->tAC;
|
||||||
ogs_assert(tAC && tAC->size == sizeof(uint16_t));
|
if (tAC->size != sizeof(tai.tac)) {
|
||||||
|
ogs_error("Invalid tAC->size = %d (expected %d)",
|
||||||
|
(int)tAC->size, (int)sizeof(tai.tac));
|
||||||
|
r = s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&tai.plmn_id, pLMNidentity->buf, sizeof(tai.plmn_id));
|
memcpy(&tai.plmn_id, pLMNidentity->buf, sizeof(tai.plmn_id));
|
||||||
memcpy(&tai.tac, tAC->buf, sizeof(tai.tac));
|
memcpy(&tai.tac, tAC->buf, sizeof(tai.tac));
|
||||||
tai.tac = be16toh(tai.tac);
|
tai.tac = be16toh(tai.tac);
|
||||||
@@ -767,9 +911,27 @@ void s1ap_handle_uplink_nas_transport(
|
|||||||
ogs_debug(" SERVED_TAI_INDEX[%d]", served_tai_index);
|
ogs_debug(" SERVED_TAI_INDEX[%d]", served_tai_index);
|
||||||
|
|
||||||
pLMNidentity = &EUTRAN_CGI->pLMNidentity;
|
pLMNidentity = &EUTRAN_CGI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(enb_ue->saved.e_cgi.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(enb_ue->saved.e_cgi.plmn_id));
|
||||||
|
r = s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
cell_ID = &EUTRAN_CGI->cell_ID;
|
cell_ID = &EUTRAN_CGI->cell_ID;
|
||||||
ogs_assert(cell_ID);
|
if (cell_ID->size != sizeof(enb_ue->saved.e_cgi.cell_id)) {
|
||||||
|
ogs_error("Invalid cell_ID->size = %d (expected %d)",
|
||||||
|
(int)cell_ID->size,
|
||||||
|
(int)sizeof(enb_ue->saved.e_cgi.cell_id));
|
||||||
|
r = s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&enb_ue->saved.e_cgi.plmn_id, pLMNidentity->buf,
|
memcpy(&enb_ue->saved.e_cgi.plmn_id, pLMNidentity->buf,
|
||||||
sizeof(enb_ue->saved.e_cgi.plmn_id));
|
sizeof(enb_ue->saved.e_cgi.plmn_id));
|
||||||
memcpy(&enb_ue->saved.e_cgi.cell_id, cell_ID->buf,
|
memcpy(&enb_ue->saved.e_cgi.cell_id, cell_ID->buf,
|
||||||
@@ -777,9 +939,26 @@ void s1ap_handle_uplink_nas_transport(
|
|||||||
enb_ue->saved.e_cgi.cell_id = (be32toh(enb_ue->saved.e_cgi.cell_id) >> 4);
|
enb_ue->saved.e_cgi.cell_id = (be32toh(enb_ue->saved.e_cgi.cell_id) >> 4);
|
||||||
|
|
||||||
pLMNidentity = &TAI->pLMNidentity;
|
pLMNidentity = &TAI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(enb_ue->saved.tai.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(enb_ue->saved.tai.plmn_id));
|
||||||
|
r = s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tAC = &TAI->tAC;
|
tAC = &TAI->tAC;
|
||||||
ogs_assert(tAC && tAC->size == sizeof(uint16_t));
|
if (tAC->size != sizeof(enb_ue->saved.tai.tac)) {
|
||||||
|
ogs_error("Invalid tAC->size = %d (expected %d)",
|
||||||
|
(int)tAC->size, (int)sizeof(enb_ue->saved.tai.tac));
|
||||||
|
r = s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&enb_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
memcpy(&enb_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
||||||
sizeof(enb_ue->saved.tai.plmn_id));
|
sizeof(enb_ue->saved.tai.plmn_id));
|
||||||
memcpy(&enb_ue->saved.tai.tac, tAC->buf, sizeof(enb_ue->saved.tai.tac));
|
memcpy(&enb_ue->saved.tai.tac, tAC->buf, sizeof(enb_ue->saved.tai.tac));
|
||||||
@@ -1042,6 +1221,17 @@ void s1ap_handle_initial_context_setup_response(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e_rab->gTP_TEID.size != sizeof(bearer->enb_s1u_teid)) {
|
||||||
|
ogs_error("Invalid e_rab->gTP_TEID.size = %d (expected %d)",
|
||||||
|
(int)e_rab->gTP_TEID.size,
|
||||||
|
(int)sizeof(bearer->enb_s1u_teid));
|
||||||
|
r = s1ap_send_error_indication2(mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
||||||
sizeof(bearer->enb_s1u_teid));
|
sizeof(bearer->enb_s1u_teid));
|
||||||
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
||||||
@@ -1576,8 +1766,19 @@ void s1ap_handle_e_rab_setup_response(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e_rab->gTP_TEID.size != sizeof(bearer->enb_s1u_teid)) {
|
||||||
|
ogs_error("Invalid e_rab->gTP_TEID.size = %d (expected %d)",
|
||||||
|
(int)e_rab->gTP_TEID.size,
|
||||||
|
(int)sizeof(bearer->enb_s1u_teid));
|
||||||
|
r = s1ap_send_error_indication2(mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
||||||
sizeof(bearer->enb_s1u_teid));
|
sizeof(bearer->enb_s1u_teid));
|
||||||
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
||||||
rv = ogs_asn_BIT_STRING_to_ip(
|
rv = ogs_asn_BIT_STRING_to_ip(
|
||||||
&e_rab->transportLayerAddress, &bearer->enb_s1u_ip);
|
&e_rab->transportLayerAddress, &bearer->enb_s1u_ip);
|
||||||
@@ -2222,6 +2423,17 @@ void s1ap_handle_e_rab_modification_indication(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e_rab->dL_GTP_TEID.size != sizeof(bearer->enb_s1u_teid)) {
|
||||||
|
ogs_error("Invalid e_rab->dL_GTP_TEID.size = %d (expected %d)",
|
||||||
|
(int)e_rab->dL_GTP_TEID.size,
|
||||||
|
(int)sizeof(bearer->enb_s1u_teid));
|
||||||
|
r = s1ap_send_error_indication2(mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&bearer->enb_s1u_teid, e_rab->dL_GTP_TEID.buf,
|
memcpy(&bearer->enb_s1u_teid, e_rab->dL_GTP_TEID.buf,
|
||||||
sizeof(bearer->enb_s1u_teid));
|
sizeof(bearer->enb_s1u_teid));
|
||||||
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
||||||
@@ -2317,7 +2529,47 @@ void s1ap_handle_enb_direct_information_transfer(
|
|||||||
switch (RIMRoutingAddress->present) {
|
switch (RIMRoutingAddress->present) {
|
||||||
case S1AP_RIMRoutingAddress_PR_gERAN_Cell_ID:
|
case S1AP_RIMRoutingAddress_PR_gERAN_Cell_ID:
|
||||||
geran_cell_id = RIMRoutingAddress->choice.gERAN_Cell_ID;
|
geran_cell_id = RIMRoutingAddress->choice.gERAN_Cell_ID;
|
||||||
ogs_assert(geran_cell_id);
|
if (!geran_cell_id) {
|
||||||
|
ogs_error("No gERAN_Cell_ID");
|
||||||
|
r = s1ap_send_error_indication(enb, NULL, NULL,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (geran_cell_id->lAI.pLMNidentity.size != sizeof(plmn_id)) {
|
||||||
|
ogs_error("Invalid geran_cell_id->lAI.pLMNidentity.size = %d "
|
||||||
|
"(expected %d)",
|
||||||
|
(int)geran_cell_id->lAI.pLMNidentity.size,
|
||||||
|
(int)sizeof(plmn_id));
|
||||||
|
r = s1ap_send_error_indication(enb, NULL, NULL,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (geran_cell_id->lAI.lAC.size != sizeof(uint16_t)) {
|
||||||
|
ogs_error("Invalid geran_cell_id->lAI.lAC.size = %d "
|
||||||
|
"(expected %d)",
|
||||||
|
(int)geran_cell_id->lAI.lAC.size,
|
||||||
|
(int)sizeof(uint16_t));
|
||||||
|
r = s1ap_send_error_indication(enb, NULL, NULL,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (geran_cell_id->cI.size != sizeof(uint16_t)) {
|
||||||
|
ogs_error("Invalid geran_cell_id->cI.size = %d "
|
||||||
|
"(expected %d)",
|
||||||
|
(int)geran_cell_id->cI.size,
|
||||||
|
(int)sizeof(uint16_t));
|
||||||
|
r = s1ap_send_error_indication(enb, NULL, NULL,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&plmn_id, geran_cell_id->lAI.pLMNidentity.buf, sizeof(plmn_id));
|
memcpy(&plmn_id, geran_cell_id->lAI.pLMNidentity.buf, sizeof(plmn_id));
|
||||||
ogs_nas_from_plmn_id(&rai.lai.nas_plmn_id, &plmn_id);
|
ogs_nas_from_plmn_id(&rai.lai.nas_plmn_id, &plmn_id);
|
||||||
memcpy(&rai.lai.lac, geran_cell_id->lAI.lAC.buf, sizeof(uint16_t));
|
memcpy(&rai.lai.lac, geran_cell_id->lAI.lAC.buf, sizeof(uint16_t));
|
||||||
@@ -2508,9 +2760,26 @@ void s1ap_handle_path_switch_request(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pLMNidentity = &TAI->pLMNidentity;
|
pLMNidentity = &TAI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(tai.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(tai.plmn_id));
|
||||||
|
r = s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tAC = &TAI->tAC;
|
tAC = &TAI->tAC;
|
||||||
ogs_assert(tAC && tAC->size == sizeof(uint16_t));
|
if (tAC->size != sizeof(tai.tac)) {
|
||||||
|
ogs_error("Invalid tAC->size = %d (expected %d)",
|
||||||
|
(int)tAC->size, (int)sizeof(tai.tac));
|
||||||
|
r = s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID,
|
||||||
|
S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&tai.plmn_id, pLMNidentity->buf, sizeof(tai.plmn_id));
|
memcpy(&tai.plmn_id, pLMNidentity->buf, sizeof(tai.plmn_id));
|
||||||
memcpy(&tai.tac, tAC->buf, sizeof(tai.tac));
|
memcpy(&tai.tac, tAC->buf, sizeof(tai.tac));
|
||||||
tai.tac = be16toh(tai.tac);
|
tai.tac = be16toh(tai.tac);
|
||||||
@@ -2577,18 +2846,61 @@ void s1ap_handle_path_switch_request(
|
|||||||
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id);
|
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id);
|
||||||
|
|
||||||
pLMNidentity = &TAI->pLMNidentity;
|
pLMNidentity = &TAI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(enb_ue->saved.tai.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(enb_ue->saved.tai.plmn_id));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tAC = &TAI->tAC;
|
tAC = &TAI->tAC;
|
||||||
ogs_assert(tAC && tAC->size == sizeof(uint16_t));
|
if (tAC->size != sizeof(enb_ue->saved.tai.tac)) {
|
||||||
|
ogs_error("Invalid tAC->size = %d (expected %d)",
|
||||||
|
(int)tAC->size, (int)sizeof(enb_ue->saved.tai.tac));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&enb_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
memcpy(&enb_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
||||||
sizeof(enb_ue->saved.tai.plmn_id));
|
sizeof(enb_ue->saved.tai.plmn_id));
|
||||||
memcpy(&enb_ue->saved.tai.tac, tAC->buf, sizeof(enb_ue->saved.tai.tac));
|
memcpy(&enb_ue->saved.tai.tac, tAC->buf, sizeof(enb_ue->saved.tai.tac));
|
||||||
enb_ue->saved.tai.tac = be16toh(enb_ue->saved.tai.tac);
|
enb_ue->saved.tai.tac = be16toh(enb_ue->saved.tai.tac);
|
||||||
|
|
||||||
pLMNidentity = &EUTRAN_CGI->pLMNidentity;
|
pLMNidentity = &EUTRAN_CGI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(enb_ue->saved.e_cgi.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(enb_ue->saved.e_cgi.plmn_id));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
cell_ID = &EUTRAN_CGI->cell_ID;
|
cell_ID = &EUTRAN_CGI->cell_ID;
|
||||||
ogs_assert(cell_ID);
|
if (cell_ID->size != sizeof(enb_ue->saved.e_cgi.cell_id)) {
|
||||||
|
ogs_error("Invalid cell_ID->size = %d (expected %d)",
|
||||||
|
(int)cell_ID->size,
|
||||||
|
(int)sizeof(enb_ue->saved.e_cgi.cell_id));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&enb_ue->saved.e_cgi.plmn_id, pLMNidentity->buf,
|
memcpy(&enb_ue->saved.e_cgi.plmn_id, pLMNidentity->buf,
|
||||||
sizeof(enb_ue->saved.e_cgi.plmn_id));
|
sizeof(enb_ue->saved.e_cgi.plmn_id));
|
||||||
memcpy(&enb_ue->saved.e_cgi.cell_id, cell_ID->buf,
|
memcpy(&enb_ue->saved.e_cgi.cell_id, cell_ID->buf,
|
||||||
@@ -2614,12 +2926,37 @@ void s1ap_handle_path_switch_request(
|
|||||||
integrityProtectionAlgorithms =
|
integrityProtectionAlgorithms =
|
||||||
&UESecurityCapabilities->integrityProtectionAlgorithms;
|
&UESecurityCapabilities->integrityProtectionAlgorithms;
|
||||||
|
|
||||||
|
if (encryptionAlgorithms->size != sizeof(eea)) {
|
||||||
|
ogs_error("Invalid encryptionAlgorithms->size = %d (expected %d)",
|
||||||
|
(int)encryptionAlgorithms->size,
|
||||||
|
(int)sizeof(eea));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&eea, encryptionAlgorithms->buf, sizeof(eea));
|
memcpy(&eea, encryptionAlgorithms->buf, sizeof(eea));
|
||||||
eea = be16toh(eea);
|
eea = be16toh(eea);
|
||||||
eea0 = mme_ue->ue_network_capability.eea0;
|
eea0 = mme_ue->ue_network_capability.eea0;
|
||||||
mme_ue->ue_network_capability.eea = eea >> 9;
|
mme_ue->ue_network_capability.eea = eea >> 9;
|
||||||
mme_ue->ue_network_capability.eea0 = eea0;
|
mme_ue->ue_network_capability.eea0 = eea0;
|
||||||
|
|
||||||
|
if (integrityProtectionAlgorithms->size != sizeof(eia)) {
|
||||||
|
ogs_error("Invalid integrityProtectionAlgorithms->size = %d "
|
||||||
|
"(expected %d)",
|
||||||
|
(int)integrityProtectionAlgorithms->size,
|
||||||
|
(int)sizeof(eia));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
enb_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&eia, integrityProtectionAlgorithms->buf, sizeof(eia));
|
memcpy(&eia, integrityProtectionAlgorithms->buf, sizeof(eia));
|
||||||
eia = be16toh(eia);
|
eia = be16toh(eia);
|
||||||
eia0 = mme_ue->ue_network_capability.eia0;
|
eia0 = mme_ue->ue_network_capability.eia0;
|
||||||
@@ -2670,6 +3007,17 @@ void s1ap_handle_path_switch_request(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e_rab->gTP_TEID.size != sizeof(bearer->enb_s1u_teid)) {
|
||||||
|
ogs_error("Invalid e_rab->gTP_TEID.size = %d (expected %d)",
|
||||||
|
(int)e_rab->gTP_TEID.size,
|
||||||
|
(int)sizeof(bearer->enb_s1u_teid));
|
||||||
|
r = s1ap_send_error_indication2(mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf,
|
||||||
sizeof(bearer->enb_s1u_teid));
|
sizeof(bearer->enb_s1u_teid));
|
||||||
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
bearer->enb_s1u_teid = be32toh(bearer->enb_s1u_teid);
|
||||||
@@ -2771,6 +3119,30 @@ void s1ap_handle_enb_configuration_transfer(
|
|||||||
ogs_s1ap_ENB_ID_to_uint32(
|
ogs_s1ap_ENB_ID_to_uint32(
|
||||||
&targeteNB_ID->global_ENB_ID.eNB_ID, &target_enb_id);
|
&targeteNB_ID->global_ENB_ID.eNB_ID, &target_enb_id);
|
||||||
|
|
||||||
|
if (sourceeNB_ID->selected_TAI.tAC.size != sizeof(source_tac)) {
|
||||||
|
ogs_error("Invalid sourceeNB_ID->selected_TAI.tAC.size = %d "
|
||||||
|
"(expected %d)",
|
||||||
|
(int)sourceeNB_ID->selected_TAI.tAC.size,
|
||||||
|
(int)sizeof(source_tac));
|
||||||
|
r = s1ap_send_error_indication(enb, NULL, NULL,
|
||||||
|
S1AP_Cause_PR_radioNetwork,
|
||||||
|
S1AP_CauseRadioNetwork_unknown_targetID);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (targeteNB_ID->selected_TAI.tAC.size != sizeof(target_tac)) {
|
||||||
|
ogs_error("Invalid targeteNB_ID->selected_TAI.tAC.size = %d "
|
||||||
|
"(expected %d)",
|
||||||
|
(int)targeteNB_ID->selected_TAI.tAC.size,
|
||||||
|
(int)sizeof(target_tac));
|
||||||
|
r = s1ap_send_error_indication(enb, NULL, NULL,
|
||||||
|
S1AP_Cause_PR_radioNetwork,
|
||||||
|
S1AP_CauseRadioNetwork_unknown_targetID);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&source_tac, sourceeNB_ID->selected_TAI.tAC.buf,
|
memcpy(&source_tac, sourceeNB_ID->selected_TAI.tAC.buf,
|
||||||
sizeof(source_tac));
|
sizeof(source_tac));
|
||||||
source_tac = be16toh(source_tac);
|
source_tac = be16toh(source_tac);
|
||||||
@@ -3208,6 +3580,17 @@ void s1ap_handle_handover_request_ack(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e_rab->gTP_TEID.size != sizeof(bearer->enb_s1u_teid)) {
|
||||||
|
ogs_error("Invalid e_rab->gTP_TEID.size = %d (expected %d)",
|
||||||
|
(int)e_rab->gTP_TEID.size,
|
||||||
|
(int)sizeof(bearer->enb_s1u_teid));
|
||||||
|
r = s1ap_send_error_indication2(mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&bearer->target_s1u_teid, e_rab->gTP_TEID.buf,
|
memcpy(&bearer->target_s1u_teid, e_rab->gTP_TEID.buf,
|
||||||
sizeof(bearer->target_s1u_teid));
|
sizeof(bearer->target_s1u_teid));
|
||||||
bearer->target_s1u_teid = be32toh(bearer->target_s1u_teid);
|
bearer->target_s1u_teid = be32toh(bearer->target_s1u_teid);
|
||||||
@@ -3225,8 +3608,17 @@ void s1ap_handle_handover_request_ack(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e_rab->dL_transportLayerAddress && e_rab->dL_gTP_TEID) {
|
if (e_rab->dL_transportLayerAddress && e_rab->dL_gTP_TEID) {
|
||||||
ogs_assert(e_rab->dL_gTP_TEID->buf);
|
if (e_rab->dL_gTP_TEID->size != sizeof(bearer->enb_dl_teid)) {
|
||||||
ogs_assert(e_rab->dL_transportLayerAddress->buf);
|
ogs_error("Invalid e_rab->dL_gTP_TEID.size = %d (expected %d)",
|
||||||
|
(int)e_rab->dL_gTP_TEID->size,
|
||||||
|
(int)sizeof(bearer->enb_dl_teid));
|
||||||
|
r = s1ap_send_error_indication2(mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&bearer->enb_dl_teid, e_rab->dL_gTP_TEID->buf,
|
memcpy(&bearer->enb_dl_teid, e_rab->dL_gTP_TEID->buf,
|
||||||
sizeof(bearer->enb_dl_teid));
|
sizeof(bearer->enb_dl_teid));
|
||||||
bearer->enb_dl_teid = be32toh(bearer->enb_dl_teid);
|
bearer->enb_dl_teid = be32toh(bearer->enb_dl_teid);
|
||||||
@@ -3245,8 +3637,17 @@ void s1ap_handle_handover_request_ack(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (e_rab->uL_TransportLayerAddress && e_rab->uL_GTP_TEID) {
|
if (e_rab->uL_TransportLayerAddress && e_rab->uL_GTP_TEID) {
|
||||||
ogs_assert(e_rab->uL_GTP_TEID->buf);
|
if (e_rab->uL_GTP_TEID->size != sizeof(bearer->enb_ul_teid)) {
|
||||||
ogs_assert(e_rab->uL_TransportLayerAddress->buf);
|
ogs_error("Invalid e_rab->uL_GTP_TEID.size = %d (expected %d)",
|
||||||
|
(int)e_rab->uL_GTP_TEID->size,
|
||||||
|
(int)sizeof(bearer->enb_ul_teid));
|
||||||
|
r = s1ap_send_error_indication2(mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&bearer->enb_ul_teid, e_rab->uL_GTP_TEID->buf,
|
memcpy(&bearer->enb_ul_teid, e_rab->uL_GTP_TEID->buf,
|
||||||
sizeof(bearer->enb_ul_teid));
|
sizeof(bearer->enb_ul_teid));
|
||||||
bearer->enb_ul_teid = be32toh(bearer->enb_ul_teid);
|
bearer->enb_ul_teid = be32toh(bearer->enb_ul_teid);
|
||||||
@@ -3763,9 +4164,30 @@ void s1ap_handle_handover_notification(
|
|||||||
CLEAR_MME_UE_TIMER(mme_ue->t_mobile_reachable);
|
CLEAR_MME_UE_TIMER(mme_ue->t_mobile_reachable);
|
||||||
|
|
||||||
pLMNidentity = &TAI->pLMNidentity;
|
pLMNidentity = &TAI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(target_ue->saved.tai.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(target_ue->saved.tai.plmn_id));
|
||||||
|
r = s1ap_send_error_indication2(
|
||||||
|
mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tAC = &TAI->tAC;
|
tAC = &TAI->tAC;
|
||||||
ogs_assert(tAC && tAC->size == sizeof(uint16_t));
|
if (tAC->size != sizeof(target_ue->saved.tai.tac)) {
|
||||||
|
ogs_error("Invalid tAC->size = %d (expected %d)",
|
||||||
|
(int)tAC->size, (int)sizeof(target_ue->saved.tai.tac));
|
||||||
|
r = s1ap_send_error_indication2(
|
||||||
|
mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&target_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
memcpy(&target_ue->saved.tai.plmn_id, pLMNidentity->buf,
|
||||||
sizeof(target_ue->saved.tai.plmn_id));
|
sizeof(target_ue->saved.tai.plmn_id));
|
||||||
memcpy(&target_ue->saved.tai.tac,
|
memcpy(&target_ue->saved.tai.tac,
|
||||||
@@ -3773,9 +4195,31 @@ void s1ap_handle_handover_notification(
|
|||||||
target_ue->saved.tai.tac = be16toh(target_ue->saved.tai.tac);
|
target_ue->saved.tai.tac = be16toh(target_ue->saved.tai.tac);
|
||||||
|
|
||||||
pLMNidentity = &EUTRAN_CGI->pLMNidentity;
|
pLMNidentity = &EUTRAN_CGI->pLMNidentity;
|
||||||
ogs_assert(pLMNidentity && pLMNidentity->size == sizeof(ogs_plmn_id_t));
|
if (pLMNidentity->size != sizeof(target_ue->saved.e_cgi.plmn_id)) {
|
||||||
|
ogs_error("Invalid pLMNidentity->size = %d (expected %d)",
|
||||||
|
(int)pLMNidentity->size,
|
||||||
|
(int)sizeof(target_ue->saved.e_cgi.plmn_id));
|
||||||
|
r = s1ap_send_error_indication2(
|
||||||
|
mme_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
cell_ID = &EUTRAN_CGI->cell_ID;
|
cell_ID = &EUTRAN_CGI->cell_ID;
|
||||||
ogs_assert(cell_ID);
|
if (cell_ID->size != sizeof(target_ue->saved.e_cgi.cell_id)) {
|
||||||
|
ogs_error("Invalid cell_ID->size = %d (expected %d)",
|
||||||
|
(int)cell_ID->size,
|
||||||
|
(int)sizeof(target_ue->saved.e_cgi.cell_id));
|
||||||
|
r = s1ap_send_error_indication1(
|
||||||
|
target_ue,
|
||||||
|
S1AP_Cause_PR_protocol,
|
||||||
|
S1AP_CauseProtocol_semantic_error);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(&target_ue->saved.e_cgi.plmn_id, pLMNidentity->buf,
|
memcpy(&target_ue->saved.e_cgi.plmn_id, pLMNidentity->buf,
|
||||||
sizeof(target_ue->saved.e_cgi.plmn_id));
|
sizeof(target_ue->saved.e_cgi.plmn_id));
|
||||||
memcpy(&target_ue->saved.e_cgi.cell_id, cell_ID->buf,
|
memcpy(&target_ue->saved.e_cgi.cell_id, cell_ID->buf,
|
||||||
|
@@ -879,27 +879,16 @@ int s1ap_send_error_indication(
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int s1ap_send_error_indication2(
|
int s1ap_send_error_indication1(
|
||||||
mme_ue_t *mme_ue, S1AP_Cause_PR group, long cause)
|
enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
mme_enb_t *enb;
|
mme_enb_t *enb;
|
||||||
enb_ue_t *enb_ue;
|
|
||||||
|
|
||||||
S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id;
|
S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id;
|
||||||
S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id;
|
S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id;
|
||||||
|
|
||||||
if (!mme_ue) {
|
ogs_assert(enb_ue);
|
||||||
ogs_error("UE(mme-ue) context has already been removed");
|
|
||||||
return OGS_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id);
|
|
||||||
if (!enb_ue) {
|
|
||||||
ogs_error("S1 context has already been removed");
|
|
||||||
return OGS_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
enb = mme_enb_find_by_id(enb_ue->enb_id);
|
enb = mme_enb_find_by_id(enb_ue->enb_id);
|
||||||
if (!enb) {
|
if (!enb) {
|
||||||
ogs_error("eNB has already been removed");
|
ogs_error("eNB has already been removed");
|
||||||
@@ -916,6 +905,25 @@ int s1ap_send_error_indication2(
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int s1ap_send_error_indication2(
|
||||||
|
mme_ue_t *mme_ue, S1AP_Cause_PR group, long cause)
|
||||||
|
{
|
||||||
|
enb_ue_t *enb_ue;
|
||||||
|
|
||||||
|
if (!mme_ue) {
|
||||||
|
ogs_error("UE(mme-ue) context has already been removed");
|
||||||
|
return OGS_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
enb_ue = enb_ue_find_by_id(mme_ue->enb_ue_id);
|
||||||
|
if (!enb_ue) {
|
||||||
|
ogs_error("S1 context has already been removed");
|
||||||
|
return OGS_NOTFOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s1ap_send_error_indication1(enb_ue, group, cause);
|
||||||
|
}
|
||||||
|
|
||||||
int s1ap_send_s1_reset_ack(
|
int s1ap_send_s1_reset_ack(
|
||||||
mme_enb_t *enb,
|
mme_enb_t *enb,
|
||||||
S1AP_UE_associatedLogicalS1_ConnectionListRes_t *partOfS1_Interface)
|
S1AP_UE_associatedLogicalS1_ConnectionListRes_t *partOfS1_Interface)
|
||||||
|
@@ -97,6 +97,8 @@ int s1ap_send_error_indication(
|
|||||||
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
|
S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id,
|
||||||
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
|
S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id,
|
||||||
S1AP_Cause_PR group, long cause);
|
S1AP_Cause_PR group, long cause);
|
||||||
|
int s1ap_send_error_indication1(
|
||||||
|
enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause);
|
||||||
int s1ap_send_error_indication2(
|
int s1ap_send_error_indication2(
|
||||||
mme_ue_t *mme_ue, S1AP_Cause_PR group, long cause);
|
mme_ue_t *mme_ue, S1AP_Cause_PR group, long cause);
|
||||||
int s1ap_send_s1_reset_ack(
|
int s1ap_send_s1_reset_ack(
|
||||||
|
Reference in New Issue
Block a user