Use a dissector table instead of strcmp
... to map vpp node names to dissector handles.
Wireshark has an easy-to-use string to dissector function handle
hashing scheme, so use it. Thanks to Guy Harris for writing up the
incantation.
Change-Id: I6c1eb609332b0afe87154ba447a98f783e13ca68
Signed-off-by: Dave Barach <dave@barachs.net>
diff --git a/extras/wireshark/packet-vpp.c b/extras/wireshark/packet-vpp.c
index fbc8154..9584e70 100644
--- a/extras/wireshark/packet-vpp.c
+++ b/extras/wireshark/packet-vpp.c
@@ -88,20 +88,39 @@
static dissector_handle_t vpp_opaque_dissector_handle;
static dissector_handle_t vpp_trace_dissector_handle;
-static dissector_handle_t eth_dissector_handle;
-static dissector_handle_t ip4_dissector_handle;
-static dissector_handle_t ip6_dissector_handle;
-static dissector_handle_t udp_dissector_handle;
+static dissector_table_t vpp_subdissector_table;
-#define foreach_node_to_dissector_handle \
-_("ip6-lookup", "ipv6", ip6_dissector_handle) \
-_("ip4-input-no-checksum", "ip", ip4_dissector_handle) \
-_("ip4-lookup", "ip", ip4_dissector_handle) \
-_("ip4-local", "ip", ip4_dissector_handle) \
-_("ip4-udp-lookup", "ip", udp_dissector_handle) \
-_("ip4-icmp-error", "ip", ip4_dissector_handle) \
-_("ip4-glean", "ip", ip4_dissector_handle) \
-_("ethernet-input", "eth_maybefcs", eth_dissector_handle)
+/* List of next dissector names that we know about */
+#define foreach_next_dissector \
+_(eth_maybefcs) \
+_(ip) \
+_(ipv6) \
+_(udp)
+
+#define _(a) static dissector_handle_t a##_dissector_handle;
+foreach_next_dissector;
+#undef _
+
+/*
+ * node-name, next dissector name pairs
+ *
+ * Unfortunately, -Werror=c++-compat causes
+ * the node names "ipX-not-enabled" to throw a shoe if
+ * not explicitly quoted. Never mind that the first macro
+ * arg is [only] used as a string (#xxx).
+ */
+
+#define foreach_node_to_dissector_pair \
+_("ip6-lookup", ipv6) \
+_("ip4-input", ip) \
+_("ip4-not-enabled", ip) \
+_("ip4-input-no-checksum", ip) \
+_("ip4-lookup", ip) \
+_("ip4-local", ip) \
+_("ip4-udp-lookup", udp) \
+_("ip4-icmp-error", ip) \
+_("ip4-glean", ip) \
+_("ethernet-input", eth_maybefcs)
static void
add_multi_line_string_to_tree(proto_tree *tree, tvbuff_t *tvb, gint start,
@@ -610,7 +629,7 @@
guint8 name_length;
guint8 *name;
guint16 trace_length;
- int i, found;
+ int i;
static const int *buffer_flags[] = {
&hf_vpp_buffer_flag_non_default_freelist,
&hf_vpp_buffer_flag_traced,
@@ -730,19 +749,15 @@
eth_tvb = tvb_new_subset_remaining (tvb, offset);
- found = 0;
-
-#define _(a,b,c) \
- { \
- if (!strcmp (name, a)) { \
- call_dissector (c, eth_tvb, pinfo, tree); \
- found = 1; \
- } \
- }
- foreach_node_to_dissector_handle;
-#undef _
- if (found == 0)
- call_dissector (eth_dissector_handle, eth_tvb, pinfo, tree);
+ /*
+ * Delegate the rest of the packet dissection to the per-node
+ * next dissector in the foreach_node_to_dissector_pair list
+ *
+ * Failing that, pretend its an ethernet packet
+ */
+ if (!dissector_try_string (vpp_subdissector_table, name, eth_tvb,
+ pinfo, tree, NULL))
+ call_dissector (eth_maybefcs_dissector_handle, eth_tvb, pinfo, tree);
g_free (name);
return tvb_captured_length(tvb);
@@ -958,8 +973,14 @@
proto_register_subtree_array (ett_trace, array_length(ett_trace));
register_dissector("vppTrace", dissect_vpp_trace, proto_vpp_trace);
-#define _(a,b,c) c = find_dissector(b);
- foreach_node_to_dissector_handle;
+ vpp_subdissector_table = register_dissector_table
+ ("vpp", "VPP per-node next dissector table", proto_vpp,
+ FT_STRING, BASE_NONE);
+
+#define _(n,d) \
+ d##_dissector_handle = find_dissector(#d); \
+ dissector_add_string ("vpp", n, d##_dissector_handle);
+ foreach_node_to_dissector_pair;
#undef _
}