X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/af7c82332e79d9f019ef344f714b0860783e8af6..035c9fc0a92fb79111633143bbf29b2bc55d6b90:/print-openflow-1.0.c diff --git a/print-openflow-1.0.c b/print-openflow-1.0.c index 590caba4..9fb0f635 100644 --- a/print-openflow-1.0.c +++ b/print-openflow-1.0.c @@ -26,7 +26,8 @@ * the nested frames. * * Partial decoding of Big Switch Networks vendor extensions is done after the - * oftest (OpenFlow Testing Framework) source code. + * oftest (OpenFlow Testing Framework) and Loxigen (library generator) source + * code. * * * Copyright (c) 2013 The TCPDUMP project @@ -55,7 +56,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -639,6 +639,9 @@ static const struct tok bsn_subtype_str[] = { { BSN_SET_MIRRORING, "SET_MIRRORING" }, { BSN_GET_MIRRORING_REQUEST, "GET_MIRRORING_REQUEST" }, { BSN_GET_MIRRORING_REPLY, "GET_MIRRORING_REPLY" }, + { BSN_SHELL_COMMAND, "SHELL_COMMAND" }, + { BSN_SHELL_OUTPUT, "SHELL_OUTPUT" }, + { BSN_SHELL_STATUS, "SHELL_STATUS" }, { BSN_GET_INTERFACES_REQUEST, "GET_INTERFACES_REQUEST" }, { BSN_GET_INTERFACES_REPLY, "GET_INTERFACES_REPLY" }, { BSN_SET_PKTIN_SUPPRESSION_REQUEST, "SET_PKTIN_SUPPRESSION_REQUEST" }, @@ -667,9 +670,33 @@ static const struct tok bsn_subtype_str[] = { { 0, NULL } }; +#define BSN_ACTION_MIRROR 1 +#define BSN_ACTION_SET_TUNNEL_DST 2 + /* 3 */ +#define BSN_ACTION_CHECKSUM 4 + +static const struct tok bsn_action_subtype_str[] = { + { BSN_ACTION_MIRROR, "MIRROR" }, + { BSN_ACTION_SET_TUNNEL_DST, "SET_TUNNEL_DST" }, + { BSN_ACTION_CHECKSUM, "CHECKSUM" }, + { 0, NULL } +}; + +static const struct tok bsn_mirror_copy_stage_str[] = { + { 0, "INGRESS" }, + { 1, "EGRESS" }, + { 0, NULL }, +}; + +static const struct tok bsn_onoff_str[] = { + { 0, "OFF" }, + { 1, "ON" }, + { 0, NULL }, +}; static const char * -vlan_str(const uint16_t vid) { +vlan_str(const uint16_t vid) +{ static char buf[sizeof("65535 (bogus)")]; const char *fmt; @@ -681,7 +708,8 @@ vlan_str(const uint16_t vid) { } static const char * -pcp_str(const uint8_t pcp) { +pcp_str(const uint8_t pcp) +{ static char buf[sizeof("255 (bogus)")]; snprintf(buf, sizeof(buf), pcp <= 7 ? "%u" : "%u (bogus)", pcp); return buf; @@ -689,7 +717,8 @@ pcp_str(const uint8_t pcp) { static void of10_bitmap_print(netdissect_options *ndo, - const struct tok *t, const uint32_t v, const uint32_t u) { + const struct tok *t, const uint32_t v, const uint32_t u) +{ const char *sep = " ("; if (v == 0) @@ -706,7 +735,8 @@ of10_bitmap_print(netdissect_options *ndo, static const u_char * of10_data_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ if (len == 0) return cp; /* data */ @@ -723,7 +753,8 @@ trunc: static const u_char * of10_bsn_message_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ const u_char *cp0 = cp; uint32_t subtype; @@ -795,15 +826,15 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * | subtype | * +---------------+---------------+---------------+---------------+ - * | ports | pad | + * | report m. p. | pad | * +---------------+---------------+---------------+---------------+ * */ if (len != 8) goto corrupt; - /* ports */ + /* report_mirror_ports */ ND_TCHECK2(*cp, 1); - ND_PRINT((ndo, ", ports %u", *cp)); + ND_PRINT((ndo, ", report_mirror_ports %s", tok2str(bsn_onoff_str, "bogus (%u)", *cp))); cp += 1; /* pad */ ND_TCHECK2(*cp, 3); @@ -843,6 +874,73 @@ of10_bsn_message_print(netdissect_options *ndo, ND_PRINT((ndo, ", vport_no %u", EXTRACT_32BITS(cp))); cp += 4; break; + case BSN_SHELL_COMMAND: + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +---------------+---------------+---------------+---------------+ + * | subtype | + * +---------------+---------------+---------------+---------------+ + * | service | + * +---------------+---------------+---------------+---------------+ + * | data ... + * +---------------+---------------+-------- + * + */ + if (len < 8) + goto corrupt; + /* service */ + ND_TCHECK2(*cp, 4); + ND_PRINT((ndo, ", service %u", EXTRACT_32BITS(cp))); + cp += 4; + /* data */ + ND_PRINT((ndo, ", data '")); + if (fn_printn(ndo, cp, len - 8, ep)) { + ND_PRINT((ndo, "'")); + goto trunc; + } + ND_PRINT((ndo, "'")); + cp += len - 8; + break; + case BSN_SHELL_OUTPUT: + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +---------------+---------------+---------------+---------------+ + * | subtype | + * +---------------+---------------+---------------+---------------+ + * | data ... + * +---------------+---------------+-------- + * + */ + /* already checked that len >= 4 */ + /* data */ + ND_PRINT((ndo, ", data '")); + if (fn_printn(ndo, cp, len - 4, ep)) { + ND_PRINT((ndo, "'")); + goto trunc; + } + ND_PRINT((ndo, "'")); + cp += len - 4; + break; + case BSN_SHELL_STATUS: + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +---------------+---------------+---------------+---------------+ + * | subtype | + * +---------------+---------------+---------------+---------------+ + * | status | + * +---------------+---------------+---------------+---------------+ + * + */ + if (len != 8) + goto corrupt; + /* status */ + ND_TCHECK2(*cp, 4); + ND_PRINT((ndo, ", status 0x%08x", EXTRACT_32BITS(cp))); + cp += 4; + break; default: ND_TCHECK2(*cp, len - 4); cp += len - 4; @@ -858,9 +956,113 @@ trunc: return ep; } +static const u_char * +of10_bsn_actions_print(netdissect_options *ndo, + const u_char *cp, const u_char *ep, const u_int len) +{ + const u_char *cp0 = cp; + uint32_t subtype, vlan_tag; + + if (len < 4) + goto corrupt; + /* subtype */ + ND_TCHECK2(*cp, 4); + subtype = EXTRACT_32BITS(cp); + cp += 4; + ND_PRINT((ndo, "\n\t subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype))); + switch (subtype) { + case BSN_ACTION_MIRROR: + /* + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +---------------+---------------+---------------+---------------+ + * | subtype | + * +---------------+---------------+---------------+---------------+ + * | dest_port | + * +---------------+---------------+---------------+---------------+ + * | vlan_tag | + * +---------------+---------------+---------------+---------------+ + * | copy_stage | pad | + * +---------------+---------------+---------------+---------------+ + * + */ + if (len != 16) + goto corrupt; + /* dest_port */ + ND_TCHECK2(*cp, 4); + ND_PRINT((ndo, ", dest_port %u", EXTRACT_32BITS(cp))); + cp += 4; + /* vlan_tag */ + ND_TCHECK2(*cp, 4); + vlan_tag = EXTRACT_32BITS(cp); + cp += 4; + switch (vlan_tag >> 16) { + case 0: + ND_PRINT((ndo, ", vlan_tag none")); + break; + case ETHERTYPE_8021Q: + ND_PRINT((ndo, ", vlan_tag 802.1Q (%s)", ieee8021q_tci_string(vlan_tag & 0xffff))); + break; + default: + ND_PRINT((ndo, ", vlan_tag unknown (0x%04x)", vlan_tag >> 16)); + } + /* copy_stage */ + ND_TCHECK2(*cp, 1); + ND_PRINT((ndo, ", copy_stage %s", tok2str(bsn_mirror_copy_stage_str, "unknown (%u)", *cp))); + cp += 1; + /* pad */ + ND_TCHECK2(*cp, 3); + cp += 3; + break; + default: + ND_TCHECK2(*cp, len - 4); + cp += len - 4; + } + + return cp; + +corrupt: + ND_PRINT((ndo, "%s", cstr)); + ND_TCHECK2(*cp0, len); + return cp0 + len; +trunc: + ND_PRINT((ndo, "%s", tstr)); + return ep; +} + +static const u_char * +of10_vendor_action_print(netdissect_options *ndo, + const u_char *cp, const u_char *ep, const u_int len) +{ + uint32_t vendor; + const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, const u_int); + + if (len < 4) + goto corrupt; + /* vendor */ + ND_TCHECK2(*cp, 4); + vendor = EXTRACT_32BITS(cp); + cp += 4; + ND_PRINT((ndo, ", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor))); + /* data */ + decoder = + vendor == OUI_BSN ? of10_bsn_actions_print : + of10_data_print; + return decoder(ndo, cp, ep, len - 4); + +corrupt: /* skip the undersized data */ + ND_PRINT((ndo, "%s", cstr)); + ND_TCHECK2(*cp, len); + return cp + len; +trunc: + ND_PRINT((ndo, "%s", tstr)); + return ep; +} + static const u_char * of10_vendor_message_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ uint32_t vendor; const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, u_int); @@ -889,7 +1091,8 @@ trunc: /* Vendor ID is mandatory, data is optional. */ static const u_char * of10_vendor_data_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ uint32_t vendor; if (len < 4) @@ -913,7 +1116,8 @@ trunc: static const u_char * of10_packet_data_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ if (len == 0) return cp; /* data */ @@ -935,7 +1139,8 @@ trunc: /* [OF10] Section 5.2.1 */ static const u_char * of10_phy_ports_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) { + const u_char *cp, const u_char *ep, u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; @@ -1009,7 +1214,8 @@ trunc: /* [OF10] Section 5.2.2 */ static const u_char * of10_queue_props_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) { + const u_char *cp, const u_char *ep, u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; uint16_t property, plen, rate; @@ -1084,7 +1290,8 @@ trunc: /* ibid */ static const u_char * of10_queues_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) { + const u_char *cp, const u_char *ep, u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; uint16_t desclen; @@ -1131,7 +1338,8 @@ trunc: /* [OF10] Section 5.2.3 */ static const u_char * of10_match_print(netdissect_options *ndo, - const char *pfx, const u_char *cp, const u_char *ep) { + const char *pfx, const u_char *cp, const u_char *ep) +{ uint32_t wildcards; uint16_t dl_type; uint8_t nw_proto; @@ -1235,7 +1443,8 @@ trunc: static const u_char * of10_actions_print(netdissect_options *ndo, const char *pfx, const u_char *cp, const u_char *ep, - u_int len) { + u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; uint16_t type, alen, output_port; @@ -1374,7 +1583,7 @@ of10_actions_print(netdissect_options *ndo, cp += 4; break; case OFPAT_VENDOR: - if (ep == (cp = of10_vendor_data_print(ndo, cp, ep, alen - 4))) + if (ep == (cp = of10_vendor_action_print(ndo, cp, ep, alen - 4))) return ep; /* end of snapshot */ break; case OFPAT_STRIP_VLAN: @@ -1400,7 +1609,8 @@ trunc: /* [OF10] Section 5.3.1 */ static const u_char * of10_features_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ /* datapath_id */ ND_TCHECK2(*cp, 8); ND_PRINT((ndo, "\n\t dpid 0x%016" PRIx64, EXTRACT_64BITS(cp))); @@ -1437,7 +1647,8 @@ trunc: /* [OF10] Section 5.3.3 */ static const u_char * of10_flow_mod_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ uint16_t command; /* match */ @@ -1494,7 +1705,8 @@ trunc: /* ibid */ static const u_char * of10_port_mod_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep) { + const u_char *cp, const u_char *ep) +{ /* port_no */ ND_TCHECK2(*cp, 2); ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); @@ -1530,7 +1742,8 @@ trunc: /* [OF10] Section 5.3.5 */ static const u_char * of10_stats_request_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) { + const u_char *cp, const u_char *ep, u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; uint16_t type; @@ -1613,7 +1826,8 @@ trunc: /* ibid */ static const u_char * of10_desc_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ if (len != OF_DESC_STATS_LEN) goto corrupt; /* mfr_desc */ @@ -1659,7 +1873,8 @@ trunc: /* ibid */ static const u_char * of10_flow_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) { + const u_char *cp, const u_char *ep, u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; uint16_t entry_len; @@ -1740,7 +1955,8 @@ trunc: static const u_char * of10_aggregate_stats_reply_print(netdissect_options *ndo, const u_char *cp, const u_char *ep, - const u_int len) { + const u_int len) +{ if (len != OF_AGGREGATE_STATS_REPLY_LEN) goto corrupt; /* packet_count */ @@ -1771,7 +1987,8 @@ trunc: /* ibid */ static const u_char * of10_table_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) { + const u_char *cp, const u_char *ep, u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; @@ -1829,7 +2046,8 @@ trunc: /* ibid */ static const u_char * of10_port_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) { + const u_char *cp, const u_char *ep, u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; @@ -1913,7 +2131,8 @@ trunc: /* ibid */ static const u_char * of10_queue_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, u_int len) { + const u_char *cp, const u_char *ep, u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; @@ -1960,7 +2179,8 @@ trunc: /* ibid */ static const u_char * of10_stats_reply_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ const u_char *cp0 = cp; uint16_t type; @@ -1999,7 +2219,8 @@ trunc: /* [OF10] Section 5.3.6 */ static const u_char * of10_packet_out_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ const u_char *cp0 = cp; const u_int len0 = len; uint16_t actions_len; @@ -2036,7 +2257,8 @@ trunc: /* [OF10] Section 5.4.1 */ static const u_char * of10_packet_in_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ /* buffer_id */ ND_TCHECK2(*cp, 4); ND_PRINT((ndo, "\n\t buffer_id %s", tok2str(bufferid_str, "0x%08x", EXTRACT_32BITS(cp)))); @@ -2068,7 +2290,8 @@ trunc: /* [OF10] Section 5.4.2 */ static const u_char * of10_flow_removed_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep) { + const u_char *cp, const u_char *ep) +{ /* match */ if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) return ep; /* end of snapshot */ @@ -2121,7 +2344,8 @@ trunc: /* [OF10] Section 5.4.4 */ static const u_char * of10_error_print(netdissect_options *ndo, - const u_char *cp, const u_char *ep, const u_int len) { + const u_char *cp, const u_char *ep, const u_int len) +{ uint16_t type; const struct tok *code_str; @@ -2153,7 +2377,8 @@ trunc: 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 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