13c602fabSXin LI /*
23c602fabSXin LI * This module implements decoding of OpenFlow protocol version 1.0 (wire
33c602fabSXin LI * protocol 0x01). The decoder implements terse (default), detailed (-v) and
43c602fabSXin LI * full (-vv) output formats and, as much as each format implies, detects and
53c602fabSXin LI * tries to work around sizing anomalies inside the messages. The decoder marks
63c602fabSXin LI * up bogus values of selected message fields and decodes partially captured
73c602fabSXin LI * messages up to the snapshot end. It is based on the specification below:
83c602fabSXin LI *
9ee67461eSJoseph Mingrone * [OF10] https://www.opennetworking.org/wp-content/uploads/2013/04/openflow-spec-v1.0.0.pdf
103c602fabSXin LI *
11ee67461eSJoseph Mingrone * Most functions in this file take the following arguments:
128bdc5a62SPatrick Kelsey * * cp -- the pointer to the first octet to decode
13ee67461eSJoseph Mingrone * * len -- the declared length of the structure to decode
14ee67461eSJoseph Mingrone * The convention is that a printer function returns iff the given structure is
15ee67461eSJoseph Mingrone * completely within the packet buffer; otherwise it processes the part that is
16ee67461eSJoseph Mingrone * within the buffer, sooner of later takes the "truncated packet" shortcut via
17ee67461eSJoseph Mingrone * longjmp() and never returns. With that in mind, the function may return
18ee67461eSJoseph Mingrone * without printing the structure completely if it is invalid or the ndo_vflag
19ee67461eSJoseph Mingrone * value is not high enough. This way the calling function can try to decode
20ee67461eSJoseph Mingrone * the next data item.
218bdc5a62SPatrick Kelsey *
223c602fabSXin LI * Decoding of Ethernet frames nested in OFPT_PACKET_IN and OFPT_PACKET_OUT
233c602fabSXin LI * messages is done only when the verbosity level set by command-line argument
243c602fabSXin LI * is "-vvv" or higher. In that case the verbosity level is temporarily
253c602fabSXin LI * decremented by 3 during the nested frame decoding. For example, running
263c602fabSXin LI * tcpdump with "-vvvv" will do full decoding of OpenFlow and "-v" decoding of
273c602fabSXin LI * the nested frames.
283c602fabSXin LI *
298bdc5a62SPatrick Kelsey * Partial decoding of Big Switch Networks vendor extensions is done after the
308bdc5a62SPatrick Kelsey * oftest (OpenFlow Testing Framework) and Loxigen (library generator) source
318bdc5a62SPatrick Kelsey * code.
328bdc5a62SPatrick Kelsey *
333c602fabSXin LI *
343c602fabSXin LI * Copyright (c) 2013 The TCPDUMP project
353c602fabSXin LI * All rights reserved.
363c602fabSXin LI *
373c602fabSXin LI * Redistribution and use in source and binary forms, with or without
383c602fabSXin LI * modification, are permitted provided that the following conditions
393c602fabSXin LI * are met:
403c602fabSXin LI * 1. Redistributions of source code must retain the above copyright
413c602fabSXin LI * notice, this list of conditions and the following disclaimer.
423c602fabSXin LI * 2. Redistributions in binary form must reproduce the above copyright
433c602fabSXin LI * notice, this list of conditions and the following disclaimer in the
443c602fabSXin LI * documentation and/or other materials provided with the distribution.
453c602fabSXin LI *
463c602fabSXin LI * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
473c602fabSXin LI * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
483c602fabSXin LI * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
493c602fabSXin LI * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
503c602fabSXin LI * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
513c602fabSXin LI * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
523c602fabSXin LI * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
533c602fabSXin LI * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
543c602fabSXin LI * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
553c602fabSXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
563c602fabSXin LI * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
573c602fabSXin LI * POSSIBILITY OF SUCH DAMAGE.
583c602fabSXin LI */
593c602fabSXin LI
603340d773SGleb Smirnoff /* \summary: OpenFlow protocol version 1.0 printer */
613340d773SGleb Smirnoff
62ee67461eSJoseph Mingrone #include <config.h>
633c602fabSXin LI
64ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
653c602fabSXin LI
66ee67461eSJoseph Mingrone #define ND_LONGJMP_FROM_TCHECK
673340d773SGleb Smirnoff #include "netdissect.h"
683c602fabSXin LI #include "extract.h"
693c602fabSXin LI #include "addrtoname.h"
703c602fabSXin LI #include "ethertype.h"
713c602fabSXin LI #include "ipproto.h"
728bdc5a62SPatrick Kelsey #include "oui.h"
733c602fabSXin LI #include "openflow.h"
743c602fabSXin LI
753c602fabSXin LI
763c602fabSXin LI #define OFPT_HELLO 0x00
773c602fabSXin LI #define OFPT_ERROR 0x01
783c602fabSXin LI #define OFPT_ECHO_REQUEST 0x02
793c602fabSXin LI #define OFPT_ECHO_REPLY 0x03
803c602fabSXin LI #define OFPT_VENDOR 0x04
813c602fabSXin LI #define OFPT_FEATURES_REQUEST 0x05
823c602fabSXin LI #define OFPT_FEATURES_REPLY 0x06
833c602fabSXin LI #define OFPT_GET_CONFIG_REQUEST 0x07
843c602fabSXin LI #define OFPT_GET_CONFIG_REPLY 0x08
853c602fabSXin LI #define OFPT_SET_CONFIG 0x09
863c602fabSXin LI #define OFPT_PACKET_IN 0x0a
873c602fabSXin LI #define OFPT_FLOW_REMOVED 0x0b
883c602fabSXin LI #define OFPT_PORT_STATUS 0x0c
893c602fabSXin LI #define OFPT_PACKET_OUT 0x0d
903c602fabSXin LI #define OFPT_FLOW_MOD 0x0e
913c602fabSXin LI #define OFPT_PORT_MOD 0x0f
923c602fabSXin LI #define OFPT_STATS_REQUEST 0x10
933c602fabSXin LI #define OFPT_STATS_REPLY 0x11
943c602fabSXin LI #define OFPT_BARRIER_REQUEST 0x12
953c602fabSXin LI #define OFPT_BARRIER_REPLY 0x13
963c602fabSXin LI #define OFPT_QUEUE_GET_CONFIG_REQUEST 0x14
973c602fabSXin LI #define OFPT_QUEUE_GET_CONFIG_REPLY 0x15
98ee67461eSJoseph Mingrone #define OFPT_MAX OFPT_QUEUE_GET_CONFIG_REPLY
993c602fabSXin LI
100ee67461eSJoseph Mingrone #define OFPPC_PORT_DOWN (1U <<0)
101ee67461eSJoseph Mingrone #define OFPPC_NO_STP (1U <<1)
102ee67461eSJoseph Mingrone #define OFPPC_NO_RECV (1U <<2)
103ee67461eSJoseph Mingrone #define OFPPC_NO_RECV_STP (1U <<3)
104ee67461eSJoseph Mingrone #define OFPPC_NO_FLOOD (1U <<4)
105ee67461eSJoseph Mingrone #define OFPPC_NO_FWD (1U <<5)
106ee67461eSJoseph Mingrone #define OFPPC_NO_PACKET_IN (1U <<6)
1073c602fabSXin LI static const struct tok ofppc_bm[] = {
1083c602fabSXin LI { OFPPC_PORT_DOWN, "PORT_DOWN" },
1093c602fabSXin LI { OFPPC_NO_STP, "NO_STP" },
1103c602fabSXin LI { OFPPC_NO_RECV, "NO_RECV" },
1113c602fabSXin LI { OFPPC_NO_RECV_STP, "NO_RECV_STP" },
1123c602fabSXin LI { OFPPC_NO_FLOOD, "NO_FLOOD" },
1133c602fabSXin LI { OFPPC_NO_FWD, "NO_FWD" },
1143c602fabSXin LI { OFPPC_NO_PACKET_IN, "NO_PACKET_IN" },
1153c602fabSXin LI { 0, NULL }
1163c602fabSXin LI };
1173c602fabSXin LI #define OFPPC_U (~(OFPPC_PORT_DOWN | OFPPC_NO_STP | OFPPC_NO_RECV | \
1183c602fabSXin LI OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD | \
1193c602fabSXin LI OFPPC_NO_PACKET_IN))
1203c602fabSXin LI
121ee67461eSJoseph Mingrone /*
122ee67461eSJoseph Mingrone * [OF10] lists all FPPS_ constants in one enum, but they mean a 1-bit bitmap
123ee67461eSJoseph Mingrone * in the least significant octet and a 2-bit code point in the next octet.
124ee67461eSJoseph Mingrone * Remember to mix or to separate these two parts as the context requires.
125ee67461eSJoseph Mingrone */
126ee67461eSJoseph Mingrone #define OFPPS_LINK_DOWN (1U << 0) /* bitmap */
127ee67461eSJoseph Mingrone #define OFPPS_STP_LISTEN (0U << 8) /* code point */
128ee67461eSJoseph Mingrone #define OFPPS_STP_LEARN (1U << 8) /* code point */
129ee67461eSJoseph Mingrone #define OFPPS_STP_FORWARD (2U << 8) /* code point */
130ee67461eSJoseph Mingrone #define OFPPS_STP_BLOCK (3U << 8) /* code point */
131ee67461eSJoseph Mingrone #define OFPPS_STP_MASK (3U << 8) /* code point bitmask */
132ee67461eSJoseph Mingrone static const struct tok ofpps_stp_str[] = {
1333c602fabSXin LI { OFPPS_STP_LISTEN, "STP_LISTEN" },
1343c602fabSXin LI { OFPPS_STP_LEARN, "STP_LEARN" },
1353c602fabSXin LI { OFPPS_STP_FORWARD, "STP_FORWARD" },
1363c602fabSXin LI { OFPPS_STP_BLOCK, "STP_BLOCK" },
1373c602fabSXin LI { 0, NULL }
1383c602fabSXin LI };
1393c602fabSXin LI #define OFPPS_U (~(OFPPS_LINK_DOWN | OFPPS_STP_LISTEN | OFPPS_STP_LEARN | \
1403c602fabSXin LI OFPPS_STP_FORWARD | OFPPS_STP_BLOCK))
1413c602fabSXin LI
142ee67461eSJoseph Mingrone #define OFPP_MAX 0xff00U
143ee67461eSJoseph Mingrone #define OFPP_IN_PORT 0xfff8U
144ee67461eSJoseph Mingrone #define OFPP_TABLE 0xfff9U
145ee67461eSJoseph Mingrone #define OFPP_NORMAL 0xfffaU
146ee67461eSJoseph Mingrone #define OFPP_FLOOD 0xfffbU
147ee67461eSJoseph Mingrone #define OFPP_ALL 0xfffcU
148ee67461eSJoseph Mingrone #define OFPP_CONTROLLER 0xfffdU
149ee67461eSJoseph Mingrone #define OFPP_LOCAL 0xfffeU
150ee67461eSJoseph Mingrone #define OFPP_NONE 0xffffU
1513c602fabSXin LI static const struct tok ofpp_str[] = {
1523c602fabSXin LI { OFPP_MAX, "MAX" },
1533c602fabSXin LI { OFPP_IN_PORT, "IN_PORT" },
1543c602fabSXin LI { OFPP_TABLE, "TABLE" },
1553c602fabSXin LI { OFPP_NORMAL, "NORMAL" },
1563c602fabSXin LI { OFPP_FLOOD, "FLOOD" },
1573c602fabSXin LI { OFPP_ALL, "ALL" },
1583c602fabSXin LI { OFPP_CONTROLLER, "CONTROLLER" },
1593c602fabSXin LI { OFPP_LOCAL, "LOCAL" },
1603c602fabSXin LI { OFPP_NONE, "NONE" },
1613c602fabSXin LI { 0, NULL }
1623c602fabSXin LI };
1633c602fabSXin LI
164ee67461eSJoseph Mingrone #define OFPPF_10MB_HD (1U << 0)
165ee67461eSJoseph Mingrone #define OFPPF_10MB_FD (1U << 1)
166ee67461eSJoseph Mingrone #define OFPPF_100MB_HD (1U << 2)
167ee67461eSJoseph Mingrone #define OFPPF_100MB_FD (1U << 3)
168ee67461eSJoseph Mingrone #define OFPPF_1GB_HD (1U << 4)
169ee67461eSJoseph Mingrone #define OFPPF_1GB_FD (1U << 5)
170ee67461eSJoseph Mingrone #define OFPPF_10GB_FD (1U << 6)
171ee67461eSJoseph Mingrone #define OFPPF_COPPER (1U << 7)
172ee67461eSJoseph Mingrone #define OFPPF_FIBER (1U << 8)
173ee67461eSJoseph Mingrone #define OFPPF_AUTONEG (1U << 9)
174ee67461eSJoseph Mingrone #define OFPPF_PAUSE (1U <<10)
175ee67461eSJoseph Mingrone #define OFPPF_PAUSE_ASYM (1U <<11)
1763c602fabSXin LI static const struct tok ofppf_bm[] = {
1773c602fabSXin LI { OFPPF_10MB_HD, "10MB_HD" },
1783c602fabSXin LI { OFPPF_10MB_FD, "10MB_FD" },
1793c602fabSXin LI { OFPPF_100MB_HD, "100MB_HD" },
1803c602fabSXin LI { OFPPF_100MB_FD, "100MB_FD" },
1813c602fabSXin LI { OFPPF_1GB_HD, "1GB_HD" },
1823c602fabSXin LI { OFPPF_1GB_FD, "1GB_FD" },
1833c602fabSXin LI { OFPPF_10GB_FD, "10GB_FD" },
1843c602fabSXin LI { OFPPF_COPPER, "COPPER" },
1853c602fabSXin LI { OFPPF_FIBER, "FIBER" },
1863c602fabSXin LI { OFPPF_AUTONEG, "AUTONEG" },
1873c602fabSXin LI { OFPPF_PAUSE, "PAUSE" },
1883c602fabSXin LI { OFPPF_PAUSE_ASYM, "PAUSE_ASYM" },
1893c602fabSXin LI { 0, NULL }
1903c602fabSXin LI };
1913c602fabSXin LI #define OFPPF_U (~(OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | \
1923c602fabSXin LI OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | \
1933c602fabSXin LI OFPPF_10GB_FD | OFPPF_COPPER | OFPPF_FIBER | \
1943c602fabSXin LI OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM))
1953c602fabSXin LI
1963c602fabSXin LI #define OFPQT_NONE 0x0000
1973c602fabSXin LI #define OFPQT_MIN_RATE 0x0001
1983c602fabSXin LI static const struct tok ofpqt_str[] = {
1993c602fabSXin LI { OFPQT_NONE, "NONE" },
2003c602fabSXin LI { OFPQT_MIN_RATE, "MIN_RATE" },
2013c602fabSXin LI { 0, NULL }
2023c602fabSXin LI };
2033c602fabSXin LI
204ee67461eSJoseph Mingrone #define OFPFW_IN_PORT (1U <<0)
205ee67461eSJoseph Mingrone #define OFPFW_DL_VLAN (1U <<1)
206ee67461eSJoseph Mingrone #define OFPFW_DL_SRC (1U <<2)
207ee67461eSJoseph Mingrone #define OFPFW_DL_DST (1U <<3)
208ee67461eSJoseph Mingrone #define OFPFW_DL_TYPE (1U <<4)
209ee67461eSJoseph Mingrone #define OFPFW_NW_PROTO (1U <<5)
210ee67461eSJoseph Mingrone #define OFPFW_TP_SRC (1U <<6)
211ee67461eSJoseph Mingrone #define OFPFW_TP_DST (1U <<7)
2123c602fabSXin LI #define OFPFW_NW_SRC_SHIFT 8
2133c602fabSXin LI #define OFPFW_NW_SRC_BITS 6
214ee67461eSJoseph Mingrone #define OFPFW_NW_SRC_MASK (((1U <<OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT)
2153c602fabSXin LI #define OFPFW_NW_DST_SHIFT 14
2163c602fabSXin LI #define OFPFW_NW_DST_BITS 6
217ee67461eSJoseph Mingrone #define OFPFW_NW_DST_MASK (((1U <<OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT)
218ee67461eSJoseph Mingrone #define OFPFW_DL_VLAN_PCP (1U <<20)
219ee67461eSJoseph Mingrone #define OFPFW_NW_TOS (1U <<21)
220ee67461eSJoseph Mingrone #define OFPFW_ALL ((1U <<22) - 1)
2213c602fabSXin LI static const struct tok ofpfw_bm[] = {
2223c602fabSXin LI { OFPFW_IN_PORT, "IN_PORT" },
2233c602fabSXin LI { OFPFW_DL_VLAN, "DL_VLAN" },
2243c602fabSXin LI { OFPFW_DL_SRC, "DL_SRC" },
2253c602fabSXin LI { OFPFW_DL_DST, "DL_DST" },
2263c602fabSXin LI { OFPFW_DL_TYPE, "DL_TYPE" },
2273c602fabSXin LI { OFPFW_NW_PROTO, "NW_PROTO" },
2283c602fabSXin LI { OFPFW_TP_SRC, "TP_SRC" },
2293c602fabSXin LI { OFPFW_TP_DST, "TP_DST" },
2303c602fabSXin LI { OFPFW_DL_VLAN_PCP, "DL_VLAN_PCP" },
2313c602fabSXin LI { OFPFW_NW_TOS, "NW_TOS" },
2323c602fabSXin LI { 0, NULL }
2333c602fabSXin LI };
2343c602fabSXin LI /* The above array does not include bits 8~13 (OFPFW_NW_SRC_*) and 14~19
2353c602fabSXin LI * (OFPFW_NW_DST_*), which are not a part of the bitmap and require decoding
2363c602fabSXin LI * other than that of tok2str(). The macro below includes these bits such that
2373c602fabSXin LI * they are not reported as bogus in the decoding. */
2383c602fabSXin LI #define OFPFW_U (~(OFPFW_ALL))
2393c602fabSXin LI
240ee67461eSJoseph Mingrone #define OFPAT_OUTPUT 0x0000U
241ee67461eSJoseph Mingrone #define OFPAT_SET_VLAN_VID 0x0001U
242ee67461eSJoseph Mingrone #define OFPAT_SET_VLAN_PCP 0x0002U
243ee67461eSJoseph Mingrone #define OFPAT_STRIP_VLAN 0x0003U
244ee67461eSJoseph Mingrone #define OFPAT_SET_DL_SRC 0x0004U
245ee67461eSJoseph Mingrone #define OFPAT_SET_DL_DST 0x0005U
246ee67461eSJoseph Mingrone #define OFPAT_SET_NW_SRC 0x0006U
247ee67461eSJoseph Mingrone #define OFPAT_SET_NW_DST 0x0007U
248ee67461eSJoseph Mingrone #define OFPAT_SET_NW_TOS 0x0008U
249ee67461eSJoseph Mingrone #define OFPAT_SET_TP_SRC 0x0009U
250ee67461eSJoseph Mingrone #define OFPAT_SET_TP_DST 0x000aU
251ee67461eSJoseph Mingrone #define OFPAT_ENQUEUE 0x000bU
252ee67461eSJoseph Mingrone #define OFPAT_VENDOR 0xffffU
2533c602fabSXin LI static const struct tok ofpat_str[] = {
2543c602fabSXin LI { OFPAT_OUTPUT, "OUTPUT" },
2553c602fabSXin LI { OFPAT_SET_VLAN_VID, "SET_VLAN_VID" },
2563c602fabSXin LI { OFPAT_SET_VLAN_PCP, "SET_VLAN_PCP" },
2573c602fabSXin LI { OFPAT_STRIP_VLAN, "STRIP_VLAN" },
2583c602fabSXin LI { OFPAT_SET_DL_SRC, "SET_DL_SRC" },
2593c602fabSXin LI { OFPAT_SET_DL_DST, "SET_DL_DST" },
2603c602fabSXin LI { OFPAT_SET_NW_SRC, "SET_NW_SRC" },
2613c602fabSXin LI { OFPAT_SET_NW_DST, "SET_NW_DST" },
2623c602fabSXin LI { OFPAT_SET_NW_TOS, "SET_NW_TOS" },
2633c602fabSXin LI { OFPAT_SET_TP_SRC, "SET_TP_SRC" },
2643c602fabSXin LI { OFPAT_SET_TP_DST, "SET_TP_DST" },
2653c602fabSXin LI { OFPAT_ENQUEUE, "ENQUEUE" },
2663c602fabSXin LI { OFPAT_VENDOR, "VENDOR" },
2673c602fabSXin LI { 0, NULL }
2683c602fabSXin LI };
2693c602fabSXin LI
2703c602fabSXin LI /* bit-shifted, w/o vendor action */
2713c602fabSXin LI static const struct tok ofpat_bm[] = {
272ee67461eSJoseph Mingrone { 1U <<OFPAT_OUTPUT, "OUTPUT" },
273ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_VLAN_VID, "SET_VLAN_VID" },
274ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_VLAN_PCP, "SET_VLAN_PCP" },
275ee67461eSJoseph Mingrone { 1U <<OFPAT_STRIP_VLAN, "STRIP_VLAN" },
276ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_DL_SRC, "SET_DL_SRC" },
277ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_DL_DST, "SET_DL_DST" },
278ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_NW_SRC, "SET_NW_SRC" },
279ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_NW_DST, "SET_NW_DST" },
280ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_NW_TOS, "SET_NW_TOS" },
281ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_TP_SRC, "SET_TP_SRC" },
282ee67461eSJoseph Mingrone { 1U <<OFPAT_SET_TP_DST, "SET_TP_DST" },
283ee67461eSJoseph Mingrone { 1U <<OFPAT_ENQUEUE, "ENQUEUE" },
2843c602fabSXin LI { 0, NULL }
2853c602fabSXin LI };
286ee67461eSJoseph Mingrone #define OFPAT_U (~(1U <<OFPAT_OUTPUT | 1U <<OFPAT_SET_VLAN_VID | \
287ee67461eSJoseph Mingrone 1U <<OFPAT_SET_VLAN_PCP | 1U <<OFPAT_STRIP_VLAN | \
288ee67461eSJoseph Mingrone 1U <<OFPAT_SET_DL_SRC | 1U <<OFPAT_SET_DL_DST | \
289ee67461eSJoseph Mingrone 1U <<OFPAT_SET_NW_SRC | 1U <<OFPAT_SET_NW_DST | \
290ee67461eSJoseph Mingrone 1U <<OFPAT_SET_NW_TOS | 1U <<OFPAT_SET_TP_SRC | \
291ee67461eSJoseph Mingrone 1U <<OFPAT_SET_TP_DST | 1U <<OFPAT_ENQUEUE))
2923c602fabSXin LI
293ee67461eSJoseph Mingrone #define OFPC_FLOW_STATS (1U <<0)
294ee67461eSJoseph Mingrone #define OFPC_TABLE_STATS (1U <<1)
295ee67461eSJoseph Mingrone #define OFPC_PORT_STATS (1U <<2)
296ee67461eSJoseph Mingrone #define OFPC_STP (1U <<3)
297ee67461eSJoseph Mingrone #define OFPC_RESERVED (1U <<4)
298ee67461eSJoseph Mingrone #define OFPC_IP_REASM (1U <<5)
299ee67461eSJoseph Mingrone #define OFPC_QUEUE_STATS (1U <<6)
300ee67461eSJoseph Mingrone #define OFPC_ARP_MATCH_IP (1U <<7)
3013c602fabSXin LI static const struct tok ofp_capabilities_bm[] = {
3023c602fabSXin LI { OFPC_FLOW_STATS, "FLOW_STATS" },
3033c602fabSXin LI { OFPC_TABLE_STATS, "TABLE_STATS" },
3043c602fabSXin LI { OFPC_PORT_STATS, "PORT_STATS" },
3053c602fabSXin LI { OFPC_STP, "STP" },
3063c602fabSXin LI { OFPC_RESERVED, "RESERVED" }, /* not in the mask below */
3073c602fabSXin LI { OFPC_IP_REASM, "IP_REASM" },
3083c602fabSXin LI { OFPC_QUEUE_STATS, "QUEUE_STATS" },
3093c602fabSXin LI { OFPC_ARP_MATCH_IP, "ARP_MATCH_IP" },
3103c602fabSXin LI { 0, NULL }
3113c602fabSXin LI };
3123c602fabSXin LI #define OFPCAP_U (~(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \
3133c602fabSXin LI OFPC_STP | OFPC_IP_REASM | OFPC_QUEUE_STATS | \
3143c602fabSXin LI OFPC_ARP_MATCH_IP))
3153c602fabSXin LI
316ee67461eSJoseph Mingrone #define OFPC_FRAG_NORMAL 0x0000U
317ee67461eSJoseph Mingrone #define OFPC_FRAG_DROP 0x0001U
318ee67461eSJoseph Mingrone #define OFPC_FRAG_REASM 0x0002U
3193c602fabSXin LI static const struct tok ofp_config_str[] = {
3203c602fabSXin LI { OFPC_FRAG_NORMAL, "FRAG_NORMAL" },
3213c602fabSXin LI { OFPC_FRAG_DROP, "FRAG_DROP" },
3223c602fabSXin LI { OFPC_FRAG_REASM, "FRAG_REASM" },
3233c602fabSXin LI { 0, NULL }
3243c602fabSXin LI };
3253c602fabSXin LI
326ee67461eSJoseph Mingrone #define OFPFC_ADD 0x0000U
327ee67461eSJoseph Mingrone #define OFPFC_MODIFY 0x0001U
328ee67461eSJoseph Mingrone #define OFPFC_MODIFY_STRICT 0x0002U
329ee67461eSJoseph Mingrone #define OFPFC_DELETE 0x0003U
330ee67461eSJoseph Mingrone #define OFPFC_DELETE_STRICT 0x0004U
3313c602fabSXin LI static const struct tok ofpfc_str[] = {
3323c602fabSXin LI { OFPFC_ADD, "ADD" },
3333c602fabSXin LI { OFPFC_MODIFY, "MODIFY" },
3343c602fabSXin LI { OFPFC_MODIFY_STRICT, "MODIFY_STRICT" },
3353c602fabSXin LI { OFPFC_DELETE, "DELETE" },
3363c602fabSXin LI { OFPFC_DELETE_STRICT, "DELETE_STRICT" },
3373c602fabSXin LI { 0, NULL }
3383c602fabSXin LI };
3393c602fabSXin LI
3403c602fabSXin LI static const struct tok bufferid_str[] = {
3413c602fabSXin LI { 0xffffffff, "NONE" },
3423c602fabSXin LI { 0, NULL }
3433c602fabSXin LI };
3443c602fabSXin LI
345ee67461eSJoseph Mingrone #define OFPFF_SEND_FLOW_REM (1U <<0)
346ee67461eSJoseph Mingrone #define OFPFF_CHECK_OVERLAP (1U <<1)
347ee67461eSJoseph Mingrone #define OFPFF_EMERG (1U <<2)
3483c602fabSXin LI static const struct tok ofpff_bm[] = {
3493c602fabSXin LI { OFPFF_SEND_FLOW_REM, "SEND_FLOW_REM" },
3503c602fabSXin LI { OFPFF_CHECK_OVERLAP, "CHECK_OVERLAP" },
3513c602fabSXin LI { OFPFF_EMERG, "EMERG" },
3523c602fabSXin LI { 0, NULL }
3533c602fabSXin LI };
3543c602fabSXin LI #define OFPFF_U (~(OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_EMERG))
3553c602fabSXin LI
356ee67461eSJoseph Mingrone #define OFPST_DESC 0x0000U
357ee67461eSJoseph Mingrone #define OFPST_FLOW 0x0001U
358ee67461eSJoseph Mingrone #define OFPST_AGGREGATE 0x0002U
359ee67461eSJoseph Mingrone #define OFPST_TABLE 0x0003U
360ee67461eSJoseph Mingrone #define OFPST_PORT 0x0004U
361ee67461eSJoseph Mingrone #define OFPST_QUEUE 0x0005U
362ee67461eSJoseph Mingrone #define OFPST_VENDOR 0xffffU
3633c602fabSXin LI static const struct tok ofpst_str[] = {
3643c602fabSXin LI { OFPST_DESC, "DESC" },
3653c602fabSXin LI { OFPST_FLOW, "FLOW" },
3663c602fabSXin LI { OFPST_AGGREGATE, "AGGREGATE" },
3673c602fabSXin LI { OFPST_TABLE, "TABLE" },
3683c602fabSXin LI { OFPST_PORT, "PORT" },
3693c602fabSXin LI { OFPST_QUEUE, "QUEUE" },
3703c602fabSXin LI { OFPST_VENDOR, "VENDOR" },
3713c602fabSXin LI { 0, NULL }
3723c602fabSXin LI };
3733c602fabSXin LI
3743c602fabSXin LI static const struct tok tableid_str[] = {
375ee67461eSJoseph Mingrone { 0xfeU, "EMERG" },
376ee67461eSJoseph Mingrone { 0xffU, "ALL" },
3773c602fabSXin LI { 0, NULL }
3783c602fabSXin LI };
3793c602fabSXin LI
380ee67461eSJoseph Mingrone #define OFPQ_ALL 0xffffffffU
3813c602fabSXin LI static const struct tok ofpq_str[] = {
3823c602fabSXin LI { OFPQ_ALL, "ALL" },
3833c602fabSXin LI { 0, NULL }
3843c602fabSXin LI };
3853c602fabSXin LI
386ee67461eSJoseph Mingrone #define OFPSF_REPLY_MORE 0x0001U
3873c602fabSXin LI static const struct tok ofpsf_reply_bm[] = {
3883c602fabSXin LI { OFPSF_REPLY_MORE, "MORE" },
3893c602fabSXin LI { 0, NULL }
3903c602fabSXin LI };
3913c602fabSXin LI #define OFPSF_REPLY_U (~(OFPSF_REPLY_MORE))
3923c602fabSXin LI
393ee67461eSJoseph Mingrone #define OFPR_NO_MATCH 0x00U
394ee67461eSJoseph Mingrone #define OFPR_ACTION 0x01U
3953c602fabSXin LI static const struct tok ofpr_str[] = {
3963c602fabSXin LI { OFPR_NO_MATCH, "NO_MATCH" },
3973c602fabSXin LI { OFPR_ACTION, "ACTION" },
3983c602fabSXin LI { 0, NULL }
3993c602fabSXin LI };
4003c602fabSXin LI
401ee67461eSJoseph Mingrone #define OFPRR_IDLE_TIMEOUT 0x00U
402ee67461eSJoseph Mingrone #define OFPRR_HARD_TIMEOUT 0x01U
403ee67461eSJoseph Mingrone #define OFPRR_DELETE 0x02U
4043c602fabSXin LI static const struct tok ofprr_str[] = {
4053c602fabSXin LI { OFPRR_IDLE_TIMEOUT, "IDLE_TIMEOUT" },
4063c602fabSXin LI { OFPRR_HARD_TIMEOUT, "HARD_TIMEOUT" },
4073c602fabSXin LI { OFPRR_DELETE, "DELETE" },
4083c602fabSXin LI { 0, NULL }
4093c602fabSXin LI };
4103c602fabSXin LI
411ee67461eSJoseph Mingrone #define OFPPR_ADD 0x00U
412ee67461eSJoseph Mingrone #define OFPPR_DELETE 0x01U
413ee67461eSJoseph Mingrone #define OFPPR_MODIFY 0x02U
4143c602fabSXin LI static const struct tok ofppr_str[] = {
4153c602fabSXin LI { OFPPR_ADD, "ADD" },
4163c602fabSXin LI { OFPPR_DELETE, "DELETE" },
4173c602fabSXin LI { OFPPR_MODIFY, "MODIFY" },
4183c602fabSXin LI { 0, NULL }
4193c602fabSXin LI };
4203c602fabSXin LI
421ee67461eSJoseph Mingrone #define OFPET_HELLO_FAILED 0x0000U
422ee67461eSJoseph Mingrone #define OFPET_BAD_REQUEST 0x0001U
423ee67461eSJoseph Mingrone #define OFPET_BAD_ACTION 0x0002U
424ee67461eSJoseph Mingrone #define OFPET_FLOW_MOD_FAILED 0x0003U
425ee67461eSJoseph Mingrone #define OFPET_PORT_MOD_FAILED 0x0004U
426ee67461eSJoseph Mingrone #define OFPET_QUEUE_OP_FAILED 0x0005U
4273c602fabSXin LI static const struct tok ofpet_str[] = {
4283c602fabSXin LI { OFPET_HELLO_FAILED, "HELLO_FAILED" },
4293c602fabSXin LI { OFPET_BAD_REQUEST, "BAD_REQUEST" },
4303c602fabSXin LI { OFPET_BAD_ACTION, "BAD_ACTION" },
4313c602fabSXin LI { OFPET_FLOW_MOD_FAILED, "FLOW_MOD_FAILED" },
4323c602fabSXin LI { OFPET_PORT_MOD_FAILED, "PORT_MOD_FAILED" },
4333c602fabSXin LI { OFPET_QUEUE_OP_FAILED, "QUEUE_OP_FAILED" },
4343c602fabSXin LI { 0, NULL }
4353c602fabSXin LI };
4363c602fabSXin LI
437ee67461eSJoseph Mingrone #define OFPHFC_INCOMPATIBLE 0x0000U
438ee67461eSJoseph Mingrone #define OFPHFC_EPERM 0x0001U
4393c602fabSXin LI static const struct tok ofphfc_str[] = {
4403c602fabSXin LI { OFPHFC_INCOMPATIBLE, "INCOMPATIBLE" },
4413c602fabSXin LI { OFPHFC_EPERM, "EPERM" },
4423c602fabSXin LI { 0, NULL }
4433c602fabSXin LI };
4443c602fabSXin LI
445ee67461eSJoseph Mingrone #define OFPBRC_BAD_VERSION 0x0000U
446ee67461eSJoseph Mingrone #define OFPBRC_BAD_TYPE 0x0001U
447ee67461eSJoseph Mingrone #define OFPBRC_BAD_STAT 0x0002U
448ee67461eSJoseph Mingrone #define OFPBRC_BAD_VENDOR 0x0003U
449ee67461eSJoseph Mingrone #define OFPBRC_BAD_SUBTYPE 0x0004U
450ee67461eSJoseph Mingrone #define OFPBRC_EPERM 0x0005U
451ee67461eSJoseph Mingrone #define OFPBRC_BAD_LEN 0x0006U
452ee67461eSJoseph Mingrone #define OFPBRC_BUFFER_EMPTY 0x0007U
453ee67461eSJoseph Mingrone #define OFPBRC_BUFFER_UNKNOWN 0x0008U
4543c602fabSXin LI static const struct tok ofpbrc_str[] = {
4553c602fabSXin LI { OFPBRC_BAD_VERSION, "BAD_VERSION" },
4563c602fabSXin LI { OFPBRC_BAD_TYPE, "BAD_TYPE" },
4573c602fabSXin LI { OFPBRC_BAD_STAT, "BAD_STAT" },
4583c602fabSXin LI { OFPBRC_BAD_VENDOR, "BAD_VENDOR" },
4593c602fabSXin LI { OFPBRC_BAD_SUBTYPE, "BAD_SUBTYPE" },
4603c602fabSXin LI { OFPBRC_EPERM, "EPERM" },
4613c602fabSXin LI { OFPBRC_BAD_LEN, "BAD_LEN" },
4623c602fabSXin LI { OFPBRC_BUFFER_EMPTY, "BUFFER_EMPTY" },
4633c602fabSXin LI { OFPBRC_BUFFER_UNKNOWN, "BUFFER_UNKNOWN" },
4643c602fabSXin LI { 0, NULL }
4653c602fabSXin LI };
4663c602fabSXin LI
467ee67461eSJoseph Mingrone #define OFPBAC_BAD_TYPE 0x0000U
468ee67461eSJoseph Mingrone #define OFPBAC_BAD_LEN 0x0001U
469ee67461eSJoseph Mingrone #define OFPBAC_BAD_VENDOR 0x0002U
470ee67461eSJoseph Mingrone #define OFPBAC_BAD_VENDOR_TYPE 0x0003U
471ee67461eSJoseph Mingrone #define OFPBAC_BAD_OUT_PORT 0x0004U
472ee67461eSJoseph Mingrone #define OFPBAC_BAD_ARGUMENT 0x0005U
473ee67461eSJoseph Mingrone #define OFPBAC_EPERM 0x0006U
474ee67461eSJoseph Mingrone #define OFPBAC_TOO_MANY 0x0007U
475ee67461eSJoseph Mingrone #define OFPBAC_BAD_QUEUE 0x0008U
4763c602fabSXin LI static const struct tok ofpbac_str[] = {
4773c602fabSXin LI { OFPBAC_BAD_TYPE, "BAD_TYPE" },
4783c602fabSXin LI { OFPBAC_BAD_LEN, "BAD_LEN" },
4793c602fabSXin LI { OFPBAC_BAD_VENDOR, "BAD_VENDOR" },
4803c602fabSXin LI { OFPBAC_BAD_VENDOR_TYPE, "BAD_VENDOR_TYPE" },
4813c602fabSXin LI { OFPBAC_BAD_OUT_PORT, "BAD_OUT_PORT" },
4823c602fabSXin LI { OFPBAC_BAD_ARGUMENT, "BAD_ARGUMENT" },
4833c602fabSXin LI { OFPBAC_EPERM, "EPERM" },
4843c602fabSXin LI { OFPBAC_TOO_MANY, "TOO_MANY" },
4853c602fabSXin LI { OFPBAC_BAD_QUEUE, "BAD_QUEUE" },
4863c602fabSXin LI { 0, NULL }
4873c602fabSXin LI };
4883c602fabSXin LI
489ee67461eSJoseph Mingrone #define OFPFMFC_ALL_TABLES_FULL 0x0000U
490ee67461eSJoseph Mingrone #define OFPFMFC_OVERLAP 0x0001U
491ee67461eSJoseph Mingrone #define OFPFMFC_EPERM 0x0002U
492ee67461eSJoseph Mingrone #define OFPFMFC_BAD_EMERG_TIMEOUT 0x0003U
493ee67461eSJoseph Mingrone #define OFPFMFC_BAD_COMMAND 0x0004U
494ee67461eSJoseph Mingrone #define OFPFMFC_UNSUPPORTED 0x0005U
4953c602fabSXin LI static const struct tok ofpfmfc_str[] = {
4963c602fabSXin LI { OFPFMFC_ALL_TABLES_FULL, "ALL_TABLES_FULL" },
4973c602fabSXin LI { OFPFMFC_OVERLAP, "OVERLAP" },
4983c602fabSXin LI { OFPFMFC_EPERM, "EPERM" },
4993c602fabSXin LI { OFPFMFC_BAD_EMERG_TIMEOUT, "BAD_EMERG_TIMEOUT" },
5003c602fabSXin LI { OFPFMFC_BAD_COMMAND, "BAD_COMMAND" },
5013c602fabSXin LI { OFPFMFC_UNSUPPORTED, "UNSUPPORTED" },
5023c602fabSXin LI { 0, NULL }
5033c602fabSXin LI };
5043c602fabSXin LI
505ee67461eSJoseph Mingrone #define OFPPMFC_BAD_PORT 0x0000U
506ee67461eSJoseph Mingrone #define OFPPMFC_BAD_HW_ADDR 0x0001U
5073c602fabSXin LI static const struct tok ofppmfc_str[] = {
5083c602fabSXin LI { OFPPMFC_BAD_PORT, "BAD_PORT" },
5093c602fabSXin LI { OFPPMFC_BAD_HW_ADDR, "BAD_HW_ADDR" },
5103c602fabSXin LI { 0, NULL }
5113c602fabSXin LI };
5123c602fabSXin LI
513ee67461eSJoseph Mingrone #define OFPQOFC_BAD_PORT 0x0000U
514ee67461eSJoseph Mingrone #define OFPQOFC_BAD_QUEUE 0x0001U
515ee67461eSJoseph Mingrone #define OFPQOFC_EPERM 0x0002U
5163c602fabSXin LI static const struct tok ofpqofc_str[] = {
5173c602fabSXin LI { OFPQOFC_BAD_PORT, "BAD_PORT" },
5183c602fabSXin LI { OFPQOFC_BAD_QUEUE, "BAD_QUEUE" },
5193c602fabSXin LI { OFPQOFC_EPERM, "EPERM" },
5203c602fabSXin LI { 0, NULL }
5213c602fabSXin LI };
5223c602fabSXin LI
523ee67461eSJoseph Mingrone static const struct uint_tokary of10_ofpet2tokary[] = {
524ee67461eSJoseph Mingrone { OFPET_HELLO_FAILED, ofphfc_str },
525ee67461eSJoseph Mingrone { OFPET_BAD_REQUEST, ofpbrc_str },
526ee67461eSJoseph Mingrone { OFPET_BAD_ACTION, ofpbac_str },
527ee67461eSJoseph Mingrone { OFPET_FLOW_MOD_FAILED, ofpfmfc_str },
528ee67461eSJoseph Mingrone { OFPET_PORT_MOD_FAILED, ofppmfc_str },
529ee67461eSJoseph Mingrone { OFPET_QUEUE_OP_FAILED, ofpqofc_str },
530ee67461eSJoseph Mingrone /* uint2tokary() does not use array termination. */
5313c602fabSXin LI };
5323c602fabSXin LI
533ee67461eSJoseph Mingrone /* lengths (fixed or minimal) of particular message types, where not 0 */
534ee67461eSJoseph Mingrone #define OF_SWITCH_CONFIG_FIXLEN (12U - OF_HEADER_FIXLEN)
535ee67461eSJoseph Mingrone #define OF_FEATURES_REPLY_MINLEN (32U - OF_HEADER_FIXLEN)
536ee67461eSJoseph Mingrone #define OF_PORT_STATUS_FIXLEN (64U - OF_HEADER_FIXLEN)
537ee67461eSJoseph Mingrone #define OF_PORT_MOD_FIXLEN (32U - OF_HEADER_FIXLEN)
538ee67461eSJoseph Mingrone #define OF_PACKET_IN_MINLEN (20U - OF_HEADER_FIXLEN) /* with 2 mock octets */
539ee67461eSJoseph Mingrone #define OF_PACKET_OUT_MINLEN (16U - OF_HEADER_FIXLEN)
540ee67461eSJoseph Mingrone #define OF_FLOW_MOD_MINLEN (72U - OF_HEADER_FIXLEN)
541ee67461eSJoseph Mingrone #define OF_FLOW_REMOVED_FIXLEN (88U - OF_HEADER_FIXLEN)
542ee67461eSJoseph Mingrone #define OF_ERROR_MSG_MINLEN (12U - OF_HEADER_FIXLEN)
543ee67461eSJoseph Mingrone #define OF_STATS_REQUEST_MINLEN (12U - OF_HEADER_FIXLEN)
544ee67461eSJoseph Mingrone #define OF_STATS_REPLY_MINLEN (12U - OF_HEADER_FIXLEN)
545ee67461eSJoseph Mingrone #define OF_VENDOR_MINLEN (12U - OF_HEADER_FIXLEN)
546ee67461eSJoseph Mingrone #define OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN (12U - OF_HEADER_FIXLEN)
547ee67461eSJoseph Mingrone #define OF_QUEUE_GET_CONFIG_REPLY_MINLEN (16U - OF_HEADER_FIXLEN)
548ee67461eSJoseph Mingrone
5493c602fabSXin LI /* lengths (fixed or minimal) of particular protocol structures */
550ee67461eSJoseph Mingrone #define OF_PHY_PORT_FIXLEN 48
551ee67461eSJoseph Mingrone #define OF_ACTION_MINLEN 8
552ee67461eSJoseph Mingrone #define OF_MATCH_FIXLEN 40
553ee67461eSJoseph Mingrone #define OF_DESC_STATS_REPLY_FIXLEN 1056
554ee67461eSJoseph Mingrone #define OF_FLOW_STATS_REQUEST_FIXLEN 44
555ee67461eSJoseph Mingrone #define OF_FLOW_STATS_REPLY_MINLEN 88
556ee67461eSJoseph Mingrone #define OF_AGGREGATE_STATS_REPLY_FIXLEN 24
557ee67461eSJoseph Mingrone #define OF_TABLE_STATS_REPLY_FIXLEN 64
558ee67461eSJoseph Mingrone #define OF_PORT_STATS_REQUEST_FIXLEN 8
559ee67461eSJoseph Mingrone #define OF_PORT_STATS_REPLY_FIXLEN 104
560ee67461eSJoseph Mingrone #define OF_QUEUE_PROP_MINLEN 8
561ee67461eSJoseph Mingrone #define OF_QUEUE_PROP_MIN_RATE_FIXLEN 16
562ee67461eSJoseph Mingrone #define OF_PACKET_QUEUE_MINLEN 8
563ee67461eSJoseph Mingrone #define OF_QUEUE_STATS_REQUEST_FIXLEN 8
564ee67461eSJoseph Mingrone #define OF_QUEUE_STATS_REPLY_FIXLEN 32
5653c602fabSXin LI
5663c602fabSXin LI /* miscellaneous constants from [OF10] */
5673c602fabSXin LI #define OFP_MAX_TABLE_NAME_LEN 32
5683c602fabSXin LI #define OFP_MAX_PORT_NAME_LEN 16
5693c602fabSXin LI #define DESC_STR_LEN 256
5703c602fabSXin LI #define SERIAL_NUM_LEN 32
571ee67461eSJoseph Mingrone #define OFP_VLAN_NONE 0xffffU
5723c602fabSXin LI
5738bdc5a62SPatrick Kelsey /* vendor extensions */
5748bdc5a62SPatrick Kelsey #define BSN_SET_IP_MASK 0
5758bdc5a62SPatrick Kelsey #define BSN_GET_IP_MASK_REQUEST 1
5768bdc5a62SPatrick Kelsey #define BSN_GET_IP_MASK_REPLY 2
5778bdc5a62SPatrick Kelsey #define BSN_SET_MIRRORING 3
5788bdc5a62SPatrick Kelsey #define BSN_GET_MIRRORING_REQUEST 4
5798bdc5a62SPatrick Kelsey #define BSN_GET_MIRRORING_REPLY 5
5808bdc5a62SPatrick Kelsey #define BSN_SHELL_COMMAND 6
5818bdc5a62SPatrick Kelsey #define BSN_SHELL_OUTPUT 7
5828bdc5a62SPatrick Kelsey #define BSN_SHELL_STATUS 8
5838bdc5a62SPatrick Kelsey #define BSN_GET_INTERFACES_REQUEST 9
5848bdc5a62SPatrick Kelsey #define BSN_GET_INTERFACES_REPLY 10
5858bdc5a62SPatrick Kelsey #define BSN_SET_PKTIN_SUPPRESSION_REQUEST 11
5868bdc5a62SPatrick Kelsey #define BSN_SET_L2_TABLE_REQUEST 12
5878bdc5a62SPatrick Kelsey #define BSN_GET_L2_TABLE_REQUEST 13
5888bdc5a62SPatrick Kelsey #define BSN_GET_L2_TABLE_REPLY 14
5898bdc5a62SPatrick Kelsey #define BSN_VIRTUAL_PORT_CREATE_REQUEST 15
5908bdc5a62SPatrick Kelsey #define BSN_VIRTUAL_PORT_CREATE_REPLY 16
5918bdc5a62SPatrick Kelsey #define BSN_VIRTUAL_PORT_REMOVE_REQUEST 17
5928bdc5a62SPatrick Kelsey #define BSN_BW_ENABLE_SET_REQUEST 18
5938bdc5a62SPatrick Kelsey #define BSN_BW_ENABLE_GET_REQUEST 19
5948bdc5a62SPatrick Kelsey #define BSN_BW_ENABLE_GET_REPLY 20
5958bdc5a62SPatrick Kelsey #define BSN_BW_CLEAR_DATA_REQUEST 21
5968bdc5a62SPatrick Kelsey #define BSN_BW_CLEAR_DATA_REPLY 22
5978bdc5a62SPatrick Kelsey #define BSN_BW_ENABLE_SET_REPLY 23
5988bdc5a62SPatrick Kelsey #define BSN_SET_L2_TABLE_REPLY 24
5998bdc5a62SPatrick Kelsey #define BSN_SET_PKTIN_SUPPRESSION_REPLY 25
6008bdc5a62SPatrick Kelsey #define BSN_VIRTUAL_PORT_REMOVE_REPLY 26
6018bdc5a62SPatrick Kelsey #define BSN_HYBRID_GET_REQUEST 27
6028bdc5a62SPatrick Kelsey #define BSN_HYBRID_GET_REPLY 28
6038bdc5a62SPatrick Kelsey /* 29 */
6048bdc5a62SPatrick Kelsey /* 30 */
6058bdc5a62SPatrick Kelsey #define BSN_PDU_TX_REQUEST 31
6068bdc5a62SPatrick Kelsey #define BSN_PDU_TX_REPLY 32
6078bdc5a62SPatrick Kelsey #define BSN_PDU_RX_REQUEST 33
6088bdc5a62SPatrick Kelsey #define BSN_PDU_RX_REPLY 34
6098bdc5a62SPatrick Kelsey #define BSN_PDU_RX_TIMEOUT 35
6108bdc5a62SPatrick Kelsey
6118bdc5a62SPatrick Kelsey static const struct tok bsn_subtype_str[] = {
6128bdc5a62SPatrick Kelsey { BSN_SET_IP_MASK, "SET_IP_MASK" },
6138bdc5a62SPatrick Kelsey { BSN_GET_IP_MASK_REQUEST, "GET_IP_MASK_REQUEST" },
6148bdc5a62SPatrick Kelsey { BSN_GET_IP_MASK_REPLY, "GET_IP_MASK_REPLY" },
6158bdc5a62SPatrick Kelsey { BSN_SET_MIRRORING, "SET_MIRRORING" },
6168bdc5a62SPatrick Kelsey { BSN_GET_MIRRORING_REQUEST, "GET_MIRRORING_REQUEST" },
6178bdc5a62SPatrick Kelsey { BSN_GET_MIRRORING_REPLY, "GET_MIRRORING_REPLY" },
6188bdc5a62SPatrick Kelsey { BSN_SHELL_COMMAND, "SHELL_COMMAND" },
6198bdc5a62SPatrick Kelsey { BSN_SHELL_OUTPUT, "SHELL_OUTPUT" },
6208bdc5a62SPatrick Kelsey { BSN_SHELL_STATUS, "SHELL_STATUS" },
6218bdc5a62SPatrick Kelsey { BSN_GET_INTERFACES_REQUEST, "GET_INTERFACES_REQUEST" },
6228bdc5a62SPatrick Kelsey { BSN_GET_INTERFACES_REPLY, "GET_INTERFACES_REPLY" },
6238bdc5a62SPatrick Kelsey { BSN_SET_PKTIN_SUPPRESSION_REQUEST, "SET_PKTIN_SUPPRESSION_REQUEST" },
6248bdc5a62SPatrick Kelsey { BSN_SET_L2_TABLE_REQUEST, "SET_L2_TABLE_REQUEST" },
6258bdc5a62SPatrick Kelsey { BSN_GET_L2_TABLE_REQUEST, "GET_L2_TABLE_REQUEST" },
6268bdc5a62SPatrick Kelsey { BSN_GET_L2_TABLE_REPLY, "GET_L2_TABLE_REPLY" },
6278bdc5a62SPatrick Kelsey { BSN_VIRTUAL_PORT_CREATE_REQUEST, "VIRTUAL_PORT_CREATE_REQUEST" },
6288bdc5a62SPatrick Kelsey { BSN_VIRTUAL_PORT_CREATE_REPLY, "VIRTUAL_PORT_CREATE_REPLY" },
6298bdc5a62SPatrick Kelsey { BSN_VIRTUAL_PORT_REMOVE_REQUEST, "VIRTUAL_PORT_REMOVE_REQUEST" },
6308bdc5a62SPatrick Kelsey { BSN_BW_ENABLE_SET_REQUEST, "BW_ENABLE_SET_REQUEST" },
6318bdc5a62SPatrick Kelsey { BSN_BW_ENABLE_GET_REQUEST, "BW_ENABLE_GET_REQUEST" },
6328bdc5a62SPatrick Kelsey { BSN_BW_ENABLE_GET_REPLY, "BW_ENABLE_GET_REPLY" },
6338bdc5a62SPatrick Kelsey { BSN_BW_CLEAR_DATA_REQUEST, "BW_CLEAR_DATA_REQUEST" },
6348bdc5a62SPatrick Kelsey { BSN_BW_CLEAR_DATA_REPLY, "BW_CLEAR_DATA_REPLY" },
6358bdc5a62SPatrick Kelsey { BSN_BW_ENABLE_SET_REPLY, "BW_ENABLE_SET_REPLY" },
6368bdc5a62SPatrick Kelsey { BSN_SET_L2_TABLE_REPLY, "SET_L2_TABLE_REPLY" },
6378bdc5a62SPatrick Kelsey { BSN_SET_PKTIN_SUPPRESSION_REPLY, "SET_PKTIN_SUPPRESSION_REPLY" },
6388bdc5a62SPatrick Kelsey { BSN_VIRTUAL_PORT_REMOVE_REPLY, "VIRTUAL_PORT_REMOVE_REPLY" },
6398bdc5a62SPatrick Kelsey { BSN_HYBRID_GET_REQUEST, "HYBRID_GET_REQUEST" },
6408bdc5a62SPatrick Kelsey { BSN_HYBRID_GET_REPLY, "HYBRID_GET_REPLY" },
6418bdc5a62SPatrick Kelsey { BSN_PDU_TX_REQUEST, "PDU_TX_REQUEST" },
6428bdc5a62SPatrick Kelsey { BSN_PDU_TX_REPLY, "PDU_TX_REPLY" },
6438bdc5a62SPatrick Kelsey { BSN_PDU_RX_REQUEST, "PDU_RX_REQUEST" },
6448bdc5a62SPatrick Kelsey { BSN_PDU_RX_REPLY, "PDU_RX_REPLY" },
6458bdc5a62SPatrick Kelsey { BSN_PDU_RX_TIMEOUT, "PDU_RX_TIMEOUT" },
6468bdc5a62SPatrick Kelsey { 0, NULL }
6478bdc5a62SPatrick Kelsey };
6488bdc5a62SPatrick Kelsey
6498bdc5a62SPatrick Kelsey #define BSN_ACTION_MIRROR 1
6508bdc5a62SPatrick Kelsey #define BSN_ACTION_SET_TUNNEL_DST 2
6518bdc5a62SPatrick Kelsey /* 3 */
6528bdc5a62SPatrick Kelsey #define BSN_ACTION_CHECKSUM 4
6538bdc5a62SPatrick Kelsey
6548bdc5a62SPatrick Kelsey static const struct tok bsn_action_subtype_str[] = {
6558bdc5a62SPatrick Kelsey { BSN_ACTION_MIRROR, "MIRROR" },
6568bdc5a62SPatrick Kelsey { BSN_ACTION_SET_TUNNEL_DST, "SET_TUNNEL_DST" },
6578bdc5a62SPatrick Kelsey { BSN_ACTION_CHECKSUM, "CHECKSUM" },
6588bdc5a62SPatrick Kelsey { 0, NULL }
6598bdc5a62SPatrick Kelsey };
6608bdc5a62SPatrick Kelsey
6618bdc5a62SPatrick Kelsey static const struct tok bsn_mirror_copy_stage_str[] = {
6628bdc5a62SPatrick Kelsey { 0, "INGRESS" },
6638bdc5a62SPatrick Kelsey { 1, "EGRESS" },
6648bdc5a62SPatrick Kelsey { 0, NULL },
6658bdc5a62SPatrick Kelsey };
6668bdc5a62SPatrick Kelsey
6678bdc5a62SPatrick Kelsey static const struct tok bsn_onoff_str[] = {
6688bdc5a62SPatrick Kelsey { 0, "OFF" },
6698bdc5a62SPatrick Kelsey { 1, "ON" },
6708bdc5a62SPatrick Kelsey { 0, NULL },
6718bdc5a62SPatrick Kelsey };
6728bdc5a62SPatrick Kelsey
6733c602fabSXin LI static const char *
vlan_str(const uint16_t vid)6748bdc5a62SPatrick Kelsey vlan_str(const uint16_t vid)
6758bdc5a62SPatrick Kelsey {
6763c602fabSXin LI static char buf[sizeof("65535 (bogus)")];
6773c602fabSXin LI
6783c602fabSXin LI if (vid == OFP_VLAN_NONE)
6793c602fabSXin LI return "NONE";
680ee67461eSJoseph Mingrone snprintf(buf, sizeof(buf), "%u%s", vid,
681ee67461eSJoseph Mingrone (vid > 0 && vid < 0x0fff) ? "" : " (bogus)");
6823c602fabSXin LI return buf;
6833c602fabSXin LI }
6843c602fabSXin LI
6853c602fabSXin LI static const char *
pcp_str(const uint8_t pcp)6868bdc5a62SPatrick Kelsey pcp_str(const uint8_t pcp)
6878bdc5a62SPatrick Kelsey {
6883c602fabSXin LI static char buf[sizeof("255 (bogus)")];
689ee67461eSJoseph Mingrone snprintf(buf, sizeof(buf), "%u%s", pcp,
690ee67461eSJoseph Mingrone pcp <= 7 ? "" : " (bogus)");
6913c602fabSXin LI return buf;
6923c602fabSXin LI }
6933c602fabSXin LI
6943c602fabSXin LI static void
of10_bsn_message_print(netdissect_options * ndo,const u_char * cp,u_int len)6958bdc5a62SPatrick Kelsey of10_bsn_message_print(netdissect_options *ndo,
696ee67461eSJoseph Mingrone const u_char *cp, u_int len)
6978bdc5a62SPatrick Kelsey {
6988bdc5a62SPatrick Kelsey uint32_t subtype;
6998bdc5a62SPatrick Kelsey
700*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t");
701*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, <, 4);
7028bdc5a62SPatrick Kelsey /* subtype */
703ee67461eSJoseph Mingrone subtype = GET_BE_U_4(cp);
704ee67461eSJoseph Mingrone OF_FWD(4);
705*0a7e5f1fSJoseph Mingrone ND_PRINT(" subtype %s", tok2str(bsn_subtype_str, "unknown (0x%08x)", subtype));
7068bdc5a62SPatrick Kelsey switch (subtype) {
7078bdc5a62SPatrick Kelsey case BSN_GET_IP_MASK_REQUEST:
7088bdc5a62SPatrick Kelsey /*
7098bdc5a62SPatrick Kelsey * 0 1 2 3
7108bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
7118bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7128bdc5a62SPatrick Kelsey * | subtype |
7138bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7148bdc5a62SPatrick Kelsey * | index | pad |
7158bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7168bdc5a62SPatrick Kelsey * | pad |
7178bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7188bdc5a62SPatrick Kelsey *
7198bdc5a62SPatrick Kelsey */
720*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, 8);
7218bdc5a62SPatrick Kelsey /* index */
722ee67461eSJoseph Mingrone ND_PRINT(", index %u", GET_U_1(cp));
723ee67461eSJoseph Mingrone OF_FWD(1);
7248bdc5a62SPatrick Kelsey /* pad */
725ee67461eSJoseph Mingrone /* Always the last field, check bounds. */
726ee67461eSJoseph Mingrone ND_TCHECK_7(cp);
7278bdc5a62SPatrick Kelsey break;
7288bdc5a62SPatrick Kelsey case BSN_SET_IP_MASK:
7298bdc5a62SPatrick Kelsey case BSN_GET_IP_MASK_REPLY:
7308bdc5a62SPatrick Kelsey /*
7318bdc5a62SPatrick Kelsey * 0 1 2 3
7328bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
7338bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7348bdc5a62SPatrick Kelsey * | subtype |
7358bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7368bdc5a62SPatrick Kelsey * | index | pad |
7378bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7388bdc5a62SPatrick Kelsey * | mask |
7398bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7408bdc5a62SPatrick Kelsey *
7418bdc5a62SPatrick Kelsey */
742*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, 8);
7438bdc5a62SPatrick Kelsey /* index */
744ee67461eSJoseph Mingrone ND_PRINT(", index %u", GET_U_1(cp));
745ee67461eSJoseph Mingrone OF_FWD(1);
7468bdc5a62SPatrick Kelsey /* pad */
747ee67461eSJoseph Mingrone OF_FWD(3);
7488bdc5a62SPatrick Kelsey /* mask */
749ee67461eSJoseph Mingrone ND_PRINT(", mask %s", GET_IPADDR_STRING(cp));
7508bdc5a62SPatrick Kelsey break;
7518bdc5a62SPatrick Kelsey case BSN_SET_MIRRORING:
7528bdc5a62SPatrick Kelsey case BSN_GET_MIRRORING_REQUEST:
7538bdc5a62SPatrick Kelsey case BSN_GET_MIRRORING_REPLY:
7548bdc5a62SPatrick Kelsey /*
7558bdc5a62SPatrick Kelsey * 0 1 2 3
7568bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
7578bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7588bdc5a62SPatrick Kelsey * | subtype |
7598bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7608bdc5a62SPatrick Kelsey * | report m. p. | pad |
7618bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7628bdc5a62SPatrick Kelsey *
7638bdc5a62SPatrick Kelsey */
764*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, 4);
7658bdc5a62SPatrick Kelsey /* report_mirror_ports */
766ee67461eSJoseph Mingrone ND_PRINT(", report_mirror_ports %s",
767ee67461eSJoseph Mingrone tok2str(bsn_onoff_str, "bogus (%u)", GET_U_1(cp)));
768ee67461eSJoseph Mingrone OF_FWD(1);
7698bdc5a62SPatrick Kelsey /* pad */
770ee67461eSJoseph Mingrone /* Always the last field, check bounds. */
771ee67461eSJoseph Mingrone ND_TCHECK_3(cp);
7728bdc5a62SPatrick Kelsey break;
7738bdc5a62SPatrick Kelsey case BSN_GET_INTERFACES_REQUEST:
7748bdc5a62SPatrick Kelsey case BSN_GET_L2_TABLE_REQUEST:
7758bdc5a62SPatrick Kelsey case BSN_BW_ENABLE_GET_REQUEST:
7768bdc5a62SPatrick Kelsey case BSN_BW_CLEAR_DATA_REQUEST:
7778bdc5a62SPatrick Kelsey case BSN_HYBRID_GET_REQUEST:
7788bdc5a62SPatrick Kelsey /*
7798bdc5a62SPatrick Kelsey * 0 1 2 3
7808bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
7818bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7828bdc5a62SPatrick Kelsey * | subtype |
7838bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7848bdc5a62SPatrick Kelsey *
7858bdc5a62SPatrick Kelsey */
786*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, 0);
7878bdc5a62SPatrick Kelsey break;
7888bdc5a62SPatrick Kelsey case BSN_VIRTUAL_PORT_REMOVE_REQUEST:
7898bdc5a62SPatrick Kelsey /*
7908bdc5a62SPatrick Kelsey * 0 1 2 3
7918bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
7928bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7938bdc5a62SPatrick Kelsey * | subtype |
7948bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7958bdc5a62SPatrick Kelsey * | vport_no |
7968bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
7978bdc5a62SPatrick Kelsey *
7988bdc5a62SPatrick Kelsey */
799*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, 4);
8008bdc5a62SPatrick Kelsey /* vport_no */
801ee67461eSJoseph Mingrone ND_PRINT(", vport_no %u", GET_BE_U_4(cp));
8028bdc5a62SPatrick Kelsey break;
8038bdc5a62SPatrick Kelsey case BSN_SHELL_COMMAND:
8048bdc5a62SPatrick Kelsey /*
8058bdc5a62SPatrick Kelsey * 0 1 2 3
8068bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
8078bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8088bdc5a62SPatrick Kelsey * | subtype |
8098bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8108bdc5a62SPatrick Kelsey * | service |
8118bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8128bdc5a62SPatrick Kelsey * | data ...
8138bdc5a62SPatrick Kelsey * +---------------+---------------+--------
8148bdc5a62SPatrick Kelsey *
8158bdc5a62SPatrick Kelsey */
816*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, <, 4);
8178bdc5a62SPatrick Kelsey /* service */
818ee67461eSJoseph Mingrone ND_PRINT(", service %u", GET_BE_U_4(cp));
819ee67461eSJoseph Mingrone OF_FWD(4);
8208bdc5a62SPatrick Kelsey /* data */
821ee67461eSJoseph Mingrone ND_PRINT(", data '");
822ee67461eSJoseph Mingrone (void)nd_printn(ndo, cp, len, NULL);
823ee67461eSJoseph Mingrone ND_PRINT("'");
8248bdc5a62SPatrick Kelsey break;
8258bdc5a62SPatrick Kelsey case BSN_SHELL_OUTPUT:
8268bdc5a62SPatrick Kelsey /*
8278bdc5a62SPatrick Kelsey * 0 1 2 3
8288bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
8298bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8308bdc5a62SPatrick Kelsey * | subtype |
8318bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8328bdc5a62SPatrick Kelsey * | data ...
8338bdc5a62SPatrick Kelsey * +---------------+---------------+--------
8348bdc5a62SPatrick Kelsey *
8358bdc5a62SPatrick Kelsey */
8368bdc5a62SPatrick Kelsey /* already checked that len >= 4 */
8378bdc5a62SPatrick Kelsey /* data */
838ee67461eSJoseph Mingrone ND_PRINT(", data '");
839ee67461eSJoseph Mingrone (void)nd_printn(ndo, cp, len, NULL);
840ee67461eSJoseph Mingrone ND_PRINT("'");
8418bdc5a62SPatrick Kelsey break;
8428bdc5a62SPatrick Kelsey case BSN_SHELL_STATUS:
8438bdc5a62SPatrick Kelsey /*
8448bdc5a62SPatrick Kelsey * 0 1 2 3
8458bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
8468bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8478bdc5a62SPatrick Kelsey * | subtype |
8488bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8498bdc5a62SPatrick Kelsey * | status |
8508bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8518bdc5a62SPatrick Kelsey *
8528bdc5a62SPatrick Kelsey */
853*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, 4);
8548bdc5a62SPatrick Kelsey /* status */
855ee67461eSJoseph Mingrone ND_PRINT(", status 0x%08x", GET_BE_U_4(cp));
8568bdc5a62SPatrick Kelsey break;
8578bdc5a62SPatrick Kelsey default:
858ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
8598bdc5a62SPatrick Kelsey }
860ee67461eSJoseph Mingrone return;
8618bdc5a62SPatrick Kelsey
8623340d773SGleb Smirnoff invalid: /* skip the undersized data */
863ee67461eSJoseph Mingrone nd_print_invalid(ndo);
864ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
8658bdc5a62SPatrick Kelsey }
8668bdc5a62SPatrick Kelsey
867ee67461eSJoseph Mingrone static void
of10_bsn_actions_print(netdissect_options * ndo,const u_char * cp,u_int len)8688bdc5a62SPatrick Kelsey of10_bsn_actions_print(netdissect_options *ndo,
869ee67461eSJoseph Mingrone const u_char *cp, u_int len)
8708bdc5a62SPatrick Kelsey {
8718bdc5a62SPatrick Kelsey uint32_t subtype, vlan_tag;
8728bdc5a62SPatrick Kelsey
873*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t ");
874*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, <, 4);
8758bdc5a62SPatrick Kelsey /* subtype */
876ee67461eSJoseph Mingrone subtype = GET_BE_U_4(cp);
877ee67461eSJoseph Mingrone OF_FWD(4);
878*0a7e5f1fSJoseph Mingrone ND_PRINT(" subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype));
8798bdc5a62SPatrick Kelsey switch (subtype) {
8808bdc5a62SPatrick Kelsey case BSN_ACTION_MIRROR:
8818bdc5a62SPatrick Kelsey /*
8828bdc5a62SPatrick Kelsey * 0 1 2 3
8838bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
8848bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8858bdc5a62SPatrick Kelsey * | subtype |
8868bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8878bdc5a62SPatrick Kelsey * | dest_port |
8888bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8898bdc5a62SPatrick Kelsey * | vlan_tag |
8908bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8918bdc5a62SPatrick Kelsey * | copy_stage | pad |
8928bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+
8938bdc5a62SPatrick Kelsey *
8948bdc5a62SPatrick Kelsey */
895*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, 12);
8968bdc5a62SPatrick Kelsey /* dest_port */
897ee67461eSJoseph Mingrone ND_PRINT(", dest_port %u", GET_BE_U_4(cp));
898ee67461eSJoseph Mingrone OF_FWD(4);
8998bdc5a62SPatrick Kelsey /* vlan_tag */
900ee67461eSJoseph Mingrone vlan_tag = GET_BE_U_4(cp);
901ee67461eSJoseph Mingrone OF_FWD(4);
9028bdc5a62SPatrick Kelsey switch (vlan_tag >> 16) {
9038bdc5a62SPatrick Kelsey case 0:
904ee67461eSJoseph Mingrone ND_PRINT(", vlan_tag none");
9058bdc5a62SPatrick Kelsey break;
9068bdc5a62SPatrick Kelsey case ETHERTYPE_8021Q:
907ee67461eSJoseph Mingrone ND_PRINT(", vlan_tag 802.1Q (%s)", ieee8021q_tci_string(vlan_tag & 0xffff));
9088bdc5a62SPatrick Kelsey break;
9098bdc5a62SPatrick Kelsey default:
910ee67461eSJoseph Mingrone ND_PRINT(", vlan_tag unknown (0x%04x)", vlan_tag >> 16);
9118bdc5a62SPatrick Kelsey }
9128bdc5a62SPatrick Kelsey /* copy_stage */
913ee67461eSJoseph Mingrone ND_PRINT(", copy_stage %s",
914ee67461eSJoseph Mingrone tok2str(bsn_mirror_copy_stage_str, "unknown (%u)", GET_U_1(cp)));
915ee67461eSJoseph Mingrone OF_FWD(1);
9168bdc5a62SPatrick Kelsey /* pad */
917ee67461eSJoseph Mingrone /* Always the last field, check bounds. */
918ee67461eSJoseph Mingrone ND_TCHECK_3(cp);
9198bdc5a62SPatrick Kelsey break;
9208bdc5a62SPatrick Kelsey default:
921ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
9228bdc5a62SPatrick Kelsey }
923ee67461eSJoseph Mingrone return;
9248bdc5a62SPatrick Kelsey
9253340d773SGleb Smirnoff invalid:
926ee67461eSJoseph Mingrone nd_print_invalid(ndo);
927ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
9288bdc5a62SPatrick Kelsey }
9298bdc5a62SPatrick Kelsey
930ee67461eSJoseph Mingrone static void
of10_vendor_action_print(netdissect_options * ndo,const u_char * cp,u_int len)9318bdc5a62SPatrick Kelsey of10_vendor_action_print(netdissect_options *ndo,
932ee67461eSJoseph Mingrone const u_char *cp, u_int len)
9338bdc5a62SPatrick Kelsey {
9348bdc5a62SPatrick Kelsey uint32_t vendor;
935ee67461eSJoseph Mingrone void (*decoder)(netdissect_options *, const u_char *, u_int);
9368bdc5a62SPatrick Kelsey
937*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, <, 4);
9383c602fabSXin LI /* vendor */
939ee67461eSJoseph Mingrone vendor = GET_BE_U_4(cp);
940ee67461eSJoseph Mingrone OF_FWD(4);
941ee67461eSJoseph Mingrone ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor));
9428bdc5a62SPatrick Kelsey /* data */
9438bdc5a62SPatrick Kelsey decoder =
9448bdc5a62SPatrick Kelsey vendor == OUI_BSN ? of10_bsn_actions_print :
945ee67461eSJoseph Mingrone of_data_print;
946ee67461eSJoseph Mingrone decoder(ndo, cp, len);
947ee67461eSJoseph Mingrone return;
9488bdc5a62SPatrick Kelsey
9493340d773SGleb Smirnoff invalid: /* skip the undersized data */
950ee67461eSJoseph Mingrone nd_print_invalid(ndo);
951ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
9528bdc5a62SPatrick Kelsey }
9538bdc5a62SPatrick Kelsey
954ee67461eSJoseph Mingrone /* [OF10] Section 5.5.4 */
955ee67461eSJoseph Mingrone static void
of10_vendor_message_print(netdissect_options * ndo,const u_char * cp,u_int len)9568bdc5a62SPatrick Kelsey of10_vendor_message_print(netdissect_options *ndo,
957ee67461eSJoseph Mingrone const u_char *cp, u_int len)
9588bdc5a62SPatrick Kelsey {
9598bdc5a62SPatrick Kelsey uint32_t vendor;
960ee67461eSJoseph Mingrone void (*decoder)(netdissect_options *, const u_char *, u_int);
9618bdc5a62SPatrick Kelsey
9628bdc5a62SPatrick Kelsey /* vendor */
963ee67461eSJoseph Mingrone vendor = GET_BE_U_4(cp);
964ee67461eSJoseph Mingrone OF_FWD(4);
965ee67461eSJoseph Mingrone ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor));
9668bdc5a62SPatrick Kelsey /* data */
9678bdc5a62SPatrick Kelsey decoder =
9688bdc5a62SPatrick Kelsey vendor == OUI_BSN ? of10_bsn_message_print :
969ee67461eSJoseph Mingrone of_data_print;
970ee67461eSJoseph Mingrone decoder(ndo, cp, len);
9718bdc5a62SPatrick Kelsey }
9728bdc5a62SPatrick Kelsey
9738bdc5a62SPatrick Kelsey /* Vendor ID is mandatory, data is optional. */
974ee67461eSJoseph Mingrone static void
of10_vendor_data_print(netdissect_options * ndo,const u_char * cp,u_int len)9758bdc5a62SPatrick Kelsey of10_vendor_data_print(netdissect_options *ndo,
976ee67461eSJoseph Mingrone const u_char *cp, u_int len)
9778bdc5a62SPatrick Kelsey {
9788bdc5a62SPatrick Kelsey uint32_t vendor;
9798bdc5a62SPatrick Kelsey
980*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, <, 4);
9818bdc5a62SPatrick Kelsey /* vendor */
982ee67461eSJoseph Mingrone vendor = GET_BE_U_4(cp);
983ee67461eSJoseph Mingrone OF_FWD(4);
984ee67461eSJoseph Mingrone ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor));
9853c602fabSXin LI /* data */
986ee67461eSJoseph Mingrone of_data_print(ndo, cp, len);
987ee67461eSJoseph Mingrone return;
9883c602fabSXin LI
9893340d773SGleb Smirnoff invalid: /* skip the undersized data */
990ee67461eSJoseph Mingrone nd_print_invalid(ndo);
991ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
9923c602fabSXin LI }
9933c602fabSXin LI
994ee67461eSJoseph Mingrone static void
of10_packet_data_print(netdissect_options * ndo,const u_char * cp,const u_int len)9953c602fabSXin LI of10_packet_data_print(netdissect_options *ndo,
996ee67461eSJoseph Mingrone const u_char *cp, const u_int len)
9978bdc5a62SPatrick Kelsey {
9983c602fabSXin LI if (len == 0)
999ee67461eSJoseph Mingrone return;
10003c602fabSXin LI /* data */
1001ee67461eSJoseph Mingrone ND_PRINT("\n\t data (%u octets)", len);
1002ee67461eSJoseph Mingrone if (ndo->ndo_vflag < 3) {
1003ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
1004ee67461eSJoseph Mingrone return;
1005ee67461eSJoseph Mingrone }
10063c602fabSXin LI ndo->ndo_vflag -= 3;
1007ee67461eSJoseph Mingrone ND_PRINT(", frame decoding below\n");
1008ee67461eSJoseph Mingrone /*
1009ee67461eSJoseph Mingrone * The encapsulated Ethernet frame is not necessarily the last
1010ee67461eSJoseph Mingrone * data of this packet (i.e. there may be more OpenFlow messages
1011ee67461eSJoseph Mingrone * after the current OFPT_PACKET_IN/OFPT_PACKET_OUT message, in
1012ee67461eSJoseph Mingrone * which case the current (outer) packet's snapshot end is not
1013ee67461eSJoseph Mingrone * what ether_print() needs to decode an Ethernet frame nested in
1014ee67461eSJoseph Mingrone * the middle of a TCP payload.
1015ee67461eSJoseph Mingrone */
1016ee67461eSJoseph Mingrone const u_char *snapend_save = ndo->ndo_snapend;
1017ee67461eSJoseph Mingrone ndo->ndo_snapend = ND_MIN(cp + len, ndo->ndo_snapend);
1018ee67461eSJoseph Mingrone ether_print(ndo, cp, len, ND_BYTES_AVAILABLE_AFTER(cp), NULL, NULL);
1019ee67461eSJoseph Mingrone ndo->ndo_snapend = snapend_save;
10203c602fabSXin LI ndo->ndo_vflag += 3;
10213c602fabSXin LI }
10223c602fabSXin LI
10233c602fabSXin LI /* [OF10] Section 5.2.1 */
1024ee67461eSJoseph Mingrone static void
of10_phy_port_print(netdissect_options * ndo,const u_char * cp)1025ee67461eSJoseph Mingrone of10_phy_port_print(netdissect_options *ndo,
1026ee67461eSJoseph Mingrone const u_char *cp)
10278bdc5a62SPatrick Kelsey {
1028ee67461eSJoseph Mingrone uint32_t state;
10293c602fabSXin LI
10303c602fabSXin LI /* port_no */
1031ee67461eSJoseph Mingrone ND_PRINT("\n\t port_no %s",
1032ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
10333c602fabSXin LI cp += 2;
10343c602fabSXin LI /* hw_addr */
1035ee67461eSJoseph Mingrone ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp));
1036ee67461eSJoseph Mingrone cp += MAC_ADDR_LEN;
10373c602fabSXin LI /* name */
1038ee67461eSJoseph Mingrone ND_PRINT(", name '");
1039ee67461eSJoseph Mingrone nd_printjnp(ndo, cp, OFP_MAX_PORT_NAME_LEN);
1040ee67461eSJoseph Mingrone ND_PRINT("'");
10413c602fabSXin LI cp += OFP_MAX_PORT_NAME_LEN;
10423c602fabSXin LI
10433c602fabSXin LI if (ndo->ndo_vflag < 2) {
1044ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, 24);
1045ee67461eSJoseph Mingrone return;
10463c602fabSXin LI }
10473c602fabSXin LI /* config */
1048ee67461eSJoseph Mingrone ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp));
1049ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U);
10503c602fabSXin LI cp += 4;
10513c602fabSXin LI /* state */
1052ee67461eSJoseph Mingrone state = GET_BE_U_4(cp);
1053ee67461eSJoseph Mingrone /*
1054ee67461eSJoseph Mingrone * Decode the code point and the single bit separately, but
1055ee67461eSJoseph Mingrone * format the result as a single sequence of comma-separated
1056ee67461eSJoseph Mingrone * strings (see the comments at the OFPPS_ props).
1057ee67461eSJoseph Mingrone */
1058ee67461eSJoseph Mingrone ND_PRINT("\n\t state 0x%08x (%s%s)%s", state,
1059ee67461eSJoseph Mingrone tok2str(ofpps_stp_str, "", state & OFPPS_STP_MASK),
1060ee67461eSJoseph Mingrone state & OFPPS_LINK_DOWN ? ", LINK_DOWN" : "",
1061ee67461eSJoseph Mingrone state & OFPPS_U ? " (bogus)" : "");
10623c602fabSXin LI cp += 4;
10633c602fabSXin LI /* curr */
1064ee67461eSJoseph Mingrone ND_PRINT("\n\t curr 0x%08x", GET_BE_U_4(cp));
1065ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
10663c602fabSXin LI cp += 4;
10673c602fabSXin LI /* advertised */
1068ee67461eSJoseph Mingrone ND_PRINT("\n\t advertised 0x%08x", GET_BE_U_4(cp));
1069ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
10703c602fabSXin LI cp += 4;
10713c602fabSXin LI /* supported */
1072ee67461eSJoseph Mingrone ND_PRINT("\n\t supported 0x%08x", GET_BE_U_4(cp));
1073ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
10743c602fabSXin LI cp += 4;
10753c602fabSXin LI /* peer */
1076ee67461eSJoseph Mingrone ND_PRINT("\n\t peer 0x%08x", GET_BE_U_4(cp));
1077ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
10783c602fabSXin LI }
10793c602fabSXin LI
10803c602fabSXin LI /* [OF10] Section 5.2.2 */
1081ee67461eSJoseph Mingrone static void
of10_queue_props_print(netdissect_options * ndo,const u_char * cp,u_int len)10823c602fabSXin LI of10_queue_props_print(netdissect_options *ndo,
1083ee67461eSJoseph Mingrone const u_char *cp, u_int len)
10848bdc5a62SPatrick Kelsey {
10853c602fabSXin LI while (len) {
1086ee67461eSJoseph Mingrone uint16_t property, plen;
10873c602fabSXin LI u_char plen_bogus = 0, skip = 0;
10883c602fabSXin LI
1089*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t ");
1090*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("remaining length", len, <, OF_QUEUE_PROP_MINLEN);
10913c602fabSXin LI /* property */
1092ee67461eSJoseph Mingrone property = GET_BE_U_2(cp);
1093ee67461eSJoseph Mingrone OF_FWD(2);
1094*0a7e5f1fSJoseph Mingrone ND_PRINT(" property %s", tok2str(ofpqt_str, "invalid (0x%04x)", property));
10953c602fabSXin LI /* len */
1096ee67461eSJoseph Mingrone plen = GET_BE_U_2(cp);
1097ee67461eSJoseph Mingrone OF_FWD(2);
1098ee67461eSJoseph Mingrone ND_PRINT(", len %u", plen);
1099*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("property length", plen, <, OF_QUEUE_PROP_MINLEN);
1100*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("property length", plen, >, len + 4);
11013c602fabSXin LI /* pad */
1102ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1103ee67461eSJoseph Mingrone OF_CHK_FWD(4);
11043c602fabSXin LI /* property-specific constraints and decoding */
11053c602fabSXin LI switch (property) {
11063c602fabSXin LI case OFPQT_NONE:
1107ee67461eSJoseph Mingrone plen_bogus = plen != OF_QUEUE_PROP_MINLEN;
11083c602fabSXin LI break;
11093c602fabSXin LI case OFPQT_MIN_RATE:
1110ee67461eSJoseph Mingrone plen_bogus = plen != OF_QUEUE_PROP_MIN_RATE_FIXLEN;
11113c602fabSXin LI break;
11123c602fabSXin LI default:
11133c602fabSXin LI skip = 1;
11143c602fabSXin LI }
11153c602fabSXin LI if (plen_bogus) {
1116ee67461eSJoseph Mingrone ND_PRINT(" (bogus)");
11173c602fabSXin LI skip = 1;
11183c602fabSXin LI }
11193c602fabSXin LI if (skip) {
1120ee67461eSJoseph Mingrone /*
1121ee67461eSJoseph Mingrone * plen >= OF_QUEUE_PROP_MINLEN
1122ee67461eSJoseph Mingrone * cp is OF_QUEUE_PROP_MINLEN bytes in
1123ee67461eSJoseph Mingrone */
1124ee67461eSJoseph Mingrone OF_CHK_FWD(plen - OF_QUEUE_PROP_MINLEN);
1125ee67461eSJoseph Mingrone continue;
11263c602fabSXin LI }
11273c602fabSXin LI if (property == OFPQT_MIN_RATE) { /* the only case of property decoding */
11283c602fabSXin LI /* rate */
1129ee67461eSJoseph Mingrone uint16_t rate = GET_BE_U_2(cp);
1130ee67461eSJoseph Mingrone OF_FWD(2);
11313c602fabSXin LI if (rate > 1000)
1132ee67461eSJoseph Mingrone ND_PRINT(", rate disabled");
11333c602fabSXin LI else
1134ee67461eSJoseph Mingrone ND_PRINT(", rate %u.%u%%", rate / 10, rate % 10);
11353c602fabSXin LI /* pad */
1136ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1137ee67461eSJoseph Mingrone OF_CHK_FWD(6);
11383c602fabSXin LI }
11393c602fabSXin LI } /* while */
1140ee67461eSJoseph Mingrone return;
11413c602fabSXin LI
11423340d773SGleb Smirnoff invalid: /* skip the rest of queue properties */
1143ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1144ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
11453c602fabSXin LI }
11463c602fabSXin LI
11473c602fabSXin LI /* ibid */
1148ee67461eSJoseph Mingrone static void
of10_queues_print(netdissect_options * ndo,const u_char * cp,u_int len)11493c602fabSXin LI of10_queues_print(netdissect_options *ndo,
1150ee67461eSJoseph Mingrone const u_char *cp, u_int len)
11518bdc5a62SPatrick Kelsey {
1152ee67461eSJoseph Mingrone while (len) {
11533c602fabSXin LI uint16_t desclen;
11543c602fabSXin LI
1155*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t ");
1156*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("remaining length", len, <, OF_PACKET_QUEUE_MINLEN);
11573c602fabSXin LI /* queue_id */
1158*0a7e5f1fSJoseph Mingrone ND_PRINT(" queue_id %u", GET_BE_U_4(cp));
1159ee67461eSJoseph Mingrone OF_FWD(4);
11603c602fabSXin LI /* len */
1161ee67461eSJoseph Mingrone desclen = GET_BE_U_2(cp);
1162ee67461eSJoseph Mingrone OF_FWD(2);
1163ee67461eSJoseph Mingrone ND_PRINT(", len %u", desclen);
1164*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("prop. desc. length", desclen, <, OF_PACKET_QUEUE_MINLEN);
1165*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("prop. desc. length", desclen, >, len + 6);
11663c602fabSXin LI /* pad */
1167ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1168ee67461eSJoseph Mingrone OF_CHK_FWD(2);
11693c602fabSXin LI /* properties */
1170ee67461eSJoseph Mingrone if (ndo->ndo_vflag >= 2)
1171ee67461eSJoseph Mingrone of10_queue_props_print(ndo, cp, desclen - OF_PACKET_QUEUE_MINLEN);
1172ee67461eSJoseph Mingrone else
1173ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, desclen - OF_PACKET_QUEUE_MINLEN);
1174ee67461eSJoseph Mingrone OF_FWD(desclen - OF_PACKET_QUEUE_MINLEN);
11753c602fabSXin LI } /* while */
1176ee67461eSJoseph Mingrone return;
11773c602fabSXin LI
11783340d773SGleb Smirnoff invalid: /* skip the rest of queues */
1179ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1180ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
11813c602fabSXin LI }
11823c602fabSXin LI
11833c602fabSXin LI /* [OF10] Section 5.2.3 */
1184ee67461eSJoseph Mingrone static void
of10_match_print(netdissect_options * ndo,const char * pfx,const u_char * cp)11853c602fabSXin LI of10_match_print(netdissect_options *ndo,
1186ee67461eSJoseph Mingrone const char *pfx, const u_char *cp)
11878bdc5a62SPatrick Kelsey {
11883c602fabSXin LI uint32_t wildcards;
11893c602fabSXin LI uint16_t dl_type;
11903c602fabSXin LI uint8_t nw_proto;
1191ee67461eSJoseph Mingrone u_int nw_bits;
11923c602fabSXin LI const char *field_name;
11933c602fabSXin LI
11943c602fabSXin LI /* wildcards */
1195ee67461eSJoseph Mingrone wildcards = GET_BE_U_4(cp);
11963c602fabSXin LI if (wildcards & OFPFW_U)
1197ee67461eSJoseph Mingrone ND_PRINT("%swildcards 0x%08x (bogus)", pfx, wildcards);
11983c602fabSXin LI cp += 4;
11993c602fabSXin LI /* in_port */
12003c602fabSXin LI if (! (wildcards & OFPFW_IN_PORT))
1201ee67461eSJoseph Mingrone ND_PRINT("%smatch in_port %s", pfx,
1202ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
12033c602fabSXin LI cp += 2;
12043c602fabSXin LI /* dl_src */
12053c602fabSXin LI if (! (wildcards & OFPFW_DL_SRC))
1206ee67461eSJoseph Mingrone ND_PRINT("%smatch dl_src %s", pfx, GET_ETHERADDR_STRING(cp));
1207ee67461eSJoseph Mingrone cp += MAC_ADDR_LEN;
12083c602fabSXin LI /* dl_dst */
12093c602fabSXin LI if (! (wildcards & OFPFW_DL_DST))
1210ee67461eSJoseph Mingrone ND_PRINT("%smatch dl_dst %s", pfx, GET_ETHERADDR_STRING(cp));
1211ee67461eSJoseph Mingrone cp += MAC_ADDR_LEN;
12123c602fabSXin LI /* dl_vlan */
12133c602fabSXin LI if (! (wildcards & OFPFW_DL_VLAN))
1214ee67461eSJoseph Mingrone ND_PRINT("%smatch dl_vlan %s", pfx, vlan_str(GET_BE_U_2(cp)));
12153c602fabSXin LI cp += 2;
12163c602fabSXin LI /* dl_vlan_pcp */
12173c602fabSXin LI if (! (wildcards & OFPFW_DL_VLAN_PCP))
1218ee67461eSJoseph Mingrone ND_PRINT("%smatch dl_vlan_pcp %s", pfx, pcp_str(GET_U_1(cp)));
12193c602fabSXin LI cp += 1;
12203c602fabSXin LI /* pad1 */
12213c602fabSXin LI cp += 1;
12223c602fabSXin LI /* dl_type */
1223ee67461eSJoseph Mingrone dl_type = GET_BE_U_2(cp);
12243c602fabSXin LI cp += 2;
12253c602fabSXin LI if (! (wildcards & OFPFW_DL_TYPE))
1226ee67461eSJoseph Mingrone ND_PRINT("%smatch dl_type 0x%04x", pfx, dl_type);
12273c602fabSXin LI /* nw_tos */
12283c602fabSXin LI if (! (wildcards & OFPFW_NW_TOS))
1229ee67461eSJoseph Mingrone ND_PRINT("%smatch nw_tos 0x%02x", pfx, GET_U_1(cp));
12303c602fabSXin LI cp += 1;
12313c602fabSXin LI /* nw_proto */
1232ee67461eSJoseph Mingrone nw_proto = GET_U_1(cp);
12333c602fabSXin LI cp += 1;
12343c602fabSXin LI if (! (wildcards & OFPFW_NW_PROTO)) {
12353c602fabSXin LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_ARP
12363c602fabSXin LI ? "arp_opcode" : "nw_proto";
1237ee67461eSJoseph Mingrone ND_PRINT("%smatch %s %u", pfx, field_name, nw_proto);
12383c602fabSXin LI }
12393c602fabSXin LI /* pad2 */
12403c602fabSXin LI cp += 2;
12413c602fabSXin LI /* nw_src */
12423c602fabSXin LI nw_bits = (wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT;
12433c602fabSXin LI if (nw_bits < 32)
1244ee67461eSJoseph Mingrone ND_PRINT("%smatch nw_src %s/%u", pfx, GET_IPADDR_STRING(cp), 32 - nw_bits);
12453c602fabSXin LI cp += 4;
12463c602fabSXin LI /* nw_dst */
12473c602fabSXin LI nw_bits = (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT;
12483c602fabSXin LI if (nw_bits < 32)
1249ee67461eSJoseph Mingrone ND_PRINT("%smatch nw_dst %s/%u", pfx, GET_IPADDR_STRING(cp), 32 - nw_bits);
12503c602fabSXin LI cp += 4;
12513c602fabSXin LI /* tp_src */
12523c602fabSXin LI if (! (wildcards & OFPFW_TP_SRC)) {
12533c602fabSXin LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP
12543c602fabSXin LI && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP
12553c602fabSXin LI ? "icmp_type" : "tp_src";
1256ee67461eSJoseph Mingrone ND_PRINT("%smatch %s %u", pfx, field_name, GET_BE_U_2(cp));
12573c602fabSXin LI }
12583c602fabSXin LI cp += 2;
12593c602fabSXin LI /* tp_dst */
1260ee67461eSJoseph Mingrone /* The last unconditional check was at nw_proto, so have an "else" here. */
12613c602fabSXin LI if (! (wildcards & OFPFW_TP_DST)) {
12623c602fabSXin LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP
12633c602fabSXin LI && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP
12643c602fabSXin LI ? "icmp_code" : "tp_dst";
1265ee67461eSJoseph Mingrone ND_PRINT("%smatch %s %u", pfx, field_name, GET_BE_U_2(cp));
1266*0a7e5f1fSJoseph Mingrone } else
1267ee67461eSJoseph Mingrone ND_TCHECK_2(cp);
12683c602fabSXin LI }
12693c602fabSXin LI
12703c602fabSXin LI /* [OF10] Section 5.2.4 */
1271ee67461eSJoseph Mingrone static void
of10_actions_print(netdissect_options * ndo,const char * pfx,const u_char * cp,u_int len)12723c602fabSXin LI of10_actions_print(netdissect_options *ndo,
1273ee67461eSJoseph Mingrone const char *pfx, const u_char *cp, u_int len)
12748bdc5a62SPatrick Kelsey {
12753c602fabSXin LI while (len) {
1276ee67461eSJoseph Mingrone uint16_t type, alen, output_port;
12773c602fabSXin LI u_char alen_bogus = 0, skip = 0;
12783c602fabSXin LI
1279*0a7e5f1fSJoseph Mingrone ND_PRINT("%saction", pfx);
1280*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("remaining length", len, <, OF_ACTION_MINLEN);
12813c602fabSXin LI /* type */
1282ee67461eSJoseph Mingrone type = GET_BE_U_2(cp);
1283ee67461eSJoseph Mingrone OF_FWD(2);
1284*0a7e5f1fSJoseph Mingrone ND_PRINT(" type %s", tok2str(ofpat_str, "invalid (0x%04x)", type));
12853c602fabSXin LI /* length */
1286ee67461eSJoseph Mingrone alen = GET_BE_U_2(cp);
1287ee67461eSJoseph Mingrone OF_FWD(2);
1288ee67461eSJoseph Mingrone ND_PRINT(", len %u", alen);
1289ee67461eSJoseph Mingrone /*
1290ee67461eSJoseph Mingrone * The 4-byte "pad" in the specification is not a field of the
1291ee67461eSJoseph Mingrone * action header, but a placeholder to illustrate the 64-bit
1292ee67461eSJoseph Mingrone * alignment requirement. Action type specific case blocks
1293ee67461eSJoseph Mingrone * below fetch these 4 bytes.
1294ee67461eSJoseph Mingrone */
1295ee67461eSJoseph Mingrone
12963c602fabSXin LI /* On action size underrun/overrun skip the rest of the action list. */
1297*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(alen, <, OF_ACTION_MINLEN);
1298*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(alen, >, len + 4);
1299ee67461eSJoseph Mingrone /*
1300ee67461eSJoseph Mingrone * After validating the basic length constraint it will be safe
1301ee67461eSJoseph Mingrone * to skip the current action if the action size is not valid
1302ee67461eSJoseph Mingrone * for the type or the type is invalid.
1303ee67461eSJoseph Mingrone */
13043c602fabSXin LI switch (type) {
13053c602fabSXin LI case OFPAT_OUTPUT:
13063c602fabSXin LI case OFPAT_SET_VLAN_VID:
13073c602fabSXin LI case OFPAT_SET_VLAN_PCP:
13083c602fabSXin LI case OFPAT_STRIP_VLAN:
13093c602fabSXin LI case OFPAT_SET_NW_SRC:
13103c602fabSXin LI case OFPAT_SET_NW_DST:
13113c602fabSXin LI case OFPAT_SET_NW_TOS:
13123c602fabSXin LI case OFPAT_SET_TP_SRC:
13133c602fabSXin LI case OFPAT_SET_TP_DST:
13143c602fabSXin LI alen_bogus = alen != 8;
13153c602fabSXin LI break;
13163c602fabSXin LI case OFPAT_SET_DL_SRC:
13173c602fabSXin LI case OFPAT_SET_DL_DST:
13183c602fabSXin LI case OFPAT_ENQUEUE:
13193c602fabSXin LI alen_bogus = alen != 16;
13203c602fabSXin LI break;
13213c602fabSXin LI case OFPAT_VENDOR:
13223c602fabSXin LI alen_bogus = alen % 8 != 0; /* already >= 8 so far */
13233c602fabSXin LI break;
13243c602fabSXin LI default:
13253c602fabSXin LI skip = 1;
13263c602fabSXin LI }
13273c602fabSXin LI if (alen_bogus) {
1328ee67461eSJoseph Mingrone ND_PRINT(" (bogus)");
13293c602fabSXin LI skip = 1;
13303c602fabSXin LI }
13313c602fabSXin LI if (skip) {
1332ee67461eSJoseph Mingrone /*
1333ee67461eSJoseph Mingrone * alen >= OF_ACTION_MINLEN
1334ee67461eSJoseph Mingrone * cp is 4 bytes in
1335ee67461eSJoseph Mingrone */
1336ee67461eSJoseph Mingrone OF_CHK_FWD(alen - 4);
1337ee67461eSJoseph Mingrone continue;
13383c602fabSXin LI }
13393c602fabSXin LI /* OK to decode the rest of the action structure */
13403c602fabSXin LI switch (type) {
13413c602fabSXin LI case OFPAT_OUTPUT:
13423c602fabSXin LI /* port */
1343ee67461eSJoseph Mingrone output_port = GET_BE_U_2(cp);
1344ee67461eSJoseph Mingrone OF_FWD(2);
1345ee67461eSJoseph Mingrone ND_PRINT(", port %s", tok2str(ofpp_str, "%u", output_port));
13463c602fabSXin LI /* max_len */
13473c602fabSXin LI if (output_port == OFPP_CONTROLLER)
1348ee67461eSJoseph Mingrone ND_PRINT(", max_len %u", GET_BE_U_2(cp));
1349ee67461eSJoseph Mingrone else
1350ee67461eSJoseph Mingrone ND_TCHECK_2(cp);
1351ee67461eSJoseph Mingrone OF_FWD(2);
13523c602fabSXin LI break;
13533c602fabSXin LI case OFPAT_SET_VLAN_VID:
13543c602fabSXin LI /* vlan_vid */
1355ee67461eSJoseph Mingrone ND_PRINT(", vlan_vid %s", vlan_str(GET_BE_U_2(cp)));
1356ee67461eSJoseph Mingrone OF_FWD(2);
13573c602fabSXin LI /* pad */
1358ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1359ee67461eSJoseph Mingrone OF_CHK_FWD(2);
13603c602fabSXin LI break;
13613c602fabSXin LI case OFPAT_SET_VLAN_PCP:
13623c602fabSXin LI /* vlan_pcp */
1363ee67461eSJoseph Mingrone ND_PRINT(", vlan_pcp %s", pcp_str(GET_U_1(cp)));
1364ee67461eSJoseph Mingrone OF_FWD(1);
13653c602fabSXin LI /* pad */
1366ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1367ee67461eSJoseph Mingrone OF_CHK_FWD(3);
13683c602fabSXin LI break;
13693c602fabSXin LI case OFPAT_SET_DL_SRC:
13703c602fabSXin LI case OFPAT_SET_DL_DST:
13713c602fabSXin LI /* dl_addr */
1372ee67461eSJoseph Mingrone ND_PRINT(", dl_addr %s", GET_ETHERADDR_STRING(cp));
1373ee67461eSJoseph Mingrone OF_FWD(MAC_ADDR_LEN);
13743c602fabSXin LI /* pad */
1375ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1376ee67461eSJoseph Mingrone OF_CHK_FWD(6);
13773c602fabSXin LI break;
13783c602fabSXin LI case OFPAT_SET_NW_SRC:
13793c602fabSXin LI case OFPAT_SET_NW_DST:
13803c602fabSXin LI /* nw_addr */
1381ee67461eSJoseph Mingrone ND_PRINT(", nw_addr %s", GET_IPADDR_STRING(cp));
1382ee67461eSJoseph Mingrone OF_FWD(4);
13833c602fabSXin LI break;
13843c602fabSXin LI case OFPAT_SET_NW_TOS:
13853c602fabSXin LI /* nw_tos */
1386ee67461eSJoseph Mingrone ND_PRINT(", nw_tos 0x%02x", GET_U_1(cp));
1387ee67461eSJoseph Mingrone OF_FWD(1);
13883c602fabSXin LI /* pad */
1389ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1390ee67461eSJoseph Mingrone OF_CHK_FWD(3);
13913c602fabSXin LI break;
13923c602fabSXin LI case OFPAT_SET_TP_SRC:
13933c602fabSXin LI case OFPAT_SET_TP_DST:
13943c602fabSXin LI /* nw_tos */
1395ee67461eSJoseph Mingrone ND_PRINT(", tp_port %u", GET_BE_U_2(cp));
1396ee67461eSJoseph Mingrone OF_FWD(2);
13973c602fabSXin LI /* pad */
1398ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1399ee67461eSJoseph Mingrone OF_CHK_FWD(2);
14003c602fabSXin LI break;
14013c602fabSXin LI case OFPAT_ENQUEUE:
14023c602fabSXin LI /* port */
1403ee67461eSJoseph Mingrone ND_PRINT(", port %s",
1404ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1405ee67461eSJoseph Mingrone OF_FWD(2);
14063c602fabSXin LI /* pad */
1407ee67461eSJoseph Mingrone OF_FWD(6);
14083c602fabSXin LI /* queue_id */
1409ee67461eSJoseph Mingrone ND_PRINT(", queue_id %s",
1410ee67461eSJoseph Mingrone tok2str(ofpq_str, "%u", GET_BE_U_4(cp)));
1411ee67461eSJoseph Mingrone OF_FWD(4);
14123c602fabSXin LI break;
14133c602fabSXin LI case OFPAT_VENDOR:
1414ee67461eSJoseph Mingrone of10_vendor_action_print(ndo, cp, alen - 4);
1415ee67461eSJoseph Mingrone OF_FWD(alen - 4);
14163c602fabSXin LI break;
14173c602fabSXin LI case OFPAT_STRIP_VLAN:
14183c602fabSXin LI /* pad */
1419ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1420ee67461eSJoseph Mingrone OF_CHK_FWD(4);
14213c602fabSXin LI break;
14223c602fabSXin LI } /* switch */
14233c602fabSXin LI } /* while */
1424ee67461eSJoseph Mingrone return;
14253c602fabSXin LI
14263340d773SGleb Smirnoff invalid: /* skip the rest of actions */
1427ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1428ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
14293c602fabSXin LI }
14303c602fabSXin LI
14313c602fabSXin LI /* [OF10] Section 5.3.1 */
1432ee67461eSJoseph Mingrone static void
of10_features_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)14333c602fabSXin LI of10_features_reply_print(netdissect_options *ndo,
1434ee67461eSJoseph Mingrone const u_char *cp, u_int len)
14358bdc5a62SPatrick Kelsey {
14363c602fabSXin LI /* datapath_id */
1437ee67461eSJoseph Mingrone ND_PRINT("\n\t dpid 0x%016" PRIx64, GET_BE_U_8(cp));
1438ee67461eSJoseph Mingrone OF_FWD(8);
14393c602fabSXin LI /* n_buffers */
1440ee67461eSJoseph Mingrone ND_PRINT(", n_buffers %u", GET_BE_U_4(cp));
1441ee67461eSJoseph Mingrone OF_FWD(4);
14423c602fabSXin LI /* n_tables */
1443ee67461eSJoseph Mingrone ND_PRINT(", n_tables %u", GET_U_1(cp));
1444ee67461eSJoseph Mingrone OF_FWD(1);
14453c602fabSXin LI /* pad */
1446ee67461eSJoseph Mingrone OF_FWD(3);
14473c602fabSXin LI /* capabilities */
1448ee67461eSJoseph Mingrone ND_PRINT("\n\t capabilities 0x%08x", GET_BE_U_4(cp));
1449ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofp_capabilities_bm, GET_BE_U_4(cp), OFPCAP_U);
1450ee67461eSJoseph Mingrone OF_FWD(4);
14513c602fabSXin LI /* actions */
1452ee67461eSJoseph Mingrone ND_PRINT("\n\t actions 0x%08x", GET_BE_U_4(cp));
1453ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofpat_bm, GET_BE_U_4(cp), OFPAT_U);
1454ee67461eSJoseph Mingrone OF_FWD(4);
14553c602fabSXin LI /* ports */
1456ee67461eSJoseph Mingrone while (len) {
1457*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("\n\t port def. length", len, <, OF_PHY_PORT_FIXLEN);
1458ee67461eSJoseph Mingrone of10_phy_port_print(ndo, cp);
1459ee67461eSJoseph Mingrone OF_FWD(OF_PHY_PORT_FIXLEN);
1460ee67461eSJoseph Mingrone }
1461ee67461eSJoseph Mingrone return;
14623c602fabSXin LI
1463ee67461eSJoseph Mingrone invalid: /* skip the undersized trailing data */
1464ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1465ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
1466ee67461eSJoseph Mingrone }
1467ee67461eSJoseph Mingrone
1468ee67461eSJoseph Mingrone /* [OF10] Section 5.3.2 */
1469ee67461eSJoseph Mingrone static void
of10_switch_config_msg_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)1470ee67461eSJoseph Mingrone of10_switch_config_msg_print(netdissect_options *ndo,
1471ee67461eSJoseph Mingrone const u_char *cp, u_int len _U_)
1472ee67461eSJoseph Mingrone {
1473ee67461eSJoseph Mingrone /* flags */
1474ee67461eSJoseph Mingrone ND_PRINT("\n\t flags %s",
1475ee67461eSJoseph Mingrone tok2str(ofp_config_str, "invalid (0x%04x)", GET_BE_U_2(cp)));
1476ee67461eSJoseph Mingrone cp += 2;
1477ee67461eSJoseph Mingrone /* miss_send_len */
1478ee67461eSJoseph Mingrone ND_PRINT(", miss_send_len %u", GET_BE_U_2(cp));
14793c602fabSXin LI }
14803c602fabSXin LI
14813c602fabSXin LI /* [OF10] Section 5.3.3 */
1482ee67461eSJoseph Mingrone static void
of10_flow_mod_print(netdissect_options * ndo,const u_char * cp,u_int len)14833c602fabSXin LI of10_flow_mod_print(netdissect_options *ndo,
1484ee67461eSJoseph Mingrone const u_char *cp, u_int len)
14858bdc5a62SPatrick Kelsey {
14863c602fabSXin LI uint16_t command;
14873c602fabSXin LI
14883c602fabSXin LI /* match */
1489ee67461eSJoseph Mingrone of10_match_print(ndo, "\n\t ", cp);
1490ee67461eSJoseph Mingrone OF_FWD(OF_MATCH_FIXLEN);
14913c602fabSXin LI /* cookie */
1492ee67461eSJoseph Mingrone ND_PRINT("\n\t cookie 0x%016" PRIx64, GET_BE_U_8(cp));
1493ee67461eSJoseph Mingrone OF_FWD(8);
14943c602fabSXin LI /* command */
1495ee67461eSJoseph Mingrone command = GET_BE_U_2(cp);
1496ee67461eSJoseph Mingrone ND_PRINT(", command %s", tok2str(ofpfc_str, "invalid (0x%04x)", command));
1497ee67461eSJoseph Mingrone OF_FWD(2);
14983c602fabSXin LI /* idle_timeout */
1499ee67461eSJoseph Mingrone if (GET_BE_U_2(cp))
1500ee67461eSJoseph Mingrone ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp));
1501ee67461eSJoseph Mingrone OF_FWD(2);
15023c602fabSXin LI /* hard_timeout */
1503ee67461eSJoseph Mingrone if (GET_BE_U_2(cp))
1504ee67461eSJoseph Mingrone ND_PRINT(", hard_timeout %u", GET_BE_U_2(cp));
1505ee67461eSJoseph Mingrone OF_FWD(2);
15063c602fabSXin LI /* priority */
1507ee67461eSJoseph Mingrone if (GET_BE_U_2(cp))
1508ee67461eSJoseph Mingrone ND_PRINT(", priority %u", GET_BE_U_2(cp));
1509ee67461eSJoseph Mingrone OF_FWD(2);
15103c602fabSXin LI /* buffer_id */
15113c602fabSXin LI if (command == OFPFC_ADD || command == OFPFC_MODIFY ||
15123c602fabSXin LI command == OFPFC_MODIFY_STRICT)
1513ee67461eSJoseph Mingrone ND_PRINT(", buffer_id %s",
1514ee67461eSJoseph Mingrone tok2str(bufferid_str, "0x%08x", GET_BE_U_4(cp)));
1515ee67461eSJoseph Mingrone OF_FWD(4);
15163c602fabSXin LI /* out_port */
15173c602fabSXin LI if (command == OFPFC_DELETE || command == OFPFC_DELETE_STRICT)
1518ee67461eSJoseph Mingrone ND_PRINT(", out_port %s",
1519ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1520ee67461eSJoseph Mingrone OF_FWD(2);
15213c602fabSXin LI /* flags */
1522ee67461eSJoseph Mingrone ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp));
1523ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofpff_bm, GET_BE_U_2(cp), OFPFF_U);
1524ee67461eSJoseph Mingrone OF_FWD(2);
15253c602fabSXin LI /* actions */
1526ee67461eSJoseph Mingrone of10_actions_print(ndo, "\n\t ", cp, len);
15273c602fabSXin LI }
15283c602fabSXin LI
15293c602fabSXin LI /* ibid */
1530ee67461eSJoseph Mingrone static void
of10_port_mod_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)15313c602fabSXin LI of10_port_mod_print(netdissect_options *ndo,
1532ee67461eSJoseph Mingrone const u_char *cp, u_int len _U_)
15338bdc5a62SPatrick Kelsey {
15343c602fabSXin LI /* port_no */
1535ee67461eSJoseph Mingrone ND_PRINT("\n\t port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
15363c602fabSXin LI cp += 2;
15373c602fabSXin LI /* hw_addr */
1538ee67461eSJoseph Mingrone ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp));
1539ee67461eSJoseph Mingrone cp += MAC_ADDR_LEN;
15403c602fabSXin LI /* config */
1541ee67461eSJoseph Mingrone ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp));
1542ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U);
15433c602fabSXin LI cp += 4;
15443c602fabSXin LI /* mask */
1545ee67461eSJoseph Mingrone ND_PRINT("\n\t mask 0x%08x", GET_BE_U_4(cp));
1546ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U);
15473c602fabSXin LI cp += 4;
15483c602fabSXin LI /* advertise */
1549ee67461eSJoseph Mingrone ND_PRINT("\n\t advertise 0x%08x", GET_BE_U_4(cp));
1550ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
15513c602fabSXin LI cp += 4;
15523c602fabSXin LI /* pad */
1553ee67461eSJoseph Mingrone /* Always the last field, check bounds. */
1554ee67461eSJoseph Mingrone ND_TCHECK_4(cp);
1555ee67461eSJoseph Mingrone }
15563c602fabSXin LI
1557ee67461eSJoseph Mingrone /* [OF10] Section 5.3.4 */
1558ee67461eSJoseph Mingrone static void
of10_queue_get_config_request_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)1559ee67461eSJoseph Mingrone of10_queue_get_config_request_print(netdissect_options *ndo,
1560ee67461eSJoseph Mingrone const u_char *cp, u_int len _U_)
1561ee67461eSJoseph Mingrone {
1562ee67461eSJoseph Mingrone /* port */
1563ee67461eSJoseph Mingrone ND_PRINT("\n\t port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1564ee67461eSJoseph Mingrone cp += 2;
1565ee67461eSJoseph Mingrone /* pad */
1566ee67461eSJoseph Mingrone /* Always the last field, check bounds. */
1567ee67461eSJoseph Mingrone ND_TCHECK_2(cp);
1568ee67461eSJoseph Mingrone }
1569ee67461eSJoseph Mingrone
1570ee67461eSJoseph Mingrone /* ibid */
1571ee67461eSJoseph Mingrone static void
of10_queue_get_config_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1572ee67461eSJoseph Mingrone of10_queue_get_config_reply_print(netdissect_options *ndo,
1573ee67461eSJoseph Mingrone const u_char *cp, u_int len)
1574ee67461eSJoseph Mingrone {
1575ee67461eSJoseph Mingrone /* port */
1576ee67461eSJoseph Mingrone ND_PRINT("\n\t port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1577ee67461eSJoseph Mingrone OF_FWD(2);
1578ee67461eSJoseph Mingrone /* pad */
1579ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
1580ee67461eSJoseph Mingrone OF_CHK_FWD(6);
1581ee67461eSJoseph Mingrone /* queues */
1582ee67461eSJoseph Mingrone of10_queues_print(ndo, cp, len);
15833c602fabSXin LI }
15843c602fabSXin LI
15853c602fabSXin LI /* [OF10] Section 5.3.5 */
1586ee67461eSJoseph Mingrone static void
of10_stats_request_print(netdissect_options * ndo,const u_char * cp,u_int len)15873c602fabSXin LI of10_stats_request_print(netdissect_options *ndo,
1588ee67461eSJoseph Mingrone const u_char *cp, u_int len)
15898bdc5a62SPatrick Kelsey {
15903c602fabSXin LI uint16_t type;
15913c602fabSXin LI
15923c602fabSXin LI /* type */
1593ee67461eSJoseph Mingrone type = GET_BE_U_2(cp);
1594ee67461eSJoseph Mingrone OF_FWD(2);
1595ee67461eSJoseph Mingrone ND_PRINT("\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type));
15963c602fabSXin LI /* flags */
1597ee67461eSJoseph Mingrone ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp));
1598ee67461eSJoseph Mingrone if (GET_BE_U_2(cp))
1599ee67461eSJoseph Mingrone ND_PRINT(" (bogus)");
1600ee67461eSJoseph Mingrone OF_FWD(2);
16013c602fabSXin LI /* type-specific body of one of fixed lengths */
16023c602fabSXin LI switch(type) {
16033c602fabSXin LI case OFPST_DESC:
16043c602fabSXin LI case OFPST_TABLE:
1605*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, 0);
1606ee67461eSJoseph Mingrone return;
16073c602fabSXin LI case OFPST_FLOW:
16083c602fabSXin LI case OFPST_AGGREGATE:
1609*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, OF_FLOW_STATS_REQUEST_FIXLEN);
16103c602fabSXin LI /* match */
1611ee67461eSJoseph Mingrone of10_match_print(ndo, "\n\t ", cp);
1612ee67461eSJoseph Mingrone OF_FWD(OF_MATCH_FIXLEN);
16133c602fabSXin LI /* table_id */
1614ee67461eSJoseph Mingrone ND_PRINT("\n\t table_id %s",
1615ee67461eSJoseph Mingrone tok2str(tableid_str, "%u", GET_U_1(cp)));
1616ee67461eSJoseph Mingrone OF_FWD(1);
16173c602fabSXin LI /* pad */
1618ee67461eSJoseph Mingrone OF_FWD(1);
16193c602fabSXin LI /* out_port */
1620ee67461eSJoseph Mingrone ND_PRINT(", out_port %s",
1621ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1622ee67461eSJoseph Mingrone return;
16233c602fabSXin LI case OFPST_PORT:
1624*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, OF_PORT_STATS_REQUEST_FIXLEN);
16253c602fabSXin LI /* port_no */
1626ee67461eSJoseph Mingrone ND_PRINT("\n\t port_no %s",
1627ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1628ee67461eSJoseph Mingrone OF_FWD(2);
16293c602fabSXin LI /* pad */
1630ee67461eSJoseph Mingrone /* Always the last field, check bounds. */
1631ee67461eSJoseph Mingrone OF_CHK_FWD(6);
1632ee67461eSJoseph Mingrone return;
16333c602fabSXin LI case OFPST_QUEUE:
1634*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, OF_QUEUE_STATS_REQUEST_FIXLEN);
16353c602fabSXin LI /* port_no */
1636ee67461eSJoseph Mingrone ND_PRINT("\n\t port_no %s",
1637ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1638ee67461eSJoseph Mingrone OF_FWD(2);
16393c602fabSXin LI /* pad */
1640ee67461eSJoseph Mingrone OF_FWD(2);
16413c602fabSXin LI /* queue_id */
1642ee67461eSJoseph Mingrone ND_PRINT(", queue_id %s",
1643ee67461eSJoseph Mingrone tok2str(ofpq_str, "%u", GET_BE_U_4(cp)));
1644ee67461eSJoseph Mingrone return;
16453c602fabSXin LI case OFPST_VENDOR:
1646ee67461eSJoseph Mingrone of10_vendor_data_print(ndo, cp, len);
1647ee67461eSJoseph Mingrone return;
16483c602fabSXin LI }
1649ee67461eSJoseph Mingrone return;
16503c602fabSXin LI
16513340d773SGleb Smirnoff invalid: /* skip the message body */
1652ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1653ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
16543c602fabSXin LI }
16553c602fabSXin LI
16563c602fabSXin LI /* ibid */
1657ee67461eSJoseph Mingrone static void
of10_desc_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)16583c602fabSXin LI of10_desc_stats_reply_print(netdissect_options *ndo,
1659ee67461eSJoseph Mingrone const u_char *cp, u_int len)
16608bdc5a62SPatrick Kelsey {
1661*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t ");
1662*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(len, !=, OF_DESC_STATS_REPLY_FIXLEN);
16633c602fabSXin LI /* mfr_desc */
1664*0a7e5f1fSJoseph Mingrone ND_PRINT(" mfr_desc '");
1665ee67461eSJoseph Mingrone nd_printjnp(ndo, cp, DESC_STR_LEN);
1666ee67461eSJoseph Mingrone ND_PRINT("'");
1667ee67461eSJoseph Mingrone OF_FWD(DESC_STR_LEN);
16683c602fabSXin LI /* hw_desc */
1669ee67461eSJoseph Mingrone ND_PRINT("\n\t hw_desc '");
1670ee67461eSJoseph Mingrone nd_printjnp(ndo, cp, DESC_STR_LEN);
1671ee67461eSJoseph Mingrone ND_PRINT("'");
1672ee67461eSJoseph Mingrone OF_FWD(DESC_STR_LEN);
16733c602fabSXin LI /* sw_desc */
1674ee67461eSJoseph Mingrone ND_PRINT("\n\t sw_desc '");
1675ee67461eSJoseph Mingrone nd_printjnp(ndo, cp, DESC_STR_LEN);
1676ee67461eSJoseph Mingrone ND_PRINT("'");
1677ee67461eSJoseph Mingrone OF_FWD(DESC_STR_LEN);
16783c602fabSXin LI /* serial_num */
1679ee67461eSJoseph Mingrone ND_PRINT("\n\t serial_num '");
1680ee67461eSJoseph Mingrone nd_printjnp(ndo, cp, SERIAL_NUM_LEN);
1681ee67461eSJoseph Mingrone ND_PRINT("'");
1682ee67461eSJoseph Mingrone OF_FWD(SERIAL_NUM_LEN);
16833c602fabSXin LI /* dp_desc */
1684ee67461eSJoseph Mingrone ND_PRINT("\n\t dp_desc '");
1685ee67461eSJoseph Mingrone nd_printjnp(ndo, cp, DESC_STR_LEN);
1686ee67461eSJoseph Mingrone ND_PRINT("'");
1687ee67461eSJoseph Mingrone return;
16883c602fabSXin LI
16893340d773SGleb Smirnoff invalid: /* skip the message body */
1690ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1691ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
16923c602fabSXin LI }
16933c602fabSXin LI
16943c602fabSXin LI /* ibid */
1695ee67461eSJoseph Mingrone static void
of10_flow_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)16963c602fabSXin LI of10_flow_stats_reply_print(netdissect_options *ndo,
1697ee67461eSJoseph Mingrone const u_char *cp, u_int len)
16988bdc5a62SPatrick Kelsey {
1699ee67461eSJoseph Mingrone while (len) {
17003c602fabSXin LI uint16_t entry_len;
17013c602fabSXin LI
1702*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t");
1703*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("remaining length", len, <, OF_FLOW_STATS_REPLY_MINLEN);
17043c602fabSXin LI /* length */
1705ee67461eSJoseph Mingrone entry_len = GET_BE_U_2(cp);
1706*0a7e5f1fSJoseph Mingrone ND_PRINT(" length %u", entry_len);
1707*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(entry_len, <, OF_FLOW_STATS_REPLY_MINLEN);
1708*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(entry_len, >, len);
1709ee67461eSJoseph Mingrone OF_FWD(2);
17103c602fabSXin LI /* table_id */
1711ee67461eSJoseph Mingrone ND_PRINT(", table_id %s",
1712ee67461eSJoseph Mingrone tok2str(tableid_str, "%u", GET_U_1(cp)));
1713ee67461eSJoseph Mingrone OF_FWD(1);
17143c602fabSXin LI /* pad */
1715ee67461eSJoseph Mingrone OF_FWD(1);
17163c602fabSXin LI /* match */
1717ee67461eSJoseph Mingrone of10_match_print(ndo, "\n\t ", cp);
1718ee67461eSJoseph Mingrone OF_FWD(OF_MATCH_FIXLEN);
17193c602fabSXin LI /* duration_sec */
1720ee67461eSJoseph Mingrone ND_PRINT("\n\t duration_sec %u", GET_BE_U_4(cp));
1721ee67461eSJoseph Mingrone OF_FWD(4);
17223c602fabSXin LI /* duration_nsec */
1723ee67461eSJoseph Mingrone ND_PRINT(", duration_nsec %u", GET_BE_U_4(cp));
1724ee67461eSJoseph Mingrone OF_FWD(4);
17253c602fabSXin LI /* priority */
1726ee67461eSJoseph Mingrone ND_PRINT(", priority %u", GET_BE_U_2(cp));
1727ee67461eSJoseph Mingrone OF_FWD(2);
17283c602fabSXin LI /* idle_timeout */
1729ee67461eSJoseph Mingrone ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp));
1730ee67461eSJoseph Mingrone OF_FWD(2);
17313c602fabSXin LI /* hard_timeout */
1732ee67461eSJoseph Mingrone ND_PRINT(", hard_timeout %u", GET_BE_U_2(cp));
1733ee67461eSJoseph Mingrone OF_FWD(2);
17343c602fabSXin LI /* pad2 */
1735ee67461eSJoseph Mingrone OF_FWD(6);
17363c602fabSXin LI /* cookie */
1737ee67461eSJoseph Mingrone ND_PRINT(", cookie 0x%016" PRIx64, GET_BE_U_8(cp));
1738ee67461eSJoseph Mingrone OF_FWD(8);
17393c602fabSXin LI /* packet_count */
1740ee67461eSJoseph Mingrone ND_PRINT(", packet_count %" PRIu64, GET_BE_U_8(cp));
1741ee67461eSJoseph Mingrone OF_FWD(8);
17423c602fabSXin LI /* byte_count */
1743ee67461eSJoseph Mingrone ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp));
1744ee67461eSJoseph Mingrone OF_FWD(8);
17453c602fabSXin LI /* actions */
1746ee67461eSJoseph Mingrone of10_actions_print(ndo, "\n\t ", cp, entry_len - OF_FLOW_STATS_REPLY_MINLEN);
1747ee67461eSJoseph Mingrone OF_FWD(entry_len - OF_FLOW_STATS_REPLY_MINLEN);
17483c602fabSXin LI } /* while */
1749ee67461eSJoseph Mingrone return;
17503c602fabSXin LI
17513340d773SGleb Smirnoff invalid: /* skip the rest of flow statistics entries */
1752ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1753ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
17543c602fabSXin LI }
17553c602fabSXin LI
17563c602fabSXin LI /* ibid */
1757ee67461eSJoseph Mingrone static void
of10_aggregate_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)17583c602fabSXin LI of10_aggregate_stats_reply_print(netdissect_options *ndo,
1759ee67461eSJoseph Mingrone const u_char *cp, u_int len)
17608bdc5a62SPatrick Kelsey {
1761*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t");
1762*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("remaining length", len, !=, OF_AGGREGATE_STATS_REPLY_FIXLEN);
17633c602fabSXin LI /* packet_count */
1764*0a7e5f1fSJoseph Mingrone ND_PRINT(" packet_count %" PRIu64, GET_BE_U_8(cp));
1765ee67461eSJoseph Mingrone OF_FWD(8);
17663c602fabSXin LI /* byte_count */
1767ee67461eSJoseph Mingrone ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp));
1768ee67461eSJoseph Mingrone OF_FWD(8);
17693c602fabSXin LI /* flow_count */
1770ee67461eSJoseph Mingrone ND_PRINT(", flow_count %u", GET_BE_U_4(cp));
1771ee67461eSJoseph Mingrone OF_FWD(4);
17723c602fabSXin LI /* pad */
1773ee67461eSJoseph Mingrone /* Always the last field, check bounds. */
1774ee67461eSJoseph Mingrone ND_TCHECK_4(cp);
1775ee67461eSJoseph Mingrone return;
17763c602fabSXin LI
17773340d773SGleb Smirnoff invalid: /* skip the message body */
1778ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1779ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
17803c602fabSXin LI }
17813c602fabSXin LI
17823c602fabSXin LI /* ibid */
1783ee67461eSJoseph Mingrone static void
of10_table_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)17843c602fabSXin LI of10_table_stats_reply_print(netdissect_options *ndo,
1785ee67461eSJoseph Mingrone const u_char *cp, u_int len)
17868bdc5a62SPatrick Kelsey {
17873c602fabSXin LI while (len) {
1788*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t");
1789*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("remaining length", len, <, OF_TABLE_STATS_REPLY_FIXLEN);
17903c602fabSXin LI /* table_id */
1791*0a7e5f1fSJoseph Mingrone ND_PRINT(" table_id %s",
1792ee67461eSJoseph Mingrone tok2str(tableid_str, "%u", GET_U_1(cp)));
1793ee67461eSJoseph Mingrone OF_FWD(1);
17943c602fabSXin LI /* pad */
1795ee67461eSJoseph Mingrone OF_FWD(3);
17963c602fabSXin LI /* name */
1797ee67461eSJoseph Mingrone ND_PRINT(", name '");
1798ee67461eSJoseph Mingrone nd_printjnp(ndo, cp, OFP_MAX_TABLE_NAME_LEN);
1799ee67461eSJoseph Mingrone ND_PRINT("'");
1800ee67461eSJoseph Mingrone OF_FWD(OFP_MAX_TABLE_NAME_LEN);
18013c602fabSXin LI /* wildcards */
1802ee67461eSJoseph Mingrone ND_PRINT("\n\t wildcards 0x%08x", GET_BE_U_4(cp));
1803ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofpfw_bm, GET_BE_U_4(cp), OFPFW_U);
1804ee67461eSJoseph Mingrone OF_FWD(4);
18053c602fabSXin LI /* max_entries */
1806ee67461eSJoseph Mingrone ND_PRINT("\n\t max_entries %u", GET_BE_U_4(cp));
1807ee67461eSJoseph Mingrone OF_FWD(4);
18083c602fabSXin LI /* active_count */
1809ee67461eSJoseph Mingrone ND_PRINT(", active_count %u", GET_BE_U_4(cp));
1810ee67461eSJoseph Mingrone OF_FWD(4);
18113c602fabSXin LI /* lookup_count */
1812ee67461eSJoseph Mingrone ND_PRINT(", lookup_count %" PRIu64, GET_BE_U_8(cp));
1813ee67461eSJoseph Mingrone OF_FWD(8);
18143c602fabSXin LI /* matched_count */
1815ee67461eSJoseph Mingrone ND_PRINT(", matched_count %" PRIu64, GET_BE_U_8(cp));
1816ee67461eSJoseph Mingrone OF_FWD(8);
18173c602fabSXin LI } /* while */
1818ee67461eSJoseph Mingrone return;
18193c602fabSXin LI
18203340d773SGleb Smirnoff invalid: /* skip the undersized trailing data */
1821ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1822ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
18233c602fabSXin LI }
18243c602fabSXin LI
18253c602fabSXin LI /* ibid */
1826ee67461eSJoseph Mingrone static void
of10_port_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)18273c602fabSXin LI of10_port_stats_reply_print(netdissect_options *ndo,
1828ee67461eSJoseph Mingrone const u_char *cp, u_int len)
18298bdc5a62SPatrick Kelsey {
18303c602fabSXin LI while (len) {
1831*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t ");
1832*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("remaining length", len, <, OF_PORT_STATS_REPLY_FIXLEN);
18333c602fabSXin LI /* port_no */
1834*0a7e5f1fSJoseph Mingrone ND_PRINT(" port_no %s",
1835ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1836ee67461eSJoseph Mingrone OF_FWD(2);
18373c602fabSXin LI if (ndo->ndo_vflag < 2) {
1838ee67461eSJoseph Mingrone OF_CHK_FWD(OF_PORT_STATS_REPLY_FIXLEN - 2);
1839ee67461eSJoseph Mingrone continue;
18403c602fabSXin LI }
18413c602fabSXin LI /* pad */
1842ee67461eSJoseph Mingrone OF_FWD(6);
18433c602fabSXin LI /* rx_packets */
1844ee67461eSJoseph Mingrone ND_PRINT(", rx_packets %" PRIu64, GET_BE_U_8(cp));
1845ee67461eSJoseph Mingrone OF_FWD(8);
18463c602fabSXin LI /* tx_packets */
1847ee67461eSJoseph Mingrone ND_PRINT(", tx_packets %" PRIu64, GET_BE_U_8(cp));
1848ee67461eSJoseph Mingrone OF_FWD(8);
18493c602fabSXin LI /* rx_bytes */
1850ee67461eSJoseph Mingrone ND_PRINT(", rx_bytes %" PRIu64, GET_BE_U_8(cp));
1851ee67461eSJoseph Mingrone OF_FWD(8);
18523c602fabSXin LI /* tx_bytes */
1853ee67461eSJoseph Mingrone ND_PRINT(", tx_bytes %" PRIu64, GET_BE_U_8(cp));
1854ee67461eSJoseph Mingrone OF_FWD(8);
18553c602fabSXin LI /* rx_dropped */
1856ee67461eSJoseph Mingrone ND_PRINT(", rx_dropped %" PRIu64, GET_BE_U_8(cp));
1857ee67461eSJoseph Mingrone OF_FWD(8);
18583c602fabSXin LI /* tx_dropped */
1859ee67461eSJoseph Mingrone ND_PRINT(", tx_dropped %" PRIu64, GET_BE_U_8(cp));
1860ee67461eSJoseph Mingrone OF_FWD(8);
18613c602fabSXin LI /* rx_errors */
1862ee67461eSJoseph Mingrone ND_PRINT(", rx_errors %" PRIu64, GET_BE_U_8(cp));
1863ee67461eSJoseph Mingrone OF_FWD(8);
18643c602fabSXin LI /* tx_errors */
1865ee67461eSJoseph Mingrone ND_PRINT(", tx_errors %" PRIu64, GET_BE_U_8(cp));
1866ee67461eSJoseph Mingrone OF_FWD(8);
18673c602fabSXin LI /* rx_frame_err */
1868ee67461eSJoseph Mingrone ND_PRINT(", rx_frame_err %" PRIu64, GET_BE_U_8(cp));
1869ee67461eSJoseph Mingrone OF_FWD(8);
18703c602fabSXin LI /* rx_over_err */
1871ee67461eSJoseph Mingrone ND_PRINT(", rx_over_err %" PRIu64, GET_BE_U_8(cp));
1872ee67461eSJoseph Mingrone OF_FWD(8);
18733c602fabSXin LI /* rx_crc_err */
1874ee67461eSJoseph Mingrone ND_PRINT(", rx_crc_err %" PRIu64, GET_BE_U_8(cp));
1875ee67461eSJoseph Mingrone OF_FWD(8);
18763c602fabSXin LI /* collisions */
1877ee67461eSJoseph Mingrone ND_PRINT(", collisions %" PRIu64, GET_BE_U_8(cp));
1878ee67461eSJoseph Mingrone OF_FWD(8);
18793c602fabSXin LI } /* while */
1880ee67461eSJoseph Mingrone return;
18813c602fabSXin LI
18823340d773SGleb Smirnoff invalid: /* skip the undersized trailing data */
1883ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1884ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
18853c602fabSXin LI }
18863c602fabSXin LI
18873c602fabSXin LI /* ibid */
1888ee67461eSJoseph Mingrone static void
of10_queue_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)18893c602fabSXin LI of10_queue_stats_reply_print(netdissect_options *ndo,
1890ee67461eSJoseph Mingrone const u_char *cp, u_int len)
18918bdc5a62SPatrick Kelsey {
18923c602fabSXin LI while (len) {
1893*0a7e5f1fSJoseph Mingrone ND_PRINT("\n\t ");
1894*0a7e5f1fSJoseph Mingrone ND_ICHECKMSG_U("remaining length", len, <, OF_QUEUE_STATS_REPLY_FIXLEN);
18953c602fabSXin LI /* port_no */
1896*0a7e5f1fSJoseph Mingrone ND_PRINT(" port_no %s",
1897ee67461eSJoseph Mingrone tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1898ee67461eSJoseph Mingrone OF_FWD(2);
18993c602fabSXin LI /* pad */
1900ee67461eSJoseph Mingrone OF_FWD(2);
19013c602fabSXin LI /* queue_id */
1902ee67461eSJoseph Mingrone ND_PRINT(", queue_id %u", GET_BE_U_4(cp));
1903ee67461eSJoseph Mingrone OF_FWD(4);
19043c602fabSXin LI /* tx_bytes */
1905ee67461eSJoseph Mingrone ND_PRINT(", tx_bytes %" PRIu64, GET_BE_U_8(cp));
1906ee67461eSJoseph Mingrone OF_FWD(8);
19073c602fabSXin LI /* tx_packets */
1908ee67461eSJoseph Mingrone ND_PRINT(", tx_packets %" PRIu64, GET_BE_U_8(cp));
1909ee67461eSJoseph Mingrone OF_FWD(8);
19103c602fabSXin LI /* tx_errors */
1911ee67461eSJoseph Mingrone ND_PRINT(", tx_errors %" PRIu64, GET_BE_U_8(cp));
1912ee67461eSJoseph Mingrone OF_FWD(8);
19133c602fabSXin LI } /* while */
1914ee67461eSJoseph Mingrone return;
19153c602fabSXin LI
19163340d773SGleb Smirnoff invalid: /* skip the undersized trailing data */
1917ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1918ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
19193c602fabSXin LI }
19203c602fabSXin LI
19213c602fabSXin LI /* ibid */
1922ee67461eSJoseph Mingrone static void
of10_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)19233c602fabSXin LI of10_stats_reply_print(netdissect_options *ndo,
1924ee67461eSJoseph Mingrone const u_char *cp, u_int len)
19258bdc5a62SPatrick Kelsey {
19263c602fabSXin LI uint16_t type;
19273c602fabSXin LI
19283c602fabSXin LI /* type */
1929ee67461eSJoseph Mingrone type = GET_BE_U_2(cp);
1930ee67461eSJoseph Mingrone ND_PRINT("\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type));
1931ee67461eSJoseph Mingrone OF_FWD(2);
19323c602fabSXin LI /* flags */
1933ee67461eSJoseph Mingrone ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp));
1934ee67461eSJoseph Mingrone of_bitmap_print(ndo, ofpsf_reply_bm, GET_BE_U_2(cp), OFPSF_REPLY_U);
1935ee67461eSJoseph Mingrone OF_FWD(2);
19363c602fabSXin LI
19373c602fabSXin LI if (ndo->ndo_vflag > 0) {
1938ee67461eSJoseph Mingrone void (*decoder)(netdissect_options *, const u_char *, u_int) =
19393c602fabSXin LI type == OFPST_DESC ? of10_desc_stats_reply_print :
19403c602fabSXin LI type == OFPST_FLOW ? of10_flow_stats_reply_print :
19413c602fabSXin LI type == OFPST_AGGREGATE ? of10_aggregate_stats_reply_print :
19423c602fabSXin LI type == OFPST_TABLE ? of10_table_stats_reply_print :
19433c602fabSXin LI type == OFPST_PORT ? of10_port_stats_reply_print :
19443c602fabSXin LI type == OFPST_QUEUE ? of10_queue_stats_reply_print :
19453c602fabSXin LI type == OFPST_VENDOR ? of10_vendor_data_print :
19463c602fabSXin LI NULL;
1947ee67461eSJoseph Mingrone if (decoder != NULL) {
1948ee67461eSJoseph Mingrone decoder(ndo, cp, len);
1949ee67461eSJoseph Mingrone return;
19503c602fabSXin LI }
1951ee67461eSJoseph Mingrone }
1952ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
19533c602fabSXin LI }
19543c602fabSXin LI
19553c602fabSXin LI /* [OF10] Section 5.3.6 */
1956ee67461eSJoseph Mingrone static void
of10_packet_out_print(netdissect_options * ndo,const u_char * cp,u_int len)19573c602fabSXin LI of10_packet_out_print(netdissect_options *ndo,
1958ee67461eSJoseph Mingrone const u_char *cp, u_int len)
19598bdc5a62SPatrick Kelsey {
19603c602fabSXin LI uint16_t actions_len;
19613c602fabSXin LI
19623c602fabSXin LI /* buffer_id */
1963ee67461eSJoseph Mingrone ND_PRINT("\n\t buffer_id 0x%08x", GET_BE_U_4(cp));
1964ee67461eSJoseph Mingrone OF_FWD(4);
19653c602fabSXin LI /* in_port */
1966ee67461eSJoseph Mingrone ND_PRINT(", in_port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1967ee67461eSJoseph Mingrone OF_FWD(2);
19683c602fabSXin LI /* actions_len */
1969ee67461eSJoseph Mingrone actions_len = GET_BE_U_2(cp);
1970*0a7e5f1fSJoseph Mingrone ND_PRINT(", actions_len %u", actions_len);
1971ee67461eSJoseph Mingrone OF_FWD(2);
1972*0a7e5f1fSJoseph Mingrone ND_ICHECK_U(actions_len, >, len);
19733c602fabSXin LI /* actions */
1974ee67461eSJoseph Mingrone of10_actions_print(ndo, "\n\t ", cp, actions_len);
1975ee67461eSJoseph Mingrone OF_FWD(actions_len);
19763c602fabSXin LI /* data */
1977ee67461eSJoseph Mingrone of10_packet_data_print(ndo, cp, len);
1978ee67461eSJoseph Mingrone return;
19793c602fabSXin LI
19803340d773SGleb Smirnoff invalid: /* skip the rest of the message body */
1981ee67461eSJoseph Mingrone nd_print_invalid(ndo);
1982ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len);
19833c602fabSXin LI }
19843c602fabSXin LI
19853c602fabSXin LI /* [OF10] Section 5.4.1 */
1986ee67461eSJoseph Mingrone static void
of10_packet_in_print(netdissect_options * ndo,const u_char * cp,u_int len)19873c602fabSXin LI of10_packet_in_print(netdissect_options *ndo,
1988ee67461eSJoseph Mingrone const u_char *cp, u_int len)
19898bdc5a62SPatrick Kelsey {
19903c602fabSXin LI /* buffer_id */
1991ee67461eSJoseph Mingrone ND_PRINT("\n\t buffer_id %s",
1992ee67461eSJoseph Mingrone tok2str(bufferid_str, "0x%08x", GET_BE_U_4(cp)));
1993ee67461eSJoseph Mingrone OF_FWD(4);
19943c602fabSXin LI /* total_len */
1995ee67461eSJoseph Mingrone ND_PRINT(", total_len %u", GET_BE_U_2(cp));
1996ee67461eSJoseph Mingrone OF_FWD(2);
19973c602fabSXin LI /* in_port */
1998ee67461eSJoseph Mingrone ND_PRINT(", in_port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1999ee67461eSJoseph Mingrone OF_FWD(2);
20003c602fabSXin LI /* reason */
2001ee67461eSJoseph Mingrone ND_PRINT(", reason %s",
2002ee67461eSJoseph Mingrone tok2str(ofpr_str, "invalid (0x%02x)", GET_U_1(cp)));
2003ee67461eSJoseph Mingrone OF_FWD(1);
20043c602fabSXin LI /* pad */
2005ee67461eSJoseph Mingrone /* Sometimes the last field, check bounds. */
2006ee67461eSJoseph Mingrone OF_CHK_FWD(1);
20073c602fabSXin LI /* data */
2008ee67461eSJoseph Mingrone of10_packet_data_print(ndo, cp, len);
20093c602fabSXin LI }
20103c602fabSXin LI
20113c602fabSXin LI /* [OF10] Section 5.4.2 */
2012ee67461eSJoseph Mingrone static void
of10_flow_removed_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)20133c602fabSXin LI of10_flow_removed_print(netdissect_options *ndo,
2014ee67461eSJoseph Mingrone const u_char *cp, u_int len _U_)
20158bdc5a62SPatrick Kelsey {
20163c602fabSXin LI /* match */
2017ee67461eSJoseph Mingrone of10_match_print(ndo, "\n\t ", cp);
2018ee67461eSJoseph Mingrone cp += OF_MATCH_FIXLEN;
20193c602fabSXin LI /* cookie */
2020ee67461eSJoseph Mingrone ND_PRINT("\n\t cookie 0x%016" PRIx64, GET_BE_U_8(cp));
20213c602fabSXin LI cp += 8;
20223c602fabSXin LI /* priority */
2023ee67461eSJoseph Mingrone if (GET_BE_U_2(cp))
2024ee67461eSJoseph Mingrone ND_PRINT(", priority %u", GET_BE_U_2(cp));
20253c602fabSXin LI cp += 2;
20263c602fabSXin LI /* reason */
2027ee67461eSJoseph Mingrone ND_PRINT(", reason %s",
2028ee67461eSJoseph Mingrone tok2str(ofprr_str, "unknown (0x%02x)", GET_U_1(cp)));
20293c602fabSXin LI cp += 1;
20303c602fabSXin LI /* pad */
20313c602fabSXin LI cp += 1;
20323c602fabSXin LI /* duration_sec */
2033ee67461eSJoseph Mingrone ND_PRINT(", duration_sec %u", GET_BE_U_4(cp));
20343c602fabSXin LI cp += 4;
20353c602fabSXin LI /* duration_nsec */
2036ee67461eSJoseph Mingrone ND_PRINT(", duration_nsec %u", GET_BE_U_4(cp));
20373c602fabSXin LI cp += 4;
20383c602fabSXin LI /* idle_timeout */
2039ee67461eSJoseph Mingrone if (GET_BE_U_2(cp))
2040ee67461eSJoseph Mingrone ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp));
20413c602fabSXin LI cp += 2;
20423c602fabSXin LI /* pad2 */
20433c602fabSXin LI cp += 2;
20443c602fabSXin LI /* packet_count */
2045ee67461eSJoseph Mingrone ND_PRINT(", packet_count %" PRIu64, GET_BE_U_8(cp));
20463c602fabSXin LI cp += 8;
20473c602fabSXin LI /* byte_count */
2048ee67461eSJoseph Mingrone ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp));
2049ee67461eSJoseph Mingrone }
20503c602fabSXin LI
2051ee67461eSJoseph Mingrone /* [OF10] Section 5.4.3 */
2052ee67461eSJoseph Mingrone static void
of10_port_status_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)2053ee67461eSJoseph Mingrone of10_port_status_print(netdissect_options *ndo,
2054ee67461eSJoseph Mingrone const u_char *cp, u_int len _U_)
2055ee67461eSJoseph Mingrone {
2056ee67461eSJoseph Mingrone /* reason */
2057ee67461eSJoseph Mingrone ND_PRINT("\n\t reason %s",
2058ee67461eSJoseph Mingrone tok2str(ofppr_str, "invalid (0x%02x)", GET_U_1(cp)));
2059ee67461eSJoseph Mingrone cp += 1;
2060ee67461eSJoseph Mingrone /* pad */
2061ee67461eSJoseph Mingrone /* No need to check bounds, more data follows. */
2062ee67461eSJoseph Mingrone cp += 7;
2063ee67461eSJoseph Mingrone /* desc */
2064ee67461eSJoseph Mingrone of10_phy_port_print(ndo, cp);
20653c602fabSXin LI }
20663c602fabSXin LI
20673c602fabSXin LI /* [OF10] Section 5.4.4 */
2068ee67461eSJoseph Mingrone static void
of10_error_print(netdissect_options * ndo,const u_char * cp,u_int len)20693c602fabSXin LI of10_error_print(netdissect_options *ndo,
2070ee67461eSJoseph Mingrone const u_char *cp, u_int len)
20718bdc5a62SPatrick Kelsey {
2072ee67461eSJoseph Mingrone uint16_t type, code;
20733c602fabSXin LI const struct tok *code_str;
20743c602fabSXin LI
20753c602fabSXin LI /* type */
2076ee67461eSJoseph Mingrone type = GET_BE_U_2(cp);
2077ee67461eSJoseph Mingrone OF_FWD(2);
2078ee67461eSJoseph Mingrone ND_PRINT("\n\t type %s", tok2str(ofpet_str, "invalid (0x%04x)", type));
20793c602fabSXin LI /* code */
2080ee67461eSJoseph Mingrone code = GET_BE_U_2(cp);
2081ee67461eSJoseph Mingrone OF_FWD(2);
2082ee67461eSJoseph Mingrone code_str = uint2tokary(of10_ofpet2tokary, type);
2083ee67461eSJoseph Mingrone if (code_str != NULL)
2084ee67461eSJoseph Mingrone ND_PRINT(", code %s",
2085ee67461eSJoseph Mingrone tok2str(code_str, "invalid (0x%04x)", code));
2086ee67461eSJoseph Mingrone else
2087ee67461eSJoseph Mingrone ND_PRINT(", code invalid (0x%04x)", code);
20883c602fabSXin LI /* data */
2089ee67461eSJoseph Mingrone of_data_print(ndo, cp, len);
20903c602fabSXin LI }
20913c602fabSXin LI
2092ee67461eSJoseph Mingrone static const struct of_msgtypeinfo of10_msgtypeinfo[OFPT_MAX + 1] = {
2093ee67461eSJoseph Mingrone /*
2094ee67461eSJoseph Mingrone * [OF10] Section 5.5.1
2095ee67461eSJoseph Mingrone * Variable-size data.
2096ee67461eSJoseph Mingrone */
20978bdc5a62SPatrick Kelsey {
2098ee67461eSJoseph Mingrone "HELLO", of_data_print,
2099ee67461eSJoseph Mingrone REQ_MINLEN, 0
2100ee67461eSJoseph Mingrone },
2101ee67461eSJoseph Mingrone /*
2102ee67461eSJoseph Mingrone * [OF10] Section 5.4.4
2103ee67461eSJoseph Mingrone * A fixed-size message body and variable-size data.
2104ee67461eSJoseph Mingrone */
2105ee67461eSJoseph Mingrone {
2106ee67461eSJoseph Mingrone "ERROR", of10_error_print,
2107ee67461eSJoseph Mingrone REQ_MINLEN, OF_ERROR_MSG_MINLEN
2108ee67461eSJoseph Mingrone },
2109ee67461eSJoseph Mingrone /*
2110ee67461eSJoseph Mingrone * [OF10] Section 5.5.2
2111ee67461eSJoseph Mingrone * Variable-size data.
2112ee67461eSJoseph Mingrone */
2113ee67461eSJoseph Mingrone {
2114ee67461eSJoseph Mingrone "ECHO_REQUEST", of_data_print,
2115ee67461eSJoseph Mingrone REQ_MINLEN, 0
2116ee67461eSJoseph Mingrone },
2117ee67461eSJoseph Mingrone /*
2118ee67461eSJoseph Mingrone * [OF10] Section 5.5.3
2119ee67461eSJoseph Mingrone * Variable-size data.
2120ee67461eSJoseph Mingrone */
2121ee67461eSJoseph Mingrone {
2122ee67461eSJoseph Mingrone "ECHO_REPLY", of_data_print,
2123ee67461eSJoseph Mingrone REQ_MINLEN, 0
2124ee67461eSJoseph Mingrone },
2125ee67461eSJoseph Mingrone /*
2126ee67461eSJoseph Mingrone * [OF10] Section 5.5.4
2127ee67461eSJoseph Mingrone * A fixed-size message body and variable-size data.
2128ee67461eSJoseph Mingrone */
2129ee67461eSJoseph Mingrone {
2130ee67461eSJoseph Mingrone "VENDOR", of10_vendor_message_print,
2131ee67461eSJoseph Mingrone REQ_MINLEN, OF_VENDOR_MINLEN
2132ee67461eSJoseph Mingrone },
2133ee67461eSJoseph Mingrone /*
2134ee67461eSJoseph Mingrone * [OF10] Section 5.3.1
2135ee67461eSJoseph Mingrone * No message body.
2136ee67461eSJoseph Mingrone */
2137ee67461eSJoseph Mingrone {
2138ee67461eSJoseph Mingrone "FEATURES_REQUEST", NULL,
2139ee67461eSJoseph Mingrone REQ_FIXLEN, 0
2140ee67461eSJoseph Mingrone },
2141ee67461eSJoseph Mingrone /*
2142ee67461eSJoseph Mingrone * [OF10] Section 5.3.1
2143ee67461eSJoseph Mingrone * A fixed-size message body and n * fixed-size data units.
2144ee67461eSJoseph Mingrone */
2145ee67461eSJoseph Mingrone {
2146ee67461eSJoseph Mingrone "FEATURES_REPLY", of10_features_reply_print,
2147ee67461eSJoseph Mingrone REQ_MINLEN, OF_FEATURES_REPLY_MINLEN
2148ee67461eSJoseph Mingrone },
2149ee67461eSJoseph Mingrone /*
2150ee67461eSJoseph Mingrone * [OF10] Section 5.3.2
2151ee67461eSJoseph Mingrone * No message body.
2152ee67461eSJoseph Mingrone */
2153ee67461eSJoseph Mingrone {
2154ee67461eSJoseph Mingrone "GET_CONFIG_REQUEST", NULL,
2155ee67461eSJoseph Mingrone REQ_FIXLEN, 0
2156ee67461eSJoseph Mingrone },
2157ee67461eSJoseph Mingrone /*
2158ee67461eSJoseph Mingrone * [OF10] Section 5.3.2
2159ee67461eSJoseph Mingrone * A fixed-size message body.
2160ee67461eSJoseph Mingrone */
2161ee67461eSJoseph Mingrone {
2162ee67461eSJoseph Mingrone "GET_CONFIG_REPLY", of10_switch_config_msg_print,
2163ee67461eSJoseph Mingrone REQ_FIXLEN, OF_SWITCH_CONFIG_FIXLEN
2164ee67461eSJoseph Mingrone },
2165ee67461eSJoseph Mingrone /*
2166ee67461eSJoseph Mingrone * [OF10] Section 5.3.2
2167ee67461eSJoseph Mingrone * A fixed-size message body.
2168ee67461eSJoseph Mingrone */
2169ee67461eSJoseph Mingrone {
2170ee67461eSJoseph Mingrone "SET_CONFIG", of10_switch_config_msg_print,
2171ee67461eSJoseph Mingrone REQ_FIXLEN, OF_SWITCH_CONFIG_FIXLEN
2172ee67461eSJoseph Mingrone },
2173ee67461eSJoseph Mingrone /*
2174ee67461eSJoseph Mingrone * [OF10] Section 5.4.1
2175ee67461eSJoseph Mingrone * A fixed-size message body and variable-size data.
2176ee67461eSJoseph Mingrone * (The 2 mock octets count in OF_PACKET_IN_MINLEN only.)
2177ee67461eSJoseph Mingrone */
2178ee67461eSJoseph Mingrone {
2179ee67461eSJoseph Mingrone "PACKET_IN", of10_packet_in_print,
2180ee67461eSJoseph Mingrone REQ_MINLEN, OF_PACKET_IN_MINLEN - 2
2181ee67461eSJoseph Mingrone },
2182ee67461eSJoseph Mingrone /*
2183ee67461eSJoseph Mingrone * [OF10] Section 5.4.2
2184ee67461eSJoseph Mingrone * A fixed-size message body.
2185ee67461eSJoseph Mingrone */
2186ee67461eSJoseph Mingrone {
2187ee67461eSJoseph Mingrone "FLOW_REMOVED", of10_flow_removed_print,
2188ee67461eSJoseph Mingrone REQ_FIXLEN, OF_FLOW_REMOVED_FIXLEN
2189ee67461eSJoseph Mingrone },
2190ee67461eSJoseph Mingrone /*
2191ee67461eSJoseph Mingrone * [OF10] Section 5.4.3
2192ee67461eSJoseph Mingrone * A fixed-size message body.
2193ee67461eSJoseph Mingrone */
2194ee67461eSJoseph Mingrone {
2195ee67461eSJoseph Mingrone "PORT_STATUS", of10_port_status_print,
2196ee67461eSJoseph Mingrone REQ_FIXLEN, OF_PORT_STATUS_FIXLEN
2197ee67461eSJoseph Mingrone },
2198ee67461eSJoseph Mingrone /*
2199ee67461eSJoseph Mingrone * [OF10] Section 5.3.6
2200ee67461eSJoseph Mingrone * A fixed-size message body, n * variable-size data units and
2201ee67461eSJoseph Mingrone * variable-size data.
2202ee67461eSJoseph Mingrone */
2203ee67461eSJoseph Mingrone {
2204ee67461eSJoseph Mingrone "PACKET_OUT", of10_packet_out_print,
2205ee67461eSJoseph Mingrone REQ_MINLEN, OF_PACKET_OUT_MINLEN
2206ee67461eSJoseph Mingrone },
2207ee67461eSJoseph Mingrone /*
2208ee67461eSJoseph Mingrone * [OF10] Section 5.3.3
2209ee67461eSJoseph Mingrone * A fixed-size message body and n * variable-size data units.
2210ee67461eSJoseph Mingrone */
2211ee67461eSJoseph Mingrone {
2212ee67461eSJoseph Mingrone "FLOW_MOD", of10_flow_mod_print,
2213ee67461eSJoseph Mingrone REQ_MINLEN, OF_FLOW_MOD_MINLEN
2214ee67461eSJoseph Mingrone },
2215ee67461eSJoseph Mingrone /*
2216ee67461eSJoseph Mingrone * [OF10] Section 5.3.3
2217ee67461eSJoseph Mingrone * A fixed-size message body.
2218ee67461eSJoseph Mingrone */
2219ee67461eSJoseph Mingrone {
2220ee67461eSJoseph Mingrone "PORT_MOD", of10_port_mod_print,
2221ee67461eSJoseph Mingrone REQ_FIXLEN, OF_PORT_MOD_FIXLEN
2222ee67461eSJoseph Mingrone },
2223ee67461eSJoseph Mingrone /*
2224ee67461eSJoseph Mingrone * [OF10] Section 5.3.5
2225ee67461eSJoseph Mingrone * A fixed-size message body and possibly more data of varying size
2226ee67461eSJoseph Mingrone * and structure.
2227ee67461eSJoseph Mingrone */
2228ee67461eSJoseph Mingrone {
2229ee67461eSJoseph Mingrone "STATS_REQUEST", of10_stats_request_print,
2230ee67461eSJoseph Mingrone REQ_MINLEN, OF_STATS_REQUEST_MINLEN
2231ee67461eSJoseph Mingrone },
2232ee67461eSJoseph Mingrone /*
2233ee67461eSJoseph Mingrone * [OF10] Section 5.3.5
2234ee67461eSJoseph Mingrone * A fixed-size message body and possibly more data of varying size
2235ee67461eSJoseph Mingrone * and structure.
2236ee67461eSJoseph Mingrone */
2237ee67461eSJoseph Mingrone {
2238ee67461eSJoseph Mingrone "STATS_REPLY", of10_stats_reply_print,
2239ee67461eSJoseph Mingrone REQ_MINLEN, OF_STATS_REPLY_MINLEN
2240ee67461eSJoseph Mingrone },
2241ee67461eSJoseph Mingrone /*
2242ee67461eSJoseph Mingrone * [OF10] Section 5.3.7
2243ee67461eSJoseph Mingrone * No message body.
2244ee67461eSJoseph Mingrone */
2245ee67461eSJoseph Mingrone {
2246ee67461eSJoseph Mingrone "BARRIER_REQUEST", NULL,
2247ee67461eSJoseph Mingrone REQ_FIXLEN, 0
2248ee67461eSJoseph Mingrone },
2249ee67461eSJoseph Mingrone /*
2250ee67461eSJoseph Mingrone * [OF10] Section 5.3.7
2251ee67461eSJoseph Mingrone * No message body.
2252ee67461eSJoseph Mingrone */
2253ee67461eSJoseph Mingrone {
2254ee67461eSJoseph Mingrone "BARRIER_REPLY", NULL,
2255ee67461eSJoseph Mingrone REQ_FIXLEN, 0
2256ee67461eSJoseph Mingrone },
2257ee67461eSJoseph Mingrone /*
2258ee67461eSJoseph Mingrone * [OF10] Section 5.3.4
2259ee67461eSJoseph Mingrone * A fixed-size message body.
2260ee67461eSJoseph Mingrone */
2261ee67461eSJoseph Mingrone {
2262ee67461eSJoseph Mingrone "QUEUE_GET_CONFIG_REQUEST", of10_queue_get_config_request_print,
2263ee67461eSJoseph Mingrone REQ_FIXLEN, OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN
2264ee67461eSJoseph Mingrone },
2265ee67461eSJoseph Mingrone /*
2266ee67461eSJoseph Mingrone * [OF10] Section 5.3.4
2267ee67461eSJoseph Mingrone * A fixed-size message body and n * variable-size data units.
2268ee67461eSJoseph Mingrone */
2269ee67461eSJoseph Mingrone {
2270ee67461eSJoseph Mingrone "QUEUE_GET_CONFIG_REPLY", of10_queue_get_config_reply_print,
2271ee67461eSJoseph Mingrone REQ_MINLEN, OF_QUEUE_GET_CONFIG_REPLY_MINLEN
2272ee67461eSJoseph Mingrone },
2273ee67461eSJoseph Mingrone };
22743c602fabSXin LI
2275ee67461eSJoseph Mingrone const struct of_msgtypeinfo *
of10_identify_msgtype(const uint8_t type)2276ee67461eSJoseph Mingrone of10_identify_msgtype(const uint8_t type)
2277ee67461eSJoseph Mingrone {
2278ee67461eSJoseph Mingrone return type <= OFPT_MAX ? &of10_msgtypeinfo[type] : NULL;
22793c602fabSXin LI }
2280