X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/fa7eedd1aa13cf963d5809bbc2f1e54bee118869..794a259a335c367d852959cd88dd9d46d183a74b:/print-openflow-1.0.c?ds=sidebyside diff --git a/print-openflow-1.0.c b/print-openflow-1.0.c index d2cc5b9e..d942fd8f 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" }, @@ -551,7 +550,7 @@ static const struct uint_tokary of10_ofpet2tokary[] = { /* lengths (fixed or minimal) of particular protocol structures */ #define OF_PHY_PORT_FIXLEN 48 -#define OF_ACTION_MINLEN 8 +#define OF_ACTION_MINLEN 8U #define OF_MATCH_FIXLEN 40 #define OF_DESC_STATS_REPLY_FIXLEN 1056 #define OF_FLOW_STATS_REQUEST_FIXLEN 44 @@ -828,7 +827,7 @@ of10_bsn_message_print(netdissect_options *ndo, OF_FWD(4); /* data */ ND_PRINT(", data '"); - (void)nd_printn(ndo, cp, len, NULL); + nd_printjn(ndo, cp, len); ND_PRINT("'"); break; case BSN_SHELL_OUTPUT: @@ -845,7 +844,7 @@ of10_bsn_message_print(netdissect_options *ndo, /* already checked that len >= 4 */ /* data */ ND_PRINT(", data '"); - (void)nd_printn(ndo, cp, len, NULL); + nd_printjn(ndo, cp, len); ND_PRINT("'"); break; case BSN_SHELL_STATUS: @@ -1018,7 +1017,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; } @@ -1279,12 +1289,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 +1307,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(len, <, alen - 4U); /* * After validating the basic length constraint it will be safe * to skip the current action if the action size is not valid @@ -1542,15 +1552,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 */ @@ -1707,13 +1717,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(len, <, entry_len); OF_FWD(2); /* table_id */ ND_PRINT(", table_id %s", @@ -1975,9 +1985,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(len, <, actions_len); /* actions */ of10_actions_print(ndo, "\n\t ", cp, actions_len); OF_FWD(actions_len);