forked from acouzens/open5gs
319 lines
10 KiB
C
319 lines
10 KiB
C
#include "core_pkbuf.h"
|
|
#include "core_lib.h"
|
|
|
|
#include "3gpp_types.h"
|
|
|
|
#include "nas/nas_message.h"
|
|
#include "mme/nas_security.h"
|
|
|
|
#include "testutil.h"
|
|
|
|
static void nas_message_test1(abts_case *tc, void *data)
|
|
{
|
|
/* Attach Request */
|
|
char *payload =
|
|
"0741020bf600f110000201030003e605"
|
|
"f07000001000050215d011d15200f110"
|
|
"30395c0a003103e5e0349011035758a6"
|
|
"5d0100e0c1";
|
|
|
|
nas_message_t message;
|
|
pkbuf_t *pkbuf;
|
|
status_t rv;
|
|
char hexbuf[MAX_SDU_LEN];
|
|
|
|
pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
|
|
ABTS_PTR_NOTNULL(tc, pkbuf);
|
|
pkbuf->len = 53;
|
|
memcpy(pkbuf->payload,
|
|
CORE_HEX(payload, strlen(payload), hexbuf), pkbuf->len);
|
|
|
|
rv = nas_emm_decode(&message, pkbuf);
|
|
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
|
|
|
pkbuf_free(pkbuf);
|
|
}
|
|
|
|
static void nas_message_test2(abts_case *tc, void *data)
|
|
{
|
|
/* Attach Accept */
|
|
char *payload =
|
|
"07420223060014f799303900325201c1"
|
|
"01090908696e7465726e657405010ae1"
|
|
"000a271b80802110020200108106c0a8"
|
|
"a8018306c0a8a801000d04c0a8a80150"
|
|
"0bf614f7992345e1000004561300f120"
|
|
"fffd2305f400e102d4640123";
|
|
char buffer[92];
|
|
|
|
char *esm_payload =
|
|
"5201c101090908696e7465726e657405"
|
|
"010ae1000a271b808021100202001081"
|
|
"06c0a8a8018306c0a8a801000d04c0a8"
|
|
"a801";
|
|
char esm_buffer[50];
|
|
|
|
nas_message_t message;
|
|
nas_attach_accept_t *attach_accept = &message.emm.attach_accept;
|
|
tai0_list_t tai0_list;
|
|
tai2_list_t tai2_list;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
status_t rv;
|
|
|
|
memset(&message, 0, sizeof(message));
|
|
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
|
|
message.emm.h.message_type = NAS_ATTACH_ACCEPT;
|
|
attach_accept->eps_attach_result.result =
|
|
NAS_ATTACH_RESULT_COMBINED_EPS_IMSI_ATTACH;
|
|
attach_accept->t3412_value.unit =
|
|
NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM;
|
|
attach_accept->t3412_value.value = 3;
|
|
|
|
memset(&tai0_list, 0, sizeof(tai0_list_t));
|
|
memset(&tai2_list, 0, sizeof(tai2_list_t));
|
|
tai0_list.tai[0].type = TAI0_TYPE;
|
|
tai0_list.tai[0].num = 1;
|
|
plmn_id_build(&tai0_list.tai[0].plmn_id, 417, 99, 2);
|
|
tai0_list.tai[0].tac[0] = 12345;
|
|
nas_tai_list_build(&attach_accept->tai_list, &tai0_list, &tai2_list);
|
|
|
|
attach_accept->esm_message_container.length = sizeof(esm_buffer);
|
|
attach_accept->esm_message_container.buffer =
|
|
CORE_HEX(esm_payload, strlen(esm_payload), esm_buffer);
|
|
|
|
attach_accept->presencemask |= NAS_ATTACH_ACCEPT_GUTI_PRESENT;
|
|
attach_accept->guti.length = 11;
|
|
attach_accept->guti.guti.type = NAS_EPS_MOBILE_IDENTITY_GUTI;
|
|
plmn_id_build(&attach_accept->guti.guti.plmn_id, 417, 99, 2);
|
|
attach_accept->guti.guti.mme_gid = 9029;
|
|
attach_accept->guti.guti.mme_code = 225;
|
|
attach_accept->guti.guti.m_tmsi = 0x00000456;
|
|
|
|
attach_accept->presencemask |=
|
|
NAS_ATTACH_ACCEPT_LOCATION_AREA_IDENTIFICATION_PRESENT;
|
|
plmn_id_build(
|
|
&attach_accept->location_area_identification.plmn_id, 1, 2, 2);
|
|
attach_accept->location_area_identification.lac = 0xfffd;
|
|
|
|
attach_accept->presencemask |= NAS_ATTACH_ACCEPT_MS_IDENTITY_PRESENT;
|
|
attach_accept->ms_identity.length = 5;
|
|
attach_accept->ms_identity.tmsi.type =
|
|
NAS_MOBILE_IDENTITY_TMSI;
|
|
attach_accept->ms_identity.tmsi.tmsi = 0x00e102d4;
|
|
|
|
attach_accept->presencemask |=
|
|
NAS_ATTACH_ACCEPT_EPS_NETWORK_FEATURE_SUPPORT_PRESENT;
|
|
attach_accept->eps_network_feature_support.length = 1;
|
|
attach_accept->eps_network_feature_support.esr_ps = 1;
|
|
attach_accept->eps_network_feature_support.emc_bs = 1;
|
|
attach_accept->eps_network_feature_support.ims_vops = 1;
|
|
|
|
rv = nas_plain_encode(&pkbuf, &message);
|
|
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
|
ABTS_INT_EQUAL(tc, sizeof(buffer), pkbuf->len);
|
|
ABTS_TRUE(tc, memcmp(CORE_HEX(payload, strlen(payload), buffer),
|
|
pkbuf->payload, pkbuf->len) == 0);
|
|
|
|
pkbuf_free(pkbuf);
|
|
}
|
|
|
|
static void nas_message_test3(abts_case *tc, void *data)
|
|
{
|
|
char *payload = "074300035200c2";
|
|
|
|
nas_message_t message;
|
|
pkbuf_t *pkbuf;
|
|
status_t rv;
|
|
char hexbuf[MAX_SDU_LEN];
|
|
|
|
pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
|
|
ABTS_PTR_NOTNULL(tc, pkbuf);
|
|
pkbuf->len = 7;
|
|
memcpy(pkbuf->payload,
|
|
CORE_HEX(payload, strlen(payload), hexbuf), pkbuf->len);
|
|
|
|
rv = nas_emm_decode(&message, pkbuf);
|
|
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
|
|
|
pkbuf_free(pkbuf);
|
|
}
|
|
|
|
static void nas_message_test4(abts_case *tc, void *data)
|
|
{
|
|
/* Attach Reject */
|
|
char *payload = "074411";
|
|
char buffer[3];
|
|
|
|
nas_message_t message;
|
|
nas_attach_reject_t *attach_reject = &message.emm.attach_reject;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
status_t rv;
|
|
|
|
memset(&message, 0, sizeof(message));
|
|
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
|
|
message.emm.h.message_type = NAS_ATTACH_REJECT;
|
|
attach_reject->emm_cause = EMM_CAUSE_NETWORK_FAILURE;
|
|
|
|
rv = nas_plain_encode(&pkbuf, &message);
|
|
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
|
ABTS_INT_EQUAL(tc, sizeof(buffer), pkbuf->len);
|
|
ABTS_TRUE(tc, memcmp(CORE_HEX(payload, strlen(payload), buffer),
|
|
pkbuf->payload, pkbuf->len) == 0);
|
|
|
|
pkbuf_free(pkbuf);
|
|
}
|
|
|
|
static void nas_message_test5(abts_case *tc, void *data)
|
|
{
|
|
mme_ue_t ue;
|
|
|
|
ue.ul_count.i32 = 0x123456;
|
|
ABTS_INT_EQUAL(tc, 0x1234, ue.ul_count.overflow);
|
|
ABTS_INT_EQUAL(tc, 0x56, ue.ul_count.sqn);
|
|
ABTS_INT_EQUAL(tc, 0, ue.ul_count.spare);
|
|
|
|
ue.ul_count.overflow = 0xabcd;
|
|
ue.ul_count.sqn = 0xef;
|
|
ABTS_INT_EQUAL(tc, 0xabcdef, ue.ul_count.i32);
|
|
}
|
|
|
|
static void nas_message_test6(abts_case *tc, void *data)
|
|
{
|
|
/* Identity Request */
|
|
char *payload = "075501";
|
|
char hexbuf[MAX_SDU_LEN];
|
|
|
|
nas_message_t message;
|
|
nas_identity_request_t *identity_request = &message.emm.identity_request;
|
|
pkbuf_t *pkbuf;
|
|
status_t rv;
|
|
|
|
pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
|
|
ABTS_PTR_NOTNULL(tc, pkbuf);
|
|
pkbuf->len = 3;
|
|
memcpy(pkbuf->payload,
|
|
CORE_HEX(payload, strlen(payload), hexbuf), pkbuf->len);
|
|
|
|
rv = nas_emm_decode(&message, pkbuf);
|
|
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
|
|
|
ABTS_INT_EQUAL(tc, NAS_PROTOCOL_DISCRIMINATOR_EMM,
|
|
message.emm.h.protocol_discriminator);
|
|
ABTS_INT_EQUAL(tc, NAS_IDENTITY_REQUEST, message.emm.h.message_type);
|
|
ABTS_INT_EQUAL(tc, NAS_IDENTITY_TYPE_2_IMSI,
|
|
identity_request->identity_type.type);
|
|
|
|
pkbuf_free(pkbuf);
|
|
}
|
|
|
|
static void nas_message_test7(abts_case *tc, void *data)
|
|
{
|
|
/* Identity Response */
|
|
char *payload = "0756080910101032548651";
|
|
char buffer[11];
|
|
|
|
nas_message_t message;
|
|
nas_identity_response_t *identity_response = &message.emm.identity_response;
|
|
|
|
pkbuf_t *pkbuf = NULL;
|
|
status_t rv;
|
|
|
|
memset(&message, 0, sizeof(message));
|
|
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
|
|
message.emm.h.message_type = NAS_IDENTITY_RESPONSE;
|
|
|
|
identity_response->mobile_identity.length = 8;
|
|
identity_response->mobile_identity.imsi.digit1 = 0;
|
|
identity_response->mobile_identity.imsi.type =
|
|
NAS_IDENTITY_TYPE_2_IMSI;
|
|
identity_response->mobile_identity.imsi.odd_even = 1;
|
|
identity_response->mobile_identity.imsi.digit2 = 0;
|
|
identity_response->mobile_identity.imsi.digit3 = 1;
|
|
identity_response->mobile_identity.imsi.digit4 = 0;
|
|
identity_response->mobile_identity.imsi.digit5 = 1;
|
|
identity_response->mobile_identity.imsi.digit6 = 0;
|
|
identity_response->mobile_identity.imsi.digit7 = 1;
|
|
identity_response->mobile_identity.imsi.digit8 = 2;
|
|
identity_response->mobile_identity.imsi.digit9 = 3;
|
|
identity_response->mobile_identity.imsi.digit10 = 4;
|
|
identity_response->mobile_identity.imsi.digit11 = 5;
|
|
identity_response->mobile_identity.imsi.digit12 = 6;
|
|
identity_response->mobile_identity.imsi.digit13 = 8;
|
|
identity_response->mobile_identity.imsi.digit14 = 1;
|
|
identity_response->mobile_identity.imsi.digit15 = 5;
|
|
|
|
rv = nas_plain_encode(&pkbuf, &message);
|
|
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
|
ABTS_INT_EQUAL(tc, sizeof(buffer), pkbuf->len);
|
|
ABTS_TRUE(tc, memcmp(CORE_HEX(payload, strlen(payload), buffer),
|
|
pkbuf->payload, pkbuf->len) == 0);
|
|
|
|
pkbuf_free(pkbuf);
|
|
}
|
|
|
|
static void nas_message_test8(abts_case *tc, void *data)
|
|
{
|
|
/* Security Request */
|
|
char *payload = "c7a8640c";
|
|
char buffer[4];
|
|
|
|
nas_message_t message;
|
|
pkbuf_t *pkbuf;
|
|
status_t rv;
|
|
char hexbuf[MAX_SDU_LEN];
|
|
nas_service_request_t *service_request = &message.emm.service_request;
|
|
nas_ksi_and_sequence_number_t *ksi_and_sequence_number =
|
|
&service_request->ksi_and_sequence_number;
|
|
|
|
pkbuf = pkbuf_alloc(0, MAX_SDU_LEN);
|
|
ABTS_PTR_NOTNULL(tc, pkbuf);
|
|
pkbuf->len = 4;
|
|
memcpy(pkbuf->payload,
|
|
CORE_HEX(payload, strlen(payload), hexbuf), pkbuf->len);
|
|
|
|
/* Decode service request */
|
|
rv = nas_emm_decode(&message, pkbuf);
|
|
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
|
ABTS_INT_EQUAL(tc, 5, ksi_and_sequence_number->ksi);
|
|
ABTS_INT_EQUAL(tc, 8, ksi_and_sequence_number->sequence_number);
|
|
ABTS_INT_EQUAL(tc, 0x640c, service_request->message_authentication_code);
|
|
|
|
pkbuf_free(pkbuf);
|
|
|
|
/* Encode service request */
|
|
memset(&message, 0, sizeof(message));
|
|
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
|
|
message.emm.h.security_header_type =
|
|
NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE;
|
|
|
|
ksi_and_sequence_number->ksi = 5;
|
|
ksi_and_sequence_number->sequence_number = 8;
|
|
service_request->message_authentication_code = 0x640c;
|
|
|
|
rv = nas_plain_encode(&pkbuf, &message);
|
|
ABTS_INT_EQUAL(tc, CORE_OK, rv);
|
|
ABTS_INT_EQUAL(tc, sizeof(buffer), pkbuf->len);
|
|
ABTS_TRUE(tc, memcmp(CORE_HEX(payload, strlen(payload), buffer),
|
|
pkbuf->payload, pkbuf->len) == 0);
|
|
|
|
pkbuf_free(pkbuf);
|
|
}
|
|
|
|
abts_suite *test_nas_message(abts_suite *suite)
|
|
{
|
|
suite = ADD_SUITE(suite)
|
|
|
|
abts_run_test(suite, nas_message_test1, NULL);
|
|
abts_run_test(suite, nas_message_test2, NULL);
|
|
abts_run_test(suite, nas_message_test3, NULL);
|
|
abts_run_test(suite, nas_message_test4, NULL);
|
|
abts_run_test(suite, nas_message_test5, NULL);
|
|
abts_run_test(suite, nas_message_test6, NULL);
|
|
abts_run_test(suite, nas_message_test7, NULL);
|
|
abts_run_test(suite, nas_message_test8, NULL);
|
|
|
|
return suite;
|
|
}
|