pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/43386?usp=email )
Change subject: xua: Validate IE lengths of incoming messages ......................................................................
xua: Validate IE lengths of incoming messages
Change-Id: I9b1ae0dbc324123790942c9e6068f6822e3bb957 --- M src/m3ua.c M src/sua.c M src/xua_msg.c M src/xua_msg.h 4 files changed, 398 insertions(+), 107 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/libosmo-sigtran refs/changes/86/43386/1
diff --git a/src/m3ua.c b/src/m3ua.c index b29cfcf..fa26707 100644 --- a/src/m3ua.c +++ b/src/m3ua.c @@ -146,11 +146,71 @@ { 0, NULL } };
-#define MAND_IES(msgt, ies) [msgt] = (ies) +#define IES(msgt, ies) \ + [msgt] = (ies) + +/* M3UA/SUA shared: */ + +#define M3UA_MSG_PART_CLASS_INFO_STRING(mandatory) \ + XUA_MSG_PART_CLASS(M3UA_IEI_ROUTE_CTX, (mandatory), 0, UINT16_MAX) + +#define M3UA_MSG_PART_CLASS_ROUTE_CTX(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_ROUTE_CTX, (mandatory)) + +#define M3UA_MSG_PART_CLASS_ROUTE_CTX1(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_ROUTE_CTX, (mandatory)) + +#define M3UA_MSG_PART_CLASS_DIAG_INFO(mandatory) \ + XUA_MSG_PART_CLASS(M3UA_IEI_DIAG_INFO, (mandatory), 0, UINT16_MAX) + +#define M3UA_MSG_PART_CLASS_ERR_CODE(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_ERR_CODE, (mandatory)) + +#define M3UA_MSG_PART_CLASS_STATUS(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_STATUS, (mandatory)) + +#define M3UA_MSG_PART_CLASS_ASP_ID(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_ASP_ID, (mandatory)) + +#define M3UA_MSG_PART_CLASS_AFFECTED_PC(mandatory) \ + XUA_MSG_PART_CLASS(M3UA_IEI_AFFECTED_PC, (mandatory), 0, UINT16_MAX) + +#define M3UA_MSG_PART_CLASS_CORR_ID(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_CORR_ID, (mandatory)) + +/* M3UA specific: */ + +#define M3UA_MSG_PART_CLASS_NET_APPEAR(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_NET_APPEAR, (mandatory)) + +#define M3UA_MSG_PART_CLASS_USER_CAUSE(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_USER_CAUSE, (mandatory)) + +#define M3UA_MSG_PART_CLASS_CONG_IND(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_CONG_IND, (mandatory)) + +#define M3UA_MSG_PART_CLASS_CONC_DEST(mandatory) \ + XUA_MSG_PART_CLASS_U32(M3UA_IEI_CONC_DEST, (mandatory)) + +#define M3UA_MSG_PART_CLASS_ROUT_KEY(mandatory) \ + XUA_MSG_PART_CLASS(M3UA_IEI_ROUT_KEY, (mandatory), 0, UINT16_MAX) + +#define M3UA_MSG_PART_CLASS_REG_RESULT(mandatory) \ + XUA_MSG_PART_CLASS(M3UA_IEI_REG_RESULT, (mandatory), 0, UINT16_MAX) + +#define M3UA_MSG_PART_CLASS_DEREG_RESULT(mandatory) \ + XUA_MSG_PART_CLASS(M3UA_IEI_DEREG_RESULT, (mandatory), 0, UINT16_MAX) + +#define M3UA_MSG_PART_CLASS_PROT_DATA(mandatory) \ + XUA_MSG_PART_CLASS(M3UA_IEI_PROT_DATA, (mandatory), 0, UINT16_MAX)
/* XFER */ -static const uint16_t data_mand_ies[] = { - M3UA_IEI_PROT_DATA, 0 +static const struct xua_msg_part_class data_ies[] = { + M3UA_MSG_PART_CLASS_NET_APPEAR(false), + M3UA_MSG_PART_CLASS_ROUTE_CTX1(false), + M3UA_MSG_PART_CLASS_PROT_DATA(true), + M3UA_MSG_PART_CLASS_CORR_ID(false), + XUA_MSG_PART_CLASS_EOF }; static const struct value_string m3ua_xfer_msgt_names[] = { { M3UA_XFER_DATA, "DATA" }, @@ -159,29 +219,56 @@ static const struct xua_msg_class msg_class_xfer = { .name = "XFER", .msgt_names = m3ua_xfer_msgt_names, - .mand_ies = { - MAND_IES(M3UA_XFER_DATA, data_mand_ies), + .ies = { + IES(M3UA_XFER_DATA, data_ies), }, };
/* SNM */ -static const uint16_t duna_mand_ies[] = { - M3UA_IEI_AFFECTED_PC, 0 +static const struct xua_msg_part_class duna_ies[] = { + M3UA_MSG_PART_CLASS_NET_APPEAR(false), + M3UA_MSG_PART_CLASS_ROUTE_CTX(false), + M3UA_MSG_PART_CLASS_AFFECTED_PC(true), + M3UA_MSG_PART_CLASS_INFO_STRING(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t dava_mand_ies[] = { - M3UA_IEI_AFFECTED_PC, 0 +static const struct xua_msg_part_class dava_ies[] = { + M3UA_MSG_PART_CLASS_NET_APPEAR(false), + M3UA_MSG_PART_CLASS_ROUTE_CTX(false), + M3UA_MSG_PART_CLASS_AFFECTED_PC(true), + M3UA_MSG_PART_CLASS_INFO_STRING(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t daud_mand_ies[] = { - M3UA_IEI_AFFECTED_PC, 0 +static const struct xua_msg_part_class daud_ies[] = { + M3UA_MSG_PART_CLASS_NET_APPEAR(false), + M3UA_MSG_PART_CLASS_ROUTE_CTX(false), + M3UA_MSG_PART_CLASS_AFFECTED_PC(true), + M3UA_MSG_PART_CLASS_INFO_STRING(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t scon_mand_ies[] = { - M3UA_IEI_AFFECTED_PC, 0 +static const struct xua_msg_part_class scon_ies[] = { + M3UA_MSG_PART_CLASS_NET_APPEAR(false), + M3UA_MSG_PART_CLASS_ROUTE_CTX(false), + M3UA_MSG_PART_CLASS_AFFECTED_PC(true), + M3UA_MSG_PART_CLASS_CONC_DEST(false), + M3UA_MSG_PART_CLASS_CONG_IND(false), + M3UA_MSG_PART_CLASS_INFO_STRING(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t dupu_mand_ies[] = { - M3UA_IEI_AFFECTED_PC, M3UA_IEI_USER_CAUSE, 0 +static const struct xua_msg_part_class dupu_ies[] = { + M3UA_MSG_PART_CLASS_NET_APPEAR(false), + M3UA_MSG_PART_CLASS_ROUTE_CTX(false), + M3UA_MSG_PART_CLASS_AFFECTED_PC(true), + M3UA_MSG_PART_CLASS_USER_CAUSE(true), + M3UA_MSG_PART_CLASS_INFO_STRING(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t drst_mand_ies[] = { - M3UA_IEI_AFFECTED_PC, 0 +static const struct xua_msg_part_class drst_ies[] = { + M3UA_MSG_PART_CLASS_NET_APPEAR(false), + M3UA_MSG_PART_CLASS_ROUTE_CTX(false), + M3UA_MSG_PART_CLASS_AFFECTED_PC(true), + M3UA_MSG_PART_CLASS_INFO_STRING(false), + XUA_MSG_PART_CLASS_EOF }; const struct value_string m3ua_snm_msgt_names[] = { { M3UA_SNM_DUNA, "DUNA" }, @@ -195,13 +282,13 @@ const struct xua_msg_class m3ua_msg_class_snm = { .name = "SNM", .msgt_names = m3ua_snm_msgt_names, - .mand_ies = { - MAND_IES(M3UA_SNM_DUNA, duna_mand_ies), - MAND_IES(M3UA_SNM_DAVA, dava_mand_ies), - MAND_IES(M3UA_SNM_DAUD, daud_mand_ies), - MAND_IES(M3UA_SNM_SCON, scon_mand_ies), - MAND_IES(M3UA_SNM_DUPU, dupu_mand_ies), - MAND_IES(M3UA_SNM_DRST, drst_mand_ies), + .ies = { + IES(M3UA_SNM_DUNA, duna_ies), + IES(M3UA_SNM_DAVA, dava_ies), + IES(M3UA_SNM_DAUD, daud_ies), + IES(M3UA_SNM_SCON, scon_ies), + IES(M3UA_SNM_DUPU, dupu_ies), + IES(M3UA_SNM_DRST, drst_ies), }, };
@@ -235,11 +322,20 @@ };
/* MGMT */ -static const uint16_t err_req_ies[] = { - M3UA_IEI_ERR_CODE, 0 +static const struct xua_msg_part_class err_req_ies[] = { + M3UA_MSG_PART_CLASS_ERR_CODE(true), + M3UA_MSG_PART_CLASS_ROUTE_CTX(false), + M3UA_MSG_PART_CLASS_NET_APPEAR(false), + M3UA_MSG_PART_CLASS_AFFECTED_PC(false), + M3UA_MSG_PART_CLASS_DIAG_INFO(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t ntfy_req_ies[] = { - M3UA_IEI_STATUS, 0 +static const struct xua_msg_part_class ntfy_req_ies[] = { + M3UA_MSG_PART_CLASS_STATUS(true), + M3UA_MSG_PART_CLASS_ASP_ID(false), + M3UA_MSG_PART_CLASS_ROUTE_CTX(false), + M3UA_MSG_PART_CLASS_INFO_STRING(false), + XUA_MSG_PART_CLASS_EOF }; static const struct value_string m3ua_mgmt_msgt_names[] = { { M3UA_MGMT_ERR, "ERROR" }, @@ -250,24 +346,28 @@ .name = "MGMT", .msgt_names = m3ua_mgmt_msgt_names, .iei_names = m3ua_iei_names, - .mand_ies = { - MAND_IES(M3UA_MGMT_ERR, err_req_ies), - MAND_IES(M3UA_MGMT_NTFY, ntfy_req_ies), + .ies = { + IES(M3UA_MGMT_ERR, err_req_ies), + IES(M3UA_MGMT_NTFY, ntfy_req_ies), }, };
/* RKM */ -static const uint16_t reg_req_ies[] = { - M3UA_IEI_ROUT_KEY, 0 +static const struct xua_msg_part_class reg_req_ies[] = { + M3UA_MSG_PART_CLASS_ROUT_KEY(true), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t reg_rsp_ies[] = { - M3UA_IEI_REG_RESULT, 0 +static const struct xua_msg_part_class reg_rsp_ies[] = { + M3UA_MSG_PART_CLASS_REG_RESULT(true), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t dereg_req_ies[] = { - M3UA_IEI_ROUTE_CTX, 0 +static const struct xua_msg_part_class dereg_req_ies[] = { + M3UA_MSG_PART_CLASS_ROUTE_CTX(true), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t dereg_rsp_ies[] = { - M3UA_IEI_DEREG_RESULT, 0 +static const struct xua_msg_part_class dereg_rsp_ies[] = { + M3UA_MSG_PART_CLASS_DEREG_RESULT(true), + XUA_MSG_PART_CLASS_EOF }; const struct value_string m3ua_rkm_msgt_names[] = { { M3UA_RKM_REG_REQ, "REG-REQ" }, @@ -280,11 +380,11 @@ .name = "RKM", .msgt_names = m3ua_rkm_msgt_names, .iei_names = m3ua_iei_names, - .mand_ies = { - MAND_IES(M3UA_RKM_REG_REQ, reg_req_ies), - MAND_IES(M3UA_RKM_REG_RSP, reg_rsp_ies), - MAND_IES(M3UA_RKM_DEREG_REQ, dereg_req_ies), - MAND_IES(M3UA_RKM_DEREG_RSP, dereg_rsp_ies), + .ies = { + IES(M3UA_RKM_REG_REQ, reg_req_ies), + IES(M3UA_RKM_REG_RSP, reg_rsp_ies), + IES(M3UA_RKM_DEREG_REQ, dereg_req_ies), + IES(M3UA_RKM_DEREG_RSP, dereg_rsp_ies), }, };
@@ -612,7 +712,7 @@ struct m3ua_data_hdr *dh; uint32_t pc;
- /* As already checked by xua_dialect_check_all_mand_ies(): */ + /* As already checked by xua_dialect_check_all_ies(): */ OSMO_ASSERT(data_ie);
if (data_ie->len < sizeof(struct m3ua_data_hdr)) { @@ -894,7 +994,7 @@ LOGPASP(asp, DLM3UA, LOGL_DEBUG, "Received M3UA Message (%s)\n", xua_hdr_dump(xua, &xua_dialect_m3ua));
- if (!xua_dialect_check_all_mand_ies(&xua_dialect_m3ua, xua)) { + if (!xua_dialect_check_all_ies(&xua_dialect_m3ua, xua)) { rc = M3UA_ERR_MISSING_PARAM; xua_msg_free(xua); goto out; diff --git a/src/sua.c b/src/sua.c index 7c6d57f..53ca3b8 100644 --- a/src/sua.c +++ b/src/sua.c @@ -121,15 +121,111 @@ { 0, NULL } };
-#define MAND_IES(msgt, ies) [msgt] = (ies) +#define IES(msgt, ies) \ + [msgt] = (ies)
-static const uint16_t cldt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, SUA_IEI_DATA, 0 +/* M3UA/SUA shared: */ + +#define SUA_MSG_PART_CLASS_INFO_STRING(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_ROUTE_CTX, (mandatory), 0, UINT16_MAX) + +#define SUA_MSG_PART_CLASS_ROUTE_CTX(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_ROUTE_CTX, (mandatory)) + +#define SUA_MSG_PART_CLASS_ROUTE_CTX1(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_ROUTE_CTX, (mandatory)) + +#define SUA_MSG_PART_CLASS_DIAG_INFO(mandatory) \ + XUA_MSG_PART_CLASS(SUA_IEI_DIAG_INFO, (mandatory), 0, UINT16_MAX) + +#define SUA_MSG_PART_CLASS_ERR_CODE(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_ERR_CODE, (mandatory)) + +#define SUA_MSG_PART_CLASS_STATUS(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_STATUS, (mandatory)) + +#define SUA_MSG_PART_CLASS_ASP_ID(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_ASP_ID, (mandatory)) + +#define SUA_MSG_PART_CLASS_AFFECTED_PC(mandatory) \ + XUA_MSG_PART_CLASS(SUA_IEI_AFFECTED_PC, (mandatory), 0, UINT16_MAX) + +#define SUA_MSG_PART_CLASS_CORR_ID(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_CORR_ID, (mandatory)) + +/* SUA specific: */ + +#define SUA_MSG_PART_CLASS_HOP_CTR(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_S7_HOP_CTR, (mandatory)) + +#define SUA_MSG_PART_CLASS_SRC_ADDR(mandatory) \ + XUA_MSG_PART_CLASS(SUA_IEI_SRC_ADDR, (mandatory), 0, UINT16_MAX) + +#define SUA_MSG_PART_CLASS_DEST_ADDR(mandatory) \ + XUA_MSG_PART_CLASS(SUA_IEI_DEST_ADDR, (mandatory), 0, UINT16_MAX) + +#define SUA_MSG_PART_CLASS_SEQ_CTRL(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_SEQ_CTRL, (mandatory)) + +#define SUA_MSG_PART_CLASS_SEQ_NR(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_SEQ_NR, (mandatory)) + +#define SUA_MSG_PART_CLASS_RX_SEQ_NR(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_RX_SEQ_NR, (mandatory)) + +#define SUA_MSG_PART_CLASS_CREDIT(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_CREDIT, (mandatory)) + +#define SUA_MSG_PART_CLASS_SRC_REF(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_SRC_REF, (mandatory)) + +#define SUA_MSG_PART_CLASS_DEST_REF(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_DEST_REF, (mandatory)) + +#define SUA_MSG_PART_CLASS_CAUSE(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_CAUSE, (mandatory)) + +#define SUA_MSG_PART_CLASS_DATA(mandatory) \ + XUA_MSG_PART_CLASS(SUA_IEI_DATA, (mandatory), 0, UINT16_MAX) + +#define SUA_MSG_PART_CLASS_IMPORTANCE(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_IMPORTANCE, (mandatory)) + +#define SUA_MSG_PART_CLASS_MSG_PRIO(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_MSG_PRIO, (mandatory)) + +#define SUA_MSG_PART_CLASS_PROTO_CLASS(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_PROTO_CLASS, (mandatory)) + +#define SUA_MSG_PART_CLASS_SEGMENTATION(mandatory) \ + XUA_MSG_PART_CLASS_U32(SUA_IEI_SEGMENTATION, (mandatory)) + +static const struct xua_msg_part_class cldt_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_PROTO_CLASS(true), + SUA_MSG_PART_CLASS_SRC_ADDR(true), + SUA_MSG_PART_CLASS_DEST_ADDR(true), + SUA_MSG_PART_CLASS_SEQ_CTRL(true), + SUA_MSG_PART_CLASS_HOP_CTR(false), + SUA_MSG_PART_CLASS_IMPORTANCE(false), + SUA_MSG_PART_CLASS_MSG_PRIO(false), + SUA_MSG_PART_CLASS_CORR_ID(false), + SUA_MSG_PART_CLASS_SEGMENTATION(false), + SUA_MSG_PART_CLASS_DATA(true), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t cldr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_CAUSE, SUA_IEI_SRC_ADDR, - SUA_IEI_DEST_ADDR, 0 +static const struct xua_msg_part_class cldr_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_CAUSE(true), + SUA_MSG_PART_CLASS_SRC_ADDR(true), + SUA_MSG_PART_CLASS_DEST_ADDR(true), + SUA_MSG_PART_CLASS_HOP_CTR(false), + SUA_MSG_PART_CLASS_IMPORTANCE(false), + SUA_MSG_PART_CLASS_MSG_PRIO(false), + SUA_MSG_PART_CLASS_CORR_ID(false), + SUA_MSG_PART_CLASS_SEGMENTATION(false), + SUA_MSG_PART_CLASS_DATA(false), + XUA_MSG_PART_CLASS_EOF }; static const struct value_string sua_cl_msgt_names[] = { { SUA_CL_CLDT, "CLDT" }, @@ -140,49 +236,110 @@ .name = "CL", .msgt_names = sua_cl_msgt_names, .iei_names = sua_iei_names, - .mand_ies = { - MAND_IES(SUA_CL_CLDT, cldt_mand_ies), - MAND_IES(SUA_CL_CLDR, cldr_mand_ies), + .ies = { + IES(SUA_CL_CLDT, cldt_ies), + IES(SUA_CL_CLDR, cldr_ies), }, };
-static const uint16_t codt_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_DATA, 0 +static const struct xua_msg_part_class codt_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_SEQ_NR(false), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_MSG_PRIO(false), + SUA_MSG_PART_CLASS_CORR_ID(false), + SUA_MSG_PART_CLASS_DATA(true), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t coda_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, 0 +static const struct xua_msg_part_class coda_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_RX_SEQ_NR(false), + SUA_MSG_PART_CLASS_RX_SEQ_NR(false), + SUA_MSG_PART_CLASS_CREDIT(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t core_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_ADDR, SUA_IEI_SEQ_CTRL, 0 +static const struct xua_msg_part_class core_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_PROTO_CLASS(true), + SUA_MSG_PART_CLASS_SRC_REF(true), + SUA_MSG_PART_CLASS_SEQ_CTRL(true), + SUA_MSG_PART_CLASS_SEQ_NR(false), + SUA_MSG_PART_CLASS_SRC_ADDR(false), + SUA_MSG_PART_CLASS_HOP_CTR(false), + SUA_MSG_PART_CLASS_IMPORTANCE(false), + SUA_MSG_PART_CLASS_MSG_PRIO(false), + SUA_MSG_PART_CLASS_CREDIT(false), + SUA_MSG_PART_CLASS_DATA(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t coak_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_DEST_REF, - SUA_IEI_SRC_REF, SUA_IEI_SEQ_CTRL, 0 +static const struct xua_msg_part_class coak_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_PROTO_CLASS(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_SRC_REF(true), + SUA_MSG_PART_CLASS_SEQ_CTRL(true), + SUA_MSG_PART_CLASS_CREDIT(false), + SUA_MSG_PART_CLASS_SRC_ADDR(false), + SUA_MSG_PART_CLASS_IMPORTANCE(false), + SUA_MSG_PART_CLASS_MSG_PRIO(false), + SUA_MSG_PART_CLASS_DEST_ADDR(false), + SUA_MSG_PART_CLASS_DATA(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t coref_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +static const struct xua_msg_part_class coref_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_CAUSE(true), + SUA_MSG_PART_CLASS_SRC_ADDR(false), + SUA_MSG_PART_CLASS_DEST_ADDR(false), + SUA_MSG_PART_CLASS_IMPORTANCE(false), + SUA_MSG_PART_CLASS_DATA(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t relre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 +static const struct xua_msg_part_class relre_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_SRC_REF(true), + SUA_MSG_PART_CLASS_CAUSE(true), + SUA_MSG_PART_CLASS_IMPORTANCE(false), + SUA_MSG_PART_CLASS_DATA(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t relco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +static const struct xua_msg_part_class relco_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_SRC_REF(true), + SUA_MSG_PART_CLASS_IMPORTANCE(false), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t resre_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, - SUA_IEI_CAUSE, 0 +static const struct xua_msg_part_class resre_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_SRC_REF(true), + SUA_MSG_PART_CLASS_CAUSE(true), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t resco_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_SRC_REF, 0 +static const struct xua_msg_part_class resco_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_SRC_REF(true), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t coerr_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_DEST_REF, SUA_IEI_CAUSE, 0 +static const struct xua_msg_part_class coerr_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_CAUSE(true), + XUA_MSG_PART_CLASS_EOF }; -static const uint16_t coit_mand_ies[] = { - SUA_IEI_ROUTE_CTX, SUA_IEI_PROTO_CLASS, SUA_IEI_SRC_REF, - SUA_IEI_DEST_REF, 0 +static const struct xua_msg_part_class coit_ies[] = { + SUA_MSG_PART_CLASS_ROUTE_CTX(true), + SUA_MSG_PART_CLASS_PROTO_CLASS(true), + SUA_MSG_PART_CLASS_SRC_REF(true), + SUA_MSG_PART_CLASS_DEST_REF(true), + SUA_MSG_PART_CLASS_SEQ_NR(false), + SUA_MSG_PART_CLASS_CREDIT(false), + XUA_MSG_PART_CLASS_EOF };
/* ITU-T Rec Q.713 */ @@ -204,18 +361,18 @@ .name = "CO", .msgt_names = sua_co_msgt_names, .iei_names = sua_iei_names, - .mand_ies = { - MAND_IES(SUA_CO_CODT, codt_mand_ies), - MAND_IES(SUA_CO_CODA, coda_mand_ies), - MAND_IES(SUA_CO_CORE, core_mand_ies), - MAND_IES(SUA_CO_COAK, coak_mand_ies), - MAND_IES(SUA_CO_COREF, coref_mand_ies), - MAND_IES(SUA_CO_RELRE, relre_mand_ies), - MAND_IES(SUA_CO_RELCO, relco_mand_ies), - MAND_IES(SUA_CO_RESRE, resre_mand_ies), - MAND_IES(SUA_CO_RESCO, resco_mand_ies), - MAND_IES(SUA_CO_COERR, coerr_mand_ies), - MAND_IES(SUA_CO_COIT, coit_mand_ies), + .ies = { + IES(SUA_CO_CODT, codt_ies), + IES(SUA_CO_CODA, coda_ies), + IES(SUA_CO_CORE, core_ies), + IES(SUA_CO_COAK, coak_ies), + IES(SUA_CO_COREF, coref_ies), + IES(SUA_CO_RELRE, relre_ies), + IES(SUA_CO_RELCO, relco_ies), + IES(SUA_CO_RESRE, resre_ies), + IES(SUA_CO_RESCO, resco_ies), + IES(SUA_CO_COERR, coerr_ies), + IES(SUA_CO_COIT, coit_ies), }, };
@@ -780,7 +937,7 @@ LOGPASP(asp, DLSUA, LOGL_DEBUG, "Received SUA Message (%s)\n", xua_hdr_dump(xua, &xua_dialect_sua));
- if (!xua_dialect_check_all_mand_ies(&xua_dialect_sua, xua)) { + if (!xua_dialect_check_all_ies(&xua_dialect_sua, xua)) { /* FIXME: Return error? */ err = sua_gen_error_msg(SUA_ERR_MISSING_PARAM, msg); goto out; diff --git a/src/xua_msg.c b/src/xua_msg.c index 1761fee..690f0a6 100644 --- a/src/xua_msg.c +++ b/src/xua_msg.c @@ -32,6 +32,7 @@
#include <string.h> #include <errno.h> +#include <inttypes.h>
static void *tall_xua = NULL;
@@ -534,31 +535,44 @@ return buf; }
-int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua) +int xua_dialect_check_all_ies(const struct xua_dialect *dialect, struct xua_msg *xua) { uint8_t msg_class = xua->hdr.msg_class; uint8_t msg_type = xua->hdr.msg_type; const struct xua_msg_class *xmc = dialect->class[msg_class]; - const uint16_t *ies; - uint16_t ie; + const struct xua_msg_part_class *ies; + const struct xua_msg_part_class *ie;
/* unknown class? */ if (!xmc) return 1;
- ies = xmc->mand_ies[msg_type]; + ies = &xmc->ies[msg_type][0]; /* no mandatory IEs? */ if (!ies) return 1;
- for (ie = *ies; ie; ie = *ies++) { - if (!xua_msg_find_tag(xua, ie)) { + for (ie = ies; ie->tag; ie = ies++) { + struct xua_msg_part *part = xua_msg_find_tag(xua, ie->tag); + if (!part) { + if (!ie->mandatory) + continue; LOGP(dialect->log_subsys, LOGL_ERROR, - "%s Message %s:%s should " - "contain IE %s, but doesn't\n", + "%s Message %s:%s should contain IE %s, but doesn't\n", dialect->name, xmc->name, xua_class_msg_name(xmc, msg_type), - xua_class_iei_name(xmc, ie)); + xua_class_iei_name(xmc, ie->tag)); + return 0; + } + + if (part->len < ie->len_min || part->len > ie->len_max) { + LOGP(dialect->log_subsys, LOGL_ERROR, + "%s Message %s:%s IE %s length %" PRIu16 + " out of range [%" PRIu16 ", %" PRIu16 "]\n", + dialect->name, xmc->name, + xua_class_msg_name(xmc, msg_type), + xua_class_iei_name(xmc, ie->tag), + part->len, ie->len_min, ie->len_max); return 0; } } diff --git a/src/xua_msg.h b/src/xua_msg.h index f5d5de4..39249e2 100644 --- a/src/xua_msg.h +++ b/src/xua_msg.h @@ -21,6 +21,7 @@
#include <osmocom/core/linuxlist.h> #include <osmocom/sigtran/mtp_sap.h> +#include <stdint.h>
#define XUA_HDR(class, type) ((struct xua_common_hdr) { .spare = 0, .msg_class = (class), .msg_type = (type) })
@@ -46,11 +47,30 @@ /* TODO: keep small data in the struct for perf reasons */ };
+struct xua_msg_part_class { + uint16_t tag; + bool mandatory; + uint16_t len_min; + uint16_t len_max; +}; +#define XUA_MSG_PART_CLASS(tag_, mandatory_, min_len, max_len) \ + { .tag = (tag_), \ + .mandatory = (mandatory_), \ + .len_min = (min_len), \ + .len_max = (max_len) \ + } +#define XUA_MSG_PART_CLASS_FIXED(tag, mandatory, len) \ + XUA_MSG_PART_CLASS((tag), (mandatory), (len), (len)) +#define XUA_MSG_PART_CLASS_U32(tag, mandatory) \ + XUA_MSG_PART_CLASS_FIXED((tag), (mandatory), sizeof(uint32_t)) +#define XUA_MSG_PART_CLASS_EOF \ + XUA_MSG_PART_CLASS(0, false, 0, 0) + struct xua_msg_class { const char *name; const struct value_string *msgt_names; const struct value_string *iei_names; - const uint16_t *mand_ies[256]; + const struct xua_msg_part_class *ies[256]; };
struct xua_dialect { @@ -105,7 +125,7 @@ const char *xua_class_iei_name(const struct xua_msg_class *xmc, uint16_t iei); char *xua_hdr_dump(const struct xua_msg *xua, const struct xua_dialect *dialect); char *xua_msg_dump(const struct xua_msg *xua, const struct xua_dialect *dialect); -int xua_dialect_check_all_mand_ies(const struct xua_dialect *dialect, struct xua_msg *xua); +int xua_dialect_check_all_ies(const struct xua_dialect *dialect, struct xua_msg *xua);
int xua_msg_event_map(const struct xua_msg *xua, const struct xua_msg_event_map *maps,