*
* [OF10] http://www.openflow.org/documents/openflow-spec-v1.0.0.pdf
*
+ * Decoding of Ethernet frames nested in OFPT_PACKET_IN and OFPT_PACKET_OUT
+ * messages is done only when the verbosity level set by command-line argument
+ * is "-vvv" or higher. In that case the verbosity level is temporarily
+ * decremented by 3 during the nested frame decoding. For example, running
+ * tcpdump with "-vvvv" will do full decoding of OpenFlow and "-v" decoding of
+ * the nested frames.
+ *
*
* Copyright (c) 2013 The TCPDUMP project
* All rights reserved.
#include "interface.h"
#include "extract.h"
#include "addrtoname.h"
+#include "ether.h"
#include "ethertype.h"
#include "ipproto.h"
#include "openflow.h"
#define OFP_MAX_PORT_NAME_LEN 16
#define DESC_STR_LEN 256
#define SERIAL_NUM_LEN 32
-#define OFP_ETH_ALEN 6
#define OFP_VLAN_NONE 0xffff
static const char *
return ep;
}
+static const u_char *
+of10_packet_data_print(const u_char *cp, const u_char *ep, const u_int len) {
+ if (len == 0)
+ return cp;
+ /* data */
+ printf("\n\t data (%u octets)", len);
+ if (vflag < 3)
+ return cp + len;
+ TCHECK2(*cp, len);
+ vflag -= 3;
+ printf(", frame decoding below\n");
+ ether_print(gndo, cp, len, snapend - cp, NULL, NULL);
+ vflag += 3;
+ return cp + len;
+
+trunc:
+ printf(" [|openflow]");
+ return ep;
+}
+
/* [OF10] Section 5.2.1 */
static const u_char *
of10_phy_ports_print(const u_char *cp, const u_char *ep, u_int len) {
printf("\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
cp += 2;
/* hw_addr */
- TCHECK2(*cp, OFP_ETH_ALEN);
+ TCHECK2(*cp, ETHER_ADDR_LEN);
printf(", hw_addr %s", etheraddr_string(cp));
- cp += OFP_ETH_ALEN;
+ cp += ETHER_ADDR_LEN;
/* name */
TCHECK2(*cp, OFP_MAX_PORT_NAME_LEN);
printf(", name '");
printf("%smatch in_port %s", pfx, tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
cp += 2;
/* dl_src */
- TCHECK2(*cp, OFP_ETH_ALEN);
+ TCHECK2(*cp, ETHER_ADDR_LEN);
if (! (wildcards & OFPFW_DL_SRC))
printf("%smatch dl_src %s", pfx, etheraddr_string(cp));
- cp += OFP_ETH_ALEN;
+ cp += ETHER_ADDR_LEN;
/* dl_dst */
- TCHECK2(*cp, OFP_ETH_ALEN);
+ TCHECK2(*cp, ETHER_ADDR_LEN);
if (! (wildcards & OFPFW_DL_DST))
printf("%smatch dl_dst %s", pfx, etheraddr_string(cp));
- cp += OFP_ETH_ALEN;
+ cp += ETHER_ADDR_LEN;
/* dl_vlan */
TCHECK2(*cp, 2);
if (! (wildcards & OFPFW_DL_VLAN))
case OFPAT_SET_DL_SRC:
case OFPAT_SET_DL_DST:
/* dl_addr */
- TCHECK2(*cp, OFP_ETH_ALEN);
+ TCHECK2(*cp, ETHER_ADDR_LEN);
printf(", dl_addr %s", etheraddr_string(cp));
- cp += OFP_ETH_ALEN;
+ cp += ETHER_ADDR_LEN;
/* pad */
TCHECK2(*cp, 6);
cp += 6;
printf("\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
cp += 2;
/* hw_addr */
- TCHECK2(*cp, OFP_ETH_ALEN);
+ TCHECK2(*cp, ETHER_ADDR_LEN);
printf(", hw_addr %s", etheraddr_string(cp));
- cp += OFP_ETH_ALEN;
+ cp += ETHER_ADDR_LEN;
/* config */
TCHECK2(*cp, 4);
printf("\n\t config 0x%08x", EXTRACT_32BITS(cp));
if (ep == (cp = of10_actions_print("\n\t ", cp, ep, actions_len)))
return ep; /* end of snapshot */
/* data */
- return of10_data_print(cp, ep, len - OF_PACKET_OUT_LEN - actions_len);
+ return of10_packet_data_print(cp, ep, len - OF_PACKET_OUT_LEN - actions_len);
corrupt: /* skip the rest of the message body */
printf(" (corrupt)");
cp += 1;
/* data */
/* 2 mock octets count in OF_PACKET_IN_LEN but not in len */
- return of10_data_print(cp, ep, len - (OF_PACKET_IN_LEN - 2));
+ return of10_packet_data_print(cp, ep, len - (OF_PACKET_IN_LEN - 2));
trunc:
printf(" [|openflow]");