From cab15b0b76602f5565f125b15da90ef27a149ca3 Mon Sep 17 00:00:00 2001 From: Kamil Zulewski <kamil.zulewski@iopsys.eu> Date: Mon, 2 Jan 2023 14:59:37 +0000 Subject: [PATCH] Enhanced error handling for map_cmdu_parse_tlvs and cmdu_parse_tlvs --- src/cmdu.c | 9 ++++++--- src/cmdu.h | 1 + src/extensions/map/map_module.h | 30 ++++++++++++++++++++++++++++++ src/extensions/map/maputil.c | 32 ++++++++++++++++++++++++++++++++ src/extensions/map/policy.c | 31 +++++++++++++++++++++++++------ 5 files changed, 94 insertions(+), 9 deletions(-) diff --git a/src/cmdu.c b/src/cmdu.c index fa5aa37b..4c17be26 100644 --- a/src/cmdu.c +++ b/src/cmdu.c @@ -182,7 +182,7 @@ int *ieee1905_get_errval(void) #define ieee1905_set_error(v) (ieee1905_errval = (v)) static const char *ieee1905_errlist[IEEE1905_ERROR_MAXNUM] = { - "Ok", + [CMDU_STATUS_OK] = "Ok", [CMDU_STATUS_ERR_TLV_MALFORMED] = "TLV is malformed", [CMDU_STATUS_ERR_TLV_NUM_LESS] = "Number of TLVs less than required", [CMDU_STATUS_ERR_TLV_NUM_MORE] = "Number of TLVs more than required", @@ -190,6 +190,7 @@ static const char *ieee1905_errlist[IEEE1905_ERROR_MAXNUM] = { [CMDU_STATUS_ERR_TLV_RESIDUE_DATA] = "Stray non-zero bytes after EOM", [CMDU_STATUS_ERR_TLV_LEN_INSUFFICIENT] = "TLV length insufficient", [CMDU_STATUS_ERR_TLV_LEN_OVERFLOW] = "TLV length points to beyond CMDU", + [CMDU_STATUS_ERR_CMDU_MALFORMED] = "CMDU input structure malformed", [CMDU_STATUS_ERR_MISC] = "Misc cmdu error", }; @@ -197,7 +198,7 @@ const char *ieee1905_strerror(int err) { int last_err = err; - if (last_err >= 0 && last_err <= IEEE1905_ERROR_LAST) + if (last_err >= 0 && last_err <= IEEE1905_ERROR_LAST && ieee1905_errlist[last_err]) return ieee1905_errlist[last_err]; return ""; @@ -723,8 +724,10 @@ int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[][16], ieee1905_set_error(CMDU_STATUS_OK); - if (!c || !c->data || !c->datalen) + if (!c || !c->data || !c->datalen) { + ieee1905_set_error(CMDU_STATUS_ERR_CMDU_MALFORMED); return -1; + } for (i = 0; i < policy_len; i++) { memset(tv[i], 0, 16 * sizeof(struct tlv *)); diff --git a/src/cmdu.h b/src/cmdu.h index 6c34fa3a..34c17191 100644 --- a/src/cmdu.h +++ b/src/cmdu.h @@ -258,6 +258,7 @@ enum CMDU_STATUS { CMDU_STATUS_ERR_TLV_RESIDUE_DATA, CMDU_STATUS_ERR_TLV_LEN_INSUFFICIENT, CMDU_STATUS_ERR_TLV_LEN_OVERFLOW, + CMDU_STATUS_ERR_CMDU_MALFORMED, CMDU_STATUS_ERR_MISC, IEEE1905_ERROR_MAXNUM, diff --git a/src/extensions/map/map_module.h b/src/extensions/map/map_module.h index 5cf46bdc..cc0a4b30 100644 --- a/src/extensions/map/map_module.h +++ b/src/extensions/map/map_module.h @@ -10,6 +10,7 @@ #ifndef MAP_MODULE_H #define MAP_MODULE_H +#include <cmdu.h> typedef uint32_t mapmodule_object_t; typedef uint8_t mapmodule_cmdu_mask_t[16]; @@ -40,6 +41,35 @@ int map_subscribe(void *bus, void *publisher, int map_unsubscribe(void *bus, void *subscriber); +enum MAP_STATUS { + /* Existing ieee1905 error codes start at 0 offset */ + MAP_STATUS_OK = CMDU_STATUS_OK, + MAP_STATUS_ERR_TLV_MALFORMED = CMDU_STATUS_ERR_TLV_MALFORMED, + MAP_STATUS_ERR_TLV_NUM_LESS = CMDU_STATUS_ERR_TLV_NUM_LESS, + MAP_STATUS_ERR_TLV_NUM_MORE = CMDU_STATUS_ERR_TLV_NUM_MORE, + MAP_STATUS_ERR_TLV_NO_EOM = CMDU_STATUS_ERR_TLV_NO_EOM, + MAP_STATUS_ERR_TLV_RESIDUE_DATA = CMDU_STATUS_ERR_TLV_RESIDUE_DATA, + MAP_STATUS_ERR_TLV_LEN_INSUFFICIENT = CMDU_STATUS_ERR_TLV_LEN_INSUFFICIENT, + MAP_STATUS_ERR_TLV_LEN_OVERFLOW = CMDU_STATUS_ERR_TLV_LEN_OVERFLOW, + MAP_STATUS_ERR_CMDU_MALFORMED = CMDU_STATUS_ERR_CMDU_MALFORMED, + MAP_STATUS_ERR_MISC = CMDU_STATUS_ERR_MISC, + + /* MAP plugin specific error codes start at 10000 offset */ + MAP_STATUS_ERR_FIRST = 10000, + + MAP_STATUS_ERR_CMDU_TYPE_NOT_SUPPORTED = MAP_STATUS_ERR_FIRST, + MAP_STATUS_ERR_MAP_PROFILE_NOT_SUPPORTED, + MAP_STATUS_ERR_MAP_POLICY_NOT_FOUND, + MAP_STATUS_ERR_TLVS_OUTPUT_ARRAY_INSUFFICIENT, + + MAP_STATUS_ERR_AFTER_LAST +}; + +int *map_get_errval(void); +#define map_error (*map_get_errval()) + +const char *map_strerror(int err); + int map_cmdu_parse_tlvs(struct cmdu_buff *cmdu, struct tlv *tv[][16], int num_tvi, int revision); #endif /* MAP_MODULE_H */ diff --git a/src/extensions/map/maputil.c b/src/extensions/map/maputil.c index 7f612f28..9528380f 100644 --- a/src/extensions/map/maputil.c +++ b/src/extensions/map/maputil.c @@ -25,6 +25,38 @@ #include "easymesh.h" #include "map_module.h" +static __thread int map_errval; + +int *map_get_errval(void) +{ + return &map_errval; +} + +static const char *map_status_to_string(enum MAP_STATUS err) +{ + switch (err) { + case MAP_STATUS_ERR_CMDU_TYPE_NOT_SUPPORTED: + return "MAP: CMDU type not supported"; + case MAP_STATUS_ERR_MAP_PROFILE_NOT_SUPPORTED: + return "MAP: Multi-AP Profile not supported"; + case MAP_STATUS_ERR_MAP_POLICY_NOT_FOUND: + return "MAP: Policy required to parse CMDU not found"; + case MAP_STATUS_ERR_TLVS_OUTPUT_ARRAY_INSUFFICIENT: + return "MAP: TLVs output array insufficient"; + + default: + return "MAP: error description not provided"; + } +} + +const char *map_strerror(int err) +{ + if (err >= MAP_STATUS_ERR_FIRST && err < MAP_STATUS_ERR_AFTER_LAST) + return map_status_to_string(err); + + return ieee1905_strerror(err); +} + #define cmdu_mask_setbit(m, f) \ do { \ if (f >= 0x8000) \ diff --git a/src/extensions/map/policy.c b/src/extensions/map/policy.c index 40373b6a..0ce80516 100644 --- a/src/extensions/map/policy.c +++ b/src/extensions/map/policy.c @@ -40,9 +40,12 @@ int map_cmdu_parse_tlvs(struct cmdu_buff *cmdu, struct tlv *tv[][16], int num_tv int idx = 0; int i; + map_error = MAP_STATUS_OK; - if (!cmdu) + if (!cmdu || !cmdu->cdata) { + map_error = MAP_STATUS_ERR_CMDU_MALFORMED; return -1; + } type = cmdu_get_type(cmdu); @@ -50,36 +53,47 @@ int map_cmdu_parse_tlvs(struct cmdu_buff *cmdu, struct tlv *tv[][16], int num_tv idx = type; } else if (type >= CMDU_TYPE_MAP_START && type <= CMDU_TYPE_MAP_END) { idx = type - CMDU_TYPE_MAP_START + CMDU_TYPE_1905_END + 1; - } else + } else { + map_error = MAP_STATUS_ERR_CMDU_TYPE_NOT_SUPPORTED; return -1; + } switch (revision) { case 2: - if (idx > ARRAY_SIZE(easymesh_policy_r2)) + if (idx > ARRAY_SIZE(easymesh_policy_r2)) { + map_error = MAP_STATUS_ERR_MAP_POLICY_NOT_FOUND; return -1; + } pol = &easymesh_policy_r2[idx]; break; #if (EASYMESH_VERSION > 2) case 4: - if (idx > ARRAY_SIZE(easymesh_policy_r4)) + if (idx > ARRAY_SIZE(easymesh_policy_r4)) { + map_error = MAP_STATUS_ERR_MAP_POLICY_NOT_FOUND; return -1; + } pol = &easymesh_policy_r4[idx]; break; #endif default: + + map_error = MAP_STATUS_ERR_MAP_PROFILE_NOT_SUPPORTED; return -1; } - if (pol->pol == NULL) + if (pol->pol == NULL) { + map_error = MAP_STATUS_ERR_MAP_POLICY_NOT_FOUND; return -1; + } if (pol->num == 0) return 0; if (num_tv < pol->num) { fprintf(stderr, "%s: minimum %zu tv needed!\n", __func__, pol->num); + map_error = MAP_STATUS_ERR_TLVS_OUTPUT_ARRAY_INSUFFICIENT; return -1; } @@ -87,5 +101,10 @@ int map_cmdu_parse_tlvs(struct cmdu_buff *cmdu, struct tlv *tv[][16], int num_tv for (i = 0; i < num_tv; i++) memset(tv[i], 0, 16 * sizeof(struct tlv *)); - return cmdu_parse_tlvs(cmdu, tv, pol->pol, pol->num); + if (cmdu_parse_tlvs(cmdu, tv, pol->pol, pol->num)) { + map_error = ieee1905_error; + return -1; + } + + return 0; } -- GitLab