Home | History | Annotate | Download | only in tcpdump
      1 /*
      2  * This module implements decoding of OpenFlow protocol version 1.0 (wire
      3  * protocol 0x01). The decoder implements terse (default), detailed (-v) and
      4  * full (-vv) output formats and, as much as each format implies, detects and
      5  * tries to work around sizing anomalies inside the messages. The decoder marks
      6  * up bogus values of selected message fields and decodes partially captured
      7  * messages up to the snapshot end. It is based on the specification below:
      8  *
      9  * [OF10] http://www.openflow.org/documents/openflow-spec-v1.0.0.pdf
     10  *
     11  * Decoding of Ethernet frames nested in OFPT_PACKET_IN and OFPT_PACKET_OUT
     12  * messages is done only when the verbosity level set by command-line argument
     13  * is "-vvv" or higher. In that case the verbosity level is temporarily
     14  * decremented by 3 during the nested frame decoding. For example, running
     15  * tcpdump with "-vvvv" will do full decoding of OpenFlow and "-v" decoding of
     16  * the nested frames.
     17  *
     18  *
     19  * Copyright (c) 2013 The TCPDUMP project
     20  * All rights reserved.
     21  *
     22  * Redistribution and use in source and binary forms, with or without
     23  * modification, are permitted provided that the following conditions
     24  * are met:
     25  * 1. Redistributions of source code must retain the above copyright
     26  *    notice, this list of conditions and the following disclaimer.
     27  * 2. Redistributions in binary form must reproduce the above copyright
     28  *    notice, this list of conditions and the following disclaimer in the
     29  *    documentation and/or other materials provided with the distribution.
     30  *
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     34  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     35  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     36  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     37  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     38  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     39  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     41  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     42  * POSSIBILITY OF SUCH DAMAGE.
     43  */
     44 
     45 #ifdef HAVE_CONFIG_H
     46 #include "config.h"
     47 #endif
     48 
     49 #include <tcpdump-stdinc.h>
     50 
     51 #include "interface.h"
     52 #include "extract.h"
     53 #include "addrtoname.h"
     54 #include "ethertype.h"
     55 #include "ipproto.h"
     56 #include "openflow.h"
     57 
     58 #define OFPT_HELLO                    0x00
     59 #define OFPT_ERROR                    0x01
     60 #define OFPT_ECHO_REQUEST             0x02
     61 #define OFPT_ECHO_REPLY               0x03
     62 #define OFPT_VENDOR                   0x04
     63 #define OFPT_FEATURES_REQUEST         0x05
     64 #define OFPT_FEATURES_REPLY           0x06
     65 #define OFPT_GET_CONFIG_REQUEST       0x07
     66 #define OFPT_GET_CONFIG_REPLY         0x08
     67 #define OFPT_SET_CONFIG               0x09
     68 #define OFPT_PACKET_IN                0x0a
     69 #define OFPT_FLOW_REMOVED             0x0b
     70 #define OFPT_PORT_STATUS              0x0c
     71 #define OFPT_PACKET_OUT               0x0d
     72 #define OFPT_FLOW_MOD                 0x0e
     73 #define OFPT_PORT_MOD                 0x0f
     74 #define OFPT_STATS_REQUEST            0x10
     75 #define OFPT_STATS_REPLY              0x11
     76 #define OFPT_BARRIER_REQUEST          0x12
     77 #define OFPT_BARRIER_REPLY            0x13
     78 #define OFPT_QUEUE_GET_CONFIG_REQUEST 0x14
     79 #define OFPT_QUEUE_GET_CONFIG_REPLY   0x15
     80 static const struct tok ofpt_str[] = {
     81 	{ OFPT_HELLO,                    "HELLO"                    },
     82 	{ OFPT_ERROR,                    "ERROR"                    },
     83 	{ OFPT_ECHO_REQUEST,             "ECHO_REQUEST"             },
     84 	{ OFPT_ECHO_REPLY,               "ECHO_REPLY"               },
     85 	{ OFPT_VENDOR,                   "VENDOR"                   },
     86 	{ OFPT_FEATURES_REQUEST,         "FEATURES_REQUEST"         },
     87 	{ OFPT_FEATURES_REPLY,           "FEATURES_REPLY"           },
     88 	{ OFPT_GET_CONFIG_REQUEST,       "GET_CONFIG_REQUEST"       },
     89 	{ OFPT_GET_CONFIG_REPLY,         "GET_CONFIG_REPLY"         },
     90 	{ OFPT_SET_CONFIG,               "SET_CONFIG"               },
     91 	{ OFPT_PACKET_IN,                "PACKET_IN"                },
     92 	{ OFPT_FLOW_REMOVED,             "FLOW_REMOVED"             },
     93 	{ OFPT_PORT_STATUS,              "PORT_STATUS"              },
     94 	{ OFPT_PACKET_OUT,               "PACKET_OUT"               },
     95 	{ OFPT_FLOW_MOD,                 "FLOW_MOD"                 },
     96 	{ OFPT_PORT_MOD,                 "PORT_MOD"                 },
     97 	{ OFPT_STATS_REQUEST,            "STATS_REQUEST"            },
     98 	{ OFPT_STATS_REPLY,              "STATS_REPLY"              },
     99 	{ OFPT_BARRIER_REQUEST,          "BARRIER_REQUEST"          },
    100 	{ OFPT_BARRIER_REPLY,            "BARRIER_REPLY"            },
    101 	{ OFPT_QUEUE_GET_CONFIG_REQUEST, "QUEUE_GET_CONFIG_REQUEST" },
    102 	{ OFPT_QUEUE_GET_CONFIG_REPLY,   "QUEUE_GET_CONFIG_REPLY"   },
    103 	{ 0, NULL }
    104 };
    105 
    106 #define OFPPC_PORT_DOWN    (1 << 0)
    107 #define OFPPC_NO_STP       (1 << 1)
    108 #define OFPPC_NO_RECV      (1 << 2)
    109 #define OFPPC_NO_RECV_STP  (1 << 3)
    110 #define OFPPC_NO_FLOOD     (1 << 4)
    111 #define OFPPC_NO_FWD       (1 << 5)
    112 #define OFPPC_NO_PACKET_IN (1 << 6)
    113 static const struct tok ofppc_bm[] = {
    114 	{ OFPPC_PORT_DOWN,    "PORT_DOWN"    },
    115 	{ OFPPC_NO_STP,       "NO_STP"       },
    116 	{ OFPPC_NO_RECV,      "NO_RECV"      },
    117 	{ OFPPC_NO_RECV_STP,  "NO_RECV_STP"  },
    118 	{ OFPPC_NO_FLOOD,     "NO_FLOOD"     },
    119 	{ OFPPC_NO_FWD,       "NO_FWD"       },
    120 	{ OFPPC_NO_PACKET_IN, "NO_PACKET_IN" },
    121 	{ 0, NULL }
    122 };
    123 #define OFPPC_U (~(OFPPC_PORT_DOWN | OFPPC_NO_STP | OFPPC_NO_RECV | \
    124                    OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD | \
    125                    OFPPC_NO_PACKET_IN))
    126 
    127 #define OFPPS_LINK_DOWN   (1 << 0)
    128 #define OFPPS_STP_LISTEN  (0 << 8)
    129 #define OFPPS_STP_LEARN   (1 << 8)
    130 #define OFPPS_STP_FORWARD (2 << 8)
    131 #define OFPPS_STP_BLOCK   (3 << 8)
    132 #define OFPPS_STP_MASK    (3 << 8)
    133 static const struct tok ofpps_bm[] = {
    134 	{ OFPPS_LINK_DOWN,   "LINK_DOWN"   },
    135 	{ OFPPS_STP_LISTEN,  "STP_LISTEN"  },
    136 	{ OFPPS_STP_LEARN,   "STP_LEARN"   },
    137 	{ OFPPS_STP_FORWARD, "STP_FORWARD" },
    138 	{ OFPPS_STP_BLOCK,   "STP_BLOCK"   },
    139 	{ 0, NULL }
    140 };
    141 #define OFPPS_U (~(OFPPS_LINK_DOWN | OFPPS_STP_LISTEN | OFPPS_STP_LEARN | \
    142                    OFPPS_STP_FORWARD | OFPPS_STP_BLOCK))
    143 
    144 #define OFPP_MAX        0xff00
    145 #define OFPP_IN_PORT    0xfff8
    146 #define OFPP_TABLE      0xfff9
    147 #define OFPP_NORMAL     0xfffa
    148 #define OFPP_FLOOD      0xfffb
    149 #define OFPP_ALL        0xfffc
    150 #define OFPP_CONTROLLER 0xfffd
    151 #define OFPP_LOCAL      0xfffe
    152 #define OFPP_NONE       0xffff
    153 static const struct tok ofpp_str[] = {
    154 	{ OFPP_MAX,        "MAX"        },
    155 	{ OFPP_IN_PORT,    "IN_PORT"    },
    156 	{ OFPP_TABLE,      "TABLE"      },
    157 	{ OFPP_NORMAL,     "NORMAL"     },
    158 	{ OFPP_FLOOD,      "FLOOD"      },
    159 	{ OFPP_ALL,        "ALL"        },
    160 	{ OFPP_CONTROLLER, "CONTROLLER" },
    161 	{ OFPP_LOCAL,      "LOCAL"      },
    162 	{ OFPP_NONE,       "NONE"       },
    163 	{ 0, NULL }
    164 };
    165 
    166 #define OFPPF_10MB_HD    (1 <<  0)
    167 #define OFPPF_10MB_FD    (1 <<  1)
    168 #define OFPPF_100MB_HD   (1 <<  2)
    169 #define OFPPF_100MB_FD   (1 <<  3)
    170 #define OFPPF_1GB_HD     (1 <<  4)
    171 #define OFPPF_1GB_FD     (1 <<  5)
    172 #define OFPPF_10GB_FD    (1 <<  6)
    173 #define OFPPF_COPPER     (1 <<  7)
    174 #define OFPPF_FIBER      (1 <<  8)
    175 #define OFPPF_AUTONEG    (1 <<  9)
    176 #define OFPPF_PAUSE      (1 << 10)
    177 #define OFPPF_PAUSE_ASYM (1 << 11)
    178 static const struct tok ofppf_bm[] = {
    179 	{ OFPPF_10MB_HD,    "10MB_HD"    },
    180 	{ OFPPF_10MB_FD,    "10MB_FD"    },
    181 	{ OFPPF_100MB_HD,   "100MB_HD"   },
    182 	{ OFPPF_100MB_FD,   "100MB_FD"   },
    183 	{ OFPPF_1GB_HD,     "1GB_HD"     },
    184 	{ OFPPF_1GB_FD,     "1GB_FD"     },
    185 	{ OFPPF_10GB_FD,    "10GB_FD"    },
    186 	{ OFPPF_COPPER,     "COPPER"     },
    187 	{ OFPPF_FIBER,      "FIBER"      },
    188 	{ OFPPF_AUTONEG,    "AUTONEG"    },
    189 	{ OFPPF_PAUSE,      "PAUSE"      },
    190 	{ OFPPF_PAUSE_ASYM, "PAUSE_ASYM" },
    191 	{ 0, NULL }
    192 };
    193 #define OFPPF_U (~(OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | \
    194                    OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | \
    195                    OFPPF_10GB_FD | OFPPF_COPPER | OFPPF_FIBER | \
    196                    OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM))
    197 
    198 #define OFPQT_NONE     0x0000
    199 #define OFPQT_MIN_RATE 0x0001
    200 static const struct tok ofpqt_str[] = {
    201 	{ OFPQT_NONE,     "NONE"     },
    202 	{ OFPQT_MIN_RATE, "MIN_RATE" },
    203 	{ 0, NULL }
    204 };
    205 
    206 #define OFPFW_IN_PORT      (1 << 0)
    207 #define OFPFW_DL_VLAN      (1 << 1)
    208 #define OFPFW_DL_SRC       (1 << 2)
    209 #define OFPFW_DL_DST       (1 << 3)
    210 #define OFPFW_DL_TYPE      (1 << 4)
    211 #define OFPFW_NW_PROTO     (1 << 5)
    212 #define OFPFW_TP_SRC       (1 << 6)
    213 #define OFPFW_TP_DST       (1 << 7)
    214 #define OFPFW_NW_SRC_SHIFT 8
    215 #define OFPFW_NW_SRC_BITS  6
    216 #define OFPFW_NW_SRC_MASK  (((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT)
    217 #define OFPFW_NW_DST_SHIFT 14
    218 #define OFPFW_NW_DST_BITS  6
    219 #define OFPFW_NW_DST_MASK  (((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT)
    220 #define OFPFW_DL_VLAN_PCP  (1 << 20)
    221 #define OFPFW_NW_TOS       (1 << 21)
    222 #define OFPFW_ALL          ((1 << 22) - 1)
    223 static const struct tok ofpfw_bm[] = {
    224 	{ OFPFW_IN_PORT,     "IN_PORT"     },
    225 	{ OFPFW_DL_VLAN,     "DL_VLAN"     },
    226 	{ OFPFW_DL_SRC,      "DL_SRC"      },
    227 	{ OFPFW_DL_DST,      "DL_DST"      },
    228 	{ OFPFW_DL_TYPE,     "DL_TYPE"     },
    229 	{ OFPFW_NW_PROTO,    "NW_PROTO"    },
    230 	{ OFPFW_TP_SRC,      "TP_SRC"      },
    231 	{ OFPFW_TP_DST,      "TP_DST"      },
    232 	{ OFPFW_DL_VLAN_PCP, "DL_VLAN_PCP" },
    233 	{ OFPFW_NW_TOS,      "NW_TOS"      },
    234 	{ 0, NULL }
    235 };
    236 /* The above array does not include bits 8~13 (OFPFW_NW_SRC_*) and 14~19
    237  * (OFPFW_NW_DST_*), which are not a part of the bitmap and require decoding
    238  * other than that of tok2str(). The macro below includes these bits such that
    239  * they are not reported as bogus in the decoding. */
    240 #define OFPFW_U (~(OFPFW_ALL))
    241 
    242 #define OFPAT_OUTPUT       0x0000
    243 #define OFPAT_SET_VLAN_VID 0x0001
    244 #define OFPAT_SET_VLAN_PCP 0x0002
    245 #define OFPAT_STRIP_VLAN   0x0003
    246 #define OFPAT_SET_DL_SRC   0x0004
    247 #define OFPAT_SET_DL_DST   0x0005
    248 #define OFPAT_SET_NW_SRC   0x0006
    249 #define OFPAT_SET_NW_DST   0x0007
    250 #define OFPAT_SET_NW_TOS   0x0008
    251 #define OFPAT_SET_TP_SRC   0x0009
    252 #define OFPAT_SET_TP_DST   0x000a
    253 #define OFPAT_ENQUEUE      0x000b
    254 #define OFPAT_VENDOR       0xffff
    255 static const struct tok ofpat_str[] = {
    256 	{ OFPAT_OUTPUT,       "OUTPUT"       },
    257 	{ OFPAT_SET_VLAN_VID, "SET_VLAN_VID" },
    258 	{ OFPAT_SET_VLAN_PCP, "SET_VLAN_PCP" },
    259 	{ OFPAT_STRIP_VLAN,   "STRIP_VLAN"   },
    260 	{ OFPAT_SET_DL_SRC,   "SET_DL_SRC"   },
    261 	{ OFPAT_SET_DL_DST,   "SET_DL_DST"   },
    262 	{ OFPAT_SET_NW_SRC,   "SET_NW_SRC"   },
    263 	{ OFPAT_SET_NW_DST,   "SET_NW_DST"   },
    264 	{ OFPAT_SET_NW_TOS,   "SET_NW_TOS"   },
    265 	{ OFPAT_SET_TP_SRC,   "SET_TP_SRC"   },
    266 	{ OFPAT_SET_TP_DST,   "SET_TP_DST"   },
    267 	{ OFPAT_ENQUEUE,      "ENQUEUE"      },
    268 	{ OFPAT_VENDOR,       "VENDOR"       },
    269 	{ 0, NULL }
    270 };
    271 
    272 /* bit-shifted, w/o vendor action */
    273 static const struct tok ofpat_bm[] = {
    274 	{ 1 << OFPAT_OUTPUT,       "OUTPUT"       },
    275 	{ 1 << OFPAT_SET_VLAN_VID, "SET_VLAN_VID" },
    276 	{ 1 << OFPAT_SET_VLAN_PCP, "SET_VLAN_PCP" },
    277 	{ 1 << OFPAT_STRIP_VLAN,   "STRIP_VLAN"   },
    278 	{ 1 << OFPAT_SET_DL_SRC,   "SET_DL_SRC"   },
    279 	{ 1 << OFPAT_SET_DL_DST,   "SET_DL_DST"   },
    280 	{ 1 << OFPAT_SET_NW_SRC,   "SET_NW_SRC"   },
    281 	{ 1 << OFPAT_SET_NW_DST,   "SET_NW_DST"   },
    282 	{ 1 << OFPAT_SET_NW_TOS,   "SET_NW_TOS"   },
    283 	{ 1 << OFPAT_SET_TP_SRC,   "SET_TP_SRC"   },
    284 	{ 1 << OFPAT_SET_TP_DST,   "SET_TP_DST"   },
    285 	{ 1 << OFPAT_ENQUEUE,      "ENQUEUE"      },
    286 	{ 0, NULL }
    287 };
    288 #define OFPAT_U (~(1 << OFPAT_OUTPUT | 1 << OFPAT_SET_VLAN_VID | \
    289                    1 << OFPAT_SET_VLAN_PCP | 1 << OFPAT_STRIP_VLAN | \
    290                    1 << OFPAT_SET_DL_SRC | 1 << OFPAT_SET_DL_DST | \
    291                    1 << OFPAT_SET_NW_SRC | 1 << OFPAT_SET_NW_DST | \
    292                    1 << OFPAT_SET_NW_TOS | 1 << OFPAT_SET_TP_SRC | \
    293                    1 << OFPAT_SET_TP_DST | 1 << OFPAT_ENQUEUE))
    294 
    295 #define OFPC_FLOW_STATS   (1 << 0)
    296 #define OFPC_TABLE_STATS  (1 << 1)
    297 #define OFPC_PORT_STATS   (1 << 2)
    298 #define OFPC_STP          (1 << 3)
    299 #define OFPC_RESERVED     (1 << 4)
    300 #define OFPC_IP_REASM     (1 << 5)
    301 #define OFPC_QUEUE_STATS  (1 << 6)
    302 #define OFPC_ARP_MATCH_IP (1 << 7)
    303 static const struct tok ofp_capabilities_bm[] = {
    304 	{ OFPC_FLOW_STATS,   "FLOW_STATS"   },
    305 	{ OFPC_TABLE_STATS,  "TABLE_STATS"  },
    306 	{ OFPC_PORT_STATS,   "PORT_STATS"   },
    307 	{ OFPC_STP,          "STP"          },
    308 	{ OFPC_RESERVED,     "RESERVED"     }, /* not in the mask below */
    309 	{ OFPC_IP_REASM,     "IP_REASM"     },
    310 	{ OFPC_QUEUE_STATS,  "QUEUE_STATS"  },
    311 	{ OFPC_ARP_MATCH_IP, "ARP_MATCH_IP" },
    312 	{ 0, NULL }
    313 };
    314 #define OFPCAP_U (~(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \
    315                     OFPC_STP | OFPC_IP_REASM | OFPC_QUEUE_STATS | \
    316                     OFPC_ARP_MATCH_IP))
    317 
    318 #define OFPC_FRAG_NORMAL 0x0000
    319 #define OFPC_FRAG_DROP   0x0001
    320 #define OFPC_FRAG_REASM  0x0002
    321 #define OFPC_FRAG_MASK   0x0003
    322 static const struct tok ofp_config_str[] = {
    323 	{ OFPC_FRAG_NORMAL, "FRAG_NORMAL" },
    324 	{ OFPC_FRAG_DROP,   "FRAG_DROP"   },
    325 	{ OFPC_FRAG_REASM,  "FRAG_REASM"  },
    326 	{ 0, NULL }
    327 };
    328 
    329 #define OFPFC_ADD           0x0000
    330 #define OFPFC_MODIFY        0x0001
    331 #define OFPFC_MODIFY_STRICT 0x0002
    332 #define OFPFC_DELETE        0x0003
    333 #define OFPFC_DELETE_STRICT 0x0004
    334 static const struct tok ofpfc_str[] = {
    335 	{ OFPFC_ADD,           "ADD"           },
    336 	{ OFPFC_MODIFY,        "MODIFY"        },
    337 	{ OFPFC_MODIFY_STRICT, "MODIFY_STRICT" },
    338 	{ OFPFC_DELETE,        "DELETE"        },
    339 	{ OFPFC_DELETE_STRICT, "DELETE_STRICT" },
    340 	{ 0, NULL }
    341 };
    342 
    343 static const struct tok bufferid_str[] = {
    344 	{ 0xffffffff, "NONE" },
    345 	{ 0, NULL }
    346 };
    347 
    348 #define OFPFF_SEND_FLOW_REM (1 << 0)
    349 #define OFPFF_CHECK_OVERLAP (1 << 1)
    350 #define OFPFF_EMERG         (1 << 2)
    351 static const struct tok ofpff_bm[] = {
    352 	{ OFPFF_SEND_FLOW_REM, "SEND_FLOW_REM" },
    353 	{ OFPFF_CHECK_OVERLAP, "CHECK_OVERLAP" },
    354 	{ OFPFF_EMERG,         "EMERG"         },
    355 	{ 0, NULL }
    356 };
    357 #define OFPFF_U (~(OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_EMERG))
    358 
    359 #define OFPST_DESC      0x0000
    360 #define OFPST_FLOW      0x0001
    361 #define OFPST_AGGREGATE 0x0002
    362 #define OFPST_TABLE     0x0003
    363 #define OFPST_PORT      0x0004
    364 #define OFPST_QUEUE     0x0005
    365 #define OFPST_VENDOR    0xffff
    366 static const struct tok ofpst_str[] = {
    367 	{ OFPST_DESC,      "DESC"      },
    368 	{ OFPST_FLOW,      "FLOW"      },
    369 	{ OFPST_AGGREGATE, "AGGREGATE" },
    370 	{ OFPST_TABLE,     "TABLE"     },
    371 	{ OFPST_PORT,      "PORT"      },
    372 	{ OFPST_QUEUE,     "QUEUE"     },
    373 	{ OFPST_VENDOR,    "VENDOR"    },
    374 	{ 0, NULL }
    375 };
    376 
    377 static const struct tok tableid_str[] = {
    378 	{ 0xfe, "EMERG" },
    379 	{ 0xff, "ALL"   },
    380 	{ 0, NULL }
    381 };
    382 
    383 #define OFPQ_ALL      0xffffffff
    384 static const struct tok ofpq_str[] = {
    385 	{ OFPQ_ALL, "ALL" },
    386 	{ 0, NULL }
    387 };
    388 
    389 #define OFPSF_REPLY_MORE 0x0001
    390 static const struct tok ofpsf_reply_bm[] = {
    391 	{ OFPSF_REPLY_MORE, "MORE" },
    392 	{ 0, NULL }
    393 };
    394 #define OFPSF_REPLY_U (~(OFPSF_REPLY_MORE))
    395 
    396 #define OFPR_NO_MATCH 0x00
    397 #define OFPR_ACTION   0x01
    398 static const struct tok ofpr_str[] = {
    399 	{ OFPR_NO_MATCH, "NO_MATCH" },
    400 	{ OFPR_ACTION,   "ACTION"   },
    401 	{ 0, NULL }
    402 };
    403 
    404 #define OFPRR_IDLE_TIMEOUT 0x00
    405 #define OFPRR_HARD_TIMEOUT 0x01
    406 #define OFPRR_DELETE       0x02
    407 static const struct tok ofprr_str[] = {
    408 	{ OFPRR_IDLE_TIMEOUT, "IDLE_TIMEOUT" },
    409 	{ OFPRR_HARD_TIMEOUT, "HARD_TIMEOUT" },
    410 	{ OFPRR_DELETE,       "DELETE"       },
    411 	{ 0, NULL }
    412 };
    413 
    414 #define OFPPR_ADD    0x00
    415 #define OFPPR_DELETE 0x01
    416 #define OFPPR_MODIFY 0x02
    417 static const struct tok ofppr_str[] = {
    418 	{ OFPPR_ADD,    "ADD"    },
    419 	{ OFPPR_DELETE, "DELETE" },
    420 	{ OFPPR_MODIFY, "MODIFY" },
    421 	{ 0, NULL }
    422 };
    423 
    424 #define OFPET_HELLO_FAILED    0x0000
    425 #define OFPET_BAD_REQUEST     0x0001
    426 #define OFPET_BAD_ACTION      0x0002
    427 #define OFPET_FLOW_MOD_FAILED 0x0003
    428 #define OFPET_PORT_MOD_FAILED 0x0004
    429 #define OFPET_QUEUE_OP_FAILED 0x0005
    430 static const struct tok ofpet_str[] = {
    431 	{ OFPET_HELLO_FAILED,    "HELLO_FAILED"    },
    432 	{ OFPET_BAD_REQUEST,     "BAD_REQUEST"     },
    433 	{ OFPET_BAD_ACTION,      "BAD_ACTION"      },
    434 	{ OFPET_FLOW_MOD_FAILED, "FLOW_MOD_FAILED" },
    435 	{ OFPET_PORT_MOD_FAILED, "PORT_MOD_FAILED" },
    436 	{ OFPET_QUEUE_OP_FAILED, "QUEUE_OP_FAILED" },
    437 	{ 0, NULL }
    438 };
    439 
    440 #define OFPHFC_INCOMPATIBLE 0x0000
    441 #define OFPHFC_EPERM        0x0001
    442 static const struct tok ofphfc_str[] = {
    443 	{ OFPHFC_INCOMPATIBLE, "INCOMPATIBLE" },
    444 	{ OFPHFC_EPERM,        "EPERM"        },
    445 	{ 0, NULL }
    446 };
    447 
    448 #define OFPBRC_BAD_VERSION    0x0000
    449 #define OFPBRC_BAD_TYPE       0x0001
    450 #define OFPBRC_BAD_STAT       0x0002
    451 #define OFPBRC_BAD_VENDOR     0x0003
    452 #define OFPBRC_BAD_SUBTYPE    0x0004
    453 #define OFPBRC_EPERM          0x0005
    454 #define OFPBRC_BAD_LEN        0x0006
    455 #define OFPBRC_BUFFER_EMPTY   0x0007
    456 #define OFPBRC_BUFFER_UNKNOWN 0x0008
    457 static const struct tok ofpbrc_str[] = {
    458 	{ OFPBRC_BAD_VERSION,    "BAD_VERSION"    },
    459 	{ OFPBRC_BAD_TYPE,       "BAD_TYPE"       },
    460 	{ OFPBRC_BAD_STAT,       "BAD_STAT"       },
    461 	{ OFPBRC_BAD_VENDOR,     "BAD_VENDOR"     },
    462 	{ OFPBRC_BAD_SUBTYPE,    "BAD_SUBTYPE"    },
    463 	{ OFPBRC_EPERM,          "EPERM"          },
    464 	{ OFPBRC_BAD_LEN,        "BAD_LEN"        },
    465 	{ OFPBRC_BUFFER_EMPTY,   "BUFFER_EMPTY"   },
    466 	{ OFPBRC_BUFFER_UNKNOWN, "BUFFER_UNKNOWN" },
    467 	{ 0, NULL }
    468 };
    469 
    470 #define OFPBAC_BAD_TYPE        0x0000
    471 #define OFPBAC_BAD_LEN         0x0001
    472 #define OFPBAC_BAD_VENDOR      0x0002
    473 #define OFPBAC_BAD_VENDOR_TYPE 0x0003
    474 #define OFPBAC_BAD_OUT_PORT    0x0004
    475 #define OFPBAC_BAD_ARGUMENT    0x0005
    476 #define OFPBAC_EPERM           0x0006
    477 #define OFPBAC_TOO_MANY        0x0007
    478 #define OFPBAC_BAD_QUEUE       0x0008
    479 static const struct tok ofpbac_str[] = {
    480 	{ OFPBAC_BAD_TYPE,        "BAD_TYPE"        },
    481 	{ OFPBAC_BAD_LEN,         "BAD_LEN"         },
    482 	{ OFPBAC_BAD_VENDOR,      "BAD_VENDOR"      },
    483 	{ OFPBAC_BAD_VENDOR_TYPE, "BAD_VENDOR_TYPE" },
    484 	{ OFPBAC_BAD_OUT_PORT,    "BAD_OUT_PORT"    },
    485 	{ OFPBAC_BAD_ARGUMENT,    "BAD_ARGUMENT"    },
    486 	{ OFPBAC_EPERM,           "EPERM"           },
    487 	{ OFPBAC_TOO_MANY,        "TOO_MANY"        },
    488 	{ OFPBAC_BAD_QUEUE,       "BAD_QUEUE"       },
    489 	{ 0, NULL }
    490 };
    491 
    492 #define OFPFMFC_ALL_TABLES_FULL   0x0000
    493 #define OFPFMFC_OVERLAP           0x0001
    494 #define OFPFMFC_EPERM             0x0002
    495 #define OFPFMFC_BAD_EMERG_TIMEOUT 0x0003
    496 #define OFPFMFC_BAD_COMMAND       0x0004
    497 #define OFPFMFC_UNSUPPORTED       0x0005
    498 static const struct tok ofpfmfc_str[] = {
    499 	{ OFPFMFC_ALL_TABLES_FULL,   "ALL_TABLES_FULL"   },
    500 	{ OFPFMFC_OVERLAP,           "OVERLAP"           },
    501 	{ OFPFMFC_EPERM,             "EPERM"             },
    502 	{ OFPFMFC_BAD_EMERG_TIMEOUT, "BAD_EMERG_TIMEOUT" },
    503 	{ OFPFMFC_BAD_COMMAND,       "BAD_COMMAND"       },
    504 	{ OFPFMFC_UNSUPPORTED,       "UNSUPPORTED"       },
    505 	{ 0, NULL }
    506 };
    507 
    508 #define OFPPMFC_BAD_PORT    0x0000
    509 #define OFPPMFC_BAD_HW_ADDR 0x0001
    510 static const struct tok ofppmfc_str[] = {
    511 	{ OFPPMFC_BAD_PORT,    "BAD_PORT"    },
    512 	{ OFPPMFC_BAD_HW_ADDR, "BAD_HW_ADDR" },
    513 	{ 0, NULL }
    514 };
    515 
    516 #define OFPQOFC_BAD_PORT  0x0000
    517 #define OFPQOFC_BAD_QUEUE 0x0001
    518 #define OFPQOFC_EPERM     0x0002
    519 static const struct tok ofpqofc_str[] = {
    520 	{ OFPQOFC_BAD_PORT,  "BAD_PORT"  },
    521 	{ OFPQOFC_BAD_QUEUE, "BAD_QUEUE" },
    522 	{ OFPQOFC_EPERM,     "EPERM"     },
    523 	{ 0, NULL }
    524 };
    525 
    526 static const struct tok empty_str[] = {
    527 	{ 0, NULL }
    528 };
    529 
    530 /* lengths (fixed or minimal) of particular protocol structures */
    531 #define OF_SWITCH_CONFIG_LEN              12
    532 #define OF_PHY_PORT_LEN                   48
    533 #define OF_SWITCH_FEATURES_LEN            32
    534 #define OF_PORT_STATUS_LEN                64
    535 #define OF_PORT_MOD_LEN                   32
    536 #define OF_PACKET_IN_LEN                  20
    537 #define OF_ACTION_OUTPUT_LEN               8
    538 #define OF_ACTION_VLAN_VID_LEN             8
    539 #define OF_ACTION_VLAN_PCP_LEN             8
    540 #define OF_ACTION_DL_ADDR_LEN             16
    541 #define OF_ACTION_NW_ADDR_LEN              8
    542 #define OF_ACTION_TP_PORT_LEN              8
    543 #define OF_ACTION_NW_TOS_LEN               8
    544 #define OF_ACTION_VENDOR_HEADER_LEN        8
    545 #define OF_ACTION_HEADER_LEN               8
    546 #define OF_PACKET_OUT_LEN                 16
    547 #define OF_MATCH_LEN                      40
    548 #define OF_FLOW_MOD_LEN                   72
    549 #define OF_FLOW_REMOVED_LEN               88
    550 #define OF_ERROR_MSG_LEN                  12
    551 #define OF_STATS_REQUEST_LEN              12
    552 #define OF_STATS_REPLY_LEN                12
    553 #define OF_DESC_STATS_LEN               1056
    554 #define OF_FLOW_STATS_REQUEST_LEN         44
    555 #define OF_FLOW_STATS_LEN                 88
    556 #define OF_AGGREGATE_STATS_REQUEST_LEN    44
    557 #define OF_AGGREGATE_STATS_REPLY_LEN      24
    558 #define OF_TABLE_STATS_LEN                64
    559 #define OF_PORT_STATS_REQUEST_LEN          8
    560 #define OF_PORT_STATS_LEN                104
    561 #define OF_VENDOR_HEADER_LEN              12
    562 #define OF_QUEUE_PROP_HEADER_LEN           8
    563 #define OF_QUEUE_PROP_MIN_RATE_LEN        16
    564 #define OF_PACKET_QUEUE_LEN                8
    565 #define OF_QUEUE_GET_CONFIG_REQUEST_LEN   12
    566 #define OF_QUEUE_GET_CONFIG_REPLY_LEN     16
    567 #define OF_ACTION_ENQUEUE_LEN             16
    568 #define OF_QUEUE_STATS_REQUEST_LEN         8
    569 #define OF_QUEUE_STATS_LEN                32
    570 
    571 /* miscellaneous constants from [OF10] */
    572 #define OFP_MAX_TABLE_NAME_LEN     32
    573 #define OFP_MAX_PORT_NAME_LEN      16
    574 #define DESC_STR_LEN              256
    575 #define SERIAL_NUM_LEN             32
    576 #define OFP_ETH_ALEN                6
    577 #define OFP_VLAN_NONE          0xffff
    578 
    579 static const char *
    580 vlan_str(const uint16_t vid) {
    581 	static char buf[sizeof("65535 (bogus)")];
    582 	const char *fmt;
    583 
    584 	if (vid == OFP_VLAN_NONE)
    585 		return "NONE";
    586 	fmt = (vid > 0 && vid < 0x0fff) ? "%u" : "%u (bogus)";
    587 	snprintf(buf, sizeof(buf), fmt, vid);
    588 	return buf;
    589 }
    590 
    591 static const char *
    592 pcp_str(const uint8_t pcp) {
    593 	static char buf[sizeof("255 (bogus)")];
    594 	snprintf(buf, sizeof(buf), pcp <= 7 ? "%u" : "%u (bogus)", pcp);
    595 	return buf;
    596 }
    597 
    598 static void
    599 of10_bitmap_print(const struct tok *t, const uint32_t v, const uint32_t u) {
    600 	const char *sep = " (";
    601 
    602 	if (v == 0)
    603 		return;
    604 	/* assigned bits */
    605 	for (; t->s != NULL; t++)
    606 		if (v & t->v) {
    607 			printf("%s%s", sep, t->s);
    608 			sep = ", ";
    609 		}
    610 	/* unassigned bits? */
    611 	printf(v & u ? ") (bogus)" : ")");
    612 }
    613 
    614 static const u_char *
    615 of10_data_print(const u_char *cp, const u_char *ep, const u_int len) {
    616 	if (len == 0)
    617 		return cp;
    618 	/* data */
    619 	printf("\n\t data (%u octets)", len);
    620 	TCHECK2(*cp, len);
    621 	if (vflag >= 2)
    622 		hex_and_ascii_print("\n\t  ", cp, len);
    623 	return cp + len;
    624 
    625 trunc:
    626 	printf(" [|openflow]");
    627 	return ep;
    628 }
    629 
    630 /* Vendor ID is mandatory, data is optional. */
    631 static const u_char *
    632 of10_vendor_data_print(const u_char *cp, const u_char *ep, const u_int len) {
    633 	if (len < 4)
    634 		goto corrupt;
    635 	/* vendor */
    636 	TCHECK2(*cp, 4);
    637 	printf(", vendor 0x%08x", EXTRACT_32BITS(cp));
    638 	cp += 4;
    639 	/* data */
    640 	return of10_data_print(cp, ep, len - 4);
    641 
    642 corrupt: /* skip the undersized data */
    643 	printf(" (corrupt)");
    644 	TCHECK2(*cp, len);
    645 	return cp + len;
    646 trunc:
    647 	printf(" [|openflow]");
    648 	return ep;
    649 }
    650 
    651 static const u_char *
    652 of10_packet_data_print(const u_char *cp, const u_char *ep, const u_int len) {
    653 	if (len == 0)
    654 		return cp;
    655 	/* data */
    656 	printf("\n\t data (%u octets)", len);
    657 	if (vflag < 3)
    658 		return cp + len;
    659 	TCHECK2(*cp, len);
    660 	vflag -= 3;
    661 	printf(", frame decoding below\n");
    662 	ether_print(gndo, cp, len, snapend - cp, NULL, NULL);
    663 	vflag += 3;
    664 	return cp + len;
    665 
    666 trunc:
    667 	printf(" [|openflow]");
    668 	return ep;
    669 }
    670 
    671 /* [OF10] Section 5.2.1 */
    672 static const u_char *
    673 of10_phy_ports_print(const u_char *cp, const u_char *ep, u_int len) {
    674 	const u_char *cp0 = cp;
    675 	const u_int len0 = len;
    676 
    677 	while (len) {
    678 		if (len < OF_PHY_PORT_LEN)
    679 			goto corrupt;
    680 		/* port_no */
    681 		TCHECK2(*cp, 2);
    682 		printf("\n\t  port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
    683 		cp += 2;
    684 		/* hw_addr */
    685 		TCHECK2(*cp, OFP_ETH_ALEN);
    686 		printf(", hw_addr %s", etheraddr_string(cp));
    687 		cp += OFP_ETH_ALEN;
    688 		/* name */
    689 		TCHECK2(*cp, OFP_MAX_PORT_NAME_LEN);
    690 		printf(", name '");
    691 		fn_print(cp, cp + OFP_MAX_PORT_NAME_LEN);
    692 		printf("'");
    693 		cp += OFP_MAX_PORT_NAME_LEN;
    694 
    695 		if (vflag < 2) {
    696 			TCHECK2(*cp, 24);
    697 			cp += 24;
    698 			goto next_port;
    699 		}
    700 		/* config */
    701 		TCHECK2(*cp, 4);
    702 		printf("\n\t   config 0x%08x", EXTRACT_32BITS(cp));
    703 		of10_bitmap_print(ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U);
    704 		cp += 4;
    705 		/* state */
    706 		TCHECK2(*cp, 4);
    707 		printf("\n\t   state 0x%08x", EXTRACT_32BITS(cp));
    708 		of10_bitmap_print(ofpps_bm, EXTRACT_32BITS(cp), OFPPS_U);
    709 		cp += 4;
    710 		/* curr */
    711 		TCHECK2(*cp, 4);
    712 		printf("\n\t   curr 0x%08x", EXTRACT_32BITS(cp));
    713 		of10_bitmap_print(ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U);
    714 		cp += 4;
    715 		/* advertised */
    716 		TCHECK2(*cp, 4);
    717 		printf("\n\t   advertised 0x%08x", EXTRACT_32BITS(cp));
    718 		of10_bitmap_print(ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U);
    719 		cp += 4;
    720 		/* supported */
    721 		TCHECK2(*cp, 4);
    722 		printf("\n\t   supported 0x%08x", EXTRACT_32BITS(cp));
    723 		of10_bitmap_print(ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U);
    724 		cp += 4;
    725 		/* peer */
    726 		TCHECK2(*cp, 4);
    727 		printf("\n\t   peer 0x%08x", EXTRACT_32BITS(cp));
    728 		of10_bitmap_print(ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U);
    729 		cp += 4;
    730 next_port:
    731 		len -= OF_PHY_PORT_LEN;
    732 	} /* while */
    733 	return cp;
    734 
    735 corrupt: /* skip the undersized trailing data */
    736 	printf(" (corrupt)");
    737 	TCHECK2(*cp0, len0);
    738 	return cp0 + len0;
    739 trunc:
    740 	printf(" [|openflow]");
    741 	return ep;
    742 }
    743 
    744 /* [OF10] Section 5.2.2 */
    745 static const u_char *
    746 of10_queue_props_print(const u_char *cp, const u_char *ep, u_int len) {
    747 	const u_char *cp0 = cp;
    748 	const u_int len0 = len;
    749 	uint16_t property, plen, rate;
    750 
    751 	while (len) {
    752 		u_char plen_bogus = 0, skip = 0;
    753 
    754 		if (len < OF_QUEUE_PROP_HEADER_LEN)
    755 			goto corrupt;
    756 		/* property */
    757 		TCHECK2(*cp, 2);
    758 		property = EXTRACT_16BITS(cp);
    759 		cp += 2;
    760 		printf("\n\t   property %s", tok2str(ofpqt_str, "invalid (0x%04x)", property));
    761 		/* len */
    762 		TCHECK2(*cp, 2);
    763 		plen = EXTRACT_16BITS(cp);
    764 		cp += 2;
    765 		printf(", len %u", plen);
    766 		if (plen < OF_QUEUE_PROP_HEADER_LEN || plen > len)
    767 			goto corrupt;
    768 		/* pad */
    769 		TCHECK2(*cp, 4);
    770 		cp += 4;
    771 		/* property-specific constraints and decoding */
    772 		switch (property) {
    773 		case OFPQT_NONE:
    774 			plen_bogus = plen != OF_QUEUE_PROP_HEADER_LEN;
    775 			break;
    776 		case OFPQT_MIN_RATE:
    777 			plen_bogus = plen != OF_QUEUE_PROP_MIN_RATE_LEN;
    778 			break;
    779 		default:
    780 			skip = 1;
    781 		}
    782 		if (plen_bogus) {
    783 			printf(" (bogus)");
    784 			skip = 1;
    785 		}
    786 		if (skip) {
    787 			TCHECK2(*cp, plen - 4);
    788 			cp += plen - 4;
    789 			goto next_property;
    790 		}
    791 		if (property == OFPQT_MIN_RATE) { /* the only case of property decoding */
    792 			/* rate */
    793 			TCHECK2(*cp, 2);
    794 			rate = EXTRACT_16BITS(cp);
    795 			cp += 2;
    796 			if (rate > 1000)
    797 				printf(", rate disabled");
    798 			else
    799 				printf(", rate %u.%u%%", rate / 10, rate % 10);
    800 			/* pad */
    801 			TCHECK2(*cp, 6);
    802 			cp += 6;
    803 		}
    804 next_property:
    805 		len -= plen;
    806 	} /* while */
    807 	return cp;
    808 
    809 corrupt: /* skip the rest of queue properties */
    810 	printf(" (corrupt)");
    811 	TCHECK2(*cp0, len0);
    812 	return cp0 + len0;
    813 trunc:
    814 	printf(" [|openflow]");
    815 	return ep;
    816 }
    817 
    818 /* ibid */
    819 static const u_char *
    820 of10_queues_print(const u_char *cp, const u_char *ep, u_int len) {
    821 	const u_char *cp0 = cp;
    822 	const u_int len0 = len;
    823 	uint16_t desclen;
    824 
    825 	while (len) {
    826 		if (len < OF_PACKET_QUEUE_LEN)
    827 			goto corrupt;
    828 		/* queue_id */
    829 		TCHECK2(*cp, 4);
    830 		printf("\n\t  queue_id %u", EXTRACT_32BITS(cp));
    831 		cp += 4;
    832 		/* len */
    833 		TCHECK2(*cp, 2);
    834 		desclen = EXTRACT_16BITS(cp);
    835 		cp += 2;
    836 		printf(", len %u", desclen);
    837 		if (desclen < OF_PACKET_QUEUE_LEN || desclen > len)
    838 			goto corrupt;
    839 		/* pad */
    840 		TCHECK2(*cp, 2);
    841 		cp += 2;
    842 		/* properties */
    843 		if (vflag < 2) {
    844 			TCHECK2(*cp, desclen - OF_PACKET_QUEUE_LEN);
    845 			cp += desclen - OF_PACKET_QUEUE_LEN;
    846 			goto next_queue;
    847 		}
    848 		if (ep == (cp = of10_queue_props_print(cp, ep, desclen - OF_PACKET_QUEUE_LEN)))
    849 			return ep; /* end of snapshot */
    850 next_queue:
    851 		len -= desclen;
    852 	} /* while */
    853 	return cp;
    854 
    855 corrupt: /* skip the rest of queues */
    856 	printf(" (corrupt)");
    857 	TCHECK2(*cp0, len0);
    858 	return cp0 + len0;
    859 trunc:
    860 	printf(" [|openflow]");
    861 	return ep;
    862 }
    863 
    864 /* [OF10] Section 5.2.3 */
    865 static const u_char *
    866 of10_match_print(const char *pfx, const u_char *cp, const u_char *ep) {
    867 	uint32_t wildcards;
    868 	uint16_t dl_type;
    869 	uint8_t nw_proto;
    870 	u_char nw_bits;
    871 	const char *field_name;
    872 
    873 	/* wildcards */
    874 	TCHECK2(*cp, 4);
    875 	wildcards = EXTRACT_32BITS(cp);
    876 	if (wildcards & OFPFW_U)
    877 		printf("%swildcards 0x%08x (bogus)", pfx, wildcards);
    878 	cp += 4;
    879 	/* in_port */
    880 	TCHECK2(*cp, 2);
    881 	if (! (wildcards & OFPFW_IN_PORT))
    882 		printf("%smatch in_port %s", pfx, tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
    883 	cp += 2;
    884 	/* dl_src */
    885 	TCHECK2(*cp, OFP_ETH_ALEN);
    886 	if (! (wildcards & OFPFW_DL_SRC))
    887 		printf("%smatch dl_src %s", pfx, etheraddr_string(cp));
    888 	cp += OFP_ETH_ALEN;
    889 	/* dl_dst */
    890 	TCHECK2(*cp, OFP_ETH_ALEN);
    891 	if (! (wildcards & OFPFW_DL_DST))
    892 		printf("%smatch dl_dst %s", pfx, etheraddr_string(cp));
    893 	cp += OFP_ETH_ALEN;
    894 	/* dl_vlan */
    895 	TCHECK2(*cp, 2);
    896 	if (! (wildcards & OFPFW_DL_VLAN))
    897 		printf("%smatch dl_vlan %s", pfx, vlan_str(EXTRACT_16BITS(cp)));
    898 	cp += 2;
    899 	/* dl_vlan_pcp */
    900 	TCHECK2(*cp, 1);
    901 	if (! (wildcards & OFPFW_DL_VLAN_PCP))
    902 		printf("%smatch dl_vlan_pcp %s", pfx, pcp_str(*cp));
    903 	cp += 1;
    904 	/* pad1 */
    905 	TCHECK2(*cp, 1);
    906 	cp += 1;
    907 	/* dl_type */
    908 	TCHECK2(*cp, 2);
    909 	dl_type = EXTRACT_16BITS(cp);
    910 	cp += 2;
    911 	if (! (wildcards & OFPFW_DL_TYPE))
    912 		printf("%smatch dl_type 0x%04x", pfx, dl_type);
    913 	/* nw_tos */
    914 	TCHECK2(*cp, 1);
    915 	if (! (wildcards & OFPFW_NW_TOS))
    916 		printf("%smatch nw_tos 0x%02x", pfx, *cp);
    917 	cp += 1;
    918 	/* nw_proto */
    919 	TCHECK2(*cp, 1);
    920 	nw_proto = *cp;
    921 	cp += 1;
    922 	if (! (wildcards & OFPFW_NW_PROTO)) {
    923 		field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_ARP
    924 		  ? "arp_opcode" : "nw_proto";
    925 		printf("%smatch %s %u", pfx, field_name, nw_proto);
    926 	}
    927 	/* pad2 */
    928 	TCHECK2(*cp, 2);
    929 	cp += 2;
    930 	/* nw_src */
    931 	TCHECK2(*cp, 4);
    932 	nw_bits = (wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT;
    933 	if (nw_bits < 32)
    934 		printf("%smatch nw_src %s/%u", pfx, ipaddr_string(cp), 32 - nw_bits);
    935 	cp += 4;
    936 	/* nw_dst */
    937 	TCHECK2(*cp, 4);
    938 	nw_bits = (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT;
    939 	if (nw_bits < 32)
    940 		printf("%smatch nw_dst %s/%u", pfx, ipaddr_string(cp), 32 - nw_bits);
    941 	cp += 4;
    942 	/* tp_src */
    943 	TCHECK2(*cp, 2);
    944 	if (! (wildcards & OFPFW_TP_SRC)) {
    945 		field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP
    946 		  && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP
    947 		  ? "icmp_type" : "tp_src";
    948 		printf("%smatch %s %u", pfx, field_name, EXTRACT_16BITS(cp));
    949 	}
    950 	cp += 2;
    951 	/* tp_dst */
    952 	TCHECK2(*cp, 2);
    953 	if (! (wildcards & OFPFW_TP_DST)) {
    954 		field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP
    955 		  && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP
    956 		  ? "icmp_code" : "tp_dst";
    957 		printf("%smatch %s %u", pfx, field_name, EXTRACT_16BITS(cp));
    958 	}
    959 	return cp + 2;
    960 
    961 trunc:
    962 	printf(" [|openflow]");
    963 	return ep;
    964 }
    965 
    966 /* [OF10] Section 5.2.4 */
    967 static const u_char *
    968 of10_actions_print(const char *pfx, const u_char *cp, const u_char *ep,
    969                    u_int len) {
    970 	const u_char *cp0 = cp;
    971 	const u_int len0 = len;
    972 	uint16_t type, alen, output_port;
    973 
    974 	while (len) {
    975 		u_char alen_bogus = 0, skip = 0;
    976 
    977 		if (len < OF_ACTION_HEADER_LEN)
    978 			goto corrupt;
    979 		/* type */
    980 		TCHECK2(*cp, 2);
    981 		type = EXTRACT_16BITS(cp);
    982 		cp += 2;
    983 		printf("%saction type %s", pfx, tok2str(ofpat_str, "invalid (0x%04x)", type));
    984 		/* length */
    985 		TCHECK2(*cp, 2);
    986 		alen = EXTRACT_16BITS(cp);
    987 		cp += 2;
    988 		printf(", len %u", alen);
    989 		/* On action size underrun/overrun skip the rest of the action list. */
    990 		if (alen < OF_ACTION_HEADER_LEN || alen > len)
    991 			goto corrupt;
    992 		/* On action size inappropriate for the given type or invalid type just skip
    993 		 * the current action, as the basic length constraint has been met. */
    994 		switch (type) {
    995 		case OFPAT_OUTPUT:
    996 		case OFPAT_SET_VLAN_VID:
    997 		case OFPAT_SET_VLAN_PCP:
    998 		case OFPAT_STRIP_VLAN:
    999 		case OFPAT_SET_NW_SRC:
   1000 		case OFPAT_SET_NW_DST:
   1001 		case OFPAT_SET_NW_TOS:
   1002 		case OFPAT_SET_TP_SRC:
   1003 		case OFPAT_SET_TP_DST:
   1004 			alen_bogus = alen != 8;
   1005 			break;
   1006 		case OFPAT_SET_DL_SRC:
   1007 		case OFPAT_SET_DL_DST:
   1008 		case OFPAT_ENQUEUE:
   1009 			alen_bogus = alen != 16;
   1010 			break;
   1011 		case OFPAT_VENDOR:
   1012 			alen_bogus = alen % 8 != 0; /* already >= 8 so far */
   1013 			break;
   1014 		default:
   1015 			skip = 1;
   1016 		}
   1017 		if (alen_bogus) {
   1018 			printf(" (bogus)");
   1019 			skip = 1;
   1020 		}
   1021 		if (skip) {
   1022 			TCHECK2(*cp, alen - 4);
   1023 			cp += alen - 4;
   1024 			goto next_action;
   1025 		}
   1026 		/* OK to decode the rest of the action structure */
   1027 		switch (type) {
   1028 		case OFPAT_OUTPUT:
   1029 			/* port */
   1030 			TCHECK2(*cp, 2);
   1031 			output_port = EXTRACT_16BITS(cp);
   1032 			cp += 2;
   1033 			printf(", port %s", tok2str(ofpp_str, "%u", output_port));
   1034 			/* max_len */
   1035 			TCHECK2(*cp, 2);
   1036 			if (output_port == OFPP_CONTROLLER)
   1037 				printf(", max_len %u", EXTRACT_16BITS(cp));
   1038 			cp += 2;
   1039 			break;
   1040 		case OFPAT_SET_VLAN_VID:
   1041 			/* vlan_vid */
   1042 			TCHECK2(*cp, 2);
   1043 			printf(", vlan_vid %s", vlan_str(EXTRACT_16BITS(cp)));
   1044 			cp += 2;
   1045 			/* pad */
   1046 			TCHECK2(*cp, 2);
   1047 			cp += 2;
   1048 			break;
   1049 		case OFPAT_SET_VLAN_PCP:
   1050 			/* vlan_pcp */
   1051 			TCHECK2(*cp, 1);
   1052 			printf(", vlan_pcp %s", pcp_str(*cp));
   1053 			cp += 1;
   1054 			/* pad */
   1055 			TCHECK2(*cp, 3);
   1056 			cp += 3;
   1057 			break;
   1058 		case OFPAT_SET_DL_SRC:
   1059 		case OFPAT_SET_DL_DST:
   1060 			/* dl_addr */
   1061 			TCHECK2(*cp, OFP_ETH_ALEN);
   1062 			printf(", dl_addr %s", etheraddr_string(cp));
   1063 			cp += OFP_ETH_ALEN;
   1064 			/* pad */
   1065 			TCHECK2(*cp, 6);
   1066 			cp += 6;
   1067 			break;
   1068 		case OFPAT_SET_NW_SRC:
   1069 		case OFPAT_SET_NW_DST:
   1070 			/* nw_addr */
   1071 			TCHECK2(*cp, 4);
   1072 			printf(", nw_addr %s", ipaddr_string(cp));
   1073 			cp += 4;
   1074 			break;
   1075 		case OFPAT_SET_NW_TOS:
   1076 			/* nw_tos */
   1077 			TCHECK2(*cp, 1);
   1078 			printf(", nw_tos 0x%02x", *cp);
   1079 			cp += 1;
   1080 			/* pad */
   1081 			TCHECK2(*cp, 3);
   1082 			cp += 3;
   1083 			break;
   1084 		case OFPAT_SET_TP_SRC:
   1085 		case OFPAT_SET_TP_DST:
   1086 			/* nw_tos */
   1087 			TCHECK2(*cp, 2);
   1088 			printf(", tp_port %u", EXTRACT_16BITS(cp));
   1089 			cp += 2;
   1090 			/* pad */
   1091 			TCHECK2(*cp, 2);
   1092 			cp += 2;
   1093 			break;
   1094 		case OFPAT_ENQUEUE:
   1095 			/* port */
   1096 			TCHECK2(*cp, 2);
   1097 			printf(", port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1098 			cp += 2;
   1099 			/* pad */
   1100 			TCHECK2(*cp, 6);
   1101 			cp += 6;
   1102 			/* queue_id */
   1103 			TCHECK2(*cp, 4);
   1104 			printf(", queue_id %s", tok2str(ofpq_str, "%u", EXTRACT_32BITS(cp)));
   1105 			cp += 4;
   1106 			break;
   1107 		case OFPAT_VENDOR:
   1108 			if (ep == (cp = of10_vendor_data_print(cp, ep, alen - 4)))
   1109 				return ep; /* end of snapshot */
   1110 			break;
   1111 		case OFPAT_STRIP_VLAN:
   1112 			/* pad */
   1113 			TCHECK2(*cp, 4);
   1114 			cp += 4;
   1115 			break;
   1116 		} /* switch */
   1117 next_action:
   1118 		len -= alen;
   1119 	} /* while */
   1120 	return cp;
   1121 
   1122 corrupt: /* skip the rest of actions */
   1123 	printf(" (corrupt)");
   1124 	TCHECK2(*cp0, len0);
   1125 	return cp0 + len0;
   1126 trunc:
   1127 	printf(" [|openflow]");
   1128 	return ep;
   1129 }
   1130 
   1131 /* [OF10] Section 5.3.1 */
   1132 static const u_char *
   1133 of10_features_reply_print(const u_char *cp, const u_char *ep, const u_int len) {
   1134 	/* datapath_id */
   1135 	TCHECK2(*cp, 8);
   1136 	printf("\n\t dpid 0x%016" PRIx64, EXTRACT_64BITS(cp));
   1137 	cp += 8;
   1138 	/* n_buffers */
   1139 	TCHECK2(*cp, 4);
   1140 	printf(", n_buffers %u", EXTRACT_32BITS(cp));
   1141 	cp += 4;
   1142 	/* n_tables */
   1143 	TCHECK2(*cp, 1);
   1144 	printf(", n_tables %u", *cp);
   1145 	cp += 1;
   1146 	/* pad */
   1147 	TCHECK2(*cp, 3);
   1148 	cp += 3;
   1149 	/* capabilities */
   1150 	TCHECK2(*cp, 4);
   1151 	printf("\n\t capabilities 0x%08x", EXTRACT_32BITS(cp));
   1152 	of10_bitmap_print(ofp_capabilities_bm, EXTRACT_32BITS(cp), OFPCAP_U);
   1153 	cp += 4;
   1154 	/* actions */
   1155 	TCHECK2(*cp, 4);
   1156 	printf("\n\t actions 0x%08x", EXTRACT_32BITS(cp));
   1157 	of10_bitmap_print(ofpat_bm, EXTRACT_32BITS(cp), OFPAT_U);
   1158 	cp += 4;
   1159 	/* ports */
   1160 	return of10_phy_ports_print(cp, ep, len - OF_SWITCH_FEATURES_LEN);
   1161 
   1162 trunc:
   1163 	printf(" [|openflow]");
   1164 	return ep;
   1165 }
   1166 
   1167 /* [OF10] Section 5.3.3 */
   1168 static const u_char *
   1169 of10_flow_mod_print(const u_char *cp, const u_char *ep, const u_int len) {
   1170 	uint16_t command;
   1171 
   1172 	/* match */
   1173 	if (ep == (cp = of10_match_print("\n\t ", cp, ep)))
   1174 		return ep; /* end of snapshot */
   1175 	/* cookie */
   1176 	TCHECK2(*cp, 8);
   1177 	printf("\n\t cookie 0x%016" PRIx64, EXTRACT_64BITS(cp));
   1178 	cp += 8;
   1179 	/* command */
   1180 	TCHECK2(*cp, 2);
   1181 	command = EXTRACT_16BITS(cp);
   1182 	printf(", command %s", tok2str(ofpfc_str, "invalid (0x%04x)", command));
   1183 	cp += 2;
   1184 	/* idle_timeout */
   1185 	TCHECK2(*cp, 2);
   1186 	if (EXTRACT_16BITS(cp))
   1187 		printf(", idle_timeout %u", EXTRACT_16BITS(cp));
   1188 	cp += 2;
   1189 	/* hard_timeout */
   1190 	TCHECK2(*cp, 2);
   1191 	if (EXTRACT_16BITS(cp))
   1192 		printf(", hard_timeout %u", EXTRACT_16BITS(cp));
   1193 	cp += 2;
   1194 	/* priority */
   1195 	TCHECK2(*cp, 2);
   1196 	if (EXTRACT_16BITS(cp))
   1197 		printf(", priority %u", EXTRACT_16BITS(cp));
   1198 	cp += 2;
   1199 	/* buffer_id */
   1200 	TCHECK2(*cp, 4);
   1201 	if (command == OFPFC_ADD || command == OFPFC_MODIFY ||
   1202 	    command == OFPFC_MODIFY_STRICT)
   1203 		printf(", buffer_id %s", tok2str(bufferid_str, "0x%08x", EXTRACT_32BITS(cp)));
   1204 	cp += 4;
   1205 	/* out_port */
   1206 	TCHECK2(*cp, 2);
   1207 	if (command == OFPFC_DELETE || command == OFPFC_DELETE_STRICT)
   1208 		printf(", out_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1209 	cp += 2;
   1210 	/* flags */
   1211 	TCHECK2(*cp, 2);
   1212 	printf(", flags 0x%04x", EXTRACT_16BITS(cp));
   1213 	of10_bitmap_print(ofpff_bm, EXTRACT_16BITS(cp), OFPFF_U);
   1214 	cp += 2;
   1215 	/* actions */
   1216 	return of10_actions_print("\n\t ", cp, ep, len - OF_FLOW_MOD_LEN);
   1217 
   1218 trunc:
   1219 	printf(" [|openflow]");
   1220 	return ep;
   1221 }
   1222 
   1223 /* ibid */
   1224 static const u_char *
   1225 of10_port_mod_print(const u_char *cp, const u_char *ep) {
   1226 	/* port_no */
   1227 	TCHECK2(*cp, 2);
   1228 	printf("\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1229 	cp += 2;
   1230 	/* hw_addr */
   1231 	TCHECK2(*cp, OFP_ETH_ALEN);
   1232 	printf(", hw_addr %s", etheraddr_string(cp));
   1233 	cp += OFP_ETH_ALEN;
   1234 	/* config */
   1235 	TCHECK2(*cp, 4);
   1236 	printf("\n\t config 0x%08x", EXTRACT_32BITS(cp));
   1237 	of10_bitmap_print(ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U);
   1238 	cp += 4;
   1239 	/* mask */
   1240 	TCHECK2(*cp, 4);
   1241 	printf("\n\t mask 0x%08x", EXTRACT_32BITS(cp));
   1242 	of10_bitmap_print(ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U);
   1243 	cp += 4;
   1244 	/* advertise */
   1245 	TCHECK2(*cp, 4);
   1246 	printf("\n\t advertise 0x%08x", EXTRACT_32BITS(cp));
   1247 	of10_bitmap_print(ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U);
   1248 	cp += 4;
   1249 	/* pad */
   1250 	TCHECK2(*cp, 4);
   1251 	return cp + 4;
   1252 
   1253 trunc:
   1254 	printf(" [|openflow]");
   1255 	return ep;
   1256 }
   1257 
   1258 /* [OF10] Section 5.3.5 */
   1259 static const u_char *
   1260 of10_stats_request_print(const u_char *cp, const u_char *ep, u_int len) {
   1261 	const u_char *cp0 = cp;
   1262 	const u_int len0 = len;
   1263 	uint16_t type;
   1264 
   1265 	/* type */
   1266 	TCHECK2(*cp, 2);
   1267 	type = EXTRACT_16BITS(cp);
   1268 	cp += 2;
   1269 	printf("\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type));
   1270 	/* flags */
   1271 	TCHECK2(*cp, 2);
   1272 	printf(", flags 0x%04x", EXTRACT_16BITS(cp));
   1273 	if (EXTRACT_16BITS(cp))
   1274 		printf(" (bogus)");
   1275 	cp += 2;
   1276 	/* type-specific body of one of fixed lengths */
   1277 	len -= OF_STATS_REQUEST_LEN;
   1278 	switch(type) {
   1279 	case OFPST_DESC:
   1280 	case OFPST_TABLE:
   1281 		if (len)
   1282 			goto corrupt;
   1283 		return cp;
   1284 	case OFPST_FLOW:
   1285 	case OFPST_AGGREGATE:
   1286 		if (len != OF_FLOW_STATS_REQUEST_LEN)
   1287 			goto corrupt;
   1288 		/* match */
   1289 		if (ep == (cp = of10_match_print("\n\t ", cp, ep)))
   1290 			return ep; /* end of snapshot */
   1291 		/* table_id */
   1292 		TCHECK2(*cp, 1);
   1293 		printf("\n\t table_id %s", tok2str(tableid_str, "%u", *cp));
   1294 		cp += 1;
   1295 		/* pad */
   1296 		TCHECK2(*cp, 1);
   1297 		cp += 1;
   1298 		/* out_port */
   1299 		TCHECK2(*cp, 2);
   1300 		printf(", out_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1301 		return cp + 2;
   1302 	case OFPST_PORT:
   1303 		if (len != OF_PORT_STATS_REQUEST_LEN)
   1304 			goto corrupt;
   1305 		/* port_no */
   1306 		TCHECK2(*cp, 2);
   1307 		printf("\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1308 		cp += 2;
   1309 		/* pad */
   1310 		TCHECK2(*cp, 6);
   1311 		return cp + 6;
   1312 	case OFPST_QUEUE:
   1313 		if (len != OF_QUEUE_STATS_REQUEST_LEN)
   1314 			goto corrupt;
   1315 		/* port_no */
   1316 		TCHECK2(*cp, 2);
   1317 		printf("\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1318 		cp += 2;
   1319 		/* pad */
   1320 		TCHECK2(*cp, 2);
   1321 		cp += 2;
   1322 		/* queue_id */
   1323 		TCHECK2(*cp, 4);
   1324 		printf(", queue_id %s", tok2str(ofpq_str, "%u", EXTRACT_32BITS(cp)));
   1325 		return cp + 4;
   1326 	case OFPST_VENDOR:
   1327 		return of10_vendor_data_print(cp, ep, len);
   1328 	}
   1329 	return cp;
   1330 
   1331 corrupt: /* skip the message body */
   1332 	printf(" (corrupt)");
   1333 	TCHECK2(*cp0, len0);
   1334 	return cp0 + len0;
   1335 trunc:
   1336 	printf(" [|openflow]");
   1337 	return ep;
   1338 }
   1339 
   1340 /* ibid */
   1341 static const u_char *
   1342 of10_desc_stats_reply_print(const u_char *cp, const u_char *ep, const u_int len) {
   1343 	if (len != OF_DESC_STATS_LEN)
   1344 		goto corrupt;
   1345 	/* mfr_desc */
   1346 	TCHECK2(*cp, DESC_STR_LEN);
   1347 	printf("\n\t  mfr_desc '");
   1348 	fn_print(cp, cp + DESC_STR_LEN);
   1349 	printf("'");
   1350 	cp += DESC_STR_LEN;
   1351 	/* hw_desc */
   1352 	TCHECK2(*cp, DESC_STR_LEN);
   1353 	printf("\n\t  hw_desc '");
   1354 	fn_print(cp, cp + DESC_STR_LEN);
   1355 	printf("'");
   1356 	cp += DESC_STR_LEN;
   1357 	/* sw_desc */
   1358 	TCHECK2(*cp, DESC_STR_LEN);
   1359 	printf("\n\t  sw_desc '");
   1360 	fn_print(cp, cp + DESC_STR_LEN);
   1361 	printf("'");
   1362 	cp += DESC_STR_LEN;
   1363 	/* serial_num */
   1364 	TCHECK2(*cp, SERIAL_NUM_LEN);
   1365 	printf("\n\t  serial_num '");
   1366 	fn_print(cp, cp + SERIAL_NUM_LEN);
   1367 	printf("'");
   1368 	cp += SERIAL_NUM_LEN;
   1369 	/* dp_desc */
   1370 	TCHECK2(*cp, DESC_STR_LEN);
   1371 	printf("\n\t  dp_desc '");
   1372 	fn_print(cp, cp + DESC_STR_LEN);
   1373 	printf("'");
   1374 	return cp + DESC_STR_LEN;
   1375 
   1376 corrupt: /* skip the message body */
   1377 	printf(" (corrupt)");
   1378 	TCHECK2(*cp, len);
   1379 	return cp + len;
   1380 trunc:
   1381 	printf(" [|openflow]");
   1382 	return ep;
   1383 }
   1384 
   1385 /* ibid */
   1386 static const u_char *
   1387 of10_flow_stats_reply_print(const u_char *cp, const u_char *ep, u_int len) {
   1388 	const u_char *cp0 = cp;
   1389 	const u_int len0 = len;
   1390 	uint16_t entry_len;
   1391 
   1392 	while (len) {
   1393 		if (len < OF_FLOW_STATS_LEN)
   1394 			goto corrupt;
   1395 		/* length */
   1396 		TCHECK2(*cp, 2);
   1397 		entry_len = EXTRACT_16BITS(cp);
   1398 		printf("\n\t length %u", entry_len);
   1399 		if (entry_len < OF_FLOW_STATS_LEN || entry_len > len)
   1400 			goto corrupt;
   1401 		cp += 2;
   1402 		/* table_id */
   1403 		TCHECK2(*cp, 1);
   1404 		printf(", table_id %s", tok2str(tableid_str, "%u", *cp));
   1405 		cp += 1;
   1406 		/* pad */
   1407 		TCHECK2(*cp, 1);
   1408 		cp += 1;
   1409 		/* match */
   1410 		if (ep == (cp = of10_match_print("\n\t  ", cp, ep)))
   1411 			return ep; /* end of snapshot */
   1412 		/* duration_sec */
   1413 		TCHECK2(*cp, 4);
   1414 		printf("\n\t  duration_sec %u", EXTRACT_32BITS(cp));
   1415 		cp += 4;
   1416 		/* duration_nsec */
   1417 		TCHECK2(*cp, 4);
   1418 		printf(", duration_nsec %u", EXTRACT_32BITS(cp));
   1419 		cp += 4;
   1420 		/* priority */
   1421 		TCHECK2(*cp, 2);
   1422 		printf(", priority %u", EXTRACT_16BITS(cp));
   1423 		cp += 2;
   1424 		/* idle_timeout */
   1425 		TCHECK2(*cp, 2);
   1426 		printf(", idle_timeout %u", EXTRACT_16BITS(cp));
   1427 		cp += 2;
   1428 		/* hard_timeout */
   1429 		TCHECK2(*cp, 2);
   1430 		printf(", hard_timeout %u", EXTRACT_16BITS(cp));
   1431 		cp += 2;
   1432 		/* pad2 */
   1433 		TCHECK2(*cp, 6);
   1434 		cp += 6;
   1435 		/* cookie */
   1436 		TCHECK2(*cp, 8);
   1437 		printf(", cookie 0x%016" PRIx64, EXTRACT_64BITS(cp));
   1438 		cp += 8;
   1439 		/* packet_count */
   1440 		TCHECK2(*cp, 8);
   1441 		printf(", packet_count %" PRIu64, EXTRACT_64BITS(cp));
   1442 		cp += 8;
   1443 		/* byte_count */
   1444 		TCHECK2(*cp, 8);
   1445 		printf(", byte_count %" PRIu64, EXTRACT_64BITS(cp));
   1446 		cp += 8;
   1447 		/* actions */
   1448 		if (ep == (cp = of10_actions_print("\n\t  ", cp, ep, entry_len - OF_FLOW_STATS_LEN)))
   1449 			return ep; /* end of snapshot */
   1450 
   1451 		len -= entry_len;
   1452 	} /* while */
   1453 	return cp;
   1454 
   1455 corrupt: /* skip the rest of flow statistics entries */
   1456 	printf(" (corrupt)");
   1457 	TCHECK2(*cp0, len0);
   1458 	return cp0 + len0;
   1459 trunc:
   1460 	printf(" [|openflow]");
   1461 	return ep;
   1462 }
   1463 
   1464 /* ibid */
   1465 static const u_char *
   1466 of10_aggregate_stats_reply_print(const u_char *cp, const u_char *ep,
   1467                                  const u_int len) {
   1468 	if (len != OF_AGGREGATE_STATS_REPLY_LEN)
   1469 		goto corrupt;
   1470 	/* packet_count */
   1471 	TCHECK2(*cp, 8);
   1472 	printf("\n\t packet_count %" PRIu64, EXTRACT_64BITS(cp));
   1473 	cp += 8;
   1474 	/* byte_count */
   1475 	TCHECK2(*cp, 8);
   1476 	printf(", byte_count %" PRIu64, EXTRACT_64BITS(cp));
   1477 	cp += 8;
   1478 	/* flow_count */
   1479 	TCHECK2(*cp, 4);
   1480 	printf(", flow_count %u", EXTRACT_32BITS(cp));
   1481 	cp += 4;
   1482 	/* pad */
   1483 	TCHECK2(*cp, 4);
   1484 	return cp + 4;
   1485 
   1486 corrupt: /* skip the message body */
   1487 	printf(" (corrupt)");
   1488 	TCHECK2(*cp, len);
   1489 	return cp + len;
   1490 trunc:
   1491 	printf(" [|openflow]");
   1492 	return ep;
   1493 }
   1494 
   1495 /* ibid */
   1496 static const u_char *
   1497 of10_table_stats_reply_print(const u_char *cp, const u_char *ep, u_int len) {
   1498 	const u_char *cp0 = cp;
   1499 	const u_int len0 = len;
   1500 
   1501 	while (len) {
   1502 		if (len < OF_TABLE_STATS_LEN)
   1503 			goto corrupt;
   1504 		/* table_id */
   1505 		TCHECK2(*cp, 1);
   1506 		printf("\n\t table_id %s", tok2str(tableid_str, "%u", *cp));
   1507 		cp += 1;
   1508 		/* pad */
   1509 		TCHECK2(*cp, 3);
   1510 		cp += 3;
   1511 		/* name */
   1512 		TCHECK2(*cp, OFP_MAX_TABLE_NAME_LEN);
   1513 		printf(", name '");
   1514 		fn_print(cp, cp + OFP_MAX_TABLE_NAME_LEN);
   1515 		printf("'");
   1516 		cp += OFP_MAX_TABLE_NAME_LEN;
   1517 		/* wildcards */
   1518 		TCHECK2(*cp, 4);
   1519 		printf("\n\t  wildcards 0x%08x", EXTRACT_32BITS(cp));
   1520 		of10_bitmap_print(ofpfw_bm, EXTRACT_32BITS(cp), OFPFW_U);
   1521 		cp += 4;
   1522 		/* max_entries */
   1523 		TCHECK2(*cp, 4);
   1524 		printf("\n\t  max_entries %u", EXTRACT_32BITS(cp));
   1525 		cp += 4;
   1526 		/* active_count */
   1527 		TCHECK2(*cp, 4);
   1528 		printf(", active_count %u", EXTRACT_32BITS(cp));
   1529 		cp += 4;
   1530 		/* lookup_count */
   1531 		TCHECK2(*cp, 8);
   1532 		printf(", lookup_count %" PRIu64, EXTRACT_64BITS(cp));
   1533 		cp += 8;
   1534 		/* matched_count */
   1535 		TCHECK2(*cp, 8);
   1536 		printf(", matched_count %" PRIu64, EXTRACT_64BITS(cp));
   1537 		cp += 8;
   1538 
   1539 		len -= OF_TABLE_STATS_LEN;
   1540 	} /* while */
   1541 	return cp;
   1542 
   1543 corrupt: /* skip the undersized trailing data */
   1544 	printf(" (corrupt)");
   1545 	TCHECK2(*cp0, len0);
   1546 	return cp0 + len0;
   1547 trunc:
   1548 	printf(" [|openflow]");
   1549 	return ep;
   1550 }
   1551 
   1552 /* ibid */
   1553 static const u_char *
   1554 of10_port_stats_reply_print(const u_char *cp, const u_char *ep, u_int len) {
   1555 	const u_char *cp0 = cp;
   1556 	const u_int len0 = len;
   1557 
   1558 	while (len) {
   1559 		if (len < OF_PORT_STATS_LEN)
   1560 			goto corrupt;
   1561 		/* port_no */
   1562 		TCHECK2(*cp, 2);
   1563 		printf("\n\t  port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1564 		cp += 2;
   1565 		if (vflag < 2) {
   1566 			TCHECK2(*cp, OF_PORT_STATS_LEN - 2);
   1567 			cp += OF_PORT_STATS_LEN - 2;
   1568 			goto next_port;
   1569 		}
   1570 		/* pad */
   1571 		TCHECK2(*cp, 6);
   1572 		cp += 6;
   1573 		/* rx_packets */
   1574 		TCHECK2(*cp, 8);
   1575 		printf(", rx_packets %" PRIu64, EXTRACT_64BITS(cp));
   1576 		cp += 8;
   1577 		/* tx_packets */
   1578 		TCHECK2(*cp, 8);
   1579 		printf(", tx_packets %" PRIu64, EXTRACT_64BITS(cp));
   1580 		cp += 8;
   1581 		/* rx_bytes */
   1582 		TCHECK2(*cp, 8);
   1583 		printf(", rx_bytes %" PRIu64, EXTRACT_64BITS(cp));
   1584 		cp += 8;
   1585 		/* tx_bytes */
   1586 		TCHECK2(*cp, 8);
   1587 		printf(", tx_bytes %" PRIu64, EXTRACT_64BITS(cp));
   1588 		cp += 8;
   1589 		/* rx_dropped */
   1590 		TCHECK2(*cp, 8);
   1591 		printf(", rx_dropped %" PRIu64, EXTRACT_64BITS(cp));
   1592 		cp += 8;
   1593 		/* tx_dropped */
   1594 		TCHECK2(*cp, 8);
   1595 		printf(", tx_dropped %" PRIu64, EXTRACT_64BITS(cp));
   1596 		cp += 8;
   1597 		/* rx_errors */
   1598 		TCHECK2(*cp, 8);
   1599 		printf(", rx_errors %" PRIu64, EXTRACT_64BITS(cp));
   1600 		cp += 8;
   1601 		/* tx_errors */
   1602 		TCHECK2(*cp, 8);
   1603 		printf(", tx_errors %" PRIu64, EXTRACT_64BITS(cp));
   1604 		cp += 8;
   1605 		/* rx_frame_err */
   1606 		TCHECK2(*cp, 8);
   1607 		printf(", rx_frame_err %" PRIu64, EXTRACT_64BITS(cp));
   1608 		cp += 8;
   1609 		/* rx_over_err */
   1610 		TCHECK2(*cp, 8);
   1611 		printf(", rx_over_err %" PRIu64, EXTRACT_64BITS(cp));
   1612 		cp += 8;
   1613 		/* rx_crc_err */
   1614 		TCHECK2(*cp, 8);
   1615 		printf(", rx_crc_err %" PRIu64, EXTRACT_64BITS(cp));
   1616 		cp += 8;
   1617 		/* collisions */
   1618 		TCHECK2(*cp, 8);
   1619 		printf(", collisions %" PRIu64, EXTRACT_64BITS(cp));
   1620 		cp += 8;
   1621 next_port:
   1622 		len -= OF_PORT_STATS_LEN;
   1623 	} /* while */
   1624 	return cp;
   1625 
   1626 corrupt: /* skip the undersized trailing data */
   1627 	printf(" (corrupt)");
   1628 	TCHECK2(*cp0, len0);
   1629 	return cp0 + len0;
   1630 trunc:
   1631 	printf(" [|openflow]");
   1632 	return ep;
   1633 }
   1634 
   1635 /* ibid */
   1636 static const u_char *
   1637 of10_queue_stats_reply_print(const u_char *cp, const u_char *ep, u_int len) {
   1638 	const u_char *cp0 = cp;
   1639 	const u_int len0 = len;
   1640 
   1641 	while (len) {
   1642 		if (len < OF_QUEUE_STATS_LEN)
   1643 			goto corrupt;
   1644 		/* port_no */
   1645 		TCHECK2(*cp, 2);
   1646 		printf("\n\t  port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1647 		cp += 2;
   1648 		/* pad */
   1649 		TCHECK2(*cp, 2);
   1650 		cp += 2;
   1651 		/* queue_id */
   1652 		TCHECK2(*cp, 4);
   1653 		printf(", queue_id %u", EXTRACT_32BITS(cp));
   1654 		cp += 4;
   1655 		/* tx_bytes */
   1656 		TCHECK2(*cp, 8);
   1657 		printf(", tx_bytes %" PRIu64, EXTRACT_64BITS(cp));
   1658 		cp += 8;
   1659 		/* tx_packets */
   1660 		TCHECK2(*cp, 8);
   1661 		printf(", tx_packets %" PRIu64, EXTRACT_64BITS(cp));
   1662 		cp += 8;
   1663 		/* tx_errors */
   1664 		TCHECK2(*cp, 8);
   1665 		printf(", tx_errors %" PRIu64, EXTRACT_64BITS(cp));
   1666 		cp += 8;
   1667 
   1668 		len -= OF_QUEUE_STATS_LEN;
   1669 	} /* while */
   1670 	return cp;
   1671 
   1672 corrupt: /* skip the undersized trailing data */
   1673 	printf(" (corrupt)");
   1674 	TCHECK2(*cp0, len0);
   1675 	return cp0 + len0;
   1676 trunc:
   1677 	printf(" [|openflow]");
   1678 	return ep;
   1679 }
   1680 
   1681 /* ibid */
   1682 static const u_char *
   1683 of10_stats_reply_print(const u_char *cp, const u_char *ep, const u_int len) {
   1684 	const u_char *cp0 = cp;
   1685 	uint16_t type;
   1686 
   1687 	/* type */
   1688 	TCHECK2(*cp, 2);
   1689 	type = EXTRACT_16BITS(cp);
   1690 	printf("\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type));
   1691 	cp += 2;
   1692 	/* flags */
   1693 	TCHECK2(*cp, 2);
   1694 	printf(", flags 0x%04x", EXTRACT_16BITS(cp));
   1695 	of10_bitmap_print(ofpsf_reply_bm, EXTRACT_16BITS(cp), OFPSF_REPLY_U);
   1696 	cp += 2;
   1697 
   1698 	if (vflag > 0) {
   1699 		const u_char *(*decoder)(const u_char *, const u_char *, u_int) =
   1700 			type == OFPST_DESC      ? of10_desc_stats_reply_print      :
   1701 			type == OFPST_FLOW      ? of10_flow_stats_reply_print      :
   1702 			type == OFPST_AGGREGATE ? of10_aggregate_stats_reply_print :
   1703 			type == OFPST_TABLE     ? of10_table_stats_reply_print     :
   1704 			type == OFPST_PORT      ? of10_port_stats_reply_print      :
   1705 			type == OFPST_QUEUE     ? of10_queue_stats_reply_print     :
   1706 			type == OFPST_VENDOR    ? of10_vendor_data_print           :
   1707 			NULL;
   1708 		if (decoder != NULL)
   1709 			return decoder(cp, ep, len - OF_STATS_REPLY_LEN);
   1710 	}
   1711 	TCHECK2(*cp0, len);
   1712 	return cp0 + len;
   1713 
   1714 trunc:
   1715 	printf(" [|openflow]");
   1716 	return ep;
   1717 }
   1718 
   1719 /* [OF10] Section 5.3.6 */
   1720 static const u_char *
   1721 of10_packet_out_print(const u_char *cp, const u_char *ep, const u_int len) {
   1722 	const u_char *cp0 = cp;
   1723 	const u_int len0 = len;
   1724 	uint16_t actions_len;
   1725 
   1726 	/* buffer_id */
   1727 	TCHECK2(*cp, 4);
   1728 	printf("\n\t buffer_id 0x%08x", EXTRACT_32BITS(cp));
   1729 	cp += 4;
   1730 	/* in_port */
   1731 	TCHECK2(*cp, 2);
   1732 	printf(", in_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1733 	cp += 2;
   1734 	/* actions_len */
   1735 	TCHECK2(*cp, 2);
   1736 	actions_len = EXTRACT_16BITS(cp);
   1737 	cp += 2;
   1738 	if (actions_len > len - OF_PACKET_OUT_LEN)
   1739 		goto corrupt;
   1740 	/* actions */
   1741 	if (ep == (cp = of10_actions_print("\n\t ", cp, ep, actions_len)))
   1742 		return ep; /* end of snapshot */
   1743 	/* data */
   1744 	return of10_packet_data_print(cp, ep, len - OF_PACKET_OUT_LEN - actions_len);
   1745 
   1746 corrupt: /* skip the rest of the message body */
   1747 	printf(" (corrupt)");
   1748 	TCHECK2(*cp0, len0);
   1749 	return cp0 + len0;
   1750 trunc:
   1751 	printf(" [|openflow]");
   1752 	return ep;
   1753 }
   1754 
   1755 /* [OF10] Section 5.4.1 */
   1756 static const u_char *
   1757 of10_packet_in_print(const u_char *cp, const u_char *ep, const u_int len) {
   1758 	/* buffer_id */
   1759 	TCHECK2(*cp, 4);
   1760 	printf("\n\t buffer_id %s", tok2str(bufferid_str, "0x%08x", EXTRACT_32BITS(cp)));
   1761 	cp += 4;
   1762 	/* total_len */
   1763 	TCHECK2(*cp, 2);
   1764 	printf(", total_len %u", EXTRACT_16BITS(cp));
   1765 	cp += 2;
   1766 	/* in_port */
   1767 	TCHECK2(*cp, 2);
   1768 	printf(", in_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1769 	cp += 2;
   1770 	/* reason */
   1771 	TCHECK2(*cp, 1);
   1772 	printf(", reason %s", tok2str(ofpr_str, "invalid (0x%02x)", *cp));
   1773 	cp += 1;
   1774 	/* pad */
   1775 	TCHECK2(*cp, 1);
   1776 	cp += 1;
   1777 	/* data */
   1778 	/* 2 mock octets count in OF_PACKET_IN_LEN but not in len */
   1779 	return of10_packet_data_print(cp, ep, len - (OF_PACKET_IN_LEN - 2));
   1780 
   1781 trunc:
   1782 	printf(" [|openflow]");
   1783 	return ep;
   1784 }
   1785 
   1786 /* [OF10] Section 5.4.2 */
   1787 static const u_char *
   1788 of10_flow_removed_print(const u_char *cp, const u_char *ep) {
   1789 	/* match */
   1790 	if (ep == (cp = of10_match_print("\n\t ", cp, ep)))
   1791 		return ep; /* end of snapshot */
   1792 	/* cookie */
   1793 	TCHECK2(*cp, 8);
   1794 	printf("\n\t cookie 0x%016" PRIx64, EXTRACT_64BITS(cp));
   1795 	cp += 8;
   1796 	/* priority */
   1797 	TCHECK2(*cp, 2);
   1798 	if (EXTRACT_16BITS(cp))
   1799 		printf(", priority %u", EXTRACT_16BITS(cp));
   1800 	cp += 2;
   1801 	/* reason */
   1802 	TCHECK2(*cp, 1);
   1803 	printf(", reason %s", tok2str(ofprr_str, "unknown (0x%02x)", *cp));
   1804 	cp += 1;
   1805 	/* pad */
   1806 	TCHECK2(*cp, 1);
   1807 	cp += 1;
   1808 	/* duration_sec */
   1809 	TCHECK2(*cp, 4);
   1810 	printf(", duration_sec %u", EXTRACT_32BITS(cp));
   1811 	cp += 4;
   1812 	/* duration_nsec */
   1813 	TCHECK2(*cp, 4);
   1814 	printf(", duration_nsec %u", EXTRACT_32BITS(cp));
   1815 	cp += 4;
   1816 	/* idle_timeout */
   1817 	TCHECK2(*cp, 2);
   1818 	if (EXTRACT_16BITS(cp))
   1819 		printf(", idle_timeout %u", EXTRACT_16BITS(cp));
   1820 	cp += 2;
   1821 	/* pad2 */
   1822 	TCHECK2(*cp, 2);
   1823 	cp += 2;
   1824 	/* packet_count */
   1825 	TCHECK2(*cp, 8);
   1826 	printf(", packet_count %" PRIu64, EXTRACT_64BITS(cp));
   1827 	cp += 8;
   1828 	/* byte_count */
   1829 	TCHECK2(*cp, 8);
   1830 	printf(", byte_count %" PRIu64, EXTRACT_64BITS(cp));
   1831 	return cp + 8;
   1832 
   1833 trunc:
   1834 	printf(" [|openflow]");
   1835 	return ep;
   1836 }
   1837 
   1838 /* [OF10] Section 5.4.4 */
   1839 static const u_char *
   1840 of10_error_print(const u_char *cp, const u_char *ep, const u_int len) {
   1841 	uint16_t type;
   1842 	const struct tok *code_str;
   1843 
   1844 	/* type */
   1845 	TCHECK2(*cp, 2);
   1846 	type = EXTRACT_16BITS(cp);
   1847 	cp += 2;
   1848 	printf("\n\t type %s", tok2str(ofpet_str, "invalid (0x%04x)", type));
   1849 	/* code */
   1850 	TCHECK2(*cp, 2);
   1851 	code_str =
   1852 		type == OFPET_HELLO_FAILED    ? ofphfc_str  :
   1853 		type == OFPET_BAD_REQUEST     ? ofpbrc_str  :
   1854 		type == OFPET_BAD_ACTION      ? ofpbac_str  :
   1855 		type == OFPET_FLOW_MOD_FAILED ? ofpfmfc_str :
   1856 		type == OFPET_PORT_MOD_FAILED ? ofppmfc_str :
   1857 		type == OFPET_QUEUE_OP_FAILED ? ofpqofc_str :
   1858 		empty_str;
   1859 	printf(", code %s", tok2str(code_str, "invalid (0x%04x)", EXTRACT_16BITS(cp)));
   1860 	cp += 2;
   1861 	/* data */
   1862 	return of10_data_print(cp, ep, len - OF_ERROR_MSG_LEN);
   1863 
   1864 trunc:
   1865 	printf(" [|openflow]");
   1866 	return ep;
   1867 }
   1868 
   1869 const u_char *
   1870 of10_header_body_print(const u_char *cp, const u_char *ep, const uint8_t type,
   1871                        const uint16_t len, const uint32_t xid) {
   1872 	const u_char *cp0 = cp;
   1873 	const u_int len0 = len;
   1874 	/* Thus far message length is not less than the basic header size, but most
   1875 	 * message types have additional assorted constraints on the length. Wherever
   1876 	 * possible, check that message length meets the constraint, in remaining
   1877 	 * cases check that the length is OK to begin decoding and leave any final
   1878 	 * verification up to a lower-layer function. When the current message is
   1879 	 * corrupt, proceed to the next message. */
   1880 
   1881 	/* [OF10] Section 5.1 */
   1882 	printf("\n\tversion 1.0, type %s, length %u, xid 0x%08x",
   1883 	       tok2str(ofpt_str, "invalid (0x%02x)", type), len, xid);
   1884 	switch (type) {
   1885 	/* OpenFlow header only. */
   1886 	case OFPT_FEATURES_REQUEST: /* [OF10] Section 5.3.1 */
   1887 	case OFPT_GET_CONFIG_REQUEST: /* [OF10] Section 5.3.2 */
   1888 	case OFPT_BARRIER_REQUEST: /* [OF10] Section 5.3.7 */
   1889 	case OFPT_BARRIER_REPLY: /* ibid */
   1890 		if (len != OF_HEADER_LEN)
   1891 			goto corrupt;
   1892 		break;
   1893 
   1894 	/* OpenFlow header and fixed-size message body. */
   1895 	case OFPT_SET_CONFIG: /* [OF10] Section 5.3.2 */
   1896 	case OFPT_GET_CONFIG_REPLY: /* ibid */
   1897 		if (len != OF_SWITCH_CONFIG_LEN)
   1898 			goto corrupt;
   1899 		if (vflag < 1)
   1900 			goto next_message;
   1901 		/* flags */
   1902 		TCHECK2(*cp, 2);
   1903 		printf("\n\t flags %s", tok2str(ofp_config_str, "invalid (0x%04x)", EXTRACT_16BITS(cp)));
   1904 		cp += 2;
   1905 		/* miss_send_len */
   1906 		TCHECK2(*cp, 2);
   1907 		printf(", miss_send_len %u", EXTRACT_16BITS(cp));
   1908 		return cp + 2;
   1909 	case OFPT_PORT_MOD:
   1910 		if (len != OF_PORT_MOD_LEN)
   1911 			goto corrupt;
   1912 		if (vflag < 1)
   1913 			goto next_message;
   1914 		return of10_port_mod_print(cp, ep);
   1915 	case OFPT_QUEUE_GET_CONFIG_REQUEST: /* [OF10] Section 5.3.4 */
   1916 		if (len != OF_QUEUE_GET_CONFIG_REQUEST_LEN)
   1917 			goto corrupt;
   1918 		if (vflag < 1)
   1919 			goto next_message;
   1920 		/* port */
   1921 		TCHECK2(*cp, 2);
   1922 		printf("\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   1923 		cp += 2;
   1924 		/* pad */
   1925 		TCHECK2(*cp, 2);
   1926 		return cp + 2;
   1927 	case OFPT_FLOW_REMOVED:
   1928 		if (len != OF_FLOW_REMOVED_LEN)
   1929 			goto corrupt;
   1930 		if (vflag < 1)
   1931 			goto next_message;
   1932 		return of10_flow_removed_print(cp, ep);
   1933 	case OFPT_PORT_STATUS: /* [OF10] Section 5.4.3 */
   1934 		if (len != OF_PORT_STATUS_LEN)
   1935 			goto corrupt;
   1936 		if (vflag < 1)
   1937 			goto next_message;
   1938 		/* reason */
   1939 		TCHECK2(*cp, 1);
   1940 		printf("\n\t reason %s", tok2str(ofppr_str, "invalid (0x%02x)", *cp));
   1941 		cp += 1;
   1942 		/* pad */
   1943 		TCHECK2(*cp, 7);
   1944 		cp += 7;
   1945 		/* desc */
   1946 		return of10_phy_ports_print(cp, ep, OF_PHY_PORT_LEN);
   1947 
   1948 	/* OpenFlow header, fixed-size message body and n * fixed-size data units. */
   1949 	case OFPT_FEATURES_REPLY:
   1950 		if (len < OF_SWITCH_FEATURES_LEN)
   1951 			goto corrupt;
   1952 		if (vflag < 1)
   1953 			goto next_message;
   1954 		return of10_features_reply_print(cp, ep, len);
   1955 
   1956 	/* OpenFlow header and variable-size data. */
   1957 	case OFPT_HELLO: /* [OF10] Section 5.5.1 */
   1958 	case OFPT_ECHO_REQUEST: /* [OF10] Section 5.5.2 */
   1959 	case OFPT_ECHO_REPLY: /* [OF10] Section 5.5.3 */
   1960 		if (vflag < 1)
   1961 			goto next_message;
   1962 		return of10_data_print(cp, ep, len - OF_HEADER_LEN);
   1963 
   1964 	/* OpenFlow header, fixed-size message body and variable-size data. */
   1965 	case OFPT_ERROR:
   1966 		if (len < OF_ERROR_MSG_LEN)
   1967 			goto corrupt;
   1968 		if (vflag < 1)
   1969 			goto next_message;
   1970 		return of10_error_print(cp, ep, len);
   1971 	case OFPT_VENDOR:
   1972 	  /* [OF10] Section 5.5.4 */
   1973 		if (len < OF_VENDOR_HEADER_LEN)
   1974 			goto corrupt;
   1975 		if (vflag < 1)
   1976 			goto next_message;
   1977 		return of10_vendor_data_print(cp, ep, len - OF_HEADER_LEN);
   1978 	case OFPT_PACKET_IN:
   1979 		/* 2 mock octets count in OF_PACKET_IN_LEN but not in len */
   1980 		if (len < OF_PACKET_IN_LEN - 2)
   1981 			goto corrupt;
   1982 		if (vflag < 1)
   1983 			goto next_message;
   1984 		return of10_packet_in_print(cp, ep, len);
   1985 
   1986 	/* a. OpenFlow header. */
   1987 	/* b. OpenFlow header and one of the fixed-size message bodies. */
   1988 	/* c. OpenFlow header, fixed-size message body and variable-size data. */
   1989 	case OFPT_STATS_REQUEST:
   1990 		if (len < OF_STATS_REQUEST_LEN)
   1991 			goto corrupt;
   1992 		if (vflag < 1)
   1993 			goto next_message;
   1994 		return of10_stats_request_print(cp, ep, len);
   1995 
   1996 	/* a. OpenFlow header and fixed-size message body. */
   1997 	/* b. OpenFlow header and n * fixed-size data units. */
   1998 	/* c. OpenFlow header and n * variable-size data units. */
   1999 	/* d. OpenFlow header, fixed-size message body and variable-size data. */
   2000 	case OFPT_STATS_REPLY:
   2001 		if (len < OF_STATS_REPLY_LEN)
   2002 			goto corrupt;
   2003 		if (vflag < 1)
   2004 			goto next_message;
   2005 		return of10_stats_reply_print(cp, ep, len);
   2006 
   2007 	/* OpenFlow header and n * variable-size data units and variable-size data. */
   2008 	case OFPT_PACKET_OUT:
   2009 		if (len < OF_PACKET_OUT_LEN)
   2010 			goto corrupt;
   2011 		if (vflag < 1)
   2012 			goto next_message;
   2013 		return of10_packet_out_print(cp, ep, len);
   2014 
   2015 	/* OpenFlow header, fixed-size message body and n * variable-size data units. */
   2016 	case OFPT_FLOW_MOD:
   2017 		if (len < OF_FLOW_MOD_LEN)
   2018 			goto corrupt;
   2019 		if (vflag < 1)
   2020 			goto next_message;
   2021 		return of10_flow_mod_print(cp, ep, len);
   2022 
   2023 	/* OpenFlow header, fixed-size message body and n * variable-size data units. */
   2024 	case OFPT_QUEUE_GET_CONFIG_REPLY: /* [OF10] Section 5.3.4 */
   2025 		if (len < OF_QUEUE_GET_CONFIG_REPLY_LEN)
   2026 			goto corrupt;
   2027 		if (vflag < 1)
   2028 			goto next_message;
   2029 		/* port */
   2030 		TCHECK2(*cp, 2);
   2031 		printf("\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)));
   2032 		cp += 2;
   2033 		/* pad */
   2034 		TCHECK2(*cp, 6);
   2035 		cp += 6;
   2036 		/* queues */
   2037 		return of10_queues_print(cp, ep, len - OF_QUEUE_GET_CONFIG_REPLY_LEN);
   2038 	} /* switch (type) */
   2039 	goto next_message;
   2040 
   2041 corrupt: /* skip the message body */
   2042 	printf(" (corrupt)");
   2043 next_message:
   2044 	TCHECK2(*cp0, len0 - OF_HEADER_LEN);
   2045 	return cp0 + len0 - OF_HEADER_LEN;
   2046 trunc:
   2047 	printf(" [|openflow]");
   2048 	return ep;
   2049 }
   2050