From c7410cb2a4ed50dbdc1dc1ae90592b057862918b Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Fri, 17 Jul 2020 16:38:32 -0400 Subject: [PATCH] Refactor patty_ax25_frame_decode_xid() Refactor patty_ax25_frame_decode_xid() to support the remote possibility of multiple ISO 8885 groups --- include/patty/ax25/frame.h | 55 ++++++++++++++++++-------- src/frame.c | 81 ++++++++++++++++++++++++++++---------- 2 files changed, 99 insertions(+), 37 deletions(-) diff --git a/include/patty/ax25/frame.h b/include/patty/ax25/frame.h index 98b05c3..d7b07b8 100644 --- a/include/patty/ax25/frame.h +++ b/include/patty/ax25/frame.h @@ -79,21 +79,13 @@ typedef struct _patty_ax25_frame { size_t infolen; } patty_ax25_frame; -#pragma pack(push) -#pragma pack(1) +enum patty_ax25_frame_xid_group_format { + PATTY_AX25_FRAME_XID_GROUP_ISO8885 = 0x82 +}; -typedef struct _patty_ax25_frame_xid_element { - uint8_t format, - group; - - uint16_t len; -} patty_ax25_frame_xid_element; - -typedef struct _patty_ax25_frame_xid_param { - uint8_t id, len; -} patty_ax25_frame_xid_param; - -#pragma pack(pop) +enum patty_ax25_frame_xid_group_type { + PATTY_AX25_FRAME_XID_GROUP_PARAMS = 0x80 +}; enum patty_ax25_frame_xid_param_type { PATTY_AX25_FRAME_XID_PARAM_CLASS = 2, @@ -105,9 +97,40 @@ enum patty_ax25_frame_xid_param_type { PATTY_AX25_FRAME_XID_PARAM_ACK = 9 }; +enum patty_ax25_frame_xid_param_class_flags { + PATTY_AX25_FRAME_XID_PARAM_CLASS_ABM = (1 << 1), + PATTY_AX25_FRAME_XID_PARAM_CLASS_HALF_DUPLEX = (1 << 6), + PATTY_AX25_FRAME_XID_PARAM_CLASS_FULL_DUPLEX = (1 << 7) +}; + +enum patty_ax25_frame_xid_param_hdlc_flags { + PATTY_AX25_FRAME_XID_PARAM_HDLC_REJ = (1 << 1), + PATTY_AX25_FRAME_XID_PARAM_HDLC_SREJ = (1 << 2), + PATTY_AX25_FRAME_XID_PARAM_HDLC_XADDR = (1 << 8), + PATTY_AX25_FRAME_XID_PARAM_HDLC_MODULO_8 = (1 << 11), + PATTY_AX25_FRAME_XID_PARAM_HDLC_MODULO_128 = (1 << 12), + PATTY_AX25_FRAME_XID_PARAM_HDLC_TEST = (1 << 14), + PATTY_AX25_FRAME_XID_PARAM_HDLC_SYNC_TX = (1 << 18) +}; + +#pragma pack(push) +#pragma pack(1) + +typedef struct _patty_ax25_frame_xid_group { + uint8_t format, + type; + + uint16_t len; +} patty_ax25_frame_xid_group; + +typedef struct _patty_ax25_frame_xid_param { + uint8_t id, len; +} patty_ax25_frame_xid_param; + +#pragma pack(pop) + typedef int (*patty_ax25_frame_xid_callback)(enum patty_ax25_frame_xid_param_type type, - size_t len, - uint8_t *data, + uint32_t value, void *ctx); ssize_t patty_ax25_frame_decode_address(patty_ax25_frame *frame, diff --git a/src/frame.c b/src/frame.c index 089e900..0ef698c 100644 --- a/src/frame.c +++ b/src/frame.c @@ -271,37 +271,45 @@ error: return -1; } -ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback, - void *data, - size_t offset, - size_t len, - void *ctx) { - size_t start = offset; - - patty_ax25_frame_xid_element *elem = (patty_ax25_frame_xid_element *) +ssize_t decode_xid_group(patty_ax25_frame_xid_callback callback, + void *data, + size_t offset, + size_t len, + void *ctx) { + patty_ax25_frame_xid_group *group = (patty_ax25_frame_xid_group *) ((uint8_t *)data + offset); - if (elem->format != 0x82 || elem->group != 0x80) { - errno = EIO; + size_t grouplen, + start = offset; + if (len - offset < sizeof(*group)) { goto error; } - if (be16toh(elem->len) != len - sizeof(*elem) - offset) { - errno = EIO; + grouplen = be16toh(group->len); - goto error; + offset += sizeof(*group); + + if (group->format != PATTY_AX25_FRAME_XID_GROUP_ISO8885 + || group->type != PATTY_AX25_FRAME_XID_GROUP_PARAMS) { + offset += grouplen; + + goto done; } - offset += sizeof(*elem); - - while (offset < len) { + while (offset - start < sizeof(*group) + grouplen) { patty_ax25_frame_xid_param *param = (patty_ax25_frame_xid_param *) ((uint8_t *)data + offset); + uint32_t value = 0; + size_t i; + + for (i=0; ilen; i++) { + value |= ((uint8_t *)(param + 1))[param->len-1-i] << (i << 3); + } + if (callback(param->id, - (size_t)param->len, - (uint8_t *)(param + 1), + value, ctx) < 0) { goto error_callback; } @@ -309,9 +317,38 @@ ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback, offset += sizeof(*param) + param->len; } - if (offset != len) { - errno = EIO; + if (offset != start + sizeof(*group) + grouplen) { + goto error; + } +done: + return offset - start; + +error: + errno = EIO; + +error_callback: + return -1; +} + +ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback, + void *data, + size_t offset, + size_t len, + void *ctx) { + size_t start = offset; + + while (offset < len) { + ssize_t decoded; + + if ((decoded = decode_xid_group(callback, data, offset, len, ctx)) < 0) { + goto error_decode_xid_group; + } else { + offset += decoded; + } + } + + if (offset != len) { goto error; } @@ -319,8 +356,10 @@ ssize_t patty_ax25_frame_decode_xid(patty_ax25_frame_xid_callback callback, return offset - start; -error_callback: error: + errno = EIO; + +error_decode_xid_group: return -1; }