* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/* \summary: Message Transfer Part 3 (MTP3) User Adaptation Layer (M3UA) printer */
+
+/* RFC 4666 */
+
#ifdef HAVE_CONFIG_H
-#include "config.h"
+#include <config.h>
#endif
-#include <tcpdump-stdinc.h>
+#include "netdissect-stdinc.h"
-#include "interface.h"
+#define ND_LONGJMP_FROM_TCHECK
+#include "netdissect.h"
#include "extract.h"
-static const char tstr[] = " [|m3ua]";
-static const char cstr[] = " (corrupt)";
-
-/* RFC 4666 */
#define M3UA_REL_1_0 1
struct m3ua_common_header {
- uint8_t v;
- uint8_t reserved;
- uint8_t msg_class;
- uint8_t msg_type;
- uint32_t len;
+ nd_uint8_t v;
+ nd_uint8_t reserved;
+ nd_uint8_t msg_class;
+ nd_uint8_t msg_type;
+ nd_uint32_t len;
};
struct m3ua_param_header {
- uint16_t tag;
- uint16_t len;
+ nd_uint16_t tag;
+ nd_uint16_t len;
};
/* message classes */
{ M3UA_MSGC_SSNM, "SS7" },
{ M3UA_MSGC_ASPSM, "ASP" },
{ M3UA_MSGC_ASPTM, "ASP" },
- { M3UA_MSGC_RKM, "Routing Key Managment" },
+ { M3UA_MSGC_RKM, "Routing Key Management"},
{ 0, NULL }
};
{ 0, NULL }
};
+static const struct uint_tokary m3ua_msgc2tokary[] = {
+ { M3UA_MSGC_MGMT, MgmtMessages },
+ { M3UA_MSGC_TRANSFER, TransferMessages },
+ { M3UA_MSGC_SSNM, SS7Messages },
+ { M3UA_MSGC_ASPSM, ASPStateMessages },
+ { M3UA_MSGC_ASPTM, ASPTrafficMessages },
+ { M3UA_MSGC_RKM, RoutingKeyMgmtMessages },
+ /* uint2tokary() does not use array termination. */
+};
+
/* M3UA Parameters */
#define M3UA_PARAM_INFO 0x0004
#define M3UA_PARAM_ROUTING_CTX 0x0006
case M3UA_PARAM_CORR_ID:
/* buf and size don't include the header */
if (size < 4)
- goto corrupt;
- ND_TCHECK2(*buf, size);
- ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(buf)));
+ goto invalid;
+ ND_PRINT("0x%08x", GET_BE_U_4(buf));
break;
/* ... */
default:
- ND_PRINT((ndo, "(length %u)", size + (u_int)sizeof(struct m3ua_param_header)));
- ND_TCHECK2(*buf, size);
+ ND_PRINT("(length %u)", size + (u_int)sizeof(struct m3ua_param_header));
}
+ ND_TCHECK_LEN(buf, size);
return;
-corrupt:
- ND_PRINT((ndo, "%s", cstr));
- ND_TCHECK2(*buf, size);
- return;
-trunc:
- ND_PRINT((ndo, "%s", tstr));
+invalid:
+ nd_print_invalid(ndo);
+ ND_TCHECK_LEN(buf, size);
}
/*
while (p < buf + size) {
if (p + sizeof(struct m3ua_param_header) > buf + size)
- goto corrupt;
- ND_TCHECK2(*p, sizeof(struct m3ua_param_header));
+ goto invalid;
/* Parameter Tag */
- hdr_tag = EXTRACT_16BITS(p);
- ND_PRINT((ndo, "\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag)));
+ hdr_tag = GET_BE_U_2(p);
+ ND_PRINT("\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", hdr_tag));
/* Parameter Length */
- hdr_len = EXTRACT_16BITS(p + 2);
+ hdr_len = GET_BE_U_2(p + 2);
if (hdr_len < sizeof(struct m3ua_param_header))
- goto corrupt;
+ goto invalid;
/* Parameter Value */
align = (p + hdr_len - buf) % 4;
align = align ? 4 - align : 0;
- ND_TCHECK2(*p, hdr_len + align);
+ ND_TCHECK_LEN(p, hdr_len + align);
tag_value_print(ndo, p, hdr_tag, hdr_len - sizeof(struct m3ua_param_header));
p += hdr_len + align;
}
return;
-corrupt:
- ND_PRINT((ndo, "%s", cstr));
- ND_TCHECK2(*buf, size);
- return;
-trunc:
- ND_PRINT((ndo, "%s", tstr));
+invalid:
+ nd_print_invalid(ndo);
+ ND_TCHECK_LEN(buf, size);
}
/*
{
const struct m3ua_common_header *hdr = (const struct m3ua_common_header *) buf;
const struct tok *dict;
+ uint8_t msg_class;
+ ndo->ndo_protocol = "m3ua";
/* size includes the header */
if (size < sizeof(struct m3ua_common_header))
- goto corrupt;
- ND_TCHECK(*hdr);
- if (hdr->v != M3UA_REL_1_0)
+ goto invalid;
+ ND_TCHECK_SIZE(hdr);
+ if (GET_U_1(hdr->v) != M3UA_REL_1_0)
return;
- dict =
- hdr->msg_class == M3UA_MSGC_MGMT ? MgmtMessages :
- hdr->msg_class == M3UA_MSGC_TRANSFER ? TransferMessages :
- hdr->msg_class == M3UA_MSGC_SSNM ? SS7Messages :
- hdr->msg_class == M3UA_MSGC_ASPSM ? ASPStateMessages :
- hdr->msg_class == M3UA_MSGC_ASPTM ? ASPTrafficMessages :
- hdr->msg_class == M3UA_MSGC_RKM ? RoutingKeyMgmtMessages :
- NULL;
+ msg_class = GET_U_1(hdr->msg_class);
+ dict = uint2tokary(m3ua_msgc2tokary, msg_class);
- ND_PRINT((ndo, "\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", hdr->msg_class)));
+ ND_PRINT("\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", msg_class));
if (dict != NULL)
- ND_PRINT((ndo, " %s Message", tok2str(dict, "Unknown (0x%02x)", hdr->msg_type)));
+ ND_PRINT(" %s Message",
+ tok2str(dict, "Unknown (0x%02x)", GET_U_1(hdr->msg_type)));
- if (size != EXTRACT_32BITS(&hdr->len))
- ND_PRINT((ndo, "\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@", EXTRACT_32BITS(&hdr->len)));
+ if (size != GET_BE_U_4(hdr->len))
+ ND_PRINT("\n\t\t\t@@@@@@ Corrupted length %u of message @@@@@@",
+ GET_BE_U_4(hdr->len));
else
- m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header), EXTRACT_32BITS(&hdr->len) - sizeof(struct m3ua_common_header));
+ m3ua_tags_print(ndo, buf + sizeof(struct m3ua_common_header),
+ GET_BE_U_4(hdr->len) - sizeof(struct m3ua_common_header));
return;
-corrupt:
- ND_PRINT((ndo, "%s", cstr));
- ND_TCHECK2(*buf, size);
- return;
-trunc:
- ND_PRINT((ndo, "%s", tstr));
+invalid:
+ nd_print_invalid(ndo);
+ ND_TCHECK_LEN(buf, size);
}