Add enc/dec function for EAP Message

Also, add EAP message (optional) enc-dec to Service Reject lib
This commit is contained in:
Guido Casati
2025-04-10 17:21:37 +02:00
parent 8c0641c676
commit 5445b12c32
6 changed files with 83 additions and 8 deletions

View File

@@ -25,8 +25,12 @@
#include <stdlib.h> // For malloc and free
#include "common/utils/ds/byte_array.h"
#define IEI_LEN 1
#define GPRS_TIMER_LENGTH 3 // octets
#define FGS_NAS_CAUSE_LENGTH 1
#define MIN_EAP_MSG_LEN 7
#define MIN_EAP_CONTENTS_LEN 4
#define MAX_EAP_CONTENTS_LEN 1500
/**
* Encode PDU Session Status and PDU session reactivation result (optional IEs)
@@ -152,12 +156,72 @@ bool eq_gprs_timer(const gprs_timer_t *a, const gprs_timer_t *b)
return true;
}
/* Decode EAP Message (todo) */
int decode_eap_msg_ie(const byte_array_t *buffer)
/** @brief Encode EAP message IE (3GPP TS 24.501 9.11.2.2) */
int encode_eap_msg_ie(byte_array_t *buffer, const byte_array_t *msg)
{
int eap_msg_len = (buffer->buf[0] << 8) | buffer->buf[1];
PRINT_NAS_ERROR("EAP message IE in NAS Service Reject is not handled\n");
return eap_msg_len + 2; // content length + 2 octets for the length IE
int encoded = 0;
// Sanity check on buffer length
if (buffer->len < MIN_EAP_MSG_LEN) {
PRINT_NAS_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);
return -1;
}
// Encode IEI
buffer->buf[encoded++] = IEI_EAPMSG;
// Encode length of EAP message content
uint16_t len = htons(msg->len);
memcpy(&buffer->buf[encoded], &len, sizeof(len));
encoded += sizeof(len);
// Encode EAP message content
memcpy(&buffer->buf[encoded], msg->buf, msg->len);
encoded += msg->len;
return encoded;
}
/** @brief Decode EAP message IE (3GPP TS 24.501 9.11.2.2):
length of contents and message payload */
int decode_eap_msg_ie(byte_array_t *eap_msg, const byte_array_t *buffer)
{
int decoded = 0;
int min_len_to_decode = MIN_EAP_MSG_LEN - IEI_LEN;
// Check buffer length validity
if (buffer->len < min_len_to_decode) {
PRINT_NAS_ERROR("Invalid buffer for decoding EAP message IE");
return -1;
}
// Decode length IE
eap_msg->len = (buffer->buf[decoded] << 8) | buffer->buf[decoded + 1];
decoded += 2;
// 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);
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);
return -1;
}
// Copy EAP payload
memcpy(eap_msg->buf, &buffer->buf[decoded], eap_msg->len);
decoded += eap_msg->len;
return decoded;
}
int encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause)

View File

@@ -164,7 +164,8 @@ 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);
int decode_gprs_timer_ie(gprs_timer_t *timer, const byte_array_t *buffer);
bool eq_gprs_timer(const gprs_timer_t *a, const gprs_timer_t *b);
int decode_eap_msg_ie(const byte_array_t *buffer);
int decode_eap_msg_ie(byte_array_t *eap_msg, const byte_array_t *buffer);
int encode_eap_msg_ie(byte_array_t *buffer, const byte_array_t *msg);
int encode_fgs_nas_cause(byte_array_t *buffer, const cause_id_t *cause);
int decode_fgs_nas_cause(cause_id_t *cause, const byte_array_t *buffer);

View File

@@ -133,7 +133,7 @@ int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t
break;
case IEI_EAPMSG:
DECODE_NAS_IE(ba, decode_eap_msg_ie(&ba), decoded);
DECODE_NAS_IE(ba, decode_eap_msg_ie(&msg->eap_msg, &ba), decoded);
break;
default:

View File

@@ -47,6 +47,9 @@ typedef struct {
// T3448 Value (Optional)
gprs_timer_t *t3448;
// EAP Message (Optional)
byte_array_t eap_msg;
} fgs_service_accept_msg_t;
int decode_fgs_service_accept(fgs_service_accept_msg_t *msg, const byte_array_t *buffer);

View File

@@ -59,6 +59,11 @@ int encode_fgs_service_reject(byte_array_t *buffer, const fgs_service_reject_msg
ENCODE_NAS_IE(ba, encode_gprs_timer_ie(&ba, IEI_T3448_VALUE, msg->t3448), encoded);
}
// EAP message (Optional)
if (msg->eap_msg) {
ENCODE_NAS_IE(ba, encode_eap_msg_ie(&ba, msg->eap_msg), encoded);
}
return encoded;
}
@@ -99,7 +104,7 @@ int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t
break;
case IEI_EAPMSG:
DECODE_NAS_IE(ba, decode_eap_msg_ie((const byte_array_t *)&ba), decoded);
DECODE_NAS_IE(ba, decode_eap_msg_ie(msg->eap_msg, &ba), decoded);
break;
case IEI_CAG_INFO_LIST: {

View File

@@ -35,6 +35,8 @@ typedef struct {
bool has_psi_status;
// T3448 Value (Optional)
gprs_timer_t *t3448;
// EAP message (optional)
byte_array_t *eap_msg;
} fgs_service_reject_msg_t;
int decode_fgs_service_reject(fgs_service_reject_msg_t *msg, const byte_array_t *buffer);