open5gs/tests/common/emm-build.c

909 lines
36 KiB
C

/*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of OpenEPS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "test-common.h"
ogs_pkbuf_t *testemm_build_attach_request(
test_ue_t *test_ue, ogs_pkbuf_t *esmbuf,
bool integrity_protected, bool ciphered)
{
int i;
uint16_t psimask = 0;
ogs_pkbuf_t *pkbuf = NULL;
ogs_nas_eps_message_t message;
ogs_nas_eps_attach_request_t *attach_request = &message.emm.attach_request;
ogs_nas_eps_attach_type_t *eps_attach_type =
&attach_request->eps_attach_type;
ogs_nas_eps_mobile_identity_t *eps_mobile_identity =
&attach_request->eps_mobile_identity;
ogs_nas_ue_network_capability_t *ue_network_capability =
&attach_request->ue_network_capability;
ogs_nas_esm_message_container_t *esm_message_container =
&attach_request->esm_message_container;
ogs_nas_tracking_area_identity_t *last_visited_registered_tai =
&attach_request->last_visited_registered_tai;
ogs_nas_drx_parameter_t *drx_parameter = &attach_request->drx_parameter;
ogs_nas_ms_network_capability_t *ms_network_capability =
&attach_request->ms_network_capability;
ogs_nas_location_area_identification_t *old_location_area_identification =
&attach_request->old_location_area_identification;
ogs_nas_tmsi_status_t *tmsi_status = &attach_request->tmsi_status;
ogs_nas_mobile_station_classmark_2_t *mobile_station_classmark_2 =
&attach_request->mobile_station_classmark_2;
ogs_nas_mobile_station_classmark_3_t *mobile_station_classmark_3 =
&attach_request->mobile_station_classmark_3;
ogs_nas_supported_codec_list_t *supported_codecs =
&attach_request->supported_codecs;
ogs_nas_additional_update_type_t *additional_update_type =
&attach_request->additional_update_type;
ogs_nas_voice_domain_preference_and_ue_usage_setting_t
*voice_domain_preference_and_ue_usage_setting =
&attach_request->voice_domain_preference_and_ue_usage_setting;
ogs_nas_guti_type_t *old_guti_type = &attach_request->old_guti_type;
ogs_nas_ms_network_feature_support_t *ms_network_feature_support =
&attach_request->ms_network_feature_support;
ogs_nas_network_resource_identifier_container_t *tmsi_based_nri_container =
&attach_request->tmsi_based_nri_container;
ogs_nas_ue_additional_security_capability_t
*ue_additional_security_capability =
&attach_request->ue_additional_security_capability;
uint8_t classmark_3[11] = "\x60\x14\x04\xef\x65\x23\x3b\x88\x78\xd2\x90";
ogs_assert(test_ue);
ogs_assert(esmbuf);
memset(&message, 0, sizeof(message));
if (integrity_protected) {
if (ciphered)
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
else
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
}
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_ATTACH_REQUEST;
esm_message_container->length = esmbuf->len;
esm_message_container->buffer = esmbuf->data;
memcpy(eps_attach_type, &test_ue->nas.data, sizeof(*eps_attach_type));
if (test_ue->attach_request_param.guti) {
eps_mobile_identity->length =
sizeof(ogs_nas_eps_mobile_identity_guti_t);
eps_mobile_identity->guti.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN;
eps_mobile_identity->guti.type = OGS_NAS_EPS_MOBILE_IDENTITY_GUTI;
eps_mobile_identity->guti.nas_plmn_id =
test_ue->nas_eps_guti.nas_plmn_id;
eps_mobile_identity->guti.mme_gid = test_ue->nas_eps_guti.mme_gid;
eps_mobile_identity->guti.mme_code = test_ue->nas_eps_guti.mme_code;
eps_mobile_identity->guti.m_tmsi = test_ue->nas_eps_guti.m_tmsi;
} else {
eps_mobile_identity->length =
sizeof(ogs_nas_mobile_identity_imsi_t);
memcpy(&eps_mobile_identity->imsi,
&test_ue->mobile_identity_imsi, eps_mobile_identity->length);
}
ue_network_capability->length = 7;
ue_network_capability->eea = 0xf0;
ue_network_capability->eia = 0xf0;
ue_network_capability->uea = 0xc0;
ue_network_capability->uia = 0x40;
ue_network_capability->notification_procedure = 1;
ue_network_capability->dual_connectivity_with_nr = 1;
if (test_ue->attach_request_param.last_visited_registered_tai) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT;
ogs_nas_from_plmn_id(&last_visited_registered_tai->nas_plmn_id,
&test_ue->e_tai.plmn_id);
last_visited_registered_tai->tac = test_ue->e_tai.tac;
}
if (test_ue->attach_request_param.drx_parameter) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_DRX_PARAMETER_PRESENT;
drx_parameter->split_pg_cycle_code = 32;
}
if (test_ue->attach_request_param.ms_network_capability) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_MS_NETWORK_CAPABILITY_PRESENT;
ms_network_capability->length = 3;
ms_network_capability->gea1 = 1;
ms_network_capability->sm_capabilities_via_dedicated_channels = 1;
ms_network_capability->sm_capabilities_via_gprs_channels = 1;
ms_network_capability->ss_screening_indicator = 1;
ms_network_capability->revision_level_indicator = 1;
ms_network_capability->pfc_feature_mode = 1;
ms_network_capability->extended_gea = 0x30;
ms_network_capability->emm_combined_procedures_capability = 1;
ms_network_capability->isr_support = 1;
ms_network_capability->epc_capability = 1;
}
if (test_ue->attach_request_param.location_area_identication) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_OLD_LOCATION_AREA_IDENTIFICATION_PRESENT;
ogs_nas_from_plmn_id(&old_location_area_identification->nas_plmn_id,
&test_ue->e_tai.plmn_id);
old_location_area_identification->lac = 1;
}
if (test_ue->attach_request_param.tmsi_status) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_TMSI_STATUS_PRESENT;
}
if (test_ue->attach_request_param.mobile_station_classmark_2) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_MOBILE_STATION_CLASSMARK_2_PRESENT;
mobile_station_classmark_2->length = 3;
mobile_station_classmark_2->revision_level = 2;
mobile_station_classmark_2->es_ind = 1;
mobile_station_classmark_2->a5_1 = 1;
mobile_station_classmark_2->rf_power_capability = 7;
mobile_station_classmark_2->ps_capa = 1;
mobile_station_classmark_2->ss_screen_indicator = 1;
mobile_station_classmark_2->sm_capabi = 1;
mobile_station_classmark_2->cm3 = 1;
mobile_station_classmark_2->lcsva_cap = 1;
mobile_station_classmark_2->cmsp = 1;
mobile_station_classmark_2->a5_3 = 1;
}
if (test_ue->attach_request_param.mobile_station_classmark_3) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_MOBILE_STATION_CLASSMARK_3_PRESENT;
mobile_station_classmark_3->length = 11;
memcpy(mobile_station_classmark_3->buffer,
classmark_3, mobile_station_classmark_3->length);
}
if (test_ue->attach_request_param.supported_codecs) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_SUPPORTED_CODECS_PRESENT;
supported_codecs->length = 8;
supported_codecs->item[0].system_identification = 0x04;
supported_codecs->item[0].length_of_bitmap = 2;
supported_codecs->item[0].codec_bitmap = htobe16(0x6004);
supported_codecs->item[1].system_identification = 0;
supported_codecs->item[1].length_of_bitmap = 2;
supported_codecs->item[1].codec_bitmap = htobe16(0x1f02);
}
if (test_ue->attach_request_param.additional_update_type) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_ADDITIONAL_UPDATE_TYPE_PRESENT;
additional_update_type->autv = 1;
}
if (test_ue->attach_request_param.ue_usage_setting) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_VOICE_DOMAIN_PREFERENCE_AND_UE_USAGE_SETTING_PRESENT;
voice_domain_preference_and_ue_usage_setting->length = 1;
voice_domain_preference_and_ue_usage_setting->ue_usage_setting = 1;
voice_domain_preference_and_ue_usage_setting->
voice_domain_preference_for_e_utran = 1;
}
if (test_ue->attach_request_param.old_guti_type) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_OLD_GUTI_TYPE_PRESENT;
}
if (test_ue->attach_request_param.ms_network_feature_support) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_MS_NETWORK_FEATURE_SUPPORT_PRESENT;
ms_network_feature_support->extended_periodic_timers = 1;
}
if (test_ue->attach_request_param.nri_container) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_TMSI_BASED_NRI_CONTAINER_PRESENT;
tmsi_based_nri_container->length = 2;
tmsi_based_nri_container->nri_container_value1 = 0x8d;
tmsi_based_nri_container->nri_container_value2 = 0x3;
}
if (test_ue->attach_request_param.ue_additional_security_capability) {
attach_request->presencemask |=
OGS_NAS_EPS_ATTACH_REQUEST_UE_ADDITIONAL_SECURITY_CAPABILITY_PRESENT;
ue_additional_security_capability->length = 4;
ue_additional_security_capability->nea = 0xf0;
ue_additional_security_capability->nia = 0xf0;
}
if (integrity_protected)
pkbuf = test_nas_eps_security_encode(test_ue, &message);
else
pkbuf = ogs_nas_eps_plain_encode(&message);
ogs_pkbuf_free(esmbuf);
return pkbuf;
}
ogs_pkbuf_t *testemm_build_identity_response(test_ue_t *test_ue)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_identity_response_t *identity_response =
&message.emm.identity_response;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.emm.h.protocol_discriminator =
OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_IDENTITY_RESPONSE;
identity_response->mobile_identity.length =
sizeof(ogs_nas_mobile_identity_imsi_t);
memcpy(&identity_response->mobile_identity.imsi,
&test_ue->mobile_identity_imsi,
identity_response->mobile_identity.length);
return ogs_nas_eps_plain_encode(&message);
}
ogs_pkbuf_t *testemm_build_authentication_response(test_ue_t *test_ue)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_authentication_response_t *authentication_response =
&message.emm.authentication_response;
ogs_nas_authentication_response_parameter_t
*authentication_response_parameter =
&authentication_response->authentication_response_parameter;
uint8_t ik[OGS_KEY_LEN];
uint8_t ck[OGS_KEY_LEN];
uint8_t ak[OGS_AK_LEN];
uint8_t sqn[OGS_SQN_LEN];
uint8_t res[OGS_MAX_RES_LEN];
ogs_nas_plmn_id_t nas_plmn_id;
uint8_t kasme[32];
int i;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_AUTHENTICATION_RESPONSE;
ogs_hex_from_string(
test_ue->k_string, test_ue->k, sizeof(test_ue->k));
ogs_hex_from_string(
test_ue->opc_string, test_ue->opc, sizeof(test_ue->opc));
milenage_f2345(test_ue->opc, test_ue->k, test_ue->rand,
res, ck, ik, ak, NULL);
for (i = 0; i < 6; i++)
sqn[i] = test_ue->autn[i] ^ ak[i];
ogs_nas_from_plmn_id(&nas_plmn_id, &test_ue->e_tai.plmn_id);
ogs_auc_kasme(ck, ik, &nas_plmn_id, sqn, ak, test_ue->kasme);
authentication_response_parameter->length = 8;
memcpy(authentication_response_parameter->res, res, 8);
return ogs_nas_eps_plain_encode(&message);
}
ogs_pkbuf_t *testemm_build_authentication_failure(
test_ue_t *test_ue, ogs_nas_emm_cause_t emm_cause, uint64_t sqn_ms)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_authentication_failure_t *authentication_failure =
&message.emm.authentication_failure;
ogs_nas_authentication_failure_parameter_t
*authentication_failure_parameter =
&authentication_failure->authentication_failure_parameter;
uint8_t ak[OGS_AK_LEN];
#if 0
uint8_t sqn_ms[OGS_SQN_LEN] = "\x00\x00\x11\x22\x33\x44";
uint8_t sqn_ms[OGS_SQN_LEN] = "\x00\x00\x00\x00\x1f\x60"; /* Issues 482 */
#endif
uint8_t sqn[OGS_SQN_LEN];
uint8_t mac_s[OGS_MAC_S_LEN];
uint8_t amf[2] = { 0, 0 };
uint8_t auts[OGS_AUTS_LEN];
int i = 0;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_AUTHENTICATION_FAILURE;
authentication_failure->emm_cause = emm_cause;
if (emm_cause == OGS_NAS_EMM_CAUSE_SYNCH_FAILURE) {
authentication_failure->presencemask |=
OGS_NAS_EPS_AUTHENTICATION_FAILURE_AUTHENTICATION_FAILURE_PARAMETER_PRESENT;
ogs_hex_from_string(
test_ue->k_string, test_ue->k, sizeof(test_ue->k));
ogs_hex_from_string(
test_ue->opc_string, test_ue->opc, sizeof(test_ue->opc));
milenage_f2345(test_ue->opc, test_ue->k, test_ue->rand,
NULL, NULL, NULL, NULL, ak);
ogs_uint64_to_buffer(sqn_ms, 6, sqn);
milenage_f1(test_ue->opc, test_ue->k, test_ue->rand,
sqn, amf, NULL, auts + OGS_SQN_LEN);
for (i = 0; i < OGS_SQN_LEN; i++)
auts[i] = sqn[i] ^ ak[i];
authentication_failure_parameter->length = OGS_AUTS_LEN;
memcpy(authentication_failure_parameter->auts, auts,
authentication_failure_parameter->length);
}
return ogs_nas_eps_plain_encode(&message);
}
ogs_pkbuf_t *testemm_build_security_mode_complete(test_ue_t *test_ue)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_security_mode_complete_t *security_mode_complete =
&message.emm.security_mode_complete;
ogs_nas_mobile_identity_t *imeisv = &security_mode_complete->imeisv;
ogs_nas_mobile_identity_imeisv_t mobile_identity_imeisv;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHTERD_WITH_NEW_INTEGRITY_CONTEXT;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_SECURITY_MODE_COMPLETE;
if (test_ue->mobile_identity_imeisv_presence) {
security_mode_complete->presencemask |=
OGS_NAS_EPS_SECURITY_MODE_COMPLETE_IMEISV_PRESENT;
memset(&mobile_identity_imeisv, 0, sizeof(mobile_identity_imeisv));
imeisv->length = sizeof(test_ue->mobile_identity_imeisv);
memcpy(&imeisv->imeisv,
&test_ue->mobile_identity_imeisv, imeisv->length);
imeisv->imeisv.type = OGS_NAS_MOBILE_IDENTITY_IMEISV;
}
return test_nas_eps_security_encode(test_ue, &message);
}
ogs_pkbuf_t *testemm_build_attach_complete(
test_ue_t *test_ue, ogs_pkbuf_t *esmbuf)
{
ogs_pkbuf_t *pkbuf = NULL;
ogs_nas_eps_message_t message;
ogs_nas_eps_attach_complete_t *attach_complete =
&message.emm.attach_complete;
ogs_nas_esm_message_container_t *esm_message_container =
&attach_complete->esm_message_container;
ogs_assert(test_ue);
ogs_assert(esmbuf);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_ATTACH_COMPLETE;
esm_message_container->length = esmbuf->len;
esm_message_container->buffer = esmbuf->data;
pkbuf = test_nas_eps_security_encode(test_ue, &message);
ogs_pkbuf_free(esmbuf);
return pkbuf;
}
ogs_pkbuf_t *testemm_build_tau_complete(test_ue_t *test_ue)
{
ogs_nas_eps_message_t message;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_TRACKING_AREA_UPDATE_COMPLETE;
return test_nas_eps_security_encode(test_ue, &message);
}
ogs_pkbuf_t *testemm_build_detach_request(
test_ue_t *test_ue, bool switch_off,
bool integrity_protected, bool ciphered)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_detach_request_from_ue_t *detach_request =
&message.emm.detach_request_from_ue;
ogs_nas_detach_type_t *detach_type = &detach_request->detach_type;
ogs_nas_eps_mobile_identity_t *eps_mobile_identity =
&detach_request->eps_mobile_identity;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
if (integrity_protected) {
if (ciphered)
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
else
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
}
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_DETACH_REQUEST;
detach_type->nas_key_set_identifier = test_ue->nas.ksi;
detach_type->switch_off = switch_off;
detach_type->value = OGS_NAS_DETACH_TYPE_FROM_UE_EPS_DETACH;
if (test_ue->nas_eps_guti.m_tmsi) {
eps_mobile_identity->length =
sizeof(ogs_nas_eps_mobile_identity_guti_t);
eps_mobile_identity->guti.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN;
eps_mobile_identity->guti.type = OGS_NAS_EPS_MOBILE_IDENTITY_GUTI;
eps_mobile_identity->guti.nas_plmn_id =
test_ue->nas_eps_guti.nas_plmn_id;
eps_mobile_identity->guti.mme_gid = test_ue->nas_eps_guti.mme_gid;
eps_mobile_identity->guti.mme_code = test_ue->nas_eps_guti.mme_code;
eps_mobile_identity->guti.m_tmsi = test_ue->nas_eps_guti.m_tmsi;
} else {
eps_mobile_identity->length =
sizeof(ogs_nas_mobile_identity_imsi_t);
memcpy(&eps_mobile_identity->imsi,
&test_ue->mobile_identity_imsi, eps_mobile_identity->length);
}
if (integrity_protected)
return test_nas_eps_security_encode(test_ue, &message);
else
return ogs_nas_eps_plain_encode(&message);
}
ogs_pkbuf_t *testemm_build_service_request(test_ue_t *test_ue)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_service_request_t *service_request =
&message.emm.service_request;
ogs_pkbuf_t *pkbuf = NULL;
ogs_pkbuf_t *new = NULL;
uint8_t mac[4];
ogs_nas_ksi_and_sequence_number_t *ksi_and_sequence_number =
&service_request->ksi_and_sequence_number;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.emm.h.security_header_type =
OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE;
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
ksi_and_sequence_number->sequence_number = test_ue->ul_count;
pkbuf = ogs_nas_eps_plain_encode(&message);
ogs_assert(pkbuf);
new = ogs_pkbuf_copy(pkbuf);
ogs_assert(new);
ogs_pkbuf_trim(new, 2);
/* To prevent error message in ogs_nas_mac_calculate() */
if (test_ue->selected_int_algorithm == OGS_NAS_SECURITY_ALGORITHMS_EIA0)
test_ue->selected_int_algorithm = OGS_NAS_SECURITY_ALGORITHMS_128_EIA1;
ogs_nas_mac_calculate(test_ue->selected_int_algorithm,
test_ue->knas_int, test_ue->ul_count, 0, 0, new, mac);
test_ue->ul_count = (test_ue->ul_count + 1) & 0xffffff; /* Use 24bit */
memcpy(pkbuf->data + 2, mac + 2, 2);
ogs_pkbuf_free(new);
return pkbuf;
}
ogs_pkbuf_t *testemm_build_tau_request(
test_ue_t *test_ue, bool active_flag, uint8_t update_type,
bool integrity_protected, bool ciphered)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_tracking_area_update_request_t *tau_request =
&message.emm.tracking_area_update_request;
ogs_nas_eps_update_type_t *eps_update_type = &tau_request->eps_update_type;
ogs_nas_eps_mobile_identity_t *old_guti = &tau_request->old_guti;
ogs_nas_ue_network_capability_t *ue_network_capability =
&tau_request->ue_network_capability;
ogs_nas_tracking_area_identity_t *last_visited_registered_tai =
&tau_request->last_visited_registered_tai;
ogs_nas_drx_parameter_t *drx_parameter = &tau_request->drx_parameter;
ogs_nas_eps_bearer_context_status_t *eps_bearer_context_status =
&tau_request->eps_bearer_context_status;
ogs_nas_ms_network_capability_t *ms_network_capability =
&tau_request->ms_network_capability;
ogs_nas_location_area_identification_t *old_location_area_identification =
&tau_request->old_location_area_identification;
ogs_nas_tmsi_status_t *tmsi_status = &tau_request->tmsi_status;
ogs_nas_mobile_station_classmark_2_t *mobile_station_classmark_2 =
&tau_request->mobile_station_classmark_2;
ogs_nas_mobile_station_classmark_3_t *mobile_station_classmark_3 =
&tau_request->mobile_station_classmark_3;
ogs_nas_supported_codec_list_t *supported_codecs =
&tau_request->supported_codecs;
ogs_nas_additional_update_type_t *additional_update_type =
&tau_request->additional_update_type;
ogs_nas_voice_domain_preference_and_ue_usage_setting_t
*voice_domain_preference_and_ue_usage_setting =
&tau_request->voice_domain_preference_and_ue_usage_setting;
ogs_nas_guti_type_t *old_guti_type = &tau_request->old_guti_type;
ogs_nas_ms_network_feature_support_t *ms_network_feature_support =
&tau_request->ms_network_feature_support;
ogs_nas_network_resource_identifier_container_t *tmsi_based_nri_container =
&tau_request->tmsi_based_nri_container;
ogs_nas_ue_additional_security_capability_t
*ue_additional_security_capability =
&tau_request->ue_additional_security_capability;
uint8_t classmark_3[11] = "\x60\x14\x04\xef\x65\x23\x3b\x88\x78\xd2\x90";
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
if (integrity_protected) {
if (ciphered) {
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
} else {
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED;
}
}
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST;
eps_update_type->nas_key_set_identifier = test_ue->nas.ksi;
eps_update_type->active_flag = active_flag;
eps_update_type->value = update_type;
old_guti->length = sizeof(ogs_nas_eps_mobile_identity_guti_t);
old_guti->guti.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN;
old_guti->guti.type = OGS_NAS_EPS_MOBILE_IDENTITY_GUTI;
old_guti->guti.nas_plmn_id = test_ue->nas_eps_guti.nas_plmn_id;
old_guti->guti.mme_gid = test_ue->nas_eps_guti.mme_gid;
old_guti->guti.mme_code = test_ue->nas_eps_guti.mme_code;
old_guti->guti.m_tmsi = test_ue->nas_eps_guti.m_tmsi;
if (test_ue->tau_request_param.ue_network_capability) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_UE_NETWORK_CAPABILITY_PRESENT;
ue_network_capability->length = 7;
ue_network_capability->eea = 0xf0;
ue_network_capability->eia = 0xf0;
ue_network_capability->uea = 0xc0;
ue_network_capability->uia = 0x40;
ue_network_capability->notification_procedure = 1;
ue_network_capability->dual_connectivity_with_nr = 1;
}
if (test_ue->tau_request_param.last_visited_registered_tai) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT;
ogs_nas_from_plmn_id(&last_visited_registered_tai->nas_plmn_id,
&test_ue->e_tai.plmn_id);
last_visited_registered_tai->tac = test_ue->e_tai.tac;
}
if (test_ue->tau_request_param.drx_parameter) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_DRX_PARAMETER_PRESENT;
drx_parameter->split_pg_cycle_code = 32;
}
if (test_ue->tau_request_param.eps_bearer_context_status) {
test_sess_t *sess = NULL;
test_bearer_t *bearer = NULL;
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_EPS_BEARER_CONTEXT_STATUS_PRESENT;
eps_bearer_context_status->length = 2;
ogs_list_for_each(&test_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
if (bearer->ebi == 5) eps_bearer_context_status->ebi5 = 1;
else if (bearer->ebi == 6) eps_bearer_context_status->ebi6 = 1;
else if (bearer->ebi == 7) eps_bearer_context_status->ebi7 = 1;
}
}
}
if (test_ue->tau_request_param.ms_network_capability) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_MS_NETWORK_CAPABILITY_PRESENT;
ms_network_capability->length = 3;
ms_network_capability->gea1 = 1;
ms_network_capability->sm_capabilities_via_dedicated_channels = 1;
ms_network_capability->sm_capabilities_via_gprs_channels = 1;
ms_network_capability->ss_screening_indicator = 1;
ms_network_capability->revision_level_indicator = 1;
ms_network_capability->pfc_feature_mode = 1;
ms_network_capability->extended_gea = 0x30;
ms_network_capability->emm_combined_procedures_capability = 1;
ms_network_capability->isr_support = 1;
ms_network_capability->epc_capability = 1;
}
if (test_ue->tau_request_param.location_area_identication) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_OLD_LOCATION_AREA_IDENTIFICATION_PRESENT;
ogs_nas_from_plmn_id(&old_location_area_identification->nas_plmn_id,
&test_ue->e_tai.plmn_id);
old_location_area_identification->lac = 1;
}
if (test_ue->tau_request_param.tmsi_status) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_TMSI_STATUS_PRESENT;
}
if (test_ue->tau_request_param.mobile_station_classmark_2) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_MOBILE_STATION_CLASSMARK_2_PRESENT;
mobile_station_classmark_2->length = 3;
mobile_station_classmark_2->revision_level = 2;
mobile_station_classmark_2->es_ind = 1;
mobile_station_classmark_2->a5_1 = 1;
mobile_station_classmark_2->rf_power_capability = 7;
mobile_station_classmark_2->ps_capa = 1;
mobile_station_classmark_2->ss_screen_indicator = 1;
mobile_station_classmark_2->sm_capabi = 1;
mobile_station_classmark_2->cm3 = 1;
mobile_station_classmark_2->lcsva_cap = 1;
mobile_station_classmark_2->cmsp = 1;
mobile_station_classmark_2->a5_3 = 1;
}
if (test_ue->tau_request_param.mobile_station_classmark_3) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_MOBILE_STATION_CLASSMARK_3_PRESENT;
mobile_station_classmark_3->length = 11;
memcpy(mobile_station_classmark_3->buffer,
classmark_3, mobile_station_classmark_3->length);
}
if (test_ue->tau_request_param.supported_codecs) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_SUPPORTED_CODECS_PRESENT;
supported_codecs->length = 8;
supported_codecs->item[0].system_identification = 0x04;
supported_codecs->item[0].length_of_bitmap = 2;
supported_codecs->item[0].codec_bitmap = htobe16(0x6004);
supported_codecs->item[1].system_identification = 0;
supported_codecs->item[1].length_of_bitmap = 2;
supported_codecs->item[1].codec_bitmap = htobe16(0x1f02);
}
if (test_ue->tau_request_param.additional_update_type) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_ADDITIONAL_UPDATE_TYPE_PRESENT;
additional_update_type->autv = 1;
}
if (test_ue->tau_request_param.ue_usage_setting) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_VOICE_DOMAIN_PREFERENCE_AND_UE_USAGE_SETTING_PRESENT;
voice_domain_preference_and_ue_usage_setting->length = 1;
voice_domain_preference_and_ue_usage_setting->ue_usage_setting = 1;
voice_domain_preference_and_ue_usage_setting->
voice_domain_preference_for_e_utran = 1;
}
if (test_ue->tau_request_param.old_guti_type) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_OLD_GUTI_TYPE_PRESENT;
}
if (test_ue->tau_request_param.ms_network_feature_support) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_MS_NETWORK_FEATURE_SUPPORT_PRESENT;
ms_network_feature_support->extended_periodic_timers = 1;
}
if (test_ue->tau_request_param.nri_container) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_TMSI_BASED_NRI_CONTAINER_PRESENT;
tmsi_based_nri_container->length = 2;
tmsi_based_nri_container->nri_container_value1 = 0x8d;
tmsi_based_nri_container->nri_container_value2 = 0x3;
}
if (test_ue->tau_request_param.ue_additional_security_capability) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_UE_ADDITIONAL_SECURITY_CAPABILITY_PRESENT;
ue_additional_security_capability->length = 4;
ue_additional_security_capability->nea = 0xf0;
ue_additional_security_capability->nia = 0xf0;
}
if (test_ue->tau_request_param.device_properties) {
tau_request->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST_DEVICE_PROPERTIES_PRESENT;
}
if (integrity_protected)
return test_nas_eps_security_encode(test_ue, &message);
else
return ogs_nas_eps_plain_encode(&message);
}
ogs_pkbuf_t *testemm_build_emm_status(
test_ue_t *test_ue, ogs_nas_emm_cause_t emm_cause)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_emm_status_t *emm_status = &message.emm.emm_status;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_EMM_STATUS;
emm_status->emm_cause = emm_cause;
return test_nas_eps_security_encode(test_ue, &message);
}
ogs_pkbuf_t *testemm_build_extended_service_request(
test_ue_t *test_ue, uint8_t type,
bool integrity_protected, bool ciphered)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_extended_service_request_t *extended_service_request =
&message.emm.extended_service_request;
ogs_nas_service_type_t *service_type =
&extended_service_request->service_type;
ogs_nas_mobile_identity_t *mobile_identity =
&extended_service_request->m_tmsi;
ogs_nas_csfb_response_t *csfb_response =
&extended_service_request->csfb_response;
ogs_nas_eps_bearer_context_status_t *eps_bearer_context_status =
&extended_service_request->eps_bearer_context_status;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
if (integrity_protected) {
if (ciphered)
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
else
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
}
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_EXTENDED_SERVICE_REQUEST;
service_type->value = type;
mobile_identity->length = 5;
mobile_identity->tmsi.type = OGS_NAS_MOBILE_IDENTITY_TMSI;
mobile_identity->tmsi.tmsi = test_ue->nas_eps_guti.m_tmsi;
if (test_ue->extended_service_request_param.csfb_response) {
extended_service_request->presencemask |=
OGS_NAS_EPS_EXTENDED_SERVICE_REQUEST_CSFB_RESPONSE_PRESENT;
csfb_response->response =
test_ue->extended_service_request_param.csfb.response;
}
if (test_ue->extended_service_request_param.eps_bearer_context_status) {
test_sess_t *sess = NULL;
test_bearer_t *bearer = NULL;
extended_service_request->presencemask |= OGS_NAS_EPS_EXTENDED_SERVICE_REQUEST_EPS_BEARER_CONTEXT_STATUS_PRESENT;
eps_bearer_context_status->length = 2;
ogs_list_for_each(&test_ue->sess_list, sess) {
ogs_list_for_each(&sess->bearer_list, bearer) {
if (bearer->ebi == 5) eps_bearer_context_status->ebi5 = 1;
else if (bearer->ebi == 6) eps_bearer_context_status->ebi6 = 1;
else if (bearer->ebi == 7) eps_bearer_context_status->ebi7 = 1;
}
}
}
if (integrity_protected)
return test_nas_eps_security_encode(test_ue, &message);
else
return ogs_nas_eps_plain_encode(&message);
}
ogs_pkbuf_t *testemm_build_uplink_nas_transport(test_ue_t *test_ue)
{
ogs_nas_eps_message_t message;
ogs_nas_eps_uplink_nas_transport_t *uplink_nas_transport =
&message.emm.uplink_nas_transport;
ogs_nas_eps_message_container_t *nas_message_container =
&uplink_nas_transport->nas_message_container;
char hexbuf[OGS_MAX_SDU_LEN];
const char *payload =
"390167000300"
"0581005155f55d11 030c914477680205 490000055ad2e2b1 252d467ff6de6c47"
"efd568375b303613 166fb51c6d160cc2 8ab462b006a3d98a 31da90060b0673c5"
"9c512684158bb119 2c88b3058b37e1ad 081bca84c1582d07 93ede4bddc6d2693"
"e566371b";
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_UPLINK_NAS_TRANSPORT;
ogs_hex_from_string(payload, hexbuf, sizeof(hexbuf));
nas_message_container->length = 106;
memcpy(nas_message_container->buffer,
hexbuf, nas_message_container->length);
return test_nas_eps_security_encode(test_ue, &message);
}