Refactor: unify equality-check macros across protocol libs

This commit centralizes equality-check behavior and removes duplicated
macro implementations across protocol stacks.

Major changes:
- add `common/utils/eq_check.h` with shared `_EQ_CHECK_*`,
  `EQ_CHECK_GENERIC`, and optional-IE pointer helpers
- replace E1AP/F1AP/NAS local equality macros and call sites with
  the shared helpers
- remove duplicated layer-specific error/equality macro definitions from
  common headers and switch includes to `eq_check.h`
- update CMake test flags to define `ENABLE_TESTS` for `e1ap_lib`,
  and 5GS NAS libraries; drop `E1AP_LOG_ERRORS` - equality-check/error
  printing is now consistently controlled by `ENABLE_TESTS`
This commit is contained in:
Guido Casati
2026-02-17 12:25:58 +01:00
parent f295252b2e
commit 563a0cfa61
24 changed files with 1059 additions and 1050 deletions
@@ -22,6 +22,7 @@
#include <stdint.h>
#include "FGSNASSecurityModeReject.h"
#include "common/utils/ds/byte_array.h"
#include "common/utils/eq_check.h"
#include "fgmm_lib.h"
int encode_fgs_security_mode_reject(byte_array_t *buffer, const fgs_security_mode_reject_msg *msg)
@@ -45,6 +46,6 @@ int decode_fgs_security_mode_reject(fgs_security_mode_reject_msg *msg, const byt
bool eq_sec_mode_reject(const fgs_security_mode_reject_msg *a, const fgs_security_mode_reject_msg *b)
{
_NAS_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_INT(a->cause, b->cause);
return true;
}
@@ -35,6 +35,7 @@
#include "conversions.h"
#include "RegistrationAccept.h"
#include "fgs_nas_utils.h"
#include "common/utils/eq_check.h"
#include "common/utils/utils.h"
#include "ds/byte_array.h"
#include "fgmm_lib.h"
@@ -47,7 +48,7 @@
static int decode_fgs_registration_result(registration_accept_msg *out, const byte_array_t buffer)
{
if (buffer.len < FGS_REGISTRATION_RESULT_LEN) {
PRINT_NAS_ERROR("5GS registration result decoding failure: invalid buffer length\n");
PRINT_ERROR("5GS registration result decoding failure: invalid buffer length\n");
return -1;
}
out->result = buffer.buf[1] & 0x7; // skip length of contents octet
@@ -58,7 +59,7 @@ static int decode_fgs_registration_result(registration_accept_msg *out, const by
static int encode_fgs_registration_result(byte_array_t buffer, const registration_accept_msg *out)
{
if (buffer.len < FGS_REGISTRATION_RESULT_LEN) {
PRINT_NAS_ERROR("5GS registration result encoding failure: invalid buffer length\n");
PRINT_ERROR("5GS registration result encoding failure: invalid buffer length\n");
return -1;
}
uint8_t *buf = buffer.buf;
@@ -125,7 +126,7 @@ static int decode_nssai_ie(nr_nas_msg_snssai_t *nssai, uint8_t *num_slices, uint
break;
default:
PRINT_NAS_ERROR("Unknown length in Allowed S-NSSAI list item\n");
PRINT_ERROR("Unknown length in Allowed S-NSSAI list item\n");
break;
}
}
@@ -139,7 +140,7 @@ size_t decode_registration_accept(registration_accept_msg *registration_accept,
byte_array_t ba = buffer; // local copy of buffer
if (ba.len < REGISTRATION_ACCEPT_MIN_LEN) {
PRINT_NAS_ERROR("Registration Accept decoding failed: invalid buffer length\n");
PRINT_ERROR("Registration Accept decoding failed: invalid buffer length\n");
return -1;
}
@@ -152,7 +153,7 @@ size_t decode_registration_accept(registration_accept_msg *registration_accept,
if (ba.len > 0 && ba.buf[0] == IEI_5G_GUTI) {
registration_accept->guti = calloc_or_fail(1, sizeof(*registration_accept->guti));
if ((dec = decode_5gs_mobile_identity(registration_accept->guti, IEI_5G_GUTI, ba.buf, ba.len)) < 0) {
PRINT_NAS_ERROR("Failed to decode 5GS Mobile Identity in Registration Accept\n");
PRINT_ERROR("Failed to decode 5GS Mobile Identity in Registration Accept\n");
return -1;
}
UPDATE_BYTE_ARRAY(ba, dec);
@@ -182,7 +183,7 @@ size_t decode_registration_accept(registration_accept_msg *registration_accept,
}
}
if(ba.len != 0) {
PRINT_NAS_ERROR("Failed to decode registration accept: ba.len = %ld\n", ba.len);
PRINT_ERROR("Failed to decode registration accept: ba.len = %ld\n", ba.len);
return -1;
}
return buffer.len;
@@ -209,22 +210,22 @@ int encode_registration_accept(const registration_accept_msg *registration_accep
bool eq_snssai(const nr_nas_msg_snssai_t *a, const nr_nas_msg_snssai_t *b)
{
_NAS_EQ_CHECK_INT(a->sst, b->sst);
_EQ_CHECK_INT(a->sst, b->sst);
if ((a->hplmn_sst && !b->hplmn_sst) || (!a->hplmn_sst && b->hplmn_sst))
return false;
if (a->hplmn_sst && b->hplmn_sst)
_NAS_EQ_CHECK_INT(*a->hplmn_sst, *b->hplmn_sst);
_EQ_CHECK_INT(*a->hplmn_sst, *b->hplmn_sst);
if ((a->sd && !b->sd) || (!a->sd && b->sd))
return false;
if (a->sd && b->sd)
_NAS_EQ_CHECK_INT(*a->sd, *b->sd);
_EQ_CHECK_INT(*a->sd, *b->sd);
if ((a->hplmn_sd && !b->hplmn_sd) || (!a->hplmn_sd && b->hplmn_sd))
return false;
if (a->hplmn_sd && b->hplmn_sd)
_NAS_EQ_CHECK_INT(*a->hplmn_sd, *b->hplmn_sd);
_EQ_CHECK_INT(*a->hplmn_sd, *b->hplmn_sd);
return true;
}
@@ -233,48 +234,48 @@ bool eq_snssai(const nr_nas_msg_snssai_t *a, const nr_nas_msg_snssai_t *b)
bool eq_fgmm_registration_accept(const registration_accept_msg *a, const registration_accept_msg *b)
{
if (!a || !b) {
PRINT_NAS_ERROR("Null pointer in registration_accept_msg_eq\n");
PRINT_ERROR("Null pointer in registration_accept_msg_eq\n");
return false;
}
// 5GS registration result (mandatory)
_NAS_EQ_CHECK_INT(a->result, b->result);
_NAS_EQ_CHECK_INT(a->sms_allowed, b->sms_allowed);
_EQ_CHECK_INT(a->result, b->result);
_EQ_CHECK_INT(a->sms_allowed, b->sms_allowed);
// GUTI (optional)
if (a->guti && b->guti) {
_NAS_EQ_CHECK_INT(a->guti->guti.spare, b->guti->guti.spare);
_NAS_EQ_CHECK_INT(a->guti->guti.oddeven, b->guti->guti.oddeven);
_NAS_EQ_CHECK_INT(a->guti->guti.typeofidentity, b->guti->guti.typeofidentity);
_NAS_EQ_CHECK_INT(a->guti->guti.mccdigit2, b->guti->guti.mccdigit2);
_NAS_EQ_CHECK_INT(a->guti->guti.mccdigit1, b->guti->guti.mccdigit1);
_NAS_EQ_CHECK_INT(a->guti->guti.mncdigit3, b->guti->guti.mncdigit3);
_NAS_EQ_CHECK_INT(a->guti->guti.mccdigit3, b->guti->guti.mccdigit3);
_NAS_EQ_CHECK_INT(a->guti->guti.mncdigit2, b->guti->guti.mncdigit2);
_NAS_EQ_CHECK_INT(a->guti->guti.mncdigit1, b->guti->guti.mncdigit1);
_NAS_EQ_CHECK_INT(a->guti->guti.amfregionid, b->guti->guti.amfregionid);
_NAS_EQ_CHECK_INT(a->guti->guti.amfsetid, b->guti->guti.amfsetid);
_NAS_EQ_CHECK_INT(a->guti->guti.amfpointer, b->guti->guti.amfpointer);
_NAS_EQ_CHECK_INT(a->guti->guti.tmsi, b->guti->guti.tmsi);
_EQ_CHECK_INT(a->guti->guti.spare, b->guti->guti.spare);
_EQ_CHECK_INT(a->guti->guti.oddeven, b->guti->guti.oddeven);
_EQ_CHECK_INT(a->guti->guti.typeofidentity, b->guti->guti.typeofidentity);
_EQ_CHECK_INT(a->guti->guti.mccdigit2, b->guti->guti.mccdigit2);
_EQ_CHECK_INT(a->guti->guti.mccdigit1, b->guti->guti.mccdigit1);
_EQ_CHECK_INT(a->guti->guti.mncdigit3, b->guti->guti.mncdigit3);
_EQ_CHECK_INT(a->guti->guti.mccdigit3, b->guti->guti.mccdigit3);
_EQ_CHECK_INT(a->guti->guti.mncdigit2, b->guti->guti.mncdigit2);
_EQ_CHECK_INT(a->guti->guti.mncdigit1, b->guti->guti.mncdigit1);
_EQ_CHECK_INT(a->guti->guti.amfregionid, b->guti->guti.amfregionid);
_EQ_CHECK_INT(a->guti->guti.amfsetid, b->guti->guti.amfsetid);
_EQ_CHECK_INT(a->guti->guti.amfpointer, b->guti->guti.amfpointer);
_EQ_CHECK_INT(a->guti->guti.tmsi, b->guti->guti.tmsi);
} else if ((a->guti && !b->guti) || (!a->guti && b->guti)) {
PRINT_NAS_ERROR("NAS Equality Check failure: One of the two GUTIs is NULL\n");
PRINT_ERROR("NAS Equality Check failure: One of the two GUTIs is NULL\n");
return false;
}
_NAS_EQ_CHECK_INT(a->num_allowed_slices, b->num_allowed_slices);
_NAS_EQ_CHECK_INT(a->num_configured_slices, b->num_configured_slices);
_EQ_CHECK_INT(a->num_allowed_slices, b->num_allowed_slices);
_EQ_CHECK_INT(a->num_configured_slices, b->num_configured_slices);
// Configured NSSAI (optional)
for (int i = 0; i < a->num_configured_slices; i++) {
if (!eq_snssai(&a->config_nssai[i], &b->config_nssai[i])) {
PRINT_NAS_ERROR("NAS Equality Check failure: Configured NSSAI\n");
PRINT_ERROR("NAS Equality Check failure: Configured NSSAI\n");
return false;
}
}
// Allowed NSSAI (optional)
for (int i = 0; i < a->num_allowed_slices; i++) {
if (!eq_snssai(&a->nas_allowed_nssai[i], &b->nas_allowed_nssai[i])) {
PRINT_NAS_ERROR("NAS Equality Check failure: Allowed NSSAI\n");
PRINT_ERROR("NAS Equality Check failure: Allowed NSSAI\n");
return false;
}
}
@@ -25,6 +25,7 @@
#include <stdlib.h> // For malloc and free
#include "fgmm_lib.h"
#include "common/utils/ds/byte_array.h"
#include "common/utils/eq_check.h"
#include "common/utils/utils.h"
#define MIN_AUTH_FAILURE_LEN 1
@@ -35,7 +36,7 @@
int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *msg)
{
if (buffer->len < MIN_AUTH_FAILURE_LEN) {
PRINT_NAS_ERROR("Missing mandatory IE in Authentication Failure");
PRINT_ERROR("Missing mandatory IE in Authentication Failure");
return -1; // missing mandatory IE
}
// 5GMM cause (Mandatory)
@@ -44,11 +45,11 @@ int encode_fgmm_auth_failure(byte_array_t *buffer, const fgmm_auth_failure_t *ms
if (msg->cause == Synch_failure) {
// Authentication failure parameter shall be present with cause Synch Failure
if (msg->authentication_failure_param.len == 0) {
PRINT_NAS_ERROR("Authentication Failure Cause is synch failure but Authentication Failure Parameter is not available");
PRINT_ERROR("Authentication Failure Cause is synch failure but Authentication Failure Parameter is not available");
return -1;
}
if (buffer->len - encoded < msg->authentication_failure_param.len + 2) {
PRINT_NAS_ERROR("Invalid buffer for encoding of Authentication Failure Parameter");
PRINT_ERROR("Invalid buffer for encoding of Authentication Failure Parameter");
return -1;
}
// Encode the IEI
@@ -76,7 +77,7 @@ int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffe
if (iei == AUTH_FAIL_PARAM_IEI) {
msg->authentication_failure_param.len = ba.buf[decoded++];
if (msg->authentication_failure_param.len > AUTH_FAILURE_PARAM_LEN - 2) { // maximum length of contents is 14 octets
PRINT_NAS_ERROR("Length of Authentication Failure Parameter contents is too large");
PRINT_ERROR("Length of Authentication Failure Parameter contents is too large");
return -1;
}
msg->authentication_failure_param.buf = malloc_or_fail(msg->authentication_failure_param.len);
@@ -90,7 +91,7 @@ int decode_fgmm_auth_failure(fgmm_auth_failure_t *msg, const byte_array_t *buffe
bool eq_fgmm_auth_failure(const fgmm_auth_failure_t *a, const fgmm_auth_failure_t *b)
{
_NAS_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_INT(a->cause, b->cause);
eq_byte_array(&a->authentication_failure_param, &b->authentication_failure_param);
return true;
}
@@ -24,6 +24,7 @@
#include <arpa/inet.h> // For htons and ntohs
#include <stdlib.h> // For malloc and free
#include "fgmm_lib.h"
#include "common/utils/eq_check.h"
#define MIN_AUTH_REJECT_LEN 3
@@ -55,13 +56,13 @@ int decode_fgmm_auth_reject(fgmm_auth_reject_msg_t *msg, const byte_array_t *buf
if (iei == IEI_EAPMSG) {
return (decoded + decode_eap_msg_ie(&msg->eap_msg, &ba));
}
PRINT_NAS_ERROR("Expected EAP MSG but it is not present");
PRINT_ERROR("Expected EAP MSG but it is not present");
return -1;
}
bool eq_auth_reject(fgmm_auth_reject_msg_t *a, fgmm_auth_reject_msg_t *b)
{
_NAS_EQ_CHECK_LONG(a->eap_msg.len, b->eap_msg.len);
_EQ_CHECK_LONG(a->eap_msg.len, b->eap_msg.len);
if (a->eap_msg.len > 0) {
return !memcmp(a->eap_msg.buf, b->eap_msg.buf, a->eap_msg.len);
}
@@ -22,11 +22,12 @@
#include "fgmm_identity_request.h"
#include <string.h>
#include "FGSMobileIdentity.h"
#include "common/utils/eq_check.h"
int decode_fgs_identity_request(fgs_identity_request_msg_t *msg, const byte_array_t *buffer)
{
if (buffer->len < 1) {
PRINT_NAS_ERROR("Failed to decode NAS Identity Request: invalid buffer length %ld\n", buffer->len);
PRINT_ERROR("Failed to decode NAS Identity Request: invalid buffer length %ld\n", buffer->len);
return -1;
}
+12 -11
View File
@@ -24,6 +24,7 @@
#include <arpa/inet.h> // For htons and ntohs
#include <stdlib.h> // For malloc and free
#include "common/utils/ds/byte_array.h"
#include "common/utils/eq_check.h"
#define IEI_LEN 1
#define GPRS_TIMER_LENGTH 3 // octets
@@ -41,7 +42,7 @@
int encode_pdu_session_ie(byte_array_t *buffer, nas_service_IEI_t iei, const uint8_t *psi)
{
if (buffer->len < MIN_PDU_SESSION_CONTENTS_LEN + 2) {
PRINT_NAS_ERROR("%s failed: buffer is too small", __func__);
PRINT_ERROR("%s failed: buffer is too small", __func__);
return -1;
}
@@ -83,14 +84,14 @@ int decode_pdu_session_ie(uint8_t *psi, const byte_array_t *buffer)
uint8_t *buf = buffer->buf;
if (buffer->len < MIN_PDU_SESSION_CONTENTS_LEN + 2) {
PRINT_NAS_ERROR("%s failed: buffer length is too small", __func__);
PRINT_ERROR("%s failed: buffer length is too small", __func__);
return -1;
}
// start decoding from length IE (IEI is decoded in the caller)
uint8_t pdu_session_status_len = buf[decoded++];
if (pdu_session_status_len > MAX_PDU_SESSION_CONTENTS_LEN) {
PRINT_NAS_ERROR("decoded length is out of bound for PDU Session Status/Reactivation result\n");
PRINT_ERROR("decoded length is out of bound for PDU Session Status/Reactivation result\n");
return -1;
}
@@ -116,7 +117,7 @@ int decode_pdu_session_ie(uint8_t *psi, const byte_array_t *buffer)
int encode_gprs_timer_ie(byte_array_t *buffer, nas_service_IEI_t iei, const gprs_timer_t *timer)
{
if (buffer->len < GPRS_TIMER_LENGTH) {
PRINT_NAS_ERROR("Buffer length is too short to encode the GPRS Timer IE\n");
PRINT_ERROR("Buffer length is too short to encode the GPRS Timer IE\n");
return -1;
}
@@ -150,8 +151,8 @@ int decode_gprs_timer_ie(gprs_timer_t *timer, const byte_array_t *buffer)
/** @brief Equality check for GPRS Timer */
bool eq_gprs_timer(const gprs_timer_t *a, const gprs_timer_t *b)
{
_NAS_EQ_CHECK_INT(a->value, b->value);
_NAS_EQ_CHECK_INT(a->unit, b->unit);
_EQ_CHECK_INT(a->value, b->value);
_EQ_CHECK_INT(a->unit, b->unit);
return true;
}
@@ -162,13 +163,13 @@ int encode_eap_msg_ie(byte_array_t *buffer, const byte_array_t *msg)
// Sanity check on buffer length
if (buffer->len < MIN_EAP_MSG_LEN) {
PRINT_NAS_ERROR("Invalid buffer length %ld", buffer->len);
PRINT_ERROR("Invalid buffer length %ld", buffer->len);
return -1;
}
// Sanity check on input length
if (msg->len < MIN_EAP_CONTENTS_LEN || msg->len > MAX_EAP_CONTENTS_LEN) {
PRINT_NAS_ERROR("Invalid EAP message length %ld", msg->len);
PRINT_ERROR("Invalid EAP message length %ld", msg->len);
return -1;
}
@@ -196,7 +197,7 @@ int decode_eap_msg_ie(byte_array_t *eap_msg, const byte_array_t *buffer)
// Check buffer length validity
if (buffer->len < min_len_to_decode) {
PRINT_NAS_ERROR("Invalid buffer for decoding EAP message IE");
PRINT_ERROR("Invalid buffer for decoding EAP message IE");
return -1;
}
@@ -206,13 +207,13 @@ int decode_eap_msg_ie(byte_array_t *eap_msg, const byte_array_t *buffer)
// Check payload length validity
if (eap_msg->len < MIN_EAP_CONTENTS_LEN || eap_msg->len > MAX_EAP_CONTENTS_LEN) {
PRINT_NAS_ERROR("Invalid EAP message length %ld", eap_msg->len);
PRINT_ERROR("Invalid EAP message length %ld", eap_msg->len);
return -1;
}
// Check for buffer overflow
if (buffer->len < decoded + eap_msg->len) {
PRINT_NAS_ERROR("Buffer too short for EAP message: %ld < %ld", buffer->len, decoded + eap_msg->len);
PRINT_ERROR("Buffer too short for EAP message: %ld < %ld", buffer->len, decoded + eap_msg->len);
return -1;
}
@@ -25,6 +25,7 @@
#include <stdlib.h> // For malloc and free
#include "common/utils/utils.h" // For malloc_or_fail
#include "common/utils/ds/byte_array.h" // For byte_array_t
#include "common/utils/eq_check.h"
#include "fgmm_lib.h"
/** @brief Encode Service Accept (8.2.17 of 3GPP TS 24.501) */
@@ -53,7 +54,7 @@ int encode_fgs_service_accept(byte_array_t *buffer, const fgs_service_accept_msg
// encode length of PDU session reactivation result error cause
uint16_t error_len = msg->num_errors * sizeof(msg->cause[0]);
if (error_len > MAX_NUM_PDU_ERRORS) {
PRINT_NAS_ERROR("encoded length is out of bound (IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE)\n");
PRINT_ERROR("encoded length is out of bound (IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE)\n");
return -1;
}
uint16_t n_len = htons(error_len);
@@ -115,7 +116,7 @@ int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t
uint16_t error_len = ntohs(tmp);
decoded += sizeof(error_len);
if (error_len > MAX_NUM_PDU_ERRORS * sizeof(msg->cause[0])) {
PRINT_NAS_ERROR("IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE: decoded length is out of bound\n");
PRINT_ERROR("IEI_PDU_SESSION_REACT_RESULT_ERROR_CAUSE: decoded length is out of bound\n");
return -1;
}
// Decode each PDU Session ID and Cause
@@ -137,7 +138,7 @@ int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t
break;
default:
PRINT_NAS_ERROR("Unkwown or invalid IEI %d\n", iei);
PRINT_ERROR("Unkwown or invalid IEI %d\n", iei);
return -1;
}
}
@@ -150,26 +151,26 @@ int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t
*/
bool eq_service_accept(const fgs_service_accept_msg_t *a, const fgs_service_accept_msg_t *b)
{
_NAS_EQ_CHECK_INT(a->has_psi_status, b->has_psi_status);
_EQ_CHECK_INT(a->has_psi_status, b->has_psi_status);
if (a->has_psi_status && b->has_psi_status) {
for (int i = 0; i < MAX_NUM_PSI; i++)
_NAS_EQ_CHECK_INT(a->psi_status[i], b->psi_status[i]);
_EQ_CHECK_INT(a->psi_status[i], b->psi_status[i]);
}
_NAS_EQ_CHECK_INT(a->has_psi_res, b->has_psi_res);
_EQ_CHECK_INT(a->has_psi_res, b->has_psi_res);
if (a->has_psi_res && b->has_psi_res) {
for (int i = 0; i < MAX_NUM_PSI; i++)
_NAS_EQ_CHECK_INT(a->psi_res[i], b->psi_res[i]);
_EQ_CHECK_INT(a->psi_res[i], b->psi_res[i]);
}
_NAS_EQ_CHECK_INT(a->num_errors, b->num_errors);
_EQ_CHECK_INT(a->num_errors, b->num_errors);
if (a->num_errors && b->num_errors) {
for (int i = 0; i < a->num_errors; i++) {
_NAS_EQ_CHECK_INT(a->cause[i].cause, b->cause[i].cause);
_NAS_EQ_CHECK_INT(a->cause[i].pdu_session_id, b->cause[i].pdu_session_id);
_EQ_CHECK_INT(a->cause[i].cause, b->cause[i].cause);
_EQ_CHECK_INT(a->cause[i].pdu_session_id, b->cause[i].pdu_session_id);
}
}
if (a->t3448 != NULL || b->t3448 != NULL) {
if (a->t3448 == NULL || b->t3448 == NULL) {
PRINT_NAS_ERROR("t3448 equality check failed\n");
PRINT_ERROR("t3448 equality check failed\n");
return false;
}
if (!eq_gprs_timer(a->t3448, b->t3448))
@@ -25,6 +25,7 @@
#include <stdlib.h> // For malloc and free
#include "common/utils/ds/byte_array.h"
#include "common/utils/utils.h"
#include "common/utils/eq_check.h"
#include "fgmm_lib.h"
#define SERVICE_REJECT_MIN_LEN 1 // 1 octet
@@ -33,7 +34,7 @@
int encode_fgs_service_reject(byte_array_t *buffer, const fgs_service_reject_msg_t *msg)
{
if (buffer->len < SERVICE_REJECT_MIN_LEN) {
PRINT_NAS_ERROR("Failed to encode Service Reject: missing Cause IE!\n");
PRINT_ERROR("Failed to encode Service Reject: missing Cause IE!\n");
return -1;
}
@@ -71,7 +72,7 @@ int encode_fgs_service_reject(byte_array_t *buffer, const fgs_service_reject_msg
int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t *buffer)
{
if (buffer->len < SERVICE_REJECT_MIN_LEN) {
PRINT_NAS_ERROR("Nothing to decode: missing Cause IE!\n");
PRINT_ERROR("Nothing to decode: missing Cause IE!\n");
return -1;
}
@@ -112,11 +113,11 @@ int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t
int cag_len = cag_list_len + 2; // encoded content + 2 octets for the length IE
decoded += cag_len;
UPDATE_BYTE_ARRAY(ba, cag_len);
PRINT_NAS_ERROR("CAG information list IE in NAS Service Reject is not handled\n");
PRINT_ERROR("CAG information list IE in NAS Service Reject is not handled\n");
} break;
default:
PRINT_NAS_ERROR("Uknown or invalid NAS Service Reject IEI %d\n", iei);
PRINT_ERROR("Uknown or invalid NAS Service Reject IEI %d\n", iei);
return -1;
}
}
@@ -127,15 +128,15 @@ int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t
/** @brief Equality check for Service Reject (enc/dec) */
bool eq_service_reject(const fgs_service_reject_msg_t *a, const fgs_service_reject_msg_t *b)
{
_NAS_EQ_CHECK_INT(a->cause, b->cause);
_NAS_EQ_CHECK_INT(a->has_psi_status, b->has_psi_status);
_EQ_CHECK_INT(a->cause, b->cause);
_EQ_CHECK_INT(a->has_psi_status, b->has_psi_status);
if (a->has_psi_status && b->has_psi_status) {
for (int i = 0; i < MAX_NUM_PSI; i++)
_NAS_EQ_CHECK_INT(a->psi_status[i], b->psi_status[i]);
_EQ_CHECK_INT(a->psi_status[i], b->psi_status[i]);
}
if (a->t3448 != NULL || b->t3448 != NULL) {
if (a->t3448 == NULL || b->t3448 == NULL) {
PRINT_NAS_ERROR("t3448 equality check failed\n");
PRINT_ERROR("t3448 equality check failed\n");
return false;
}
if (!eq_gprs_timer(a->t3448, b->t3448))
@@ -143,7 +144,7 @@ bool eq_service_reject(const fgs_service_reject_msg_t *a, const fgs_service_reje
}
if (a->t3446 != NULL || b->t3446 != NULL) {
if (a->t3446 == NULL || b->t3446 == NULL) {
PRINT_NAS_ERROR("t3448 equality check failed\n");
PRINT_ERROR("t3448 equality check failed\n");
return false;
}
if (!eq_gprs_timer(a->t3446, b->t3446))
@@ -205,7 +205,7 @@ int decode_pdu_session_establishment_accept_msg(pdu_session_establishment_accept
}
default:
PRINT_NAS_ERROR("Unknown IEI %d\n", psea_iei);
PRINT_ERROR("Unknown IEI %d\n", psea_iei);
curPtr = buffer + msg_length; // we force stop processing
break;
}
+7
View File
@@ -3,6 +3,9 @@ add_subdirectory(5GMM/IES)
add_subdirectory(5GSM/MSG)
if(ENABLE_TESTS)
target_compile_definitions(fgs_5gmm_lib PRIVATE ENABLE_TESTS)
target_compile_definitions(fgs_5gmm_ies_lib PRIVATE ENABLE_TESTS)
target_compile_definitions(fgs_5gsm_lib PRIVATE ENABLE_TESTS)
add_subdirectory(tests)
endif()
add_library(fgs_lib fgs_nas_lib.c)
@@ -16,3 +19,7 @@ target_link_libraries(fgs_lib PUBLIC
)
target_include_directories(fgs_lib PUBLIC . 5GMM/MSG 5GMM/IES)
if(ENABLE_TESTS)
target_compile_definitions(fgs_lib PRIVATE ENABLE_TESTS)
endif()
+7 -6
View File
@@ -22,6 +22,7 @@
#include "NR_NAS_defs.h"
#include "nas_log.h"
#include "TLVEncoder.h"
#include "common/utils/eq_check.h"
#include "fgs_nas_utils.h"
int _nas_mm_msg_encode_header(const fgmm_msg_header_t *header, uint8_t *buffer, uint32_t len)
@@ -56,7 +57,7 @@ int mm_msg_encode(const fgmm_nas_message_plain_t *p, uint8_t *buffer, uint32_t l
int enc_header = _nas_mm_msg_encode_header(&p->header, buffer, len);
if (enc_header < 0) {
PRINT_NAS_ERROR("Failed to encode 5GMM message header\n");
PRINT_ERROR("Failed to encode 5GMM message header\n");
return enc_header;
}
@@ -104,7 +105,7 @@ int mm_msg_encode(const fgmm_nas_message_plain_t *p, uint8_t *buffer, uint32_t l
}
if (enc_msg < 0) {
PRINT_NAS_ERROR("Failed to encode 5GMM message\n");
PRINT_ERROR("Failed to encode 5GMM message\n");
return enc_msg;
}
@@ -116,7 +117,7 @@ int nas_protected_security_header_encode(uint8_t *buffer, const fgs_nas_message_
int size = 0;
if (length < sizeof(fgs_nas_message_security_header_t)) {
PRINT_NAS_ERROR("Could not encode the NAS security header\n");
PRINT_ERROR("Could not encode the NAS security header\n");
return -1;
}
@@ -140,7 +141,7 @@ int nas_protected_security_header_encode(uint8_t *buffer, const fgs_nas_message_
uint8_t decode_5gmm_msg_header(fgmm_msg_header_t *mm_header, const uint8_t *buffer, uint32_t len)
{
if (len < sizeof(fgmm_msg_header_t)) {
PRINT_NAS_ERROR("Failed to decode plain 5GMM header: buffer length too short\n");
PRINT_ERROR("Failed to decode plain 5GMM header: buffer length too short\n");
return -1;
}
mm_header->ex_protocol_discriminator = *buffer++;
@@ -155,7 +156,7 @@ uint8_t decode_5gmm_msg_header(fgmm_msg_header_t *mm_header, const uint8_t *buff
uint8_t decode_5gsm_msg_header(fgsm_msg_header_t *sm_header, const uint8_t *buffer, uint32_t len)
{
if (len < sizeof(fgsm_msg_header_t)) {
PRINT_NAS_ERROR("Failed to decode plain 5GSM header: buffer length too short\n");
PRINT_ERROR("Failed to decode plain 5GSM header: buffer length too short\n");
return -1;
}
sm_header->ex_protocol_discriminator = *buffer++;
@@ -172,7 +173,7 @@ int decode_5gs_security_protected_header(fgs_nas_message_security_header_t *head
{
int decoded = 0;
if (len < sizeof(fgs_nas_message_security_header_t)) {
PRINT_NAS_ERROR("Failed to decode security protected 5GS header: buffer length too short\n");
PRINT_ERROR("Failed to decode security protected 5GS header: buffer length too short\n");
return -1;
}
header->protocol_discriminator = *buf++;
+2 -18
View File
@@ -26,24 +26,8 @@
#include <arpa/inet.h>
#include <string.h> // For memcpy
#include <stdio.h>
#define PRINT_NAS_ERROR(...) fprintf(stderr, ##__VA_ARGS__)
#define _NAS_EQ_CHECK_GENERIC(condition, fmt, ...) \
do { \
if (!(condition)) { \
PRINT_NAS_ERROR("NAS Equality Check failure: %s:%d: Condition '%s' failed: " fmt " != " fmt "\n", \
__FILE__, \
__LINE__, \
#condition, \
##__VA_ARGS__); \
return false; \
} \
} while (0)
#define _NAS_EQ_CHECK_LONG(A, B) _NAS_EQ_CHECK_GENERIC(A == B, "%ld", A, B);
#define _NAS_EQ_CHECK_INT(A, B) _NAS_EQ_CHECK_GENERIC(A == B, "%d", A, B);
#define _NAS_EQ_CHECK_STR(A, B) _NAS_EQ_CHECK_GENERIC(strcmp(A, B) == 0, "'%s'", A, B);
#include "utils.h" // text_info_t, TO_ENUM, TO_TEXT
#include "common/utils/eq_check.h"
/* Map task id to printable name. */
typedef struct {