extern const char *tok2strary_internal(const char **, int, const char *, int);
#define tok2strary(a,f,i) tok2strary_internal(a, sizeof(a)/sizeof(a[0]),f,i)
+struct uint_tokary
+{
+ u_int uintval;
+ const struct tok *tokary;
+};
+
+extern const struct tok *uint2tokary_internal(const struct uint_tokary[], const size_t, const u_int);
+#define uint2tokary(a, i) uint2tokary_internal(a, sizeof(a)/sizeof(a[0]), i)
+
extern if_printer lookup_printer(int);
#define ND_DEBUG {printf(" [%s:%d %s] ", __FILE__, __LINE__, __FUNCTION__); fflush(stdout);}
{ 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
return;
msg_class = GET_U_1(hdr->msg_class);
- dict =
- msg_class == M3UA_MSGC_MGMT ? MgmtMessages :
- msg_class == M3UA_MSGC_TRANSFER ? TransferMessages :
- msg_class == M3UA_MSGC_SSNM ? SS7Messages :
- msg_class == M3UA_MSGC_ASPSM ? ASPStateMessages :
- msg_class == M3UA_MSGC_ASPTM ? ASPTrafficMessages :
- msg_class == M3UA_MSGC_RKM ? RoutingKeyMgmtMessages :
- NULL;
+ dict = uint2tokary(m3ua_msgc2tokary, msg_class);
ND_PRINT("\n\t\t%s", tok2str(MessageClasses, "Unknown message class %i", msg_class));
if (dict != NULL)
{ OFPET_QUEUE_OP_FAILED, "QUEUE_OP_FAILED" },
{ 0, NULL }
};
-#define OFPET_MAX OFPET_QUEUE_OP_FAILED /* for of10_error_print() */
#define OFPHFC_INCOMPATIBLE 0x0000U
#define OFPHFC_EPERM 0x0001U
{ 0, NULL }
};
+static const struct uint_tokary of10_ofpet2tokary[] = {
+ { OFPET_HELLO_FAILED, ofphfc_str },
+ { OFPET_BAD_REQUEST, ofpbrc_str },
+ { OFPET_BAD_ACTION, ofpbac_str },
+ { OFPET_FLOW_MOD_FAILED, ofpfmfc_str },
+ { OFPET_PORT_MOD_FAILED, ofppmfc_str },
+ { OFPET_QUEUE_OP_FAILED, ofpqofc_str },
+ /* uint2tokary() does not use array termination. */
+};
+
/* lengths (fixed or minimal) of particular protocol structures */
#define OF_SWITCH_CONFIG_FIXLEN 12
#define OF_PHY_PORT_FIXLEN 48
const u_char *cp, u_int len)
{
uint16_t type, code;
- const struct tok *code_str[OFPET_MAX + 1] = {
- /* [OFPET_HELLO_FAILED ] = */ ofphfc_str,
- /* [OFPET_BAD_REQUEST ] = */ ofpbrc_str,
- /* [OFPET_BAD_ACTION ] = */ ofpbac_str,
- /* [OFPET_FLOW_MOD_FAILED] = */ ofpfmfc_str,
- /* [OFPET_PORT_MOD_FAILED] = */ ofppmfc_str,
- /* [OFPET_QUEUE_OP_FAILED] = */ ofpqofc_str,
- };
+ const struct tok *code_str;
/* type */
type = GET_BE_U_2(cp);
/* code */
code = GET_BE_U_2(cp);
OF_FWD(2);
- if (type <= OFPET_MAX && code_str[type] != NULL)
+ code_str = uint2tokary(of10_ofpet2tokary, type);
+ if (code_str != NULL)
ND_PRINT(", code %s",
- tok2str(code_str[type], "invalid (0x%04x)", code));
+ tok2str(code_str, "invalid (0x%04x)", code));
else
ND_PRINT(", code invalid (0x%04x)", code);
/* data */
{ OFPET_EXPERIMENTER, "EXPERIMENTER" },
{ 0, NULL }
};
-/*
- * As far as of13_error_print() is concerned, OFPET_EXPERIMENTER is too large
- * and defines no codes anyway.
- */
-#define OFPET_MAX OFPET_TABLE_FEATURES_FAILED
#define OFPHFC_INCOMPATIBLE 0U
#define OFPHFC_EPERM 1U
{ 0, NULL }
};
+static const struct uint_tokary of13_ofpet2tokary[] = {
+ { OFPET_HELLO_FAILED, ofphfc_str },
+ { OFPET_BAD_REQUEST, ofpbrc_str },
+ { OFPET_BAD_ACTION, ofpbac_str },
+ { OFPET_BAD_INSTRUCTION, ofpbic_str },
+ { OFPET_BAD_MATCH, ofpbmc_str },
+ { OFPET_FLOW_MOD_FAILED, ofpfmfc_str },
+ { OFPET_GROUP_MOD_FAILED, ofpgmfc_str },
+ { OFPET_PORT_MOD_FAILED, ofppmfc_str },
+ { OFPET_TABLE_MOD_FAILED, ofptmfc_str },
+ { OFPET_QUEUE_OP_FAILED, ofpqofc_str },
+ { OFPET_SWITCH_CONFIG_FAILED, ofpscfc_str },
+ { OFPET_ROLE_REQUEST_FAILED, ofprrfc_str },
+ { OFPET_METER_MOD_FAILED, ofpmmfc_str },
+ { OFPET_TABLE_FEATURES_FAILED, ofptffc_str },
+ { OFPET_EXPERIMENTER, NULL }, /* defines no codes */
+ /* uint2tokary() does not use array termination. */
+};
+
/* lengths (fixed or minimal) of particular protocol structures */
#define OF_HELLO_ELEM_MINSIZE 4U
#define OF_ERROR_MSG_MINLEN 12U
const u_char *cp, u_int len)
{
uint16_t type, code;
- const struct tok *code_str[OFPET_MAX + 1] = {
- /* [OFPET_HELLO_FAILED ] = */ ofphfc_str,
- /* [OFPET_BAD_REQUEST ] = */ ofpbrc_str,
- /* [OFPET_BAD_ACTION ] = */ ofpbac_str,
- /* [OFPET_BAD_INSTRUCTION ] = */ ofpbic_str,
- /* [OFPET_BAD_MATCH ] = */ ofpbmc_str,
- /* [OFPET_FLOW_MOD_FAILED ] = */ ofpfmfc_str,
- /* [OFPET_GROUP_MOD_FAILED ] = */ ofpgmfc_str,
- /* [OFPET_PORT_MOD_FAILED ] = */ ofppmfc_str,
- /* [OFPET_TABLE_MOD_FAILED ] = */ ofptmfc_str,
- /* [OFPET_QUEUE_OP_FAILED ] = */ ofpqofc_str,
- /* [OFPET_SWITCH_CONFIG_FAILED ] = */ ofpscfc_str,
- /* [OFPET_ROLE_REQUEST_FAILED ] = */ ofprrfc_str,
- /* [OFPET_METER_MOD_FAILED ] = */ ofpmmfc_str,
- /* [OFPET_TABLE_FEATURES_FAILED] = */ ofptffc_str,
- };
+ const struct tok *code_str;
/* type */
type = GET_BE_U_2(cp);
/* code */
code = GET_BE_U_2(cp);
OF_FWD(2);
- if (type <= OFPET_MAX && code_str[type] != NULL)
+ code_str = uint2tokary(of13_ofpet2tokary, type);
+ if (code_str != NULL)
ND_PRINT(", code %s",
- tok2str(code_str[type], "invalid (0x%04x)", code));
+ tok2str(code_str, "invalid (0x%04x)", code));
else
ND_PRINT(", code invalid (0x%04x)", code);
/* data */
return (buf);
}
+const struct tok *
+uint2tokary_internal(const struct uint_tokary dict[], const size_t size,
+ const u_int val)
+{
+ size_t i;
+ /* Try a direct lookup before the full scan. */
+ if (val < size && dict[val].uintval == val)
+ return dict[val].tokary; /* OK if NULL */
+ for (i = 0; i < size; i++)
+ if (dict[i].uintval == val)
+ return dict[i].tokary; /* OK if NULL */
+ return NULL;
+}
+
/*
* Convert a 32-bit netmask to prefixlen if possible
* the function returns the prefix-len; if plen == -1