]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-openflow-1.0.c
Merge pull request #344 from glebius/master
[tcpdump] / print-openflow-1.0.c
index f4bd977bfefa6c58552672f127202397e176fa6e..435b424b20073add79f3d70247ce17516c76a40b 100644 (file)
@@ -8,6 +8,13 @@
  *
  * [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.
@@ -44,6 +51,7 @@
 #include "interface.h"
 #include "extract.h"
 #include "addrtoname.h"
+#include "ether.h"
 #include "ethertype.h"
 #include "ipproto.h"
 #include "openflow.h"
@@ -566,7 +574,6 @@ static const struct tok empty_str[] = {
 #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 *
@@ -641,6 +648,26 @@ trunc:
        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) {
@@ -655,9 +682,9 @@ 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 '");
@@ -855,15 +882,15 @@ of10_match_print(const char *pfx, const u_char *cp, const u_char *ep) {
                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))
@@ -1031,9 +1058,9 @@ of10_actions_print(const char *pfx, const u_char *cp, const u_char *ep,
                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;
@@ -1201,9 +1228,9 @@ of10_port_mod_print(const u_char *cp, const u_char *ep) {
        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));
@@ -1714,7 +1741,7 @@ of10_packet_out_print(const u_char *cp, const u_char *ep, const u_int len) {
        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)");
@@ -1749,7 +1776,7 @@ of10_packet_in_print(const u_char *cp, const u_char *ep, const u_int len) {
        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]");