]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-m3ua.c
CI: Add warning exemptions for Sun C (suncc-5.15) on Solaris 10
[tcpdump] / print-m3ua.c
index ba851699618d25e6c91768d1c90ff98718d9888f..403a417b0202f7a628f883de8a1e2441b1ddc689 100644 (file)
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#define NETDISSECT_REWORKED
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+/* \summary: Message Transfer Part 3 (MTP3) User Adaptation Layer (M3UA) printer */
 
-#include <tcpdump-stdinc.h>
+/* RFC 4666 */
+
+#include <config.h>
 
-#include "interface.h"
+#include "netdissect-stdinc.h"
+
+#define ND_LONGJMP_FROM_TCHECK
+#include "netdissect.h"
 #include "extract.h"
 
-/* RFC 4666 */
+
+#define M3UA_REL_1_0 1
 
 struct m3ua_common_header {
-  u_int8_t  v;
-  u_int8_t  reserved;
-  u_int8_t  msg_class;
-  u_int8_t  msg_type;
-  u_int32_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 {
-  u_int16_t tag;
-  u_int16_t len;
+  nd_uint16_t tag;
+  nd_uint16_t len;
 };
 
 /* message classes */
@@ -62,7 +65,7 @@ static const struct tok MessageClasses[] = {
        { 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 }
 };
 
@@ -148,6 +151,16 @@ static const struct tok RoutingKeyMgmtMessages[] = {
   { 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
@@ -205,57 +218,118 @@ static const struct tok ParamName[] = {
 
 static void
 tag_value_print(netdissect_options *ndo,
-                const u_char *buf, const u_int16_t tag, const u_int16_t size)
+                const u_char *buf, const uint16_t tag, const uint16_t size)
 {
   switch (tag) {
   case M3UA_PARAM_NETWORK_APPEARANCE:
   case M3UA_PARAM_ROUTING_CTX:
   case M3UA_PARAM_CORR_ID:
-    ND_PRINT((ndo, "0x%08x", EXTRACT_32BITS(buf)));
+    /* buf and size don't include the header */
+    if (size < 4)
+      goto invalid;
+    ND_PRINT("0x%08x", GET_BE_U_4(buf));
     break;
   /* ... */
   default:
-    ND_PRINT((ndo, "(length %u)", size));
+    ND_PRINT("(length %zu)", size + sizeof(struct m3ua_param_header));
   }
+  ND_TCHECK_LEN(buf, size);
+  return;
+
+invalid:
+  nd_print_invalid(ndo);
+  ND_TCHECK_LEN(buf, size);
 }
 
+/*
+ *     0                   1                   2                   3
+ *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |          Parameter Tag        |       Parameter Length        |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    \                                                               \
+ *    /                       Parameter Value                         /
+ *    \                                                               \
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
 static void
 m3ua_tags_print(netdissect_options *ndo,
                 const u_char *buf, const u_int size)
 {
   const u_char *p = buf;
   int align;
+  uint16_t hdr_tag;
+  uint16_t hdr_len;
+
   while (p < buf + size) {
-    const struct m3ua_param_header *hdr = (const struct m3ua_param_header *) p;
-    ND_PRINT((ndo, "\n\t\t\t%s: ", tok2str(ParamName, "Unknown Parameter (0x%04x)", EXTRACT_16BITS(&hdr->tag))));
-    tag_value_print(ndo, p + sizeof(struct m3ua_param_header), EXTRACT_16BITS(&hdr->tag), EXTRACT_16BITS(&hdr->len));
-    p += EXTRACT_16BITS(&hdr->len);
-    align = (p - buf) % 4;
-    p += (align) ? 4 - align : 0;
+    if (p + sizeof(struct m3ua_param_header) > buf + size)
+      goto invalid;
+    /* Parameter 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 = GET_BE_U_2(p + 2);
+    if (hdr_len < sizeof(struct m3ua_param_header))
+      goto invalid;
+    /* Parameter Value */
+    align = (p + hdr_len - buf) % 4;
+    align = align ? 4 - align : 0;
+    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;
+
+invalid:
+  nd_print_invalid(ndo);
+  ND_TCHECK_LEN(buf, size);
 }
 
+/*
+ *     0                   1                   2                   3
+ *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |    Version    |   Reserved    | Message Class | Message Type  |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                        Message Length                         |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    \                                                               \
+ *    /                                                               /
+ */
 void
 m3ua_print(netdissect_options *ndo,
            const u_char *buf, const u_int size)
 {
   const struct m3ua_common_header *hdr = (const struct m3ua_common_header *) buf;
-  const struct tok *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;
-
-  ND_PRINT((ndo, "\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", hdr->msg_class)));
+  const struct tok *dict;
+  uint8_t msg_class;
+
+  ndo->ndo_protocol = "m3ua";
+  /* size includes the header */
+  if (size < sizeof(struct m3ua_common_header))
+    goto invalid;
+  ND_TCHECK_SIZE(hdr);
+  if (GET_U_1(hdr->v) != M3UA_REL_1_0)
+    return;
+
+  msg_class = GET_U_1(hdr->msg_class);
+  dict = uint2tokary(m3ua_msgc2tokary, 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;
+
+invalid:
+  nd_print_invalid(ndo);
+  ND_TCHECK_LEN(buf, size);
 }