+static void
+of_message_print(netdissect_options *ndo,
+ const u_char *cp, uint16_t len,
+ const struct of_msgtypeinfo *mti)
+{
+ /*
+ * Here "cp" and "len" stand for the message part beyond the common
+ * OpenFlow 1.0 header, if any.
+ *
+ * Most message types are longer than just the header, and the length
+ * constraints may be complex. When possible, validate the constraint
+ * completely here (REQ_FIXLEN), otherwise check that the message is
+ * long enough to begin the decoding (REQ_MINLEN) and have the
+ * type-specific function do any remaining validation.
+ */
+
+ if (!mti)
+ goto tcheck_remainder;
+
+ if ((mti->req_what == REQ_FIXLEN && len != mti->req_value) ||
+ (mti->req_what == REQ_MINLEN && len < mti->req_value))
+ goto invalid;
+
+ if (!ndo->ndo_vflag || !mti->decoder)
+ goto tcheck_remainder;
+
+ mti->decoder(ndo, cp, len);
+ return;
+
+invalid:
+ nd_print_invalid(ndo);
+tcheck_remainder:
+ ND_TCHECK_LEN(cp, len);
+}
+