X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/8bd8cb7c591feb05ced9b078d900d6102ebf55f4..3b46f347ca330d3a063aeede8e96e00265dfaab6:/print-openflow-1.0.c diff --git a/print-openflow-1.0.c b/print-openflow-1.0.c index 473a8dc3..dd42866a 100644 --- a/print-openflow-1.0.c +++ b/print-openflow-1.0.c @@ -144,14 +144,18 @@ static const struct tok ofppc_bm[] = { OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD | \ OFPPC_NO_PACKET_IN)) -#define OFPPS_LINK_DOWN (1U << 0) -#define OFPPS_STP_LISTEN (0U << 8) -#define OFPPS_STP_LEARN (1U << 8) -#define OFPPS_STP_FORWARD (2U << 8) -#define OFPPS_STP_BLOCK (3U << 8) -#define OFPPS_STP_MASK (3U << 8) -static const struct tok ofpps_bm[] = { - { OFPPS_LINK_DOWN, "LINK_DOWN" }, +/* + * [OF10] lists all FPPS_ constants in one enum, but they mean a 1-bit bitmap + * in the least significant octet and a 2-bit code point in the next octet. + * Remember to mix or to separate these two parts as the context requires. + */ +#define OFPPS_LINK_DOWN (1U << 0) /* bitmap */ +#define OFPPS_STP_LISTEN (0U << 8) /* code point */ +#define OFPPS_STP_LEARN (1U << 8) /* code point */ +#define OFPPS_STP_FORWARD (2U << 8) /* code point */ +#define OFPPS_STP_BLOCK (3U << 8) /* code point */ +#define OFPPS_STP_MASK (3U << 8) /* code point bitmask */ +static const struct tok ofpps_stp_str[] = { { OFPPS_STP_LISTEN, "STP_LISTEN" }, { OFPPS_STP_LEARN, "STP_LEARN" }, { OFPPS_STP_FORWARD, "STP_FORWARD" }, @@ -456,7 +460,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 +547,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 @@ -682,6 +695,12 @@ static const struct tok bsn_onoff_str[] = { { 0, NULL }, }; +/* [OF10] Section 5.1 */ +const char * of10_msgtype_str(const uint8_t type) +{ + return tok2str(ofpt_str, "invalid (0x%02x)", type); +} + static const char * vlan_str(const uint16_t vid) { @@ -703,24 +722,6 @@ pcp_str(const uint8_t pcp) return buf; } -static void -of10_bitmap_print(netdissect_options *ndo, - const struct tok *t, const uint32_t v, const uint32_t u) -{ - const char *sep = " ("; - - if (v == 0) - return; - /* assigned bits */ - for (; t->s != NULL; t++) - if (v & t->v) { - ND_PRINT("%s%s", sep, t->s); - sep = ", "; - } - /* unassigned bits? */ - ND_PRINT((v & u) ? ") (bogus)" : ")"); -} - static void of10_bsn_message_print(netdissect_options *ndo, const u_char *cp, u_int len) @@ -1061,6 +1062,8 @@ of10_phy_ports_print(netdissect_options *ndo, const u_char *cp, u_int len) { while (len) { + uint32_t state; + if (len < OF_PHY_PORT_FIXLEN) goto invalid; /* port_no */ @@ -1082,27 +1085,35 @@ of10_phy_ports_print(netdissect_options *ndo, } /* config */ ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); OF_FWD(4); /* state */ - ND_PRINT("\n\t state 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofpps_bm, GET_BE_U_4(cp), OFPPS_U); + state = GET_BE_U_4(cp); + /* + * Decode the code point and the single bit separately, but + * format the result as a single sequence of comma-separated + * strings (see the comments at the OFPPS_ props). + */ + ND_PRINT("\n\t state 0x%08x (%s%s)%s", state, + tok2str(ofpps_stp_str, "", state & OFPPS_STP_MASK), + state & OFPPS_LINK_DOWN ? ", LINK_DOWN" : "", + state & OFPPS_U ? " (bogus)" : ""); OF_FWD(4); /* curr */ ND_PRINT("\n\t curr 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); OF_FWD(4); /* advertised */ ND_PRINT("\n\t advertised 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); OF_FWD(4); /* supported */ ND_PRINT("\n\t supported 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); OF_FWD(4); /* peer */ ND_PRINT("\n\t peer 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); OF_FWD(4); } /* while */ return; @@ -1482,11 +1493,11 @@ of10_features_reply_print(netdissect_options *ndo, OF_FWD(3); /* capabilities */ ND_PRINT("\n\t capabilities 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofp_capabilities_bm, GET_BE_U_4(cp), OFPCAP_U); + of_bitmap_print(ndo, ofp_capabilities_bm, GET_BE_U_4(cp), OFPCAP_U); OF_FWD(4); /* actions */ ND_PRINT("\n\t actions 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofpat_bm, GET_BE_U_4(cp), OFPAT_U); + of_bitmap_print(ndo, ofpat_bm, GET_BE_U_4(cp), OFPAT_U); OF_FWD(4); /* ports */ of10_phy_ports_print(ndo, cp, len); @@ -1534,7 +1545,7 @@ of10_flow_mod_print(netdissect_options *ndo, OF_FWD(2); /* flags */ ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp)); - of10_bitmap_print(ndo, ofpff_bm, GET_BE_U_2(cp), OFPFF_U); + of_bitmap_print(ndo, ofpff_bm, GET_BE_U_2(cp), OFPFF_U); OF_FWD(2); /* actions */ of10_actions_print(ndo, "\n\t ", cp, len); @@ -1553,15 +1564,15 @@ of10_port_mod_print(netdissect_options *ndo, cp += MAC_ADDR_LEN; /* config */ ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); cp += 4; /* mask */ ND_PRINT("\n\t mask 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); + of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U); cp += 4; /* advertise */ ND_PRINT("\n\t advertise 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); + of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); cp += 4; /* pad */ /* Always the last field, check bounds. */ @@ -1790,7 +1801,7 @@ of10_table_stats_reply_print(netdissect_options *ndo, OF_FWD(OFP_MAX_TABLE_NAME_LEN); /* wildcards */ ND_PRINT("\n\t wildcards 0x%08x", GET_BE_U_4(cp)); - of10_bitmap_print(ndo, ofpfw_bm, GET_BE_U_4(cp), OFPFW_U); + of_bitmap_print(ndo, ofpfw_bm, GET_BE_U_4(cp), OFPFW_U); OF_FWD(4); /* max_entries */ ND_PRINT("\n\t max_entries %u", GET_BE_U_4(cp)); @@ -1921,7 +1932,7 @@ of10_stats_reply_print(netdissect_options *ndo, OF_FWD(2); /* flags */ ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp)); - of10_bitmap_print(ndo, ofpsf_reply_bm, GET_BE_U_2(cp), OFPSF_REPLY_U); + of_bitmap_print(ndo, ofpsf_reply_bm, GET_BE_U_2(cp), OFPSF_REPLY_U); OF_FWD(2); if (ndo->ndo_vflag > 0) { @@ -2044,14 +2055,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); @@ -2060,9 +2064,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 */ @@ -2070,17 +2075,15 @@ of10_error_print(netdissect_options *ndo, } void -of10_header_body_print(netdissect_options *ndo, - const u_char *cp, const uint8_t type, - uint16_t len, const uint32_t xid) +of10_message_print(netdissect_options *ndo, + const u_char *cp, uint16_t len, const uint8_t type) { /* * Here "cp" and "len" stand for the message part beyond the common - * OpenFlow 1.0 header, if any. Add OF_HEADER_FIXLEN when printing the - * message header. Subtract OF_HEADER_FIXLEN from the type-specific - * lengths, which include the header length, when (and only when) - * validating the length in this function, which is the only one in - * this file that needs to know about OF_HEADER_FIXLEN. + * OpenFlow 1.0 header, if any. Subtract OF_HEADER_FIXLEN from the + * type-specific lengths, which include the header length, when (and + * only when) validating the length in this function. No other code + * in this file needs to take OF_HEADER_FIXLEN into account. * * Most message types are longer than just the header, and the length * constraints may be complex. When possible, validate the constraint @@ -2088,11 +2091,6 @@ of10_header_body_print(netdissect_options *ndo, * begin the decoding and let the lower-layer function do any remaining * validation. */ - - /* [OF10] Section 5.1 */ - ND_PRINT("\n\tversion 1.0, type %s, length %u, xid 0x%08x", - tok2str(ofpt_str, "invalid (0x%02x)", type), - OF_HEADER_FIXLEN + len, xid); switch (type) { /* OpenFlow header only. */ case OFPT_FEATURES_REQUEST: /* [OF10] Section 5.3.1 */