X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/e379a5690f6db797179fa5e0845ff731db2a7af7..refs/pull/1034/head:/print-openflow-1.0.c diff --git a/print-openflow-1.0.c b/print-openflow-1.0.c index 1d9bcdaf..00c4fdd3 100644 --- a/print-openflow-1.0.c +++ b/print-openflow-1.0.c @@ -318,7 +318,6 @@ static const struct tok ofp_capabilities_bm[] = { #define OFPC_FRAG_NORMAL 0x0000U #define OFPC_FRAG_DROP 0x0001U #define OFPC_FRAG_REASM 0x0002U -#define OFPC_FRAG_MASK 0x0003U static const struct tok ofp_config_str[] = { { OFPC_FRAG_NORMAL, "FRAG_NORMAL" }, { OFPC_FRAG_DROP, "FRAG_DROP" }, @@ -700,12 +699,12 @@ of10_bsn_message_print(netdissect_options *ndo, { uint32_t subtype; - if (len < 4) - goto invalid; + ND_PRINT("\n\t"); + ND_ICHECK_U(len, <, 4); /* subtype */ subtype = GET_BE_U_4(cp); OF_FWD(4); - ND_PRINT("\n\t subtype %s", tok2str(bsn_subtype_str, "unknown (0x%08x)", subtype)); + ND_PRINT(" subtype %s", tok2str(bsn_subtype_str, "unknown (0x%08x)", subtype)); switch (subtype) { case BSN_GET_IP_MASK_REQUEST: /* @@ -720,8 +719,7 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 8) - goto invalid; + ND_ICHECK_U(len, !=, 8); /* index */ ND_PRINT(", index %u", GET_U_1(cp)); OF_FWD(1); @@ -743,8 +741,7 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 8) - goto invalid; + ND_ICHECK_U(len, !=, 8); /* index */ ND_PRINT(", index %u", GET_U_1(cp)); OF_FWD(1); @@ -766,8 +763,7 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 4) - goto invalid; + ND_ICHECK_U(len, !=, 4); /* report_mirror_ports */ ND_PRINT(", report_mirror_ports %s", tok2str(bsn_onoff_str, "bogus (%u)", GET_U_1(cp))); @@ -789,8 +785,7 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len) - goto invalid; + ND_ICHECK_U(len, !=, 0); break; case BSN_VIRTUAL_PORT_REMOVE_REQUEST: /* @@ -803,8 +798,7 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 4) - goto invalid; + ND_ICHECK_U(len, !=, 4); /* vport_no */ ND_PRINT(", vport_no %u", GET_BE_U_4(cp)); break; @@ -821,14 +815,13 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+-------- * */ - if (len < 4) - goto invalid; + ND_ICHECK_U(len, <, 4); /* service */ ND_PRINT(", service %u", GET_BE_U_4(cp)); OF_FWD(4); /* data */ ND_PRINT(", data '"); - nd_printn(ndo, cp, len, NULL); + nd_printjn(ndo, cp, len); ND_PRINT("'"); break; case BSN_SHELL_OUTPUT: @@ -845,7 +838,7 @@ of10_bsn_message_print(netdissect_options *ndo, /* already checked that len >= 4 */ /* data */ ND_PRINT(", data '"); - nd_printn(ndo, cp, len, NULL); + nd_printjn(ndo, cp, len); ND_PRINT("'"); break; case BSN_SHELL_STATUS: @@ -859,8 +852,7 @@ of10_bsn_message_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 4) - goto invalid; + ND_ICHECK_U(len, !=, 4); /* status */ ND_PRINT(", status 0x%08x", GET_BE_U_4(cp)); break; @@ -880,12 +872,12 @@ of10_bsn_actions_print(netdissect_options *ndo, { uint32_t subtype, vlan_tag; - if (len < 4) - goto invalid; + ND_PRINT("\n\t "); + ND_ICHECK_U(len, <, 4); /* subtype */ subtype = GET_BE_U_4(cp); OF_FWD(4); - ND_PRINT("\n\t subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype)); + ND_PRINT(" subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype)); switch (subtype) { case BSN_ACTION_MIRROR: /* @@ -902,8 +894,7 @@ of10_bsn_actions_print(netdissect_options *ndo, * +---------------+---------------+---------------+---------------+ * */ - if (len != 12) - goto invalid; + ND_ICHECK_U(len, !=, 12); /* dest_port */ ND_PRINT(", dest_port %u", GET_BE_U_4(cp)); OF_FWD(4); @@ -945,8 +936,7 @@ of10_vendor_action_print(netdissect_options *ndo, uint32_t vendor; void (*decoder)(netdissect_options *, const u_char *, u_int); - if (len < 4) - goto invalid; + ND_ICHECK_U(len, <, 4); /* vendor */ vendor = GET_BE_U_4(cp); OF_FWD(4); @@ -989,8 +979,7 @@ of10_vendor_data_print(netdissect_options *ndo, { uint32_t vendor; - if (len < 4) - goto invalid; + ND_ICHECK_U(len, <, 4); /* vendor */ vendor = GET_BE_U_4(cp); OF_FWD(4); @@ -1018,7 +1007,18 @@ of10_packet_data_print(netdissect_options *ndo, } ndo->ndo_vflag -= 3; ND_PRINT(", frame decoding below\n"); + /* + * The encapsulated Ethernet frame is not necessarily the last + * data of this packet (i.e. there may be more OpenFlow messages + * after the current OFPT_PACKET_IN/OFPT_PACKET_OUT message, in + * which case the current (outer) packet's snapshot end is not + * what ether_print() needs to decode an Ethernet frame nested in + * the middle of a TCP payload. + */ + const u_char *snapend_save = ndo->ndo_snapend; + ndo->ndo_snapend = ND_MIN(cp + len, ndo->ndo_snapend); ether_print(ndo, cp, len, ND_BYTES_AVAILABLE_AFTER(cp), NULL, NULL); + ndo->ndo_snapend = snapend_save; ndo->ndo_vflag += 3; } @@ -1038,7 +1038,7 @@ of10_phy_port_print(netdissect_options *ndo, cp += MAC_ADDR_LEN; /* name */ ND_PRINT(", name '"); - (void)nd_print(ndo, cp, cp + OFP_MAX_PORT_NAME_LEN); + nd_printjnp(ndo, cp, OFP_MAX_PORT_NAME_LEN); ND_PRINT("'"); cp += OFP_MAX_PORT_NAME_LEN; @@ -1088,18 +1088,18 @@ of10_queue_props_print(netdissect_options *ndo, uint16_t property, plen; u_char plen_bogus = 0, skip = 0; - if (len < OF_QUEUE_PROP_MINLEN) - goto invalid; + ND_PRINT("\n\t "); + ND_ICHECKMSG_U("remaining length", len, <, OF_QUEUE_PROP_MINLEN); /* property */ property = GET_BE_U_2(cp); OF_FWD(2); - ND_PRINT("\n\t property %s", tok2str(ofpqt_str, "invalid (0x%04x)", property)); + ND_PRINT(" property %s", tok2str(ofpqt_str, "invalid (0x%04x)", property)); /* len */ plen = GET_BE_U_2(cp); OF_FWD(2); ND_PRINT(", len %u", plen); - if (plen < OF_QUEUE_PROP_MINLEN || plen > len + 4) - goto invalid; + ND_ICHECKMSG_U("property length", plen, <, OF_QUEUE_PROP_MINLEN); + ND_ICHECKMSG_U("property length", plen, >, len + 4); /* pad */ /* Sometimes the last field, check bounds. */ OF_CHK_FWD(4); @@ -1154,17 +1154,17 @@ of10_queues_print(netdissect_options *ndo, while (len) { uint16_t desclen; - if (len < OF_PACKET_QUEUE_MINLEN) - goto invalid; + ND_PRINT("\n\t "); + ND_ICHECKMSG_U("remaining length", len, <, OF_PACKET_QUEUE_MINLEN); /* queue_id */ - ND_PRINT("\n\t queue_id %u", GET_BE_U_4(cp)); + ND_PRINT(" queue_id %u", GET_BE_U_4(cp)); OF_FWD(4); /* len */ desclen = GET_BE_U_2(cp); OF_FWD(2); ND_PRINT(", len %u", desclen); - if (desclen < OF_PACKET_QUEUE_MINLEN || desclen > len + 6) - goto invalid; + ND_ICHECKMSG_U("prop. desc. length", desclen, <, OF_PACKET_QUEUE_MINLEN); + ND_ICHECKMSG_U("prop. desc. length", desclen, >, len + 6); /* pad */ /* Sometimes the last field, check bounds. */ OF_CHK_FWD(2); @@ -1279,12 +1279,12 @@ of10_actions_print(netdissect_options *ndo, uint16_t type, alen, output_port; u_char alen_bogus = 0, skip = 0; - if (len < OF_ACTION_MINLEN) - goto invalid; + ND_PRINT("%saction", pfx); + ND_ICHECKMSG_U("remaining length", len, <, OF_ACTION_MINLEN); /* type */ type = GET_BE_U_2(cp); OF_FWD(2); - ND_PRINT("%saction type %s", pfx, tok2str(ofpat_str, "invalid (0x%04x)", type)); + ND_PRINT(" type %s", tok2str(ofpat_str, "invalid (0x%04x)", type)); /* length */ alen = GET_BE_U_2(cp); OF_FWD(2); @@ -1297,8 +1297,8 @@ of10_actions_print(netdissect_options *ndo, */ /* On action size underrun/overrun skip the rest of the action list. */ - if (alen < OF_ACTION_MINLEN || alen > len + 4) - goto invalid; + ND_ICHECK_U(alen, <, OF_ACTION_MINLEN); + ND_ICHECK_U(alen, >, len + 4); /* * After validating the basic length constraint it will be safe * to skip the current action if the action size is not valid @@ -1457,8 +1457,7 @@ of10_features_reply_print(netdissect_options *ndo, OF_FWD(4); /* ports */ while (len) { - if (len < OF_PHY_PORT_FIXLEN) - goto invalid; + ND_ICHECKMSG_U("\n\t port def. length", len, <, OF_PHY_PORT_FIXLEN); of10_phy_port_print(ndo, cp); OF_FWD(OF_PHY_PORT_FIXLEN); } @@ -1542,15 +1541,15 @@ of10_port_mod_print(netdissect_options *ndo, ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp)); cp += MAC_ADDR_LEN; /* config */ - ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); + ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp)); 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)); + ND_PRINT("\n\t mask 0x%08x", GET_BE_U_4(cp)); 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)); + ND_PRINT("\n\t advertise 0x%08x", GET_BE_U_4(cp)); of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U); cp += 4; /* pad */ @@ -1606,13 +1605,11 @@ of10_stats_request_print(netdissect_options *ndo, switch(type) { case OFPST_DESC: case OFPST_TABLE: - if (len) - goto invalid; + ND_ICHECK_U(len, !=, 0); return; case OFPST_FLOW: case OFPST_AGGREGATE: - if (len != OF_FLOW_STATS_REQUEST_FIXLEN) - goto invalid; + ND_ICHECK_U(len, !=, OF_FLOW_STATS_REQUEST_FIXLEN); /* match */ of10_match_print(ndo, "\n\t ", cp); OF_FWD(OF_MATCH_FIXLEN); @@ -1627,8 +1624,7 @@ of10_stats_request_print(netdissect_options *ndo, tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); return; case OFPST_PORT: - if (len != OF_PORT_STATS_REQUEST_FIXLEN) - goto invalid; + ND_ICHECK_U(len, !=, OF_PORT_STATS_REQUEST_FIXLEN); /* port_no */ ND_PRINT("\n\t port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); @@ -1638,8 +1634,7 @@ of10_stats_request_print(netdissect_options *ndo, OF_CHK_FWD(6); return; case OFPST_QUEUE: - if (len != OF_QUEUE_STATS_REQUEST_FIXLEN) - goto invalid; + ND_ICHECK_U(len, !=, OF_QUEUE_STATS_REQUEST_FIXLEN); /* port_no */ ND_PRINT("\n\t port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); @@ -1666,31 +1661,31 @@ static void of10_desc_stats_reply_print(netdissect_options *ndo, const u_char *cp, u_int len) { - if (len != OF_DESC_STATS_REPLY_FIXLEN) - goto invalid; + ND_PRINT("\n\t "); + ND_ICHECK_U(len, !=, OF_DESC_STATS_REPLY_FIXLEN); /* mfr_desc */ - ND_PRINT("\n\t mfr_desc '"); - (void)nd_print(ndo, cp, cp + DESC_STR_LEN); + ND_PRINT(" mfr_desc '"); + nd_printjnp(ndo, cp, DESC_STR_LEN); ND_PRINT("'"); OF_FWD(DESC_STR_LEN); /* hw_desc */ ND_PRINT("\n\t hw_desc '"); - (void)nd_print(ndo, cp, cp + DESC_STR_LEN); + nd_printjnp(ndo, cp, DESC_STR_LEN); ND_PRINT("'"); OF_FWD(DESC_STR_LEN); /* sw_desc */ ND_PRINT("\n\t sw_desc '"); - (void)nd_print(ndo, cp, cp + DESC_STR_LEN); + nd_printjnp(ndo, cp, DESC_STR_LEN); ND_PRINT("'"); OF_FWD(DESC_STR_LEN); /* serial_num */ ND_PRINT("\n\t serial_num '"); - (void)nd_print(ndo, cp, cp + SERIAL_NUM_LEN); + nd_printjnp(ndo, cp, SERIAL_NUM_LEN); ND_PRINT("'"); OF_FWD(SERIAL_NUM_LEN); /* dp_desc */ ND_PRINT("\n\t dp_desc '"); - (void)nd_print(ndo, cp, cp + DESC_STR_LEN); + nd_printjnp(ndo, cp, DESC_STR_LEN); ND_PRINT("'"); return; @@ -1707,13 +1702,13 @@ of10_flow_stats_reply_print(netdissect_options *ndo, while (len) { uint16_t entry_len; - if (len < OF_FLOW_STATS_REPLY_MINLEN) - goto invalid; + ND_PRINT("\n\t"); + ND_ICHECKMSG_U("remaining length", len, <, OF_FLOW_STATS_REPLY_MINLEN); /* length */ entry_len = GET_BE_U_2(cp); - ND_PRINT("\n\t length %u", entry_len); - if (entry_len < OF_FLOW_STATS_REPLY_MINLEN || entry_len > len) - goto invalid; + ND_PRINT(" length %u", entry_len); + ND_ICHECK_U(entry_len, <, OF_FLOW_STATS_REPLY_MINLEN); + ND_ICHECK_U(entry_len, >, len); OF_FWD(2); /* table_id */ ND_PRINT(", table_id %s", @@ -1766,10 +1761,10 @@ static void of10_aggregate_stats_reply_print(netdissect_options *ndo, const u_char *cp, u_int len) { - if (len != OF_AGGREGATE_STATS_REPLY_FIXLEN) - goto invalid; + ND_PRINT("\n\t"); + ND_ICHECKMSG_U("remaining length", len, !=, OF_AGGREGATE_STATS_REPLY_FIXLEN); /* packet_count */ - ND_PRINT("\n\t packet_count %" PRIu64, GET_BE_U_8(cp)); + ND_PRINT(" packet_count %" PRIu64, GET_BE_U_8(cp)); OF_FWD(8); /* byte_count */ ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp)); @@ -1793,17 +1788,17 @@ of10_table_stats_reply_print(netdissect_options *ndo, const u_char *cp, u_int len) { while (len) { - if (len < OF_TABLE_STATS_REPLY_FIXLEN) - goto invalid; + ND_PRINT("\n\t"); + ND_ICHECKMSG_U("remaining length", len, <, OF_TABLE_STATS_REPLY_FIXLEN); /* table_id */ - ND_PRINT("\n\t table_id %s", + ND_PRINT(" table_id %s", tok2str(tableid_str, "%u", GET_U_1(cp))); OF_FWD(1); /* pad */ OF_FWD(3); /* name */ ND_PRINT(", name '"); - (void)nd_print(ndo, cp, cp + OFP_MAX_TABLE_NAME_LEN); + nd_printjnp(ndo, cp, OFP_MAX_TABLE_NAME_LEN); ND_PRINT("'"); OF_FWD(OFP_MAX_TABLE_NAME_LEN); /* wildcards */ @@ -1836,10 +1831,10 @@ of10_port_stats_reply_print(netdissect_options *ndo, const u_char *cp, u_int len) { while (len) { - if (len < OF_PORT_STATS_REPLY_FIXLEN) - goto invalid; + ND_PRINT("\n\t "); + ND_ICHECKMSG_U("remaining length", len, <, OF_PORT_STATS_REPLY_FIXLEN); /* port_no */ - ND_PRINT("\n\t port_no %s", + ND_PRINT(" port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); OF_FWD(2); if (ndo->ndo_vflag < 2) { @@ -1898,10 +1893,10 @@ of10_queue_stats_reply_print(netdissect_options *ndo, const u_char *cp, u_int len) { while (len) { - if (len < OF_QUEUE_STATS_REPLY_FIXLEN) - goto invalid; + ND_PRINT("\n\t "); + ND_ICHECKMSG_U("remaining length", len, <, OF_QUEUE_STATS_REPLY_FIXLEN); /* port_no */ - ND_PRINT("\n\t port_no %s", + ND_PRINT(" port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp))); OF_FWD(2); /* pad */ @@ -1975,9 +1970,9 @@ of10_packet_out_print(netdissect_options *ndo, OF_FWD(2); /* actions_len */ actions_len = GET_BE_U_2(cp); + ND_PRINT(", actions_len %u", actions_len); OF_FWD(2); - if (actions_len > len) - goto invalid; + ND_ICHECK_U(actions_len, >, len); /* actions */ of10_actions_print(ndo, "\n\t ", cp, actions_len); OF_FWD(actions_len);