-const u_char *
-of10_header_body_print(netdissect_options *ndo,
- const u_char *cp, const u_char *ep, const uint8_t type,
- const uint16_t len, const uint32_t xid)
-{
- const u_char *cp0 = cp;
- const u_int len0 = len;
- /* Thus far message length is not less than the basic header size, but most
- * message types have additional assorted constraints on the length. Wherever
- * possible, check that message length meets the constraint, in remaining
- * cases check that the length is OK to begin decoding and leave any final
- * verification up to a lower-layer function. When the current message is
- * invalid, proceed to the next message. */
-
- /* [OF10] Section 5.1 */
- ND_PRINT((ndo, "\n\tversion 1.0, type %s, length %u, xid 0x%08x",
- tok2str(ofpt_str, "invalid (0x%02x)", type), len, xid));
- switch (type) {
- /* OpenFlow header only. */
- case OFPT_FEATURES_REQUEST: /* [OF10] Section 5.3.1 */
- case OFPT_GET_CONFIG_REQUEST: /* [OF10] Section 5.3.2 */
- case OFPT_BARRIER_REQUEST: /* [OF10] Section 5.3.7 */
- case OFPT_BARRIER_REPLY: /* ibid */
- if (len != OF_HEADER_LEN)
- goto invalid;
- break;
-
- /* OpenFlow header and fixed-size message body. */
- case OFPT_SET_CONFIG: /* [OF10] Section 5.3.2 */
- case OFPT_GET_CONFIG_REPLY: /* ibid */
- if (len != OF_SWITCH_CONFIG_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- /* flags */
- ND_TCHECK_2(cp);
- ND_PRINT((ndo, "\n\t flags %s", tok2str(ofp_config_str, "invalid (0x%04x)", EXTRACT_BE_U_2(cp))));
- cp += 2;
- /* miss_send_len */
- ND_TCHECK_2(cp);
- ND_PRINT((ndo, ", miss_send_len %u", EXTRACT_BE_U_2(cp)));
- return cp + 2;
- case OFPT_PORT_MOD:
- if (len != OF_PORT_MOD_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_port_mod_print(ndo, cp, ep);
- case OFPT_QUEUE_GET_CONFIG_REQUEST: /* [OF10] Section 5.3.4 */
- if (len != OF_QUEUE_GET_CONFIG_REQUEST_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- /* port */
- ND_TCHECK_2(cp);
- ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_BE_U_2(cp))));
- cp += 2;
- /* pad */
- ND_TCHECK_2(cp);
- return cp + 2;
- case OFPT_FLOW_REMOVED:
- if (len != OF_FLOW_REMOVED_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_flow_removed_print(ndo, cp, ep);
- case OFPT_PORT_STATUS: /* [OF10] Section 5.4.3 */
- if (len != OF_PORT_STATUS_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- /* reason */
- ND_TCHECK_1(cp);
- ND_PRINT((ndo, "\n\t reason %s", tok2str(ofppr_str, "invalid (0x%02x)", EXTRACT_U_1(cp))));
- cp += 1;
- /* pad */
- ND_TCHECK_7(cp);
- cp += 7;
- /* desc */
- return of10_phy_ports_print(ndo, cp, ep, OF_PHY_PORT_LEN);
-
- /* OpenFlow header, fixed-size message body and n * fixed-size data units. */
- case OFPT_FEATURES_REPLY:
- if (len < OF_SWITCH_FEATURES_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_features_reply_print(ndo, cp, ep, len);
-
- /* OpenFlow header and variable-size data. */
- case OFPT_HELLO: /* [OF10] Section 5.5.1 */
- case OFPT_ECHO_REQUEST: /* [OF10] Section 5.5.2 */
- case OFPT_ECHO_REPLY: /* [OF10] Section 5.5.3 */
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_data_print(ndo, cp, ep, len - OF_HEADER_LEN);
-
- /* OpenFlow header, fixed-size message body and variable-size data. */
- case OFPT_ERROR:
- if (len < OF_ERROR_MSG_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_error_print(ndo, cp, ep, len);
- case OFPT_VENDOR:
- /* [OF10] Section 5.5.4 */
- if (len < OF_VENDOR_HEADER_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_vendor_message_print(ndo, cp, ep, len - OF_HEADER_LEN);
- case OFPT_PACKET_IN:
- /* 2 mock octets count in OF_PACKET_IN_LEN but not in len */
- if (len < OF_PACKET_IN_LEN - 2)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_packet_in_print(ndo, cp, ep, len);
-
- /* a. OpenFlow header. */
- /* b. OpenFlow header and one of the fixed-size message bodies. */
- /* c. OpenFlow header, fixed-size message body and variable-size data. */
- case OFPT_STATS_REQUEST:
- if (len < OF_STATS_REQUEST_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_stats_request_print(ndo, cp, ep, len);
-
- /* a. OpenFlow header and fixed-size message body. */
- /* b. OpenFlow header and n * fixed-size data units. */
- /* c. OpenFlow header and n * variable-size data units. */
- /* d. OpenFlow header, fixed-size message body and variable-size data. */
- case OFPT_STATS_REPLY:
- if (len < OF_STATS_REPLY_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_stats_reply_print(ndo, cp, ep, len);
-
- /* OpenFlow header and n * variable-size data units and variable-size data. */
- case OFPT_PACKET_OUT:
- if (len < OF_PACKET_OUT_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_packet_out_print(ndo, cp, ep, len);
-
- /* OpenFlow header, fixed-size message body and n * variable-size data units. */
- case OFPT_FLOW_MOD:
- if (len < OF_FLOW_MOD_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- return of10_flow_mod_print(ndo, cp, ep, len);
-
- /* OpenFlow header, fixed-size message body and n * variable-size data units. */
- case OFPT_QUEUE_GET_CONFIG_REPLY: /* [OF10] Section 5.3.4 */
- if (len < OF_QUEUE_GET_CONFIG_REPLY_LEN)
- goto invalid;
- if (ndo->ndo_vflag < 1)
- goto next_message;
- /* port */
- ND_TCHECK_2(cp);
- ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_BE_U_2(cp))));
- cp += 2;
- /* pad */
- ND_TCHECK_6(cp);
- cp += 6;
- /* queues */
- return of10_queues_print(ndo, cp, ep, len - OF_QUEUE_GET_CONFIG_REPLY_LEN);
- } /* switch (type) */
- goto next_message;
+static const struct of_msgtypeinfo of10_msgtypeinfo[OFPT_MAX + 1] = {
+ /*
+ * [OF10] Section 5.5.1
+ * Variable-size data.
+ */
+ {
+ "HELLO", of_data_print,
+ REQ_MINLEN, 0
+ },
+ /*
+ * [OF10] Section 5.4.4
+ * A fixed-size message body and variable-size data.
+ */
+ {
+ "ERROR", of10_error_print,
+ REQ_MINLEN, OF_ERROR_MSG_MINLEN
+ },
+ /*
+ * [OF10] Section 5.5.2
+ * Variable-size data.
+ */
+ {
+ "ECHO_REQUEST", of_data_print,
+ REQ_MINLEN, 0
+ },
+ /*
+ * [OF10] Section 5.5.3
+ * Variable-size data.
+ */
+ {
+ "ECHO_REPLY", of_data_print,
+ REQ_MINLEN, 0
+ },
+ /*
+ * [OF10] Section 5.5.4
+ * A fixed-size message body and variable-size data.
+ */
+ {
+ "VENDOR", of10_vendor_message_print,
+ REQ_MINLEN, OF_VENDOR_MINLEN
+ },
+ /*
+ * [OF10] Section 5.3.1
+ * No message body.
+ */
+ {
+ "FEATURES_REQUEST", NULL,
+ REQ_FIXLEN, 0
+ },
+ /*
+ * [OF10] Section 5.3.1
+ * A fixed-size message body and n * fixed-size data units.
+ */
+ {
+ "FEATURES_REPLY", of10_features_reply_print,
+ REQ_MINLEN, OF_FEATURES_REPLY_MINLEN
+ },
+ /*
+ * [OF10] Section 5.3.2
+ * No message body.
+ */
+ {
+ "GET_CONFIG_REQUEST", NULL,
+ REQ_FIXLEN, 0
+ },
+ /*
+ * [OF10] Section 5.3.2
+ * A fixed-size message body.
+ */
+ {
+ "GET_CONFIG_REPLY", of10_switch_config_msg_print,
+ REQ_FIXLEN, OF_SWITCH_CONFIG_FIXLEN
+ },
+ /*
+ * [OF10] Section 5.3.2
+ * A fixed-size message body.
+ */
+ {
+ "SET_CONFIG", of10_switch_config_msg_print,
+ REQ_FIXLEN, OF_SWITCH_CONFIG_FIXLEN
+ },
+ /*
+ * [OF10] Section 5.4.1
+ * A fixed-size message body and variable-size data.
+ * (The 2 mock octets count in OF_PACKET_IN_MINLEN only.)
+ */
+ {
+ "PACKET_IN", of10_packet_in_print,
+ REQ_MINLEN, OF_PACKET_IN_MINLEN - 2
+ },
+ /*
+ * [OF10] Section 5.4.2
+ * A fixed-size message body.
+ */
+ {
+ "FLOW_REMOVED", of10_flow_removed_print,
+ REQ_FIXLEN, OF_FLOW_REMOVED_FIXLEN
+ },
+ /*
+ * [OF10] Section 5.4.3
+ * A fixed-size message body.
+ */
+ {
+ "PORT_STATUS", of10_port_status_print,
+ REQ_FIXLEN, OF_PORT_STATUS_FIXLEN
+ },
+ /*
+ * [OF10] Section 5.3.6
+ * A fixed-size message body, n * variable-size data units and
+ * variable-size data.
+ */
+ {
+ "PACKET_OUT", of10_packet_out_print,
+ REQ_MINLEN, OF_PACKET_OUT_MINLEN
+ },
+ /*
+ * [OF10] Section 5.3.3
+ * A fixed-size message body and n * variable-size data units.
+ */
+ {
+ "FLOW_MOD", of10_flow_mod_print,
+ REQ_MINLEN, OF_FLOW_MOD_MINLEN
+ },
+ /*
+ * [OF10] Section 5.3.3
+ * A fixed-size message body.
+ */
+ {
+ "PORT_MOD", of10_port_mod_print,
+ REQ_FIXLEN, OF_PORT_MOD_FIXLEN
+ },
+ /*
+ * [OF10] Section 5.3.5
+ * A fixed-size message body and possibly more data of varying size
+ * and structure.
+ */
+ {
+ "STATS_REQUEST", of10_stats_request_print,
+ REQ_MINLEN, OF_STATS_REQUEST_MINLEN
+ },
+ /*
+ * [OF10] Section 5.3.5
+ * A fixed-size message body and possibly more data of varying size
+ * and structure.
+ */
+ {
+ "STATS_REPLY", of10_stats_reply_print,
+ REQ_MINLEN, OF_STATS_REPLY_MINLEN
+ },
+ /*
+ * [OF10] Section 5.3.7
+ * No message body.
+ */
+ {
+ "BARRIER_REQUEST", NULL,
+ REQ_FIXLEN, 0
+ },
+ /*
+ * [OF10] Section 5.3.7
+ * No message body.
+ */
+ {
+ "BARRIER_REPLY", NULL,
+ REQ_FIXLEN, 0
+ },
+ /*
+ * [OF10] Section 5.3.4
+ * A fixed-size message body.
+ */
+ {
+ "QUEUE_GET_CONFIG_REQUEST", of10_queue_get_config_request_print,
+ REQ_FIXLEN, OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN
+ },
+ /*
+ * [OF10] Section 5.3.4
+ * A fixed-size message body and n * variable-size data units.
+ */
+ {
+ "QUEUE_GET_CONFIG_REPLY", of10_queue_get_config_reply_print,
+ REQ_MINLEN, OF_QUEUE_GET_CONFIG_REPLY_MINLEN
+ },
+};