summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Ovsienko <denis@ovsienko.info>2020-09-30 21:45:25 +0100
committerDenis Ovsienko <denis@ovsienko.info>2020-09-30 21:48:28 +0100
commite1fd57e0849de3b53eba7b380ce978f87de88e9c (patch)
tree48717301a7399395d081940c7dcfa7b994d7a3d8
parentfaf8fb70af3a013e5d662b8283dec742fd6b1a77 (diff)
downloadtcpdump-e1fd57e0849de3b53eba7b380ce978f87de88e9c.tar.gz
Wrap some common code up as uint2tokary().
I like the ternary operator (in programming languages that define it with the same associativity as humans tend to presume), but sometimes a lookup function is better.
-rw-r--r--netdissect.h9
-rw-r--r--print-m3ua.c19
-rw-r--r--print-openflow-1.0.c25
-rw-r--r--print-openflow-1.3.c46
-rw-r--r--util-print.c14
5 files changed, 71 insertions, 42 deletions
diff --git a/netdissect.h b/netdissect.h
index 74a113fc..e288d031 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -451,6 +451,15 @@ extern int unaligned_memcmp(const void *, const void *, size_t);
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);}
diff --git a/print-m3ua.c b/print-m3ua.c
index f70b6df7..66ec9efd 100644
--- a/print-m3ua.c
+++ b/print-m3ua.c
@@ -153,6 +153,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
@@ -305,14 +315,7 @@ m3ua_print(netdissect_options *ndo,
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)
diff --git a/print-openflow-1.0.c b/print-openflow-1.0.c
index 6e659b30..92b20eb3 100644
--- a/print-openflow-1.0.c
+++ b/print-openflow-1.0.c
@@ -456,7 +456,6 @@ static const struct tok ofpet_str[] = {
{ 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
@@ -544,6 +543,16 @@ static const struct tok ofpqofc_str[] = {
{ 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
@@ -2032,14 +2041,7 @@ of10_error_print(netdissect_options *ndo,
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);
@@ -2048,9 +2050,10 @@ of10_error_print(netdissect_options *ndo,
/* 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 */
diff --git a/print-openflow-1.3.c b/print-openflow-1.3.c
index 34e4b873..1e799e89 100644
--- a/print-openflow-1.3.c
+++ b/print-openflow-1.3.c
@@ -208,11 +208,6 @@ static const struct tok ofpet_str[] = {
{ 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
@@ -492,6 +487,25 @@ static const struct tok ofptffc_str[] = {
{ 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
@@ -592,22 +606,7 @@ of13_error_print(netdissect_options *ndo,
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);
@@ -616,9 +615,10 @@ of13_error_print(netdissect_options *ndo,
/* 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 */
diff --git a/util-print.c b/util-print.c
index e22e535e..00160b43 100644
--- a/util-print.c
+++ b/util-print.c
@@ -625,6 +625,20 @@ tok2strary_internal(const char **lp, int n, const char *fmt,
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