]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Wrap some common code up as uint2tokary().
authorDenis Ovsienko <[email protected]>
Wed, 30 Sep 2020 20:45:25 +0000 (21:45 +0100)
committerDenis Ovsienko <[email protected]>
Wed, 30 Sep 2020 20:48:28 +0000 (21:48 +0100)
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.

netdissect.h
print-m3ua.c
print-openflow-1.0.c
print-openflow-1.3.c
util-print.c

index 74a113fc8f8eff1585bf9b7a70ba3e78e3313fbd..e288d0317fe5b720ddced1545d864b47ce5cd306 100644 (file)
@@ -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);}
index f70b6df7ba2022b404a0a652a4d18562d4eef87d..66ec9efd1ca4624ced36aba639e0e1380bcdebc5 100644 (file)
@@ -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)
index 6e659b30c9a6cece38a8b171136edf4dc5188278..92b20eb3cb1bc35ca060c962b9087a2880489624 100644 (file)
@@ -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 */
index 34e4b873cde4cc206b6e3d289d6be3a7308722f8..1e799e8987ba28563359d83ea146eb6cf3c721bb 100644 (file)
@@ -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 */
index e22e535e8d2b2d62c9ead781614180d9f0301567..00160b432d06a0f2a7d78c9319f7cb91ef8373b6 100644 (file)
@@ -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