X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/f5d8a72d30c80c4a964c4e16bdde398b577ed47c..c115ab8ae92fd369ac227e93419e76fd6ae8e75c:/print-openflow-1.0.c diff --git a/print-openflow-1.0.c b/print-openflow-1.0.c index 6f86709d..a36c32f3 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 @@ -670,9 +671,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; @@ -684,7 +709,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; @@ -692,7 +718,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) @@ -709,7 +736,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 */ @@ -726,7 +754,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; @@ -798,15 +827,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); @@ -846,6 +875,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; @@ -861,9 +957,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); @@ -892,7 +1092,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) @@ -916,7 +1117,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 */ @@ -938,7 +1140,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; @@ -1012,7 +1215,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; @@ -1087,7 +1291,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; @@ -1134,7 +1339,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; @@ -1238,7 +1444,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; @@ -1377,7 +1584,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: @@ -1403,7 +1610,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))); @@ -1440,7 +1648,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 */ @@ -1497,7 +1706,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)))); @@ -1533,7 +1743,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; @@ -1616,7 +1827,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 */ @@ -1662,7 +1874,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; @@ -1743,7 +1956,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 */ @@ -1774,7 +1988,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; @@ -1832,7 +2047,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; @@ -1916,7 +2132,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; @@ -1963,7 +2180,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; @@ -2002,7 +2220,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; @@ -2039,7 +2258,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)))); @@ -2071,7 +2291,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 */ @@ -2124,7 +2345,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; @@ -2156,7 +2378,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