1411677aeSAaron LI /*
2411677aeSAaron LI * This module implements decoding of OpenFlow protocol version 1.0 (wire
3411677aeSAaron LI * protocol 0x01). The decoder implements terse (default), detailed (-v) and
4411677aeSAaron LI * full (-vv) output formats and, as much as each format implies, detects and
5411677aeSAaron LI * tries to work around sizing anomalies inside the messages. The decoder marks
6411677aeSAaron LI * up bogus values of selected message fields and decodes partially captured
7411677aeSAaron LI * messages up to the snapshot end. It is based on the specification below:
8411677aeSAaron LI *
9*ed775ee7SAntonio Huete Jimenez * [OF10] https://www.opennetworking.org/wp-content/uploads/2013/04/openflow-spec-v1.0.0.pdf
10411677aeSAaron LI *
11*ed775ee7SAntonio Huete Jimenez * Most functions in this file take the following arguments:
12411677aeSAaron LI * * cp -- the pointer to the first octet to decode
13*ed775ee7SAntonio Huete Jimenez * * len -- the declared length of the structure to decode
14*ed775ee7SAntonio Huete Jimenez * The convention is that a printer function returns iff the given structure is
15*ed775ee7SAntonio Huete Jimenez * completely within the packet buffer; otherwise it processes the part that is
16*ed775ee7SAntonio Huete Jimenez * within the buffer, sooner of later takes the "truncated packet" shortcut via
17*ed775ee7SAntonio Huete Jimenez * longjmp() and never returns. With that in mind, the function may return
18*ed775ee7SAntonio Huete Jimenez * without printing the structure completely if it is invalid or the ndo_vflag
19*ed775ee7SAntonio Huete Jimenez * value is not high enough. This way the calling function can try to decode
20*ed775ee7SAntonio Huete Jimenez * the next data item.
21411677aeSAaron LI *
22411677aeSAaron LI * Decoding of Ethernet frames nested in OFPT_PACKET_IN and OFPT_PACKET_OUT
23411677aeSAaron LI * messages is done only when the verbosity level set by command-line argument
24411677aeSAaron LI * is "-vvv" or higher. In that case the verbosity level is temporarily
25411677aeSAaron LI * decremented by 3 during the nested frame decoding. For example, running
26411677aeSAaron LI * tcpdump with "-vvvv" will do full decoding of OpenFlow and "-v" decoding of
27411677aeSAaron LI * the nested frames.
28411677aeSAaron LI *
29411677aeSAaron LI * Partial decoding of Big Switch Networks vendor extensions is done after the
30411677aeSAaron LI * oftest (OpenFlow Testing Framework) and Loxigen (library generator) source
31411677aeSAaron LI * code.
32411677aeSAaron LI *
33411677aeSAaron LI *
34411677aeSAaron LI * Copyright (c) 2013 The TCPDUMP project
35411677aeSAaron LI * All rights reserved.
36411677aeSAaron LI *
37411677aeSAaron LI * Redistribution and use in source and binary forms, with or without
38411677aeSAaron LI * modification, are permitted provided that the following conditions
39411677aeSAaron LI * are met:
40411677aeSAaron LI * 1. Redistributions of source code must retain the above copyright
41411677aeSAaron LI * notice, this list of conditions and the following disclaimer.
42411677aeSAaron LI * 2. Redistributions in binary form must reproduce the above copyright
43411677aeSAaron LI * notice, this list of conditions and the following disclaimer in the
44411677aeSAaron LI * documentation and/or other materials provided with the distribution.
45411677aeSAaron LI *
46411677aeSAaron LI * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
47411677aeSAaron LI * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
48411677aeSAaron LI * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
49411677aeSAaron LI * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
50411677aeSAaron LI * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
51411677aeSAaron LI * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
52411677aeSAaron LI * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53411677aeSAaron LI * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
54411677aeSAaron LI * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55411677aeSAaron LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
56411677aeSAaron LI * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57411677aeSAaron LI * POSSIBILITY OF SUCH DAMAGE.
58411677aeSAaron LI */
59411677aeSAaron LI
60411677aeSAaron LI /* \summary: OpenFlow protocol version 1.0 printer */
61411677aeSAaron LI
62411677aeSAaron LI #ifdef HAVE_CONFIG_H
63*ed775ee7SAntonio Huete Jimenez #include <config.h>
64411677aeSAaron LI #endif
65411677aeSAaron LI
66*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
67411677aeSAaron LI
68*ed775ee7SAntonio Huete Jimenez #define ND_LONGJMP_FROM_TCHECK
69411677aeSAaron LI #include "netdissect.h"
70411677aeSAaron LI #include "extract.h"
71411677aeSAaron LI #include "addrtoname.h"
72411677aeSAaron LI #include "ethertype.h"
73411677aeSAaron LI #include "ipproto.h"
74411677aeSAaron LI #include "oui.h"
75411677aeSAaron LI #include "openflow.h"
76411677aeSAaron LI
77411677aeSAaron LI
78411677aeSAaron LI #define OFPT_HELLO 0x00
79411677aeSAaron LI #define OFPT_ERROR 0x01
80411677aeSAaron LI #define OFPT_ECHO_REQUEST 0x02
81411677aeSAaron LI #define OFPT_ECHO_REPLY 0x03
82411677aeSAaron LI #define OFPT_VENDOR 0x04
83411677aeSAaron LI #define OFPT_FEATURES_REQUEST 0x05
84411677aeSAaron LI #define OFPT_FEATURES_REPLY 0x06
85411677aeSAaron LI #define OFPT_GET_CONFIG_REQUEST 0x07
86411677aeSAaron LI #define OFPT_GET_CONFIG_REPLY 0x08
87411677aeSAaron LI #define OFPT_SET_CONFIG 0x09
88411677aeSAaron LI #define OFPT_PACKET_IN 0x0a
89411677aeSAaron LI #define OFPT_FLOW_REMOVED 0x0b
90411677aeSAaron LI #define OFPT_PORT_STATUS 0x0c
91411677aeSAaron LI #define OFPT_PACKET_OUT 0x0d
92411677aeSAaron LI #define OFPT_FLOW_MOD 0x0e
93411677aeSAaron LI #define OFPT_PORT_MOD 0x0f
94411677aeSAaron LI #define OFPT_STATS_REQUEST 0x10
95411677aeSAaron LI #define OFPT_STATS_REPLY 0x11
96411677aeSAaron LI #define OFPT_BARRIER_REQUEST 0x12
97411677aeSAaron LI #define OFPT_BARRIER_REPLY 0x13
98411677aeSAaron LI #define OFPT_QUEUE_GET_CONFIG_REQUEST 0x14
99411677aeSAaron LI #define OFPT_QUEUE_GET_CONFIG_REPLY 0x15
100*ed775ee7SAntonio Huete Jimenez #define OFPT_MAX OFPT_QUEUE_GET_CONFIG_REPLY
101411677aeSAaron LI
102*ed775ee7SAntonio Huete Jimenez #define OFPPC_PORT_DOWN (1U <<0)
103*ed775ee7SAntonio Huete Jimenez #define OFPPC_NO_STP (1U <<1)
104*ed775ee7SAntonio Huete Jimenez #define OFPPC_NO_RECV (1U <<2)
105*ed775ee7SAntonio Huete Jimenez #define OFPPC_NO_RECV_STP (1U <<3)
106*ed775ee7SAntonio Huete Jimenez #define OFPPC_NO_FLOOD (1U <<4)
107*ed775ee7SAntonio Huete Jimenez #define OFPPC_NO_FWD (1U <<5)
108*ed775ee7SAntonio Huete Jimenez #define OFPPC_NO_PACKET_IN (1U <<6)
109411677aeSAaron LI static const struct tok ofppc_bm[] = {
110411677aeSAaron LI { OFPPC_PORT_DOWN, "PORT_DOWN" },
111411677aeSAaron LI { OFPPC_NO_STP, "NO_STP" },
112411677aeSAaron LI { OFPPC_NO_RECV, "NO_RECV" },
113411677aeSAaron LI { OFPPC_NO_RECV_STP, "NO_RECV_STP" },
114411677aeSAaron LI { OFPPC_NO_FLOOD, "NO_FLOOD" },
115411677aeSAaron LI { OFPPC_NO_FWD, "NO_FWD" },
116411677aeSAaron LI { OFPPC_NO_PACKET_IN, "NO_PACKET_IN" },
117411677aeSAaron LI { 0, NULL }
118411677aeSAaron LI };
119411677aeSAaron LI #define OFPPC_U (~(OFPPC_PORT_DOWN | OFPPC_NO_STP | OFPPC_NO_RECV | \
120411677aeSAaron LI OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD | \
121411677aeSAaron LI OFPPC_NO_PACKET_IN))
122411677aeSAaron LI
123*ed775ee7SAntonio Huete Jimenez /*
124*ed775ee7SAntonio Huete Jimenez * [OF10] lists all FPPS_ constants in one enum, but they mean a 1-bit bitmap
125*ed775ee7SAntonio Huete Jimenez * in the least significant octet and a 2-bit code point in the next octet.
126*ed775ee7SAntonio Huete Jimenez * Remember to mix or to separate these two parts as the context requires.
127*ed775ee7SAntonio Huete Jimenez */
128*ed775ee7SAntonio Huete Jimenez #define OFPPS_LINK_DOWN (1U << 0) /* bitmap */
129*ed775ee7SAntonio Huete Jimenez #define OFPPS_STP_LISTEN (0U << 8) /* code point */
130*ed775ee7SAntonio Huete Jimenez #define OFPPS_STP_LEARN (1U << 8) /* code point */
131*ed775ee7SAntonio Huete Jimenez #define OFPPS_STP_FORWARD (2U << 8) /* code point */
132*ed775ee7SAntonio Huete Jimenez #define OFPPS_STP_BLOCK (3U << 8) /* code point */
133*ed775ee7SAntonio Huete Jimenez #define OFPPS_STP_MASK (3U << 8) /* code point bitmask */
134*ed775ee7SAntonio Huete Jimenez static const struct tok ofpps_stp_str[] = {
135411677aeSAaron LI { OFPPS_STP_LISTEN, "STP_LISTEN" },
136411677aeSAaron LI { OFPPS_STP_LEARN, "STP_LEARN" },
137411677aeSAaron LI { OFPPS_STP_FORWARD, "STP_FORWARD" },
138411677aeSAaron LI { OFPPS_STP_BLOCK, "STP_BLOCK" },
139411677aeSAaron LI { 0, NULL }
140411677aeSAaron LI };
141411677aeSAaron LI #define OFPPS_U (~(OFPPS_LINK_DOWN | OFPPS_STP_LISTEN | OFPPS_STP_LEARN | \
142411677aeSAaron LI OFPPS_STP_FORWARD | OFPPS_STP_BLOCK))
143411677aeSAaron LI
144*ed775ee7SAntonio Huete Jimenez #define OFPP_MAX 0xff00U
145*ed775ee7SAntonio Huete Jimenez #define OFPP_IN_PORT 0xfff8U
146*ed775ee7SAntonio Huete Jimenez #define OFPP_TABLE 0xfff9U
147*ed775ee7SAntonio Huete Jimenez #define OFPP_NORMAL 0xfffaU
148*ed775ee7SAntonio Huete Jimenez #define OFPP_FLOOD 0xfffbU
149*ed775ee7SAntonio Huete Jimenez #define OFPP_ALL 0xfffcU
150*ed775ee7SAntonio Huete Jimenez #define OFPP_CONTROLLER 0xfffdU
151*ed775ee7SAntonio Huete Jimenez #define OFPP_LOCAL 0xfffeU
152*ed775ee7SAntonio Huete Jimenez #define OFPP_NONE 0xffffU
153411677aeSAaron LI static const struct tok ofpp_str[] = {
154411677aeSAaron LI { OFPP_MAX, "MAX" },
155411677aeSAaron LI { OFPP_IN_PORT, "IN_PORT" },
156411677aeSAaron LI { OFPP_TABLE, "TABLE" },
157411677aeSAaron LI { OFPP_NORMAL, "NORMAL" },
158411677aeSAaron LI { OFPP_FLOOD, "FLOOD" },
159411677aeSAaron LI { OFPP_ALL, "ALL" },
160411677aeSAaron LI { OFPP_CONTROLLER, "CONTROLLER" },
161411677aeSAaron LI { OFPP_LOCAL, "LOCAL" },
162411677aeSAaron LI { OFPP_NONE, "NONE" },
163411677aeSAaron LI { 0, NULL }
164411677aeSAaron LI };
165411677aeSAaron LI
166*ed775ee7SAntonio Huete Jimenez #define OFPPF_10MB_HD (1U << 0)
167*ed775ee7SAntonio Huete Jimenez #define OFPPF_10MB_FD (1U << 1)
168*ed775ee7SAntonio Huete Jimenez #define OFPPF_100MB_HD (1U << 2)
169*ed775ee7SAntonio Huete Jimenez #define OFPPF_100MB_FD (1U << 3)
170*ed775ee7SAntonio Huete Jimenez #define OFPPF_1GB_HD (1U << 4)
171*ed775ee7SAntonio Huete Jimenez #define OFPPF_1GB_FD (1U << 5)
172*ed775ee7SAntonio Huete Jimenez #define OFPPF_10GB_FD (1U << 6)
173*ed775ee7SAntonio Huete Jimenez #define OFPPF_COPPER (1U << 7)
174*ed775ee7SAntonio Huete Jimenez #define OFPPF_FIBER (1U << 8)
175*ed775ee7SAntonio Huete Jimenez #define OFPPF_AUTONEG (1U << 9)
176*ed775ee7SAntonio Huete Jimenez #define OFPPF_PAUSE (1U <<10)
177*ed775ee7SAntonio Huete Jimenez #define OFPPF_PAUSE_ASYM (1U <<11)
178411677aeSAaron LI static const struct tok ofppf_bm[] = {
179411677aeSAaron LI { OFPPF_10MB_HD, "10MB_HD" },
180411677aeSAaron LI { OFPPF_10MB_FD, "10MB_FD" },
181411677aeSAaron LI { OFPPF_100MB_HD, "100MB_HD" },
182411677aeSAaron LI { OFPPF_100MB_FD, "100MB_FD" },
183411677aeSAaron LI { OFPPF_1GB_HD, "1GB_HD" },
184411677aeSAaron LI { OFPPF_1GB_FD, "1GB_FD" },
185411677aeSAaron LI { OFPPF_10GB_FD, "10GB_FD" },
186411677aeSAaron LI { OFPPF_COPPER, "COPPER" },
187411677aeSAaron LI { OFPPF_FIBER, "FIBER" },
188411677aeSAaron LI { OFPPF_AUTONEG, "AUTONEG" },
189411677aeSAaron LI { OFPPF_PAUSE, "PAUSE" },
190411677aeSAaron LI { OFPPF_PAUSE_ASYM, "PAUSE_ASYM" },
191411677aeSAaron LI { 0, NULL }
192411677aeSAaron LI };
193411677aeSAaron LI #define OFPPF_U (~(OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | \
194411677aeSAaron LI OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | \
195411677aeSAaron LI OFPPF_10GB_FD | OFPPF_COPPER | OFPPF_FIBER | \
196411677aeSAaron LI OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM))
197411677aeSAaron LI
198411677aeSAaron LI #define OFPQT_NONE 0x0000
199411677aeSAaron LI #define OFPQT_MIN_RATE 0x0001
200411677aeSAaron LI static const struct tok ofpqt_str[] = {
201411677aeSAaron LI { OFPQT_NONE, "NONE" },
202411677aeSAaron LI { OFPQT_MIN_RATE, "MIN_RATE" },
203411677aeSAaron LI { 0, NULL }
204411677aeSAaron LI };
205411677aeSAaron LI
206*ed775ee7SAntonio Huete Jimenez #define OFPFW_IN_PORT (1U <<0)
207*ed775ee7SAntonio Huete Jimenez #define OFPFW_DL_VLAN (1U <<1)
208*ed775ee7SAntonio Huete Jimenez #define OFPFW_DL_SRC (1U <<2)
209*ed775ee7SAntonio Huete Jimenez #define OFPFW_DL_DST (1U <<3)
210*ed775ee7SAntonio Huete Jimenez #define OFPFW_DL_TYPE (1U <<4)
211*ed775ee7SAntonio Huete Jimenez #define OFPFW_NW_PROTO (1U <<5)
212*ed775ee7SAntonio Huete Jimenez #define OFPFW_TP_SRC (1U <<6)
213*ed775ee7SAntonio Huete Jimenez #define OFPFW_TP_DST (1U <<7)
214411677aeSAaron LI #define OFPFW_NW_SRC_SHIFT 8
215411677aeSAaron LI #define OFPFW_NW_SRC_BITS 6
216*ed775ee7SAntonio Huete Jimenez #define OFPFW_NW_SRC_MASK (((1U <<OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT)
217411677aeSAaron LI #define OFPFW_NW_DST_SHIFT 14
218411677aeSAaron LI #define OFPFW_NW_DST_BITS 6
219*ed775ee7SAntonio Huete Jimenez #define OFPFW_NW_DST_MASK (((1U <<OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT)
220*ed775ee7SAntonio Huete Jimenez #define OFPFW_DL_VLAN_PCP (1U <<20)
221*ed775ee7SAntonio Huete Jimenez #define OFPFW_NW_TOS (1U <<21)
222*ed775ee7SAntonio Huete Jimenez #define OFPFW_ALL ((1U <<22) - 1)
223411677aeSAaron LI static const struct tok ofpfw_bm[] = {
224411677aeSAaron LI { OFPFW_IN_PORT, "IN_PORT" },
225411677aeSAaron LI { OFPFW_DL_VLAN, "DL_VLAN" },
226411677aeSAaron LI { OFPFW_DL_SRC, "DL_SRC" },
227411677aeSAaron LI { OFPFW_DL_DST, "DL_DST" },
228411677aeSAaron LI { OFPFW_DL_TYPE, "DL_TYPE" },
229411677aeSAaron LI { OFPFW_NW_PROTO, "NW_PROTO" },
230411677aeSAaron LI { OFPFW_TP_SRC, "TP_SRC" },
231411677aeSAaron LI { OFPFW_TP_DST, "TP_DST" },
232411677aeSAaron LI { OFPFW_DL_VLAN_PCP, "DL_VLAN_PCP" },
233411677aeSAaron LI { OFPFW_NW_TOS, "NW_TOS" },
234411677aeSAaron LI { 0, NULL }
235411677aeSAaron LI };
236411677aeSAaron LI /* The above array does not include bits 8~13 (OFPFW_NW_SRC_*) and 14~19
237411677aeSAaron LI * (OFPFW_NW_DST_*), which are not a part of the bitmap and require decoding
238411677aeSAaron LI * other than that of tok2str(). The macro below includes these bits such that
239411677aeSAaron LI * they are not reported as bogus in the decoding. */
240411677aeSAaron LI #define OFPFW_U (~(OFPFW_ALL))
241411677aeSAaron LI
242*ed775ee7SAntonio Huete Jimenez #define OFPAT_OUTPUT 0x0000U
243*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_VLAN_VID 0x0001U
244*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_VLAN_PCP 0x0002U
245*ed775ee7SAntonio Huete Jimenez #define OFPAT_STRIP_VLAN 0x0003U
246*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_DL_SRC 0x0004U
247*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_DL_DST 0x0005U
248*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_NW_SRC 0x0006U
249*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_NW_DST 0x0007U
250*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_NW_TOS 0x0008U
251*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_TP_SRC 0x0009U
252*ed775ee7SAntonio Huete Jimenez #define OFPAT_SET_TP_DST 0x000aU
253*ed775ee7SAntonio Huete Jimenez #define OFPAT_ENQUEUE 0x000bU
254*ed775ee7SAntonio Huete Jimenez #define OFPAT_VENDOR 0xffffU
255411677aeSAaron LI static const struct tok ofpat_str[] = {
256411677aeSAaron LI { OFPAT_OUTPUT, "OUTPUT" },
257411677aeSAaron LI { OFPAT_SET_VLAN_VID, "SET_VLAN_VID" },
258411677aeSAaron LI { OFPAT_SET_VLAN_PCP, "SET_VLAN_PCP" },
259411677aeSAaron LI { OFPAT_STRIP_VLAN, "STRIP_VLAN" },
260411677aeSAaron LI { OFPAT_SET_DL_SRC, "SET_DL_SRC" },
261411677aeSAaron LI { OFPAT_SET_DL_DST, "SET_DL_DST" },
262411677aeSAaron LI { OFPAT_SET_NW_SRC, "SET_NW_SRC" },
263411677aeSAaron LI { OFPAT_SET_NW_DST, "SET_NW_DST" },
264411677aeSAaron LI { OFPAT_SET_NW_TOS, "SET_NW_TOS" },
265411677aeSAaron LI { OFPAT_SET_TP_SRC, "SET_TP_SRC" },
266411677aeSAaron LI { OFPAT_SET_TP_DST, "SET_TP_DST" },
267411677aeSAaron LI { OFPAT_ENQUEUE, "ENQUEUE" },
268411677aeSAaron LI { OFPAT_VENDOR, "VENDOR" },
269411677aeSAaron LI { 0, NULL }
270411677aeSAaron LI };
271411677aeSAaron LI
272411677aeSAaron LI /* bit-shifted, w/o vendor action */
273411677aeSAaron LI static const struct tok ofpat_bm[] = {
274*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_OUTPUT, "OUTPUT" },
275*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_VLAN_VID, "SET_VLAN_VID" },
276*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_VLAN_PCP, "SET_VLAN_PCP" },
277*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_STRIP_VLAN, "STRIP_VLAN" },
278*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_DL_SRC, "SET_DL_SRC" },
279*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_DL_DST, "SET_DL_DST" },
280*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_NW_SRC, "SET_NW_SRC" },
281*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_NW_DST, "SET_NW_DST" },
282*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_NW_TOS, "SET_NW_TOS" },
283*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_TP_SRC, "SET_TP_SRC" },
284*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_SET_TP_DST, "SET_TP_DST" },
285*ed775ee7SAntonio Huete Jimenez { 1U <<OFPAT_ENQUEUE, "ENQUEUE" },
286411677aeSAaron LI { 0, NULL }
287411677aeSAaron LI };
288*ed775ee7SAntonio Huete Jimenez #define OFPAT_U (~(1U <<OFPAT_OUTPUT | 1U <<OFPAT_SET_VLAN_VID | \
289*ed775ee7SAntonio Huete Jimenez 1U <<OFPAT_SET_VLAN_PCP | 1U <<OFPAT_STRIP_VLAN | \
290*ed775ee7SAntonio Huete Jimenez 1U <<OFPAT_SET_DL_SRC | 1U <<OFPAT_SET_DL_DST | \
291*ed775ee7SAntonio Huete Jimenez 1U <<OFPAT_SET_NW_SRC | 1U <<OFPAT_SET_NW_DST | \
292*ed775ee7SAntonio Huete Jimenez 1U <<OFPAT_SET_NW_TOS | 1U <<OFPAT_SET_TP_SRC | \
293*ed775ee7SAntonio Huete Jimenez 1U <<OFPAT_SET_TP_DST | 1U <<OFPAT_ENQUEUE))
294411677aeSAaron LI
295*ed775ee7SAntonio Huete Jimenez #define OFPC_FLOW_STATS (1U <<0)
296*ed775ee7SAntonio Huete Jimenez #define OFPC_TABLE_STATS (1U <<1)
297*ed775ee7SAntonio Huete Jimenez #define OFPC_PORT_STATS (1U <<2)
298*ed775ee7SAntonio Huete Jimenez #define OFPC_STP (1U <<3)
299*ed775ee7SAntonio Huete Jimenez #define OFPC_RESERVED (1U <<4)
300*ed775ee7SAntonio Huete Jimenez #define OFPC_IP_REASM (1U <<5)
301*ed775ee7SAntonio Huete Jimenez #define OFPC_QUEUE_STATS (1U <<6)
302*ed775ee7SAntonio Huete Jimenez #define OFPC_ARP_MATCH_IP (1U <<7)
303411677aeSAaron LI static const struct tok ofp_capabilities_bm[] = {
304411677aeSAaron LI { OFPC_FLOW_STATS, "FLOW_STATS" },
305411677aeSAaron LI { OFPC_TABLE_STATS, "TABLE_STATS" },
306411677aeSAaron LI { OFPC_PORT_STATS, "PORT_STATS" },
307411677aeSAaron LI { OFPC_STP, "STP" },
308411677aeSAaron LI { OFPC_RESERVED, "RESERVED" }, /* not in the mask below */
309411677aeSAaron LI { OFPC_IP_REASM, "IP_REASM" },
310411677aeSAaron LI { OFPC_QUEUE_STATS, "QUEUE_STATS" },
311411677aeSAaron LI { OFPC_ARP_MATCH_IP, "ARP_MATCH_IP" },
312411677aeSAaron LI { 0, NULL }
313411677aeSAaron LI };
314411677aeSAaron LI #define OFPCAP_U (~(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \
315411677aeSAaron LI OFPC_STP | OFPC_IP_REASM | OFPC_QUEUE_STATS | \
316411677aeSAaron LI OFPC_ARP_MATCH_IP))
317411677aeSAaron LI
318*ed775ee7SAntonio Huete Jimenez #define OFPC_FRAG_NORMAL 0x0000U
319*ed775ee7SAntonio Huete Jimenez #define OFPC_FRAG_DROP 0x0001U
320*ed775ee7SAntonio Huete Jimenez #define OFPC_FRAG_REASM 0x0002U
321*ed775ee7SAntonio Huete Jimenez #define OFPC_FRAG_MASK 0x0003U
322411677aeSAaron LI static const struct tok ofp_config_str[] = {
323411677aeSAaron LI { OFPC_FRAG_NORMAL, "FRAG_NORMAL" },
324411677aeSAaron LI { OFPC_FRAG_DROP, "FRAG_DROP" },
325411677aeSAaron LI { OFPC_FRAG_REASM, "FRAG_REASM" },
326411677aeSAaron LI { 0, NULL }
327411677aeSAaron LI };
328411677aeSAaron LI
329*ed775ee7SAntonio Huete Jimenez #define OFPFC_ADD 0x0000U
330*ed775ee7SAntonio Huete Jimenez #define OFPFC_MODIFY 0x0001U
331*ed775ee7SAntonio Huete Jimenez #define OFPFC_MODIFY_STRICT 0x0002U
332*ed775ee7SAntonio Huete Jimenez #define OFPFC_DELETE 0x0003U
333*ed775ee7SAntonio Huete Jimenez #define OFPFC_DELETE_STRICT 0x0004U
334411677aeSAaron LI static const struct tok ofpfc_str[] = {
335411677aeSAaron LI { OFPFC_ADD, "ADD" },
336411677aeSAaron LI { OFPFC_MODIFY, "MODIFY" },
337411677aeSAaron LI { OFPFC_MODIFY_STRICT, "MODIFY_STRICT" },
338411677aeSAaron LI { OFPFC_DELETE, "DELETE" },
339411677aeSAaron LI { OFPFC_DELETE_STRICT, "DELETE_STRICT" },
340411677aeSAaron LI { 0, NULL }
341411677aeSAaron LI };
342411677aeSAaron LI
343411677aeSAaron LI static const struct tok bufferid_str[] = {
344411677aeSAaron LI { 0xffffffff, "NONE" },
345411677aeSAaron LI { 0, NULL }
346411677aeSAaron LI };
347411677aeSAaron LI
348*ed775ee7SAntonio Huete Jimenez #define OFPFF_SEND_FLOW_REM (1U <<0)
349*ed775ee7SAntonio Huete Jimenez #define OFPFF_CHECK_OVERLAP (1U <<1)
350*ed775ee7SAntonio Huete Jimenez #define OFPFF_EMERG (1U <<2)
351411677aeSAaron LI static const struct tok ofpff_bm[] = {
352411677aeSAaron LI { OFPFF_SEND_FLOW_REM, "SEND_FLOW_REM" },
353411677aeSAaron LI { OFPFF_CHECK_OVERLAP, "CHECK_OVERLAP" },
354411677aeSAaron LI { OFPFF_EMERG, "EMERG" },
355411677aeSAaron LI { 0, NULL }
356411677aeSAaron LI };
357411677aeSAaron LI #define OFPFF_U (~(OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_EMERG))
358411677aeSAaron LI
359*ed775ee7SAntonio Huete Jimenez #define OFPST_DESC 0x0000U
360*ed775ee7SAntonio Huete Jimenez #define OFPST_FLOW 0x0001U
361*ed775ee7SAntonio Huete Jimenez #define OFPST_AGGREGATE 0x0002U
362*ed775ee7SAntonio Huete Jimenez #define OFPST_TABLE 0x0003U
363*ed775ee7SAntonio Huete Jimenez #define OFPST_PORT 0x0004U
364*ed775ee7SAntonio Huete Jimenez #define OFPST_QUEUE 0x0005U
365*ed775ee7SAntonio Huete Jimenez #define OFPST_VENDOR 0xffffU
366411677aeSAaron LI static const struct tok ofpst_str[] = {
367411677aeSAaron LI { OFPST_DESC, "DESC" },
368411677aeSAaron LI { OFPST_FLOW, "FLOW" },
369411677aeSAaron LI { OFPST_AGGREGATE, "AGGREGATE" },
370411677aeSAaron LI { OFPST_TABLE, "TABLE" },
371411677aeSAaron LI { OFPST_PORT, "PORT" },
372411677aeSAaron LI { OFPST_QUEUE, "QUEUE" },
373411677aeSAaron LI { OFPST_VENDOR, "VENDOR" },
374411677aeSAaron LI { 0, NULL }
375411677aeSAaron LI };
376411677aeSAaron LI
377411677aeSAaron LI static const struct tok tableid_str[] = {
378*ed775ee7SAntonio Huete Jimenez { 0xfeU, "EMERG" },
379*ed775ee7SAntonio Huete Jimenez { 0xffU, "ALL" },
380411677aeSAaron LI { 0, NULL }
381411677aeSAaron LI };
382411677aeSAaron LI
383*ed775ee7SAntonio Huete Jimenez #define OFPQ_ALL 0xffffffffU
384411677aeSAaron LI static const struct tok ofpq_str[] = {
385411677aeSAaron LI { OFPQ_ALL, "ALL" },
386411677aeSAaron LI { 0, NULL }
387411677aeSAaron LI };
388411677aeSAaron LI
389*ed775ee7SAntonio Huete Jimenez #define OFPSF_REPLY_MORE 0x0001U
390411677aeSAaron LI static const struct tok ofpsf_reply_bm[] = {
391411677aeSAaron LI { OFPSF_REPLY_MORE, "MORE" },
392411677aeSAaron LI { 0, NULL }
393411677aeSAaron LI };
394411677aeSAaron LI #define OFPSF_REPLY_U (~(OFPSF_REPLY_MORE))
395411677aeSAaron LI
396*ed775ee7SAntonio Huete Jimenez #define OFPR_NO_MATCH 0x00U
397*ed775ee7SAntonio Huete Jimenez #define OFPR_ACTION 0x01U
398411677aeSAaron LI static const struct tok ofpr_str[] = {
399411677aeSAaron LI { OFPR_NO_MATCH, "NO_MATCH" },
400411677aeSAaron LI { OFPR_ACTION, "ACTION" },
401411677aeSAaron LI { 0, NULL }
402411677aeSAaron LI };
403411677aeSAaron LI
404*ed775ee7SAntonio Huete Jimenez #define OFPRR_IDLE_TIMEOUT 0x00U
405*ed775ee7SAntonio Huete Jimenez #define OFPRR_HARD_TIMEOUT 0x01U
406*ed775ee7SAntonio Huete Jimenez #define OFPRR_DELETE 0x02U
407411677aeSAaron LI static const struct tok ofprr_str[] = {
408411677aeSAaron LI { OFPRR_IDLE_TIMEOUT, "IDLE_TIMEOUT" },
409411677aeSAaron LI { OFPRR_HARD_TIMEOUT, "HARD_TIMEOUT" },
410411677aeSAaron LI { OFPRR_DELETE, "DELETE" },
411411677aeSAaron LI { 0, NULL }
412411677aeSAaron LI };
413411677aeSAaron LI
414*ed775ee7SAntonio Huete Jimenez #define OFPPR_ADD 0x00U
415*ed775ee7SAntonio Huete Jimenez #define OFPPR_DELETE 0x01U
416*ed775ee7SAntonio Huete Jimenez #define OFPPR_MODIFY 0x02U
417411677aeSAaron LI static const struct tok ofppr_str[] = {
418411677aeSAaron LI { OFPPR_ADD, "ADD" },
419411677aeSAaron LI { OFPPR_DELETE, "DELETE" },
420411677aeSAaron LI { OFPPR_MODIFY, "MODIFY" },
421411677aeSAaron LI { 0, NULL }
422411677aeSAaron LI };
423411677aeSAaron LI
424*ed775ee7SAntonio Huete Jimenez #define OFPET_HELLO_FAILED 0x0000U
425*ed775ee7SAntonio Huete Jimenez #define OFPET_BAD_REQUEST 0x0001U
426*ed775ee7SAntonio Huete Jimenez #define OFPET_BAD_ACTION 0x0002U
427*ed775ee7SAntonio Huete Jimenez #define OFPET_FLOW_MOD_FAILED 0x0003U
428*ed775ee7SAntonio Huete Jimenez #define OFPET_PORT_MOD_FAILED 0x0004U
429*ed775ee7SAntonio Huete Jimenez #define OFPET_QUEUE_OP_FAILED 0x0005U
430411677aeSAaron LI static const struct tok ofpet_str[] = {
431411677aeSAaron LI { OFPET_HELLO_FAILED, "HELLO_FAILED" },
432411677aeSAaron LI { OFPET_BAD_REQUEST, "BAD_REQUEST" },
433411677aeSAaron LI { OFPET_BAD_ACTION, "BAD_ACTION" },
434411677aeSAaron LI { OFPET_FLOW_MOD_FAILED, "FLOW_MOD_FAILED" },
435411677aeSAaron LI { OFPET_PORT_MOD_FAILED, "PORT_MOD_FAILED" },
436411677aeSAaron LI { OFPET_QUEUE_OP_FAILED, "QUEUE_OP_FAILED" },
437411677aeSAaron LI { 0, NULL }
438411677aeSAaron LI };
439411677aeSAaron LI
440*ed775ee7SAntonio Huete Jimenez #define OFPHFC_INCOMPATIBLE 0x0000U
441*ed775ee7SAntonio Huete Jimenez #define OFPHFC_EPERM 0x0001U
442411677aeSAaron LI static const struct tok ofphfc_str[] = {
443411677aeSAaron LI { OFPHFC_INCOMPATIBLE, "INCOMPATIBLE" },
444411677aeSAaron LI { OFPHFC_EPERM, "EPERM" },
445411677aeSAaron LI { 0, NULL }
446411677aeSAaron LI };
447411677aeSAaron LI
448*ed775ee7SAntonio Huete Jimenez #define OFPBRC_BAD_VERSION 0x0000U
449*ed775ee7SAntonio Huete Jimenez #define OFPBRC_BAD_TYPE 0x0001U
450*ed775ee7SAntonio Huete Jimenez #define OFPBRC_BAD_STAT 0x0002U
451*ed775ee7SAntonio Huete Jimenez #define OFPBRC_BAD_VENDOR 0x0003U
452*ed775ee7SAntonio Huete Jimenez #define OFPBRC_BAD_SUBTYPE 0x0004U
453*ed775ee7SAntonio Huete Jimenez #define OFPBRC_EPERM 0x0005U
454*ed775ee7SAntonio Huete Jimenez #define OFPBRC_BAD_LEN 0x0006U
455*ed775ee7SAntonio Huete Jimenez #define OFPBRC_BUFFER_EMPTY 0x0007U
456*ed775ee7SAntonio Huete Jimenez #define OFPBRC_BUFFER_UNKNOWN 0x0008U
457411677aeSAaron LI static const struct tok ofpbrc_str[] = {
458411677aeSAaron LI { OFPBRC_BAD_VERSION, "BAD_VERSION" },
459411677aeSAaron LI { OFPBRC_BAD_TYPE, "BAD_TYPE" },
460411677aeSAaron LI { OFPBRC_BAD_STAT, "BAD_STAT" },
461411677aeSAaron LI { OFPBRC_BAD_VENDOR, "BAD_VENDOR" },
462411677aeSAaron LI { OFPBRC_BAD_SUBTYPE, "BAD_SUBTYPE" },
463411677aeSAaron LI { OFPBRC_EPERM, "EPERM" },
464411677aeSAaron LI { OFPBRC_BAD_LEN, "BAD_LEN" },
465411677aeSAaron LI { OFPBRC_BUFFER_EMPTY, "BUFFER_EMPTY" },
466411677aeSAaron LI { OFPBRC_BUFFER_UNKNOWN, "BUFFER_UNKNOWN" },
467411677aeSAaron LI { 0, NULL }
468411677aeSAaron LI };
469411677aeSAaron LI
470*ed775ee7SAntonio Huete Jimenez #define OFPBAC_BAD_TYPE 0x0000U
471*ed775ee7SAntonio Huete Jimenez #define OFPBAC_BAD_LEN 0x0001U
472*ed775ee7SAntonio Huete Jimenez #define OFPBAC_BAD_VENDOR 0x0002U
473*ed775ee7SAntonio Huete Jimenez #define OFPBAC_BAD_VENDOR_TYPE 0x0003U
474*ed775ee7SAntonio Huete Jimenez #define OFPBAC_BAD_OUT_PORT 0x0004U
475*ed775ee7SAntonio Huete Jimenez #define OFPBAC_BAD_ARGUMENT 0x0005U
476*ed775ee7SAntonio Huete Jimenez #define OFPBAC_EPERM 0x0006U
477*ed775ee7SAntonio Huete Jimenez #define OFPBAC_TOO_MANY 0x0007U
478*ed775ee7SAntonio Huete Jimenez #define OFPBAC_BAD_QUEUE 0x0008U
479411677aeSAaron LI static const struct tok ofpbac_str[] = {
480411677aeSAaron LI { OFPBAC_BAD_TYPE, "BAD_TYPE" },
481411677aeSAaron LI { OFPBAC_BAD_LEN, "BAD_LEN" },
482411677aeSAaron LI { OFPBAC_BAD_VENDOR, "BAD_VENDOR" },
483411677aeSAaron LI { OFPBAC_BAD_VENDOR_TYPE, "BAD_VENDOR_TYPE" },
484411677aeSAaron LI { OFPBAC_BAD_OUT_PORT, "BAD_OUT_PORT" },
485411677aeSAaron LI { OFPBAC_BAD_ARGUMENT, "BAD_ARGUMENT" },
486411677aeSAaron LI { OFPBAC_EPERM, "EPERM" },
487411677aeSAaron LI { OFPBAC_TOO_MANY, "TOO_MANY" },
488411677aeSAaron LI { OFPBAC_BAD_QUEUE, "BAD_QUEUE" },
489411677aeSAaron LI { 0, NULL }
490411677aeSAaron LI };
491411677aeSAaron LI
492*ed775ee7SAntonio Huete Jimenez #define OFPFMFC_ALL_TABLES_FULL 0x0000U
493*ed775ee7SAntonio Huete Jimenez #define OFPFMFC_OVERLAP 0x0001U
494*ed775ee7SAntonio Huete Jimenez #define OFPFMFC_EPERM 0x0002U
495*ed775ee7SAntonio Huete Jimenez #define OFPFMFC_BAD_EMERG_TIMEOUT 0x0003U
496*ed775ee7SAntonio Huete Jimenez #define OFPFMFC_BAD_COMMAND 0x0004U
497*ed775ee7SAntonio Huete Jimenez #define OFPFMFC_UNSUPPORTED 0x0005U
498411677aeSAaron LI static const struct tok ofpfmfc_str[] = {
499411677aeSAaron LI { OFPFMFC_ALL_TABLES_FULL, "ALL_TABLES_FULL" },
500411677aeSAaron LI { OFPFMFC_OVERLAP, "OVERLAP" },
501411677aeSAaron LI { OFPFMFC_EPERM, "EPERM" },
502411677aeSAaron LI { OFPFMFC_BAD_EMERG_TIMEOUT, "BAD_EMERG_TIMEOUT" },
503411677aeSAaron LI { OFPFMFC_BAD_COMMAND, "BAD_COMMAND" },
504411677aeSAaron LI { OFPFMFC_UNSUPPORTED, "UNSUPPORTED" },
505411677aeSAaron LI { 0, NULL }
506411677aeSAaron LI };
507411677aeSAaron LI
508*ed775ee7SAntonio Huete Jimenez #define OFPPMFC_BAD_PORT 0x0000U
509*ed775ee7SAntonio Huete Jimenez #define OFPPMFC_BAD_HW_ADDR 0x0001U
510411677aeSAaron LI static const struct tok ofppmfc_str[] = {
511411677aeSAaron LI { OFPPMFC_BAD_PORT, "BAD_PORT" },
512411677aeSAaron LI { OFPPMFC_BAD_HW_ADDR, "BAD_HW_ADDR" },
513411677aeSAaron LI { 0, NULL }
514411677aeSAaron LI };
515411677aeSAaron LI
516*ed775ee7SAntonio Huete Jimenez #define OFPQOFC_BAD_PORT 0x0000U
517*ed775ee7SAntonio Huete Jimenez #define OFPQOFC_BAD_QUEUE 0x0001U
518*ed775ee7SAntonio Huete Jimenez #define OFPQOFC_EPERM 0x0002U
519411677aeSAaron LI static const struct tok ofpqofc_str[] = {
520411677aeSAaron LI { OFPQOFC_BAD_PORT, "BAD_PORT" },
521411677aeSAaron LI { OFPQOFC_BAD_QUEUE, "BAD_QUEUE" },
522411677aeSAaron LI { OFPQOFC_EPERM, "EPERM" },
523411677aeSAaron LI { 0, NULL }
524411677aeSAaron LI };
525411677aeSAaron LI
526*ed775ee7SAntonio Huete Jimenez static const struct uint_tokary of10_ofpet2tokary[] = {
527*ed775ee7SAntonio Huete Jimenez { OFPET_HELLO_FAILED, ofphfc_str },
528*ed775ee7SAntonio Huete Jimenez { OFPET_BAD_REQUEST, ofpbrc_str },
529*ed775ee7SAntonio Huete Jimenez { OFPET_BAD_ACTION, ofpbac_str },
530*ed775ee7SAntonio Huete Jimenez { OFPET_FLOW_MOD_FAILED, ofpfmfc_str },
531*ed775ee7SAntonio Huete Jimenez { OFPET_PORT_MOD_FAILED, ofppmfc_str },
532*ed775ee7SAntonio Huete Jimenez { OFPET_QUEUE_OP_FAILED, ofpqofc_str },
533*ed775ee7SAntonio Huete Jimenez /* uint2tokary() does not use array termination. */
534411677aeSAaron LI };
535411677aeSAaron LI
536*ed775ee7SAntonio Huete Jimenez /* lengths (fixed or minimal) of particular message types, where not 0 */
537*ed775ee7SAntonio Huete Jimenez #define OF_SWITCH_CONFIG_FIXLEN (12U - OF_HEADER_FIXLEN)
538*ed775ee7SAntonio Huete Jimenez #define OF_FEATURES_REPLY_MINLEN (32U - OF_HEADER_FIXLEN)
539*ed775ee7SAntonio Huete Jimenez #define OF_PORT_STATUS_FIXLEN (64U - OF_HEADER_FIXLEN)
540*ed775ee7SAntonio Huete Jimenez #define OF_PORT_MOD_FIXLEN (32U - OF_HEADER_FIXLEN)
541*ed775ee7SAntonio Huete Jimenez #define OF_PACKET_IN_MINLEN (20U - OF_HEADER_FIXLEN) /* with 2 mock octets */
542*ed775ee7SAntonio Huete Jimenez #define OF_PACKET_OUT_MINLEN (16U - OF_HEADER_FIXLEN)
543*ed775ee7SAntonio Huete Jimenez #define OF_FLOW_MOD_MINLEN (72U - OF_HEADER_FIXLEN)
544*ed775ee7SAntonio Huete Jimenez #define OF_FLOW_REMOVED_FIXLEN (88U - OF_HEADER_FIXLEN)
545*ed775ee7SAntonio Huete Jimenez #define OF_ERROR_MSG_MINLEN (12U - OF_HEADER_FIXLEN)
546*ed775ee7SAntonio Huete Jimenez #define OF_STATS_REQUEST_MINLEN (12U - OF_HEADER_FIXLEN)
547*ed775ee7SAntonio Huete Jimenez #define OF_STATS_REPLY_MINLEN (12U - OF_HEADER_FIXLEN)
548*ed775ee7SAntonio Huete Jimenez #define OF_VENDOR_MINLEN (12U - OF_HEADER_FIXLEN)
549*ed775ee7SAntonio Huete Jimenez #define OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN (12U - OF_HEADER_FIXLEN)
550*ed775ee7SAntonio Huete Jimenez #define OF_QUEUE_GET_CONFIG_REPLY_MINLEN (16U - OF_HEADER_FIXLEN)
551*ed775ee7SAntonio Huete Jimenez
552411677aeSAaron LI /* lengths (fixed or minimal) of particular protocol structures */
553*ed775ee7SAntonio Huete Jimenez #define OF_PHY_PORT_FIXLEN 48
554*ed775ee7SAntonio Huete Jimenez #define OF_ACTION_MINLEN 8
555*ed775ee7SAntonio Huete Jimenez #define OF_MATCH_FIXLEN 40
556*ed775ee7SAntonio Huete Jimenez #define OF_DESC_STATS_REPLY_FIXLEN 1056
557*ed775ee7SAntonio Huete Jimenez #define OF_FLOW_STATS_REQUEST_FIXLEN 44
558*ed775ee7SAntonio Huete Jimenez #define OF_FLOW_STATS_REPLY_MINLEN 88
559*ed775ee7SAntonio Huete Jimenez #define OF_AGGREGATE_STATS_REPLY_FIXLEN 24
560*ed775ee7SAntonio Huete Jimenez #define OF_TABLE_STATS_REPLY_FIXLEN 64
561*ed775ee7SAntonio Huete Jimenez #define OF_PORT_STATS_REQUEST_FIXLEN 8
562*ed775ee7SAntonio Huete Jimenez #define OF_PORT_STATS_REPLY_FIXLEN 104
563*ed775ee7SAntonio Huete Jimenez #define OF_QUEUE_PROP_MINLEN 8
564*ed775ee7SAntonio Huete Jimenez #define OF_QUEUE_PROP_MIN_RATE_FIXLEN 16
565*ed775ee7SAntonio Huete Jimenez #define OF_PACKET_QUEUE_MINLEN 8
566*ed775ee7SAntonio Huete Jimenez #define OF_QUEUE_STATS_REQUEST_FIXLEN 8
567*ed775ee7SAntonio Huete Jimenez #define OF_QUEUE_STATS_REPLY_FIXLEN 32
568411677aeSAaron LI
569411677aeSAaron LI /* miscellaneous constants from [OF10] */
570411677aeSAaron LI #define OFP_MAX_TABLE_NAME_LEN 32
571411677aeSAaron LI #define OFP_MAX_PORT_NAME_LEN 16
572411677aeSAaron LI #define DESC_STR_LEN 256
573411677aeSAaron LI #define SERIAL_NUM_LEN 32
574*ed775ee7SAntonio Huete Jimenez #define OFP_VLAN_NONE 0xffffU
575411677aeSAaron LI
576411677aeSAaron LI /* vendor extensions */
577411677aeSAaron LI #define BSN_SET_IP_MASK 0
578411677aeSAaron LI #define BSN_GET_IP_MASK_REQUEST 1
579411677aeSAaron LI #define BSN_GET_IP_MASK_REPLY 2
580411677aeSAaron LI #define BSN_SET_MIRRORING 3
581411677aeSAaron LI #define BSN_GET_MIRRORING_REQUEST 4
582411677aeSAaron LI #define BSN_GET_MIRRORING_REPLY 5
583411677aeSAaron LI #define BSN_SHELL_COMMAND 6
584411677aeSAaron LI #define BSN_SHELL_OUTPUT 7
585411677aeSAaron LI #define BSN_SHELL_STATUS 8
586411677aeSAaron LI #define BSN_GET_INTERFACES_REQUEST 9
587411677aeSAaron LI #define BSN_GET_INTERFACES_REPLY 10
588411677aeSAaron LI #define BSN_SET_PKTIN_SUPPRESSION_REQUEST 11
589411677aeSAaron LI #define BSN_SET_L2_TABLE_REQUEST 12
590411677aeSAaron LI #define BSN_GET_L2_TABLE_REQUEST 13
591411677aeSAaron LI #define BSN_GET_L2_TABLE_REPLY 14
592411677aeSAaron LI #define BSN_VIRTUAL_PORT_CREATE_REQUEST 15
593411677aeSAaron LI #define BSN_VIRTUAL_PORT_CREATE_REPLY 16
594411677aeSAaron LI #define BSN_VIRTUAL_PORT_REMOVE_REQUEST 17
595411677aeSAaron LI #define BSN_BW_ENABLE_SET_REQUEST 18
596411677aeSAaron LI #define BSN_BW_ENABLE_GET_REQUEST 19
597411677aeSAaron LI #define BSN_BW_ENABLE_GET_REPLY 20
598411677aeSAaron LI #define BSN_BW_CLEAR_DATA_REQUEST 21
599411677aeSAaron LI #define BSN_BW_CLEAR_DATA_REPLY 22
600411677aeSAaron LI #define BSN_BW_ENABLE_SET_REPLY 23
601411677aeSAaron LI #define BSN_SET_L2_TABLE_REPLY 24
602411677aeSAaron LI #define BSN_SET_PKTIN_SUPPRESSION_REPLY 25
603411677aeSAaron LI #define BSN_VIRTUAL_PORT_REMOVE_REPLY 26
604411677aeSAaron LI #define BSN_HYBRID_GET_REQUEST 27
605411677aeSAaron LI #define BSN_HYBRID_GET_REPLY 28
606411677aeSAaron LI /* 29 */
607411677aeSAaron LI /* 30 */
608411677aeSAaron LI #define BSN_PDU_TX_REQUEST 31
609411677aeSAaron LI #define BSN_PDU_TX_REPLY 32
610411677aeSAaron LI #define BSN_PDU_RX_REQUEST 33
611411677aeSAaron LI #define BSN_PDU_RX_REPLY 34
612411677aeSAaron LI #define BSN_PDU_RX_TIMEOUT 35
613411677aeSAaron LI
614411677aeSAaron LI static const struct tok bsn_subtype_str[] = {
615411677aeSAaron LI { BSN_SET_IP_MASK, "SET_IP_MASK" },
616411677aeSAaron LI { BSN_GET_IP_MASK_REQUEST, "GET_IP_MASK_REQUEST" },
617411677aeSAaron LI { BSN_GET_IP_MASK_REPLY, "GET_IP_MASK_REPLY" },
618411677aeSAaron LI { BSN_SET_MIRRORING, "SET_MIRRORING" },
619411677aeSAaron LI { BSN_GET_MIRRORING_REQUEST, "GET_MIRRORING_REQUEST" },
620411677aeSAaron LI { BSN_GET_MIRRORING_REPLY, "GET_MIRRORING_REPLY" },
621411677aeSAaron LI { BSN_SHELL_COMMAND, "SHELL_COMMAND" },
622411677aeSAaron LI { BSN_SHELL_OUTPUT, "SHELL_OUTPUT" },
623411677aeSAaron LI { BSN_SHELL_STATUS, "SHELL_STATUS" },
624411677aeSAaron LI { BSN_GET_INTERFACES_REQUEST, "GET_INTERFACES_REQUEST" },
625411677aeSAaron LI { BSN_GET_INTERFACES_REPLY, "GET_INTERFACES_REPLY" },
626411677aeSAaron LI { BSN_SET_PKTIN_SUPPRESSION_REQUEST, "SET_PKTIN_SUPPRESSION_REQUEST" },
627411677aeSAaron LI { BSN_SET_L2_TABLE_REQUEST, "SET_L2_TABLE_REQUEST" },
628411677aeSAaron LI { BSN_GET_L2_TABLE_REQUEST, "GET_L2_TABLE_REQUEST" },
629411677aeSAaron LI { BSN_GET_L2_TABLE_REPLY, "GET_L2_TABLE_REPLY" },
630411677aeSAaron LI { BSN_VIRTUAL_PORT_CREATE_REQUEST, "VIRTUAL_PORT_CREATE_REQUEST" },
631411677aeSAaron LI { BSN_VIRTUAL_PORT_CREATE_REPLY, "VIRTUAL_PORT_CREATE_REPLY" },
632411677aeSAaron LI { BSN_VIRTUAL_PORT_REMOVE_REQUEST, "VIRTUAL_PORT_REMOVE_REQUEST" },
633411677aeSAaron LI { BSN_BW_ENABLE_SET_REQUEST, "BW_ENABLE_SET_REQUEST" },
634411677aeSAaron LI { BSN_BW_ENABLE_GET_REQUEST, "BW_ENABLE_GET_REQUEST" },
635411677aeSAaron LI { BSN_BW_ENABLE_GET_REPLY, "BW_ENABLE_GET_REPLY" },
636411677aeSAaron LI { BSN_BW_CLEAR_DATA_REQUEST, "BW_CLEAR_DATA_REQUEST" },
637411677aeSAaron LI { BSN_BW_CLEAR_DATA_REPLY, "BW_CLEAR_DATA_REPLY" },
638411677aeSAaron LI { BSN_BW_ENABLE_SET_REPLY, "BW_ENABLE_SET_REPLY" },
639411677aeSAaron LI { BSN_SET_L2_TABLE_REPLY, "SET_L2_TABLE_REPLY" },
640411677aeSAaron LI { BSN_SET_PKTIN_SUPPRESSION_REPLY, "SET_PKTIN_SUPPRESSION_REPLY" },
641411677aeSAaron LI { BSN_VIRTUAL_PORT_REMOVE_REPLY, "VIRTUAL_PORT_REMOVE_REPLY" },
642411677aeSAaron LI { BSN_HYBRID_GET_REQUEST, "HYBRID_GET_REQUEST" },
643411677aeSAaron LI { BSN_HYBRID_GET_REPLY, "HYBRID_GET_REPLY" },
644411677aeSAaron LI { BSN_PDU_TX_REQUEST, "PDU_TX_REQUEST" },
645411677aeSAaron LI { BSN_PDU_TX_REPLY, "PDU_TX_REPLY" },
646411677aeSAaron LI { BSN_PDU_RX_REQUEST, "PDU_RX_REQUEST" },
647411677aeSAaron LI { BSN_PDU_RX_REPLY, "PDU_RX_REPLY" },
648411677aeSAaron LI { BSN_PDU_RX_TIMEOUT, "PDU_RX_TIMEOUT" },
649411677aeSAaron LI { 0, NULL }
650411677aeSAaron LI };
651411677aeSAaron LI
652411677aeSAaron LI #define BSN_ACTION_MIRROR 1
653411677aeSAaron LI #define BSN_ACTION_SET_TUNNEL_DST 2
654411677aeSAaron LI /* 3 */
655411677aeSAaron LI #define BSN_ACTION_CHECKSUM 4
656411677aeSAaron LI
657411677aeSAaron LI static const struct tok bsn_action_subtype_str[] = {
658411677aeSAaron LI { BSN_ACTION_MIRROR, "MIRROR" },
659411677aeSAaron LI { BSN_ACTION_SET_TUNNEL_DST, "SET_TUNNEL_DST" },
660411677aeSAaron LI { BSN_ACTION_CHECKSUM, "CHECKSUM" },
661411677aeSAaron LI { 0, NULL }
662411677aeSAaron LI };
663411677aeSAaron LI
664411677aeSAaron LI static const struct tok bsn_mirror_copy_stage_str[] = {
665411677aeSAaron LI { 0, "INGRESS" },
666411677aeSAaron LI { 1, "EGRESS" },
667411677aeSAaron LI { 0, NULL },
668411677aeSAaron LI };
669411677aeSAaron LI
670411677aeSAaron LI static const struct tok bsn_onoff_str[] = {
671411677aeSAaron LI { 0, "OFF" },
672411677aeSAaron LI { 1, "ON" },
673411677aeSAaron LI { 0, NULL },
674411677aeSAaron LI };
675411677aeSAaron LI
676411677aeSAaron LI static const char *
vlan_str(const uint16_t vid)677411677aeSAaron LI vlan_str(const uint16_t vid)
678411677aeSAaron LI {
679411677aeSAaron LI static char buf[sizeof("65535 (bogus)")];
680411677aeSAaron LI
681411677aeSAaron LI if (vid == OFP_VLAN_NONE)
682411677aeSAaron LI return "NONE";
683*ed775ee7SAntonio Huete Jimenez snprintf(buf, sizeof(buf), "%u%s", vid,
684*ed775ee7SAntonio Huete Jimenez (vid > 0 && vid < 0x0fff) ? "" : " (bogus)");
685411677aeSAaron LI return buf;
686411677aeSAaron LI }
687411677aeSAaron LI
688411677aeSAaron LI static const char *
pcp_str(const uint8_t pcp)689411677aeSAaron LI pcp_str(const uint8_t pcp)
690411677aeSAaron LI {
691411677aeSAaron LI static char buf[sizeof("255 (bogus)")];
692*ed775ee7SAntonio Huete Jimenez snprintf(buf, sizeof(buf), "%u%s", pcp,
693*ed775ee7SAntonio Huete Jimenez pcp <= 7 ? "" : " (bogus)");
694411677aeSAaron LI return buf;
695411677aeSAaron LI }
696411677aeSAaron LI
697411677aeSAaron LI static void
of10_bsn_message_print(netdissect_options * ndo,const u_char * cp,u_int len)698411677aeSAaron LI of10_bsn_message_print(netdissect_options *ndo,
699*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
700411677aeSAaron LI {
701411677aeSAaron LI uint32_t subtype;
702411677aeSAaron LI
703411677aeSAaron LI if (len < 4)
704411677aeSAaron LI goto invalid;
705411677aeSAaron LI /* subtype */
706*ed775ee7SAntonio Huete Jimenez subtype = GET_BE_U_4(cp);
707*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
708*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t subtype %s", tok2str(bsn_subtype_str, "unknown (0x%08x)", subtype));
709411677aeSAaron LI switch (subtype) {
710411677aeSAaron LI case BSN_GET_IP_MASK_REQUEST:
711411677aeSAaron LI /*
712411677aeSAaron LI * 0 1 2 3
713411677aeSAaron LI * 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
714411677aeSAaron LI * +---------------+---------------+---------------+---------------+
715411677aeSAaron LI * | subtype |
716411677aeSAaron LI * +---------------+---------------+---------------+---------------+
717411677aeSAaron LI * | index | pad |
718411677aeSAaron LI * +---------------+---------------+---------------+---------------+
719411677aeSAaron LI * | pad |
720411677aeSAaron LI * +---------------+---------------+---------------+---------------+
721411677aeSAaron LI *
722411677aeSAaron LI */
723*ed775ee7SAntonio Huete Jimenez if (len != 8)
724411677aeSAaron LI goto invalid;
725411677aeSAaron LI /* index */
726*ed775ee7SAntonio Huete Jimenez ND_PRINT(", index %u", GET_U_1(cp));
727*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
728411677aeSAaron LI /* pad */
729*ed775ee7SAntonio Huete Jimenez /* Always the last field, check bounds. */
730*ed775ee7SAntonio Huete Jimenez ND_TCHECK_7(cp);
731411677aeSAaron LI break;
732411677aeSAaron LI case BSN_SET_IP_MASK:
733411677aeSAaron LI case BSN_GET_IP_MASK_REPLY:
734411677aeSAaron LI /*
735411677aeSAaron LI * 0 1 2 3
736411677aeSAaron LI * 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
737411677aeSAaron LI * +---------------+---------------+---------------+---------------+
738411677aeSAaron LI * | subtype |
739411677aeSAaron LI * +---------------+---------------+---------------+---------------+
740411677aeSAaron LI * | index | pad |
741411677aeSAaron LI * +---------------+---------------+---------------+---------------+
742411677aeSAaron LI * | mask |
743411677aeSAaron LI * +---------------+---------------+---------------+---------------+
744411677aeSAaron LI *
745411677aeSAaron LI */
746*ed775ee7SAntonio Huete Jimenez if (len != 8)
747411677aeSAaron LI goto invalid;
748411677aeSAaron LI /* index */
749*ed775ee7SAntonio Huete Jimenez ND_PRINT(", index %u", GET_U_1(cp));
750*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
751411677aeSAaron LI /* pad */
752*ed775ee7SAntonio Huete Jimenez OF_FWD(3);
753411677aeSAaron LI /* mask */
754*ed775ee7SAntonio Huete Jimenez ND_PRINT(", mask %s", GET_IPADDR_STRING(cp));
755411677aeSAaron LI break;
756411677aeSAaron LI case BSN_SET_MIRRORING:
757411677aeSAaron LI case BSN_GET_MIRRORING_REQUEST:
758411677aeSAaron LI case BSN_GET_MIRRORING_REPLY:
759411677aeSAaron LI /*
760411677aeSAaron LI * 0 1 2 3
761411677aeSAaron LI * 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
762411677aeSAaron LI * +---------------+---------------+---------------+---------------+
763411677aeSAaron LI * | subtype |
764411677aeSAaron LI * +---------------+---------------+---------------+---------------+
765411677aeSAaron LI * | report m. p. | pad |
766411677aeSAaron LI * +---------------+---------------+---------------+---------------+
767411677aeSAaron LI *
768411677aeSAaron LI */
769*ed775ee7SAntonio Huete Jimenez if (len != 4)
770411677aeSAaron LI goto invalid;
771411677aeSAaron LI /* report_mirror_ports */
772*ed775ee7SAntonio Huete Jimenez ND_PRINT(", report_mirror_ports %s",
773*ed775ee7SAntonio Huete Jimenez tok2str(bsn_onoff_str, "bogus (%u)", GET_U_1(cp)));
774*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
775411677aeSAaron LI /* pad */
776*ed775ee7SAntonio Huete Jimenez /* Always the last field, check bounds. */
777*ed775ee7SAntonio Huete Jimenez ND_TCHECK_3(cp);
778411677aeSAaron LI break;
779411677aeSAaron LI case BSN_GET_INTERFACES_REQUEST:
780411677aeSAaron LI case BSN_GET_L2_TABLE_REQUEST:
781411677aeSAaron LI case BSN_BW_ENABLE_GET_REQUEST:
782411677aeSAaron LI case BSN_BW_CLEAR_DATA_REQUEST:
783411677aeSAaron LI case BSN_HYBRID_GET_REQUEST:
784411677aeSAaron LI /*
785411677aeSAaron LI * 0 1 2 3
786411677aeSAaron LI * 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
787411677aeSAaron LI * +---------------+---------------+---------------+---------------+
788411677aeSAaron LI * | subtype |
789411677aeSAaron LI * +---------------+---------------+---------------+---------------+
790411677aeSAaron LI *
791411677aeSAaron LI */
792*ed775ee7SAntonio Huete Jimenez if (len)
793411677aeSAaron LI goto invalid;
794411677aeSAaron LI break;
795411677aeSAaron LI case BSN_VIRTUAL_PORT_REMOVE_REQUEST:
796411677aeSAaron LI /*
797411677aeSAaron LI * 0 1 2 3
798411677aeSAaron LI * 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
799411677aeSAaron LI * +---------------+---------------+---------------+---------------+
800411677aeSAaron LI * | subtype |
801411677aeSAaron LI * +---------------+---------------+---------------+---------------+
802411677aeSAaron LI * | vport_no |
803411677aeSAaron LI * +---------------+---------------+---------------+---------------+
804411677aeSAaron LI *
805411677aeSAaron LI */
806*ed775ee7SAntonio Huete Jimenez if (len != 4)
807411677aeSAaron LI goto invalid;
808411677aeSAaron LI /* vport_no */
809*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vport_no %u", GET_BE_U_4(cp));
810411677aeSAaron LI break;
811411677aeSAaron LI case BSN_SHELL_COMMAND:
812411677aeSAaron LI /*
813411677aeSAaron LI * 0 1 2 3
814411677aeSAaron LI * 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
815411677aeSAaron LI * +---------------+---------------+---------------+---------------+
816411677aeSAaron LI * | subtype |
817411677aeSAaron LI * +---------------+---------------+---------------+---------------+
818411677aeSAaron LI * | service |
819411677aeSAaron LI * +---------------+---------------+---------------+---------------+
820411677aeSAaron LI * | data ...
821411677aeSAaron LI * +---------------+---------------+--------
822411677aeSAaron LI *
823411677aeSAaron LI */
824*ed775ee7SAntonio Huete Jimenez if (len < 4)
825411677aeSAaron LI goto invalid;
826411677aeSAaron LI /* service */
827*ed775ee7SAntonio Huete Jimenez ND_PRINT(", service %u", GET_BE_U_4(cp));
828*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
829411677aeSAaron LI /* data */
830*ed775ee7SAntonio Huete Jimenez ND_PRINT(", data '");
831*ed775ee7SAntonio Huete Jimenez (void)nd_printn(ndo, cp, len, NULL);
832*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
833411677aeSAaron LI break;
834411677aeSAaron LI case BSN_SHELL_OUTPUT:
835411677aeSAaron LI /*
836411677aeSAaron LI * 0 1 2 3
837411677aeSAaron LI * 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
838411677aeSAaron LI * +---------------+---------------+---------------+---------------+
839411677aeSAaron LI * | subtype |
840411677aeSAaron LI * +---------------+---------------+---------------+---------------+
841411677aeSAaron LI * | data ...
842411677aeSAaron LI * +---------------+---------------+--------
843411677aeSAaron LI *
844411677aeSAaron LI */
845411677aeSAaron LI /* already checked that len >= 4 */
846411677aeSAaron LI /* data */
847*ed775ee7SAntonio Huete Jimenez ND_PRINT(", data '");
848*ed775ee7SAntonio Huete Jimenez (void)nd_printn(ndo, cp, len, NULL);
849*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
850411677aeSAaron LI break;
851411677aeSAaron LI case BSN_SHELL_STATUS:
852411677aeSAaron LI /*
853411677aeSAaron LI * 0 1 2 3
854411677aeSAaron LI * 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
855411677aeSAaron LI * +---------------+---------------+---------------+---------------+
856411677aeSAaron LI * | subtype |
857411677aeSAaron LI * +---------------+---------------+---------------+---------------+
858411677aeSAaron LI * | status |
859411677aeSAaron LI * +---------------+---------------+---------------+---------------+
860411677aeSAaron LI *
861411677aeSAaron LI */
862*ed775ee7SAntonio Huete Jimenez if (len != 4)
863411677aeSAaron LI goto invalid;
864411677aeSAaron LI /* status */
865*ed775ee7SAntonio Huete Jimenez ND_PRINT(", status 0x%08x", GET_BE_U_4(cp));
866411677aeSAaron LI break;
867411677aeSAaron LI default:
868*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
869411677aeSAaron LI }
870*ed775ee7SAntonio Huete Jimenez return;
871411677aeSAaron LI
872411677aeSAaron LI invalid: /* skip the undersized data */
873*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
874*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
875411677aeSAaron LI }
876411677aeSAaron LI
877*ed775ee7SAntonio Huete Jimenez static void
of10_bsn_actions_print(netdissect_options * ndo,const u_char * cp,u_int len)878411677aeSAaron LI of10_bsn_actions_print(netdissect_options *ndo,
879*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
880411677aeSAaron LI {
881411677aeSAaron LI uint32_t subtype, vlan_tag;
882411677aeSAaron LI
883411677aeSAaron LI if (len < 4)
884411677aeSAaron LI goto invalid;
885411677aeSAaron LI /* subtype */
886*ed775ee7SAntonio Huete Jimenez subtype = GET_BE_U_4(cp);
887*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
888*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype));
889411677aeSAaron LI switch (subtype) {
890411677aeSAaron LI case BSN_ACTION_MIRROR:
891411677aeSAaron LI /*
892411677aeSAaron LI * 0 1 2 3
893411677aeSAaron LI * 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
894411677aeSAaron LI * +---------------+---------------+---------------+---------------+
895411677aeSAaron LI * | subtype |
896411677aeSAaron LI * +---------------+---------------+---------------+---------------+
897411677aeSAaron LI * | dest_port |
898411677aeSAaron LI * +---------------+---------------+---------------+---------------+
899411677aeSAaron LI * | vlan_tag |
900411677aeSAaron LI * +---------------+---------------+---------------+---------------+
901411677aeSAaron LI * | copy_stage | pad |
902411677aeSAaron LI * +---------------+---------------+---------------+---------------+
903411677aeSAaron LI *
904411677aeSAaron LI */
905*ed775ee7SAntonio Huete Jimenez if (len != 12)
906411677aeSAaron LI goto invalid;
907411677aeSAaron LI /* dest_port */
908*ed775ee7SAntonio Huete Jimenez ND_PRINT(", dest_port %u", GET_BE_U_4(cp));
909*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
910411677aeSAaron LI /* vlan_tag */
911*ed775ee7SAntonio Huete Jimenez vlan_tag = GET_BE_U_4(cp);
912*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
913411677aeSAaron LI switch (vlan_tag >> 16) {
914411677aeSAaron LI case 0:
915*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vlan_tag none");
916411677aeSAaron LI break;
917411677aeSAaron LI case ETHERTYPE_8021Q:
918*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vlan_tag 802.1Q (%s)", ieee8021q_tci_string(vlan_tag & 0xffff));
919411677aeSAaron LI break;
920411677aeSAaron LI default:
921*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vlan_tag unknown (0x%04x)", vlan_tag >> 16);
922411677aeSAaron LI }
923411677aeSAaron LI /* copy_stage */
924*ed775ee7SAntonio Huete Jimenez ND_PRINT(", copy_stage %s",
925*ed775ee7SAntonio Huete Jimenez tok2str(bsn_mirror_copy_stage_str, "unknown (%u)", GET_U_1(cp)));
926*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
927411677aeSAaron LI /* pad */
928*ed775ee7SAntonio Huete Jimenez /* Always the last field, check bounds. */
929*ed775ee7SAntonio Huete Jimenez ND_TCHECK_3(cp);
930411677aeSAaron LI break;
931411677aeSAaron LI default:
932*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
933411677aeSAaron LI }
934*ed775ee7SAntonio Huete Jimenez return;
935411677aeSAaron LI
936411677aeSAaron LI invalid:
937*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
938*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
939411677aeSAaron LI }
940411677aeSAaron LI
941*ed775ee7SAntonio Huete Jimenez static void
of10_vendor_action_print(netdissect_options * ndo,const u_char * cp,u_int len)942411677aeSAaron LI of10_vendor_action_print(netdissect_options *ndo,
943*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
944411677aeSAaron LI {
945411677aeSAaron LI uint32_t vendor;
946*ed775ee7SAntonio Huete Jimenez void (*decoder)(netdissect_options *, const u_char *, u_int);
947411677aeSAaron LI
948411677aeSAaron LI if (len < 4)
949411677aeSAaron LI goto invalid;
950411677aeSAaron LI /* vendor */
951*ed775ee7SAntonio Huete Jimenez vendor = GET_BE_U_4(cp);
952*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
953*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor));
954411677aeSAaron LI /* data */
955411677aeSAaron LI decoder =
956411677aeSAaron LI vendor == OUI_BSN ? of10_bsn_actions_print :
957*ed775ee7SAntonio Huete Jimenez of_data_print;
958*ed775ee7SAntonio Huete Jimenez decoder(ndo, cp, len);
959*ed775ee7SAntonio Huete Jimenez return;
960411677aeSAaron LI
961411677aeSAaron LI invalid: /* skip the undersized data */
962*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
963*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
964411677aeSAaron LI }
965411677aeSAaron LI
966*ed775ee7SAntonio Huete Jimenez /* [OF10] Section 5.5.4 */
967*ed775ee7SAntonio Huete Jimenez static void
of10_vendor_message_print(netdissect_options * ndo,const u_char * cp,u_int len)968411677aeSAaron LI of10_vendor_message_print(netdissect_options *ndo,
969*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
970411677aeSAaron LI {
971411677aeSAaron LI uint32_t vendor;
972*ed775ee7SAntonio Huete Jimenez void (*decoder)(netdissect_options *, const u_char *, u_int);
973411677aeSAaron LI
974411677aeSAaron LI /* vendor */
975*ed775ee7SAntonio Huete Jimenez vendor = GET_BE_U_4(cp);
976*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
977*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor));
978411677aeSAaron LI /* data */
979411677aeSAaron LI decoder =
980411677aeSAaron LI vendor == OUI_BSN ? of10_bsn_message_print :
981*ed775ee7SAntonio Huete Jimenez of_data_print;
982*ed775ee7SAntonio Huete Jimenez decoder(ndo, cp, len);
983411677aeSAaron LI }
984411677aeSAaron LI
985411677aeSAaron LI /* Vendor ID is mandatory, data is optional. */
986*ed775ee7SAntonio Huete Jimenez static void
of10_vendor_data_print(netdissect_options * ndo,const u_char * cp,u_int len)987411677aeSAaron LI of10_vendor_data_print(netdissect_options *ndo,
988*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
989411677aeSAaron LI {
990411677aeSAaron LI uint32_t vendor;
991411677aeSAaron LI
992411677aeSAaron LI if (len < 4)
993411677aeSAaron LI goto invalid;
994411677aeSAaron LI /* vendor */
995*ed775ee7SAntonio Huete Jimenez vendor = GET_BE_U_4(cp);
996*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
997*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor));
998411677aeSAaron LI /* data */
999*ed775ee7SAntonio Huete Jimenez of_data_print(ndo, cp, len);
1000*ed775ee7SAntonio Huete Jimenez return;
1001411677aeSAaron LI
1002411677aeSAaron LI invalid: /* skip the undersized data */
1003*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1004*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1005411677aeSAaron LI }
1006411677aeSAaron LI
1007*ed775ee7SAntonio Huete Jimenez static void
of10_packet_data_print(netdissect_options * ndo,const u_char * cp,const u_int len)1008411677aeSAaron LI of10_packet_data_print(netdissect_options *ndo,
1009*ed775ee7SAntonio Huete Jimenez const u_char *cp, const u_int len)
1010411677aeSAaron LI {
1011411677aeSAaron LI if (len == 0)
1012*ed775ee7SAntonio Huete Jimenez return;
1013411677aeSAaron LI /* data */
1014*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t data (%u octets)", len);
1015*ed775ee7SAntonio Huete Jimenez if (ndo->ndo_vflag < 3) {
1016*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1017*ed775ee7SAntonio Huete Jimenez return;
1018*ed775ee7SAntonio Huete Jimenez }
1019411677aeSAaron LI ndo->ndo_vflag -= 3;
1020*ed775ee7SAntonio Huete Jimenez ND_PRINT(", frame decoding below\n");
1021*ed775ee7SAntonio Huete Jimenez /*
1022*ed775ee7SAntonio Huete Jimenez * The encapsulated Ethernet frame is not necessarily the last
1023*ed775ee7SAntonio Huete Jimenez * data of this packet (i.e. there may be more OpenFlow messages
1024*ed775ee7SAntonio Huete Jimenez * after the current OFPT_PACKET_IN/OFPT_PACKET_OUT message, in
1025*ed775ee7SAntonio Huete Jimenez * which case the current (outer) packet's snapshot end is not
1026*ed775ee7SAntonio Huete Jimenez * what ether_print() needs to decode an Ethernet frame nested in
1027*ed775ee7SAntonio Huete Jimenez * the middle of a TCP payload.
1028*ed775ee7SAntonio Huete Jimenez */
1029*ed775ee7SAntonio Huete Jimenez const u_char *snapend_save = ndo->ndo_snapend;
1030*ed775ee7SAntonio Huete Jimenez ndo->ndo_snapend = ND_MIN(cp + len, ndo->ndo_snapend);
1031*ed775ee7SAntonio Huete Jimenez ether_print(ndo, cp, len, ND_BYTES_AVAILABLE_AFTER(cp), NULL, NULL);
1032*ed775ee7SAntonio Huete Jimenez ndo->ndo_snapend = snapend_save;
1033411677aeSAaron LI ndo->ndo_vflag += 3;
1034411677aeSAaron LI }
1035411677aeSAaron LI
1036411677aeSAaron LI /* [OF10] Section 5.2.1 */
1037*ed775ee7SAntonio Huete Jimenez static void
of10_phy_port_print(netdissect_options * ndo,const u_char * cp)1038*ed775ee7SAntonio Huete Jimenez of10_phy_port_print(netdissect_options *ndo,
1039*ed775ee7SAntonio Huete Jimenez const u_char *cp)
1040411677aeSAaron LI {
1041*ed775ee7SAntonio Huete Jimenez uint32_t state;
1042411677aeSAaron LI
1043411677aeSAaron LI /* port_no */
1044*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t port_no %s",
1045*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1046411677aeSAaron LI cp += 2;
1047411677aeSAaron LI /* hw_addr */
1048*ed775ee7SAntonio Huete Jimenez ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp));
1049*ed775ee7SAntonio Huete Jimenez cp += MAC_ADDR_LEN;
1050411677aeSAaron LI /* name */
1051*ed775ee7SAntonio Huete Jimenez ND_PRINT(", name '");
1052*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, cp, OFP_MAX_PORT_NAME_LEN);
1053*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
1054411677aeSAaron LI cp += OFP_MAX_PORT_NAME_LEN;
1055411677aeSAaron LI
1056411677aeSAaron LI if (ndo->ndo_vflag < 2) {
1057*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, 24);
1058*ed775ee7SAntonio Huete Jimenez return;
1059411677aeSAaron LI }
1060411677aeSAaron LI /* config */
1061*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp));
1062*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U);
1063411677aeSAaron LI cp += 4;
1064411677aeSAaron LI /* state */
1065*ed775ee7SAntonio Huete Jimenez state = GET_BE_U_4(cp);
1066*ed775ee7SAntonio Huete Jimenez /*
1067*ed775ee7SAntonio Huete Jimenez * Decode the code point and the single bit separately, but
1068*ed775ee7SAntonio Huete Jimenez * format the result as a single sequence of comma-separated
1069*ed775ee7SAntonio Huete Jimenez * strings (see the comments at the OFPPS_ props).
1070*ed775ee7SAntonio Huete Jimenez */
1071*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t state 0x%08x (%s%s)%s", state,
1072*ed775ee7SAntonio Huete Jimenez tok2str(ofpps_stp_str, "", state & OFPPS_STP_MASK),
1073*ed775ee7SAntonio Huete Jimenez state & OFPPS_LINK_DOWN ? ", LINK_DOWN" : "",
1074*ed775ee7SAntonio Huete Jimenez state & OFPPS_U ? " (bogus)" : "");
1075411677aeSAaron LI cp += 4;
1076411677aeSAaron LI /* curr */
1077*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t curr 0x%08x", GET_BE_U_4(cp));
1078*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
1079411677aeSAaron LI cp += 4;
1080411677aeSAaron LI /* advertised */
1081*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t advertised 0x%08x", GET_BE_U_4(cp));
1082*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
1083411677aeSAaron LI cp += 4;
1084411677aeSAaron LI /* supported */
1085*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t supported 0x%08x", GET_BE_U_4(cp));
1086*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
1087411677aeSAaron LI cp += 4;
1088411677aeSAaron LI /* peer */
1089*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t peer 0x%08x", GET_BE_U_4(cp));
1090*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
1091411677aeSAaron LI }
1092411677aeSAaron LI
1093411677aeSAaron LI /* [OF10] Section 5.2.2 */
1094*ed775ee7SAntonio Huete Jimenez static void
of10_queue_props_print(netdissect_options * ndo,const u_char * cp,u_int len)1095411677aeSAaron LI of10_queue_props_print(netdissect_options *ndo,
1096*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1097411677aeSAaron LI {
1098411677aeSAaron LI while (len) {
1099*ed775ee7SAntonio Huete Jimenez uint16_t property, plen;
1100411677aeSAaron LI u_char plen_bogus = 0, skip = 0;
1101411677aeSAaron LI
1102*ed775ee7SAntonio Huete Jimenez if (len < OF_QUEUE_PROP_MINLEN)
1103411677aeSAaron LI goto invalid;
1104411677aeSAaron LI /* property */
1105*ed775ee7SAntonio Huete Jimenez property = GET_BE_U_2(cp);
1106*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1107*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t property %s", tok2str(ofpqt_str, "invalid (0x%04x)", property));
1108411677aeSAaron LI /* len */
1109*ed775ee7SAntonio Huete Jimenez plen = GET_BE_U_2(cp);
1110*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1111*ed775ee7SAntonio Huete Jimenez ND_PRINT(", len %u", plen);
1112*ed775ee7SAntonio Huete Jimenez if (plen < OF_QUEUE_PROP_MINLEN || plen > len + 4)
1113411677aeSAaron LI goto invalid;
1114411677aeSAaron LI /* pad */
1115*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1116*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(4);
1117411677aeSAaron LI /* property-specific constraints and decoding */
1118411677aeSAaron LI switch (property) {
1119411677aeSAaron LI case OFPQT_NONE:
1120*ed775ee7SAntonio Huete Jimenez plen_bogus = plen != OF_QUEUE_PROP_MINLEN;
1121411677aeSAaron LI break;
1122411677aeSAaron LI case OFPQT_MIN_RATE:
1123*ed775ee7SAntonio Huete Jimenez plen_bogus = plen != OF_QUEUE_PROP_MIN_RATE_FIXLEN;
1124411677aeSAaron LI break;
1125411677aeSAaron LI default:
1126411677aeSAaron LI skip = 1;
1127411677aeSAaron LI }
1128411677aeSAaron LI if (plen_bogus) {
1129*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (bogus)");
1130411677aeSAaron LI skip = 1;
1131411677aeSAaron LI }
1132411677aeSAaron LI if (skip) {
1133*ed775ee7SAntonio Huete Jimenez /*
1134*ed775ee7SAntonio Huete Jimenez * plen >= OF_QUEUE_PROP_MINLEN
1135*ed775ee7SAntonio Huete Jimenez * cp is OF_QUEUE_PROP_MINLEN bytes in
1136*ed775ee7SAntonio Huete Jimenez */
1137*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(plen - OF_QUEUE_PROP_MINLEN);
1138*ed775ee7SAntonio Huete Jimenez continue;
1139411677aeSAaron LI }
1140411677aeSAaron LI if (property == OFPQT_MIN_RATE) { /* the only case of property decoding */
1141411677aeSAaron LI /* rate */
1142*ed775ee7SAntonio Huete Jimenez uint16_t rate = GET_BE_U_2(cp);
1143*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1144411677aeSAaron LI if (rate > 1000)
1145*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rate disabled");
1146411677aeSAaron LI else
1147*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rate %u.%u%%", rate / 10, rate % 10);
1148411677aeSAaron LI /* pad */
1149*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1150*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(6);
1151411677aeSAaron LI }
1152411677aeSAaron LI } /* while */
1153*ed775ee7SAntonio Huete Jimenez return;
1154411677aeSAaron LI
1155411677aeSAaron LI invalid: /* skip the rest of queue properties */
1156*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1157*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1158411677aeSAaron LI }
1159411677aeSAaron LI
1160411677aeSAaron LI /* ibid */
1161*ed775ee7SAntonio Huete Jimenez static void
of10_queues_print(netdissect_options * ndo,const u_char * cp,u_int len)1162411677aeSAaron LI of10_queues_print(netdissect_options *ndo,
1163*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1164411677aeSAaron LI {
1165*ed775ee7SAntonio Huete Jimenez while (len) {
1166411677aeSAaron LI uint16_t desclen;
1167411677aeSAaron LI
1168*ed775ee7SAntonio Huete Jimenez if (len < OF_PACKET_QUEUE_MINLEN)
1169411677aeSAaron LI goto invalid;
1170411677aeSAaron LI /* queue_id */
1171*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t queue_id %u", GET_BE_U_4(cp));
1172*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1173411677aeSAaron LI /* len */
1174*ed775ee7SAntonio Huete Jimenez desclen = GET_BE_U_2(cp);
1175*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1176*ed775ee7SAntonio Huete Jimenez ND_PRINT(", len %u", desclen);
1177*ed775ee7SAntonio Huete Jimenez if (desclen < OF_PACKET_QUEUE_MINLEN || desclen > len + 6)
1178411677aeSAaron LI goto invalid;
1179411677aeSAaron LI /* pad */
1180*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1181*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(2);
1182411677aeSAaron LI /* properties */
1183*ed775ee7SAntonio Huete Jimenez if (ndo->ndo_vflag >= 2)
1184*ed775ee7SAntonio Huete Jimenez of10_queue_props_print(ndo, cp, desclen - OF_PACKET_QUEUE_MINLEN);
1185*ed775ee7SAntonio Huete Jimenez else
1186*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, desclen - OF_PACKET_QUEUE_MINLEN);
1187*ed775ee7SAntonio Huete Jimenez OF_FWD(desclen - OF_PACKET_QUEUE_MINLEN);
1188411677aeSAaron LI } /* while */
1189*ed775ee7SAntonio Huete Jimenez return;
1190411677aeSAaron LI
1191411677aeSAaron LI invalid: /* skip the rest of queues */
1192*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1193*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1194411677aeSAaron LI }
1195411677aeSAaron LI
1196411677aeSAaron LI /* [OF10] Section 5.2.3 */
1197*ed775ee7SAntonio Huete Jimenez static void
of10_match_print(netdissect_options * ndo,const char * pfx,const u_char * cp)1198411677aeSAaron LI of10_match_print(netdissect_options *ndo,
1199*ed775ee7SAntonio Huete Jimenez const char *pfx, const u_char *cp)
1200411677aeSAaron LI {
1201411677aeSAaron LI uint32_t wildcards;
1202411677aeSAaron LI uint16_t dl_type;
1203411677aeSAaron LI uint8_t nw_proto;
1204*ed775ee7SAntonio Huete Jimenez u_int nw_bits;
1205411677aeSAaron LI const char *field_name;
1206411677aeSAaron LI
1207411677aeSAaron LI /* wildcards */
1208*ed775ee7SAntonio Huete Jimenez wildcards = GET_BE_U_4(cp);
1209411677aeSAaron LI if (wildcards & OFPFW_U)
1210*ed775ee7SAntonio Huete Jimenez ND_PRINT("%swildcards 0x%08x (bogus)", pfx, wildcards);
1211411677aeSAaron LI cp += 4;
1212411677aeSAaron LI /* in_port */
1213411677aeSAaron LI if (! (wildcards & OFPFW_IN_PORT))
1214*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch in_port %s", pfx,
1215*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1216411677aeSAaron LI cp += 2;
1217411677aeSAaron LI /* dl_src */
1218411677aeSAaron LI if (! (wildcards & OFPFW_DL_SRC))
1219*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch dl_src %s", pfx, GET_ETHERADDR_STRING(cp));
1220*ed775ee7SAntonio Huete Jimenez cp += MAC_ADDR_LEN;
1221411677aeSAaron LI /* dl_dst */
1222411677aeSAaron LI if (! (wildcards & OFPFW_DL_DST))
1223*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch dl_dst %s", pfx, GET_ETHERADDR_STRING(cp));
1224*ed775ee7SAntonio Huete Jimenez cp += MAC_ADDR_LEN;
1225411677aeSAaron LI /* dl_vlan */
1226411677aeSAaron LI if (! (wildcards & OFPFW_DL_VLAN))
1227*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch dl_vlan %s", pfx, vlan_str(GET_BE_U_2(cp)));
1228411677aeSAaron LI cp += 2;
1229411677aeSAaron LI /* dl_vlan_pcp */
1230411677aeSAaron LI if (! (wildcards & OFPFW_DL_VLAN_PCP))
1231*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch dl_vlan_pcp %s", pfx, pcp_str(GET_U_1(cp)));
1232411677aeSAaron LI cp += 1;
1233411677aeSAaron LI /* pad1 */
1234411677aeSAaron LI cp += 1;
1235411677aeSAaron LI /* dl_type */
1236*ed775ee7SAntonio Huete Jimenez dl_type = GET_BE_U_2(cp);
1237411677aeSAaron LI cp += 2;
1238411677aeSAaron LI if (! (wildcards & OFPFW_DL_TYPE))
1239*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch dl_type 0x%04x", pfx, dl_type);
1240411677aeSAaron LI /* nw_tos */
1241411677aeSAaron LI if (! (wildcards & OFPFW_NW_TOS))
1242*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch nw_tos 0x%02x", pfx, GET_U_1(cp));
1243411677aeSAaron LI cp += 1;
1244411677aeSAaron LI /* nw_proto */
1245*ed775ee7SAntonio Huete Jimenez nw_proto = GET_U_1(cp);
1246411677aeSAaron LI cp += 1;
1247411677aeSAaron LI if (! (wildcards & OFPFW_NW_PROTO)) {
1248411677aeSAaron LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_ARP
1249411677aeSAaron LI ? "arp_opcode" : "nw_proto";
1250*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch %s %u", pfx, field_name, nw_proto);
1251411677aeSAaron LI }
1252411677aeSAaron LI /* pad2 */
1253411677aeSAaron LI cp += 2;
1254411677aeSAaron LI /* nw_src */
1255411677aeSAaron LI nw_bits = (wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT;
1256411677aeSAaron LI if (nw_bits < 32)
1257*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch nw_src %s/%u", pfx, GET_IPADDR_STRING(cp), 32 - nw_bits);
1258411677aeSAaron LI cp += 4;
1259411677aeSAaron LI /* nw_dst */
1260411677aeSAaron LI nw_bits = (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT;
1261411677aeSAaron LI if (nw_bits < 32)
1262*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch nw_dst %s/%u", pfx, GET_IPADDR_STRING(cp), 32 - nw_bits);
1263411677aeSAaron LI cp += 4;
1264411677aeSAaron LI /* tp_src */
1265411677aeSAaron LI if (! (wildcards & OFPFW_TP_SRC)) {
1266411677aeSAaron LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP
1267411677aeSAaron LI && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP
1268411677aeSAaron LI ? "icmp_type" : "tp_src";
1269*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch %s %u", pfx, field_name, GET_BE_U_2(cp));
1270411677aeSAaron LI }
1271411677aeSAaron LI cp += 2;
1272411677aeSAaron LI /* tp_dst */
1273*ed775ee7SAntonio Huete Jimenez /* The last unconditional check was at nw_proto, so have an "else" here. */
1274411677aeSAaron LI if (! (wildcards & OFPFW_TP_DST)) {
1275411677aeSAaron LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP
1276411677aeSAaron LI && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP
1277411677aeSAaron LI ? "icmp_code" : "tp_dst";
1278*ed775ee7SAntonio Huete Jimenez ND_PRINT("%smatch %s %u", pfx, field_name, GET_BE_U_2(cp));
1279411677aeSAaron LI }
1280*ed775ee7SAntonio Huete Jimenez else
1281*ed775ee7SAntonio Huete Jimenez ND_TCHECK_2(cp);
1282411677aeSAaron LI }
1283411677aeSAaron LI
1284411677aeSAaron LI /* [OF10] Section 5.2.4 */
1285*ed775ee7SAntonio Huete Jimenez static void
of10_actions_print(netdissect_options * ndo,const char * pfx,const u_char * cp,u_int len)1286411677aeSAaron LI of10_actions_print(netdissect_options *ndo,
1287*ed775ee7SAntonio Huete Jimenez const char *pfx, const u_char *cp, u_int len)
1288411677aeSAaron LI {
1289411677aeSAaron LI while (len) {
1290*ed775ee7SAntonio Huete Jimenez uint16_t type, alen, output_port;
1291411677aeSAaron LI u_char alen_bogus = 0, skip = 0;
1292411677aeSAaron LI
1293*ed775ee7SAntonio Huete Jimenez if (len < OF_ACTION_MINLEN)
1294411677aeSAaron LI goto invalid;
1295411677aeSAaron LI /* type */
1296*ed775ee7SAntonio Huete Jimenez type = GET_BE_U_2(cp);
1297*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1298*ed775ee7SAntonio Huete Jimenez ND_PRINT("%saction type %s", pfx, tok2str(ofpat_str, "invalid (0x%04x)", type));
1299411677aeSAaron LI /* length */
1300*ed775ee7SAntonio Huete Jimenez alen = GET_BE_U_2(cp);
1301*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1302*ed775ee7SAntonio Huete Jimenez ND_PRINT(", len %u", alen);
1303*ed775ee7SAntonio Huete Jimenez /*
1304*ed775ee7SAntonio Huete Jimenez * The 4-byte "pad" in the specification is not a field of the
1305*ed775ee7SAntonio Huete Jimenez * action header, but a placeholder to illustrate the 64-bit
1306*ed775ee7SAntonio Huete Jimenez * alignment requirement. Action type specific case blocks
1307*ed775ee7SAntonio Huete Jimenez * below fetch these 4 bytes.
1308*ed775ee7SAntonio Huete Jimenez */
1309*ed775ee7SAntonio Huete Jimenez
1310411677aeSAaron LI /* On action size underrun/overrun skip the rest of the action list. */
1311*ed775ee7SAntonio Huete Jimenez if (alen < OF_ACTION_MINLEN || alen > len + 4)
1312411677aeSAaron LI goto invalid;
1313*ed775ee7SAntonio Huete Jimenez /*
1314*ed775ee7SAntonio Huete Jimenez * After validating the basic length constraint it will be safe
1315*ed775ee7SAntonio Huete Jimenez * to skip the current action if the action size is not valid
1316*ed775ee7SAntonio Huete Jimenez * for the type or the type is invalid.
1317*ed775ee7SAntonio Huete Jimenez */
1318411677aeSAaron LI switch (type) {
1319411677aeSAaron LI case OFPAT_OUTPUT:
1320411677aeSAaron LI case OFPAT_SET_VLAN_VID:
1321411677aeSAaron LI case OFPAT_SET_VLAN_PCP:
1322411677aeSAaron LI case OFPAT_STRIP_VLAN:
1323411677aeSAaron LI case OFPAT_SET_NW_SRC:
1324411677aeSAaron LI case OFPAT_SET_NW_DST:
1325411677aeSAaron LI case OFPAT_SET_NW_TOS:
1326411677aeSAaron LI case OFPAT_SET_TP_SRC:
1327411677aeSAaron LI case OFPAT_SET_TP_DST:
1328411677aeSAaron LI alen_bogus = alen != 8;
1329411677aeSAaron LI break;
1330411677aeSAaron LI case OFPAT_SET_DL_SRC:
1331411677aeSAaron LI case OFPAT_SET_DL_DST:
1332411677aeSAaron LI case OFPAT_ENQUEUE:
1333411677aeSAaron LI alen_bogus = alen != 16;
1334411677aeSAaron LI break;
1335411677aeSAaron LI case OFPAT_VENDOR:
1336411677aeSAaron LI alen_bogus = alen % 8 != 0; /* already >= 8 so far */
1337411677aeSAaron LI break;
1338411677aeSAaron LI default:
1339411677aeSAaron LI skip = 1;
1340411677aeSAaron LI }
1341411677aeSAaron LI if (alen_bogus) {
1342*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (bogus)");
1343411677aeSAaron LI skip = 1;
1344411677aeSAaron LI }
1345411677aeSAaron LI if (skip) {
1346*ed775ee7SAntonio Huete Jimenez /*
1347*ed775ee7SAntonio Huete Jimenez * alen >= OF_ACTION_MINLEN
1348*ed775ee7SAntonio Huete Jimenez * cp is 4 bytes in
1349*ed775ee7SAntonio Huete Jimenez */
1350*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(alen - 4);
1351*ed775ee7SAntonio Huete Jimenez continue;
1352411677aeSAaron LI }
1353411677aeSAaron LI /* OK to decode the rest of the action structure */
1354411677aeSAaron LI switch (type) {
1355411677aeSAaron LI case OFPAT_OUTPUT:
1356411677aeSAaron LI /* port */
1357*ed775ee7SAntonio Huete Jimenez output_port = GET_BE_U_2(cp);
1358*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1359*ed775ee7SAntonio Huete Jimenez ND_PRINT(", port %s", tok2str(ofpp_str, "%u", output_port));
1360411677aeSAaron LI /* max_len */
1361411677aeSAaron LI if (output_port == OFPP_CONTROLLER)
1362*ed775ee7SAntonio Huete Jimenez ND_PRINT(", max_len %u", GET_BE_U_2(cp));
1363*ed775ee7SAntonio Huete Jimenez else
1364*ed775ee7SAntonio Huete Jimenez ND_TCHECK_2(cp);
1365*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1366411677aeSAaron LI break;
1367411677aeSAaron LI case OFPAT_SET_VLAN_VID:
1368411677aeSAaron LI /* vlan_vid */
1369*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vlan_vid %s", vlan_str(GET_BE_U_2(cp)));
1370*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1371411677aeSAaron LI /* pad */
1372*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1373*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(2);
1374411677aeSAaron LI break;
1375411677aeSAaron LI case OFPAT_SET_VLAN_PCP:
1376411677aeSAaron LI /* vlan_pcp */
1377*ed775ee7SAntonio Huete Jimenez ND_PRINT(", vlan_pcp %s", pcp_str(GET_U_1(cp)));
1378*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
1379411677aeSAaron LI /* pad */
1380*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1381*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(3);
1382411677aeSAaron LI break;
1383411677aeSAaron LI case OFPAT_SET_DL_SRC:
1384411677aeSAaron LI case OFPAT_SET_DL_DST:
1385411677aeSAaron LI /* dl_addr */
1386*ed775ee7SAntonio Huete Jimenez ND_PRINT(", dl_addr %s", GET_ETHERADDR_STRING(cp));
1387*ed775ee7SAntonio Huete Jimenez OF_FWD(MAC_ADDR_LEN);
1388411677aeSAaron LI /* pad */
1389*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1390*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(6);
1391411677aeSAaron LI break;
1392411677aeSAaron LI case OFPAT_SET_NW_SRC:
1393411677aeSAaron LI case OFPAT_SET_NW_DST:
1394411677aeSAaron LI /* nw_addr */
1395*ed775ee7SAntonio Huete Jimenez ND_PRINT(", nw_addr %s", GET_IPADDR_STRING(cp));
1396*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1397411677aeSAaron LI break;
1398411677aeSAaron LI case OFPAT_SET_NW_TOS:
1399411677aeSAaron LI /* nw_tos */
1400*ed775ee7SAntonio Huete Jimenez ND_PRINT(", nw_tos 0x%02x", GET_U_1(cp));
1401*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
1402411677aeSAaron LI /* pad */
1403*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1404*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(3);
1405411677aeSAaron LI break;
1406411677aeSAaron LI case OFPAT_SET_TP_SRC:
1407411677aeSAaron LI case OFPAT_SET_TP_DST:
1408411677aeSAaron LI /* nw_tos */
1409*ed775ee7SAntonio Huete Jimenez ND_PRINT(", tp_port %u", GET_BE_U_2(cp));
1410*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1411411677aeSAaron LI /* pad */
1412*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1413*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(2);
1414411677aeSAaron LI break;
1415411677aeSAaron LI case OFPAT_ENQUEUE:
1416411677aeSAaron LI /* port */
1417*ed775ee7SAntonio Huete Jimenez ND_PRINT(", port %s",
1418*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1419*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1420411677aeSAaron LI /* pad */
1421*ed775ee7SAntonio Huete Jimenez OF_FWD(6);
1422411677aeSAaron LI /* queue_id */
1423*ed775ee7SAntonio Huete Jimenez ND_PRINT(", queue_id %s",
1424*ed775ee7SAntonio Huete Jimenez tok2str(ofpq_str, "%u", GET_BE_U_4(cp)));
1425*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1426411677aeSAaron LI break;
1427411677aeSAaron LI case OFPAT_VENDOR:
1428*ed775ee7SAntonio Huete Jimenez of10_vendor_action_print(ndo, cp, alen - 4);
1429*ed775ee7SAntonio Huete Jimenez OF_FWD(alen - 4);
1430411677aeSAaron LI break;
1431411677aeSAaron LI case OFPAT_STRIP_VLAN:
1432411677aeSAaron LI /* pad */
1433*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1434*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(4);
1435411677aeSAaron LI break;
1436411677aeSAaron LI } /* switch */
1437411677aeSAaron LI } /* while */
1438*ed775ee7SAntonio Huete Jimenez return;
1439411677aeSAaron LI
1440411677aeSAaron LI invalid: /* skip the rest of actions */
1441*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1442*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1443411677aeSAaron LI }
1444411677aeSAaron LI
1445411677aeSAaron LI /* [OF10] Section 5.3.1 */
1446*ed775ee7SAntonio Huete Jimenez static void
of10_features_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1447411677aeSAaron LI of10_features_reply_print(netdissect_options *ndo,
1448*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1449411677aeSAaron LI {
1450411677aeSAaron LI /* datapath_id */
1451*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t dpid 0x%016" PRIx64, GET_BE_U_8(cp));
1452*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1453411677aeSAaron LI /* n_buffers */
1454*ed775ee7SAntonio Huete Jimenez ND_PRINT(", n_buffers %u", GET_BE_U_4(cp));
1455*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1456411677aeSAaron LI /* n_tables */
1457*ed775ee7SAntonio Huete Jimenez ND_PRINT(", n_tables %u", GET_U_1(cp));
1458*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
1459411677aeSAaron LI /* pad */
1460*ed775ee7SAntonio Huete Jimenez OF_FWD(3);
1461411677aeSAaron LI /* capabilities */
1462*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t capabilities 0x%08x", GET_BE_U_4(cp));
1463*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofp_capabilities_bm, GET_BE_U_4(cp), OFPCAP_U);
1464*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1465411677aeSAaron LI /* actions */
1466*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t actions 0x%08x", GET_BE_U_4(cp));
1467*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofpat_bm, GET_BE_U_4(cp), OFPAT_U);
1468*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1469411677aeSAaron LI /* ports */
1470*ed775ee7SAntonio Huete Jimenez while (len) {
1471*ed775ee7SAntonio Huete Jimenez if (len < OF_PHY_PORT_FIXLEN)
1472*ed775ee7SAntonio Huete Jimenez goto invalid;
1473*ed775ee7SAntonio Huete Jimenez of10_phy_port_print(ndo, cp);
1474*ed775ee7SAntonio Huete Jimenez OF_FWD(OF_PHY_PORT_FIXLEN);
1475*ed775ee7SAntonio Huete Jimenez }
1476*ed775ee7SAntonio Huete Jimenez return;
1477411677aeSAaron LI
1478*ed775ee7SAntonio Huete Jimenez invalid: /* skip the undersized trailing data */
1479*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1480*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1481*ed775ee7SAntonio Huete Jimenez }
1482*ed775ee7SAntonio Huete Jimenez
1483*ed775ee7SAntonio Huete Jimenez /* [OF10] Section 5.3.2 */
1484*ed775ee7SAntonio Huete Jimenez static void
of10_switch_config_msg_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)1485*ed775ee7SAntonio Huete Jimenez of10_switch_config_msg_print(netdissect_options *ndo,
1486*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len _U_)
1487*ed775ee7SAntonio Huete Jimenez {
1488*ed775ee7SAntonio Huete Jimenez /* flags */
1489*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t flags %s",
1490*ed775ee7SAntonio Huete Jimenez tok2str(ofp_config_str, "invalid (0x%04x)", GET_BE_U_2(cp)));
1491*ed775ee7SAntonio Huete Jimenez cp += 2;
1492*ed775ee7SAntonio Huete Jimenez /* miss_send_len */
1493*ed775ee7SAntonio Huete Jimenez ND_PRINT(", miss_send_len %u", GET_BE_U_2(cp));
1494411677aeSAaron LI }
1495411677aeSAaron LI
1496411677aeSAaron LI /* [OF10] Section 5.3.3 */
1497*ed775ee7SAntonio Huete Jimenez static void
of10_flow_mod_print(netdissect_options * ndo,const u_char * cp,u_int len)1498411677aeSAaron LI of10_flow_mod_print(netdissect_options *ndo,
1499*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1500411677aeSAaron LI {
1501411677aeSAaron LI uint16_t command;
1502411677aeSAaron LI
1503411677aeSAaron LI /* match */
1504*ed775ee7SAntonio Huete Jimenez of10_match_print(ndo, "\n\t ", cp);
1505*ed775ee7SAntonio Huete Jimenez OF_FWD(OF_MATCH_FIXLEN);
1506411677aeSAaron LI /* cookie */
1507*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t cookie 0x%016" PRIx64, GET_BE_U_8(cp));
1508*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1509411677aeSAaron LI /* command */
1510*ed775ee7SAntonio Huete Jimenez command = GET_BE_U_2(cp);
1511*ed775ee7SAntonio Huete Jimenez ND_PRINT(", command %s", tok2str(ofpfc_str, "invalid (0x%04x)", command));
1512*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1513411677aeSAaron LI /* idle_timeout */
1514*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(cp))
1515*ed775ee7SAntonio Huete Jimenez ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp));
1516*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1517411677aeSAaron LI /* hard_timeout */
1518*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(cp))
1519*ed775ee7SAntonio Huete Jimenez ND_PRINT(", hard_timeout %u", GET_BE_U_2(cp));
1520*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1521411677aeSAaron LI /* priority */
1522*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(cp))
1523*ed775ee7SAntonio Huete Jimenez ND_PRINT(", priority %u", GET_BE_U_2(cp));
1524*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1525411677aeSAaron LI /* buffer_id */
1526411677aeSAaron LI if (command == OFPFC_ADD || command == OFPFC_MODIFY ||
1527411677aeSAaron LI command == OFPFC_MODIFY_STRICT)
1528*ed775ee7SAntonio Huete Jimenez ND_PRINT(", buffer_id %s",
1529*ed775ee7SAntonio Huete Jimenez tok2str(bufferid_str, "0x%08x", GET_BE_U_4(cp)));
1530*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1531411677aeSAaron LI /* out_port */
1532411677aeSAaron LI if (command == OFPFC_DELETE || command == OFPFC_DELETE_STRICT)
1533*ed775ee7SAntonio Huete Jimenez ND_PRINT(", out_port %s",
1534*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1535*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1536411677aeSAaron LI /* flags */
1537*ed775ee7SAntonio Huete Jimenez ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp));
1538*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofpff_bm, GET_BE_U_2(cp), OFPFF_U);
1539*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1540411677aeSAaron LI /* actions */
1541*ed775ee7SAntonio Huete Jimenez of10_actions_print(ndo, "\n\t ", cp, len);
1542411677aeSAaron LI }
1543411677aeSAaron LI
1544411677aeSAaron LI /* ibid */
1545*ed775ee7SAntonio Huete Jimenez static void
of10_port_mod_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)1546411677aeSAaron LI of10_port_mod_print(netdissect_options *ndo,
1547*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len _U_)
1548411677aeSAaron LI {
1549411677aeSAaron LI /* port_no */
1550*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t port_no %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1551411677aeSAaron LI cp += 2;
1552411677aeSAaron LI /* hw_addr */
1553*ed775ee7SAntonio Huete Jimenez ND_PRINT(", hw_addr %s", GET_ETHERADDR_STRING(cp));
1554*ed775ee7SAntonio Huete Jimenez cp += MAC_ADDR_LEN;
1555411677aeSAaron LI /* config */
1556*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t config 0x%08x", GET_BE_U_4(cp));
1557*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U);
1558411677aeSAaron LI cp += 4;
1559411677aeSAaron LI /* mask */
1560*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t mask 0x%08x", GET_BE_U_4(cp));
1561*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofppc_bm, GET_BE_U_4(cp), OFPPC_U);
1562411677aeSAaron LI cp += 4;
1563411677aeSAaron LI /* advertise */
1564*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t advertise 0x%08x", GET_BE_U_4(cp));
1565*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofppf_bm, GET_BE_U_4(cp), OFPPF_U);
1566411677aeSAaron LI cp += 4;
1567411677aeSAaron LI /* pad */
1568*ed775ee7SAntonio Huete Jimenez /* Always the last field, check bounds. */
1569*ed775ee7SAntonio Huete Jimenez ND_TCHECK_4(cp);
1570*ed775ee7SAntonio Huete Jimenez }
1571411677aeSAaron LI
1572*ed775ee7SAntonio Huete Jimenez /* [OF10] Section 5.3.4 */
1573*ed775ee7SAntonio Huete Jimenez static void
of10_queue_get_config_request_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)1574*ed775ee7SAntonio Huete Jimenez of10_queue_get_config_request_print(netdissect_options *ndo,
1575*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len _U_)
1576*ed775ee7SAntonio Huete Jimenez {
1577*ed775ee7SAntonio Huete Jimenez /* port */
1578*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1579*ed775ee7SAntonio Huete Jimenez cp += 2;
1580*ed775ee7SAntonio Huete Jimenez /* pad */
1581*ed775ee7SAntonio Huete Jimenez /* Always the last field, check bounds. */
1582*ed775ee7SAntonio Huete Jimenez ND_TCHECK_2(cp);
1583*ed775ee7SAntonio Huete Jimenez }
1584*ed775ee7SAntonio Huete Jimenez
1585*ed775ee7SAntonio Huete Jimenez /* ibid */
1586*ed775ee7SAntonio Huete Jimenez static void
of10_queue_get_config_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1587*ed775ee7SAntonio Huete Jimenez of10_queue_get_config_reply_print(netdissect_options *ndo,
1588*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1589*ed775ee7SAntonio Huete Jimenez {
1590*ed775ee7SAntonio Huete Jimenez /* port */
1591*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1592*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1593*ed775ee7SAntonio Huete Jimenez /* pad */
1594*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
1595*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(6);
1596*ed775ee7SAntonio Huete Jimenez /* queues */
1597*ed775ee7SAntonio Huete Jimenez of10_queues_print(ndo, cp, len);
1598411677aeSAaron LI }
1599411677aeSAaron LI
1600411677aeSAaron LI /* [OF10] Section 5.3.5 */
1601*ed775ee7SAntonio Huete Jimenez static void
of10_stats_request_print(netdissect_options * ndo,const u_char * cp,u_int len)1602411677aeSAaron LI of10_stats_request_print(netdissect_options *ndo,
1603*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1604411677aeSAaron LI {
1605411677aeSAaron LI uint16_t type;
1606411677aeSAaron LI
1607411677aeSAaron LI /* type */
1608*ed775ee7SAntonio Huete Jimenez type = GET_BE_U_2(cp);
1609*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1610*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type));
1611411677aeSAaron LI /* flags */
1612*ed775ee7SAntonio Huete Jimenez ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp));
1613*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(cp))
1614*ed775ee7SAntonio Huete Jimenez ND_PRINT(" (bogus)");
1615*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1616411677aeSAaron LI /* type-specific body of one of fixed lengths */
1617411677aeSAaron LI switch(type) {
1618411677aeSAaron LI case OFPST_DESC:
1619411677aeSAaron LI case OFPST_TABLE:
1620411677aeSAaron LI if (len)
1621411677aeSAaron LI goto invalid;
1622*ed775ee7SAntonio Huete Jimenez return;
1623411677aeSAaron LI case OFPST_FLOW:
1624411677aeSAaron LI case OFPST_AGGREGATE:
1625*ed775ee7SAntonio Huete Jimenez if (len != OF_FLOW_STATS_REQUEST_FIXLEN)
1626411677aeSAaron LI goto invalid;
1627411677aeSAaron LI /* match */
1628*ed775ee7SAntonio Huete Jimenez of10_match_print(ndo, "\n\t ", cp);
1629*ed775ee7SAntonio Huete Jimenez OF_FWD(OF_MATCH_FIXLEN);
1630411677aeSAaron LI /* table_id */
1631*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t table_id %s",
1632*ed775ee7SAntonio Huete Jimenez tok2str(tableid_str, "%u", GET_U_1(cp)));
1633*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
1634411677aeSAaron LI /* pad */
1635*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
1636411677aeSAaron LI /* out_port */
1637*ed775ee7SAntonio Huete Jimenez ND_PRINT(", out_port %s",
1638*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1639*ed775ee7SAntonio Huete Jimenez return;
1640411677aeSAaron LI case OFPST_PORT:
1641*ed775ee7SAntonio Huete Jimenez if (len != OF_PORT_STATS_REQUEST_FIXLEN)
1642411677aeSAaron LI goto invalid;
1643411677aeSAaron LI /* port_no */
1644*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t port_no %s",
1645*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1646*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1647411677aeSAaron LI /* pad */
1648*ed775ee7SAntonio Huete Jimenez /* Always the last field, check bounds. */
1649*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(6);
1650*ed775ee7SAntonio Huete Jimenez return;
1651411677aeSAaron LI case OFPST_QUEUE:
1652*ed775ee7SAntonio Huete Jimenez if (len != OF_QUEUE_STATS_REQUEST_FIXLEN)
1653411677aeSAaron LI goto invalid;
1654411677aeSAaron LI /* port_no */
1655*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t port_no %s",
1656*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1657*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1658411677aeSAaron LI /* pad */
1659*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1660411677aeSAaron LI /* queue_id */
1661*ed775ee7SAntonio Huete Jimenez ND_PRINT(", queue_id %s",
1662*ed775ee7SAntonio Huete Jimenez tok2str(ofpq_str, "%u", GET_BE_U_4(cp)));
1663*ed775ee7SAntonio Huete Jimenez return;
1664411677aeSAaron LI case OFPST_VENDOR:
1665*ed775ee7SAntonio Huete Jimenez of10_vendor_data_print(ndo, cp, len);
1666*ed775ee7SAntonio Huete Jimenez return;
1667411677aeSAaron LI }
1668*ed775ee7SAntonio Huete Jimenez return;
1669411677aeSAaron LI
1670411677aeSAaron LI invalid: /* skip the message body */
1671*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1672*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1673411677aeSAaron LI }
1674411677aeSAaron LI
1675411677aeSAaron LI /* ibid */
1676*ed775ee7SAntonio Huete Jimenez static void
of10_desc_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1677411677aeSAaron LI of10_desc_stats_reply_print(netdissect_options *ndo,
1678*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1679411677aeSAaron LI {
1680*ed775ee7SAntonio Huete Jimenez if (len != OF_DESC_STATS_REPLY_FIXLEN)
1681411677aeSAaron LI goto invalid;
1682411677aeSAaron LI /* mfr_desc */
1683*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t mfr_desc '");
1684*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, cp, DESC_STR_LEN);
1685*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
1686*ed775ee7SAntonio Huete Jimenez OF_FWD(DESC_STR_LEN);
1687411677aeSAaron LI /* hw_desc */
1688*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t hw_desc '");
1689*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, cp, DESC_STR_LEN);
1690*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
1691*ed775ee7SAntonio Huete Jimenez OF_FWD(DESC_STR_LEN);
1692411677aeSAaron LI /* sw_desc */
1693*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t sw_desc '");
1694*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, cp, DESC_STR_LEN);
1695*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
1696*ed775ee7SAntonio Huete Jimenez OF_FWD(DESC_STR_LEN);
1697411677aeSAaron LI /* serial_num */
1698*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t serial_num '");
1699*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, cp, SERIAL_NUM_LEN);
1700*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
1701*ed775ee7SAntonio Huete Jimenez OF_FWD(SERIAL_NUM_LEN);
1702411677aeSAaron LI /* dp_desc */
1703*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t dp_desc '");
1704*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, cp, DESC_STR_LEN);
1705*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
1706*ed775ee7SAntonio Huete Jimenez return;
1707411677aeSAaron LI
1708411677aeSAaron LI invalid: /* skip the message body */
1709*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1710*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1711411677aeSAaron LI }
1712411677aeSAaron LI
1713411677aeSAaron LI /* ibid */
1714*ed775ee7SAntonio Huete Jimenez static void
of10_flow_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1715411677aeSAaron LI of10_flow_stats_reply_print(netdissect_options *ndo,
1716*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1717411677aeSAaron LI {
1718*ed775ee7SAntonio Huete Jimenez while (len) {
1719411677aeSAaron LI uint16_t entry_len;
1720411677aeSAaron LI
1721*ed775ee7SAntonio Huete Jimenez if (len < OF_FLOW_STATS_REPLY_MINLEN)
1722411677aeSAaron LI goto invalid;
1723411677aeSAaron LI /* length */
1724*ed775ee7SAntonio Huete Jimenez entry_len = GET_BE_U_2(cp);
1725*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t length %u", entry_len);
1726*ed775ee7SAntonio Huete Jimenez if (entry_len < OF_FLOW_STATS_REPLY_MINLEN || entry_len > len)
1727411677aeSAaron LI goto invalid;
1728*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1729411677aeSAaron LI /* table_id */
1730*ed775ee7SAntonio Huete Jimenez ND_PRINT(", table_id %s",
1731*ed775ee7SAntonio Huete Jimenez tok2str(tableid_str, "%u", GET_U_1(cp)));
1732*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
1733411677aeSAaron LI /* pad */
1734*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
1735411677aeSAaron LI /* match */
1736*ed775ee7SAntonio Huete Jimenez of10_match_print(ndo, "\n\t ", cp);
1737*ed775ee7SAntonio Huete Jimenez OF_FWD(OF_MATCH_FIXLEN);
1738411677aeSAaron LI /* duration_sec */
1739*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t duration_sec %u", GET_BE_U_4(cp));
1740*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1741411677aeSAaron LI /* duration_nsec */
1742*ed775ee7SAntonio Huete Jimenez ND_PRINT(", duration_nsec %u", GET_BE_U_4(cp));
1743*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1744411677aeSAaron LI /* priority */
1745*ed775ee7SAntonio Huete Jimenez ND_PRINT(", priority %u", GET_BE_U_2(cp));
1746*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1747411677aeSAaron LI /* idle_timeout */
1748*ed775ee7SAntonio Huete Jimenez ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp));
1749*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1750411677aeSAaron LI /* hard_timeout */
1751*ed775ee7SAntonio Huete Jimenez ND_PRINT(", hard_timeout %u", GET_BE_U_2(cp));
1752*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1753411677aeSAaron LI /* pad2 */
1754*ed775ee7SAntonio Huete Jimenez OF_FWD(6);
1755411677aeSAaron LI /* cookie */
1756*ed775ee7SAntonio Huete Jimenez ND_PRINT(", cookie 0x%016" PRIx64, GET_BE_U_8(cp));
1757*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1758411677aeSAaron LI /* packet_count */
1759*ed775ee7SAntonio Huete Jimenez ND_PRINT(", packet_count %" PRIu64, GET_BE_U_8(cp));
1760*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1761411677aeSAaron LI /* byte_count */
1762*ed775ee7SAntonio Huete Jimenez ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp));
1763*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1764411677aeSAaron LI /* actions */
1765*ed775ee7SAntonio Huete Jimenez of10_actions_print(ndo, "\n\t ", cp, entry_len - OF_FLOW_STATS_REPLY_MINLEN);
1766*ed775ee7SAntonio Huete Jimenez OF_FWD(entry_len - OF_FLOW_STATS_REPLY_MINLEN);
1767411677aeSAaron LI } /* while */
1768*ed775ee7SAntonio Huete Jimenez return;
1769411677aeSAaron LI
1770411677aeSAaron LI invalid: /* skip the rest of flow statistics entries */
1771*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1772*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1773411677aeSAaron LI }
1774411677aeSAaron LI
1775411677aeSAaron LI /* ibid */
1776*ed775ee7SAntonio Huete Jimenez static void
of10_aggregate_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1777411677aeSAaron LI of10_aggregate_stats_reply_print(netdissect_options *ndo,
1778*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1779411677aeSAaron LI {
1780*ed775ee7SAntonio Huete Jimenez if (len != OF_AGGREGATE_STATS_REPLY_FIXLEN)
1781411677aeSAaron LI goto invalid;
1782411677aeSAaron LI /* packet_count */
1783*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t packet_count %" PRIu64, GET_BE_U_8(cp));
1784*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1785411677aeSAaron LI /* byte_count */
1786*ed775ee7SAntonio Huete Jimenez ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp));
1787*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1788411677aeSAaron LI /* flow_count */
1789*ed775ee7SAntonio Huete Jimenez ND_PRINT(", flow_count %u", GET_BE_U_4(cp));
1790*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1791411677aeSAaron LI /* pad */
1792*ed775ee7SAntonio Huete Jimenez /* Always the last field, check bounds. */
1793*ed775ee7SAntonio Huete Jimenez ND_TCHECK_4(cp);
1794*ed775ee7SAntonio Huete Jimenez return;
1795411677aeSAaron LI
1796411677aeSAaron LI invalid: /* skip the message body */
1797*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1798*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1799411677aeSAaron LI }
1800411677aeSAaron LI
1801411677aeSAaron LI /* ibid */
1802*ed775ee7SAntonio Huete Jimenez static void
of10_table_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1803411677aeSAaron LI of10_table_stats_reply_print(netdissect_options *ndo,
1804*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1805411677aeSAaron LI {
1806411677aeSAaron LI while (len) {
1807*ed775ee7SAntonio Huete Jimenez if (len < OF_TABLE_STATS_REPLY_FIXLEN)
1808411677aeSAaron LI goto invalid;
1809411677aeSAaron LI /* table_id */
1810*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t table_id %s",
1811*ed775ee7SAntonio Huete Jimenez tok2str(tableid_str, "%u", GET_U_1(cp)));
1812*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
1813411677aeSAaron LI /* pad */
1814*ed775ee7SAntonio Huete Jimenez OF_FWD(3);
1815411677aeSAaron LI /* name */
1816*ed775ee7SAntonio Huete Jimenez ND_PRINT(", name '");
1817*ed775ee7SAntonio Huete Jimenez nd_printjnp(ndo, cp, OFP_MAX_TABLE_NAME_LEN);
1818*ed775ee7SAntonio Huete Jimenez ND_PRINT("'");
1819*ed775ee7SAntonio Huete Jimenez OF_FWD(OFP_MAX_TABLE_NAME_LEN);
1820411677aeSAaron LI /* wildcards */
1821*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t wildcards 0x%08x", GET_BE_U_4(cp));
1822*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofpfw_bm, GET_BE_U_4(cp), OFPFW_U);
1823*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1824411677aeSAaron LI /* max_entries */
1825*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t max_entries %u", GET_BE_U_4(cp));
1826*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1827411677aeSAaron LI /* active_count */
1828*ed775ee7SAntonio Huete Jimenez ND_PRINT(", active_count %u", GET_BE_U_4(cp));
1829*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1830411677aeSAaron LI /* lookup_count */
1831*ed775ee7SAntonio Huete Jimenez ND_PRINT(", lookup_count %" PRIu64, GET_BE_U_8(cp));
1832*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1833411677aeSAaron LI /* matched_count */
1834*ed775ee7SAntonio Huete Jimenez ND_PRINT(", matched_count %" PRIu64, GET_BE_U_8(cp));
1835*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1836411677aeSAaron LI } /* while */
1837*ed775ee7SAntonio Huete Jimenez return;
1838411677aeSAaron LI
1839411677aeSAaron LI invalid: /* skip the undersized trailing data */
1840*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1841*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1842411677aeSAaron LI }
1843411677aeSAaron LI
1844411677aeSAaron LI /* ibid */
1845*ed775ee7SAntonio Huete Jimenez static void
of10_port_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1846411677aeSAaron LI of10_port_stats_reply_print(netdissect_options *ndo,
1847*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1848411677aeSAaron LI {
1849411677aeSAaron LI while (len) {
1850*ed775ee7SAntonio Huete Jimenez if (len < OF_PORT_STATS_REPLY_FIXLEN)
1851411677aeSAaron LI goto invalid;
1852411677aeSAaron LI /* port_no */
1853*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t port_no %s",
1854*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1855*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1856411677aeSAaron LI if (ndo->ndo_vflag < 2) {
1857*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(OF_PORT_STATS_REPLY_FIXLEN - 2);
1858*ed775ee7SAntonio Huete Jimenez continue;
1859411677aeSAaron LI }
1860411677aeSAaron LI /* pad */
1861*ed775ee7SAntonio Huete Jimenez OF_FWD(6);
1862411677aeSAaron LI /* rx_packets */
1863*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rx_packets %" PRIu64, GET_BE_U_8(cp));
1864*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1865411677aeSAaron LI /* tx_packets */
1866*ed775ee7SAntonio Huete Jimenez ND_PRINT(", tx_packets %" PRIu64, GET_BE_U_8(cp));
1867*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1868411677aeSAaron LI /* rx_bytes */
1869*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rx_bytes %" PRIu64, GET_BE_U_8(cp));
1870*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1871411677aeSAaron LI /* tx_bytes */
1872*ed775ee7SAntonio Huete Jimenez ND_PRINT(", tx_bytes %" PRIu64, GET_BE_U_8(cp));
1873*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1874411677aeSAaron LI /* rx_dropped */
1875*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rx_dropped %" PRIu64, GET_BE_U_8(cp));
1876*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1877411677aeSAaron LI /* tx_dropped */
1878*ed775ee7SAntonio Huete Jimenez ND_PRINT(", tx_dropped %" PRIu64, GET_BE_U_8(cp));
1879*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1880411677aeSAaron LI /* rx_errors */
1881*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rx_errors %" PRIu64, GET_BE_U_8(cp));
1882*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1883411677aeSAaron LI /* tx_errors */
1884*ed775ee7SAntonio Huete Jimenez ND_PRINT(", tx_errors %" PRIu64, GET_BE_U_8(cp));
1885*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1886411677aeSAaron LI /* rx_frame_err */
1887*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rx_frame_err %" PRIu64, GET_BE_U_8(cp));
1888*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1889411677aeSAaron LI /* rx_over_err */
1890*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rx_over_err %" PRIu64, GET_BE_U_8(cp));
1891*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1892411677aeSAaron LI /* rx_crc_err */
1893*ed775ee7SAntonio Huete Jimenez ND_PRINT(", rx_crc_err %" PRIu64, GET_BE_U_8(cp));
1894*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1895411677aeSAaron LI /* collisions */
1896*ed775ee7SAntonio Huete Jimenez ND_PRINT(", collisions %" PRIu64, GET_BE_U_8(cp));
1897*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1898411677aeSAaron LI } /* while */
1899*ed775ee7SAntonio Huete Jimenez return;
1900411677aeSAaron LI
1901411677aeSAaron LI invalid: /* skip the undersized trailing data */
1902*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1903*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1904411677aeSAaron LI }
1905411677aeSAaron LI
1906411677aeSAaron LI /* ibid */
1907*ed775ee7SAntonio Huete Jimenez static void
of10_queue_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1908411677aeSAaron LI of10_queue_stats_reply_print(netdissect_options *ndo,
1909*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1910411677aeSAaron LI {
1911411677aeSAaron LI while (len) {
1912*ed775ee7SAntonio Huete Jimenez if (len < OF_QUEUE_STATS_REPLY_FIXLEN)
1913411677aeSAaron LI goto invalid;
1914411677aeSAaron LI /* port_no */
1915*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t port_no %s",
1916*ed775ee7SAntonio Huete Jimenez tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1917*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1918411677aeSAaron LI /* pad */
1919*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1920411677aeSAaron LI /* queue_id */
1921*ed775ee7SAntonio Huete Jimenez ND_PRINT(", queue_id %u", GET_BE_U_4(cp));
1922*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1923411677aeSAaron LI /* tx_bytes */
1924*ed775ee7SAntonio Huete Jimenez ND_PRINT(", tx_bytes %" PRIu64, GET_BE_U_8(cp));
1925*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1926411677aeSAaron LI /* tx_packets */
1927*ed775ee7SAntonio Huete Jimenez ND_PRINT(", tx_packets %" PRIu64, GET_BE_U_8(cp));
1928*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1929411677aeSAaron LI /* tx_errors */
1930*ed775ee7SAntonio Huete Jimenez ND_PRINT(", tx_errors %" PRIu64, GET_BE_U_8(cp));
1931*ed775ee7SAntonio Huete Jimenez OF_FWD(8);
1932411677aeSAaron LI } /* while */
1933*ed775ee7SAntonio Huete Jimenez return;
1934411677aeSAaron LI
1935411677aeSAaron LI invalid: /* skip the undersized trailing data */
1936*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
1937*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1938411677aeSAaron LI }
1939411677aeSAaron LI
1940411677aeSAaron LI /* ibid */
1941*ed775ee7SAntonio Huete Jimenez static void
of10_stats_reply_print(netdissect_options * ndo,const u_char * cp,u_int len)1942411677aeSAaron LI of10_stats_reply_print(netdissect_options *ndo,
1943*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1944411677aeSAaron LI {
1945411677aeSAaron LI uint16_t type;
1946411677aeSAaron LI
1947411677aeSAaron LI /* type */
1948*ed775ee7SAntonio Huete Jimenez type = GET_BE_U_2(cp);
1949*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type));
1950*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1951411677aeSAaron LI /* flags */
1952*ed775ee7SAntonio Huete Jimenez ND_PRINT(", flags 0x%04x", GET_BE_U_2(cp));
1953*ed775ee7SAntonio Huete Jimenez of_bitmap_print(ndo, ofpsf_reply_bm, GET_BE_U_2(cp), OFPSF_REPLY_U);
1954*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1955411677aeSAaron LI
1956411677aeSAaron LI if (ndo->ndo_vflag > 0) {
1957*ed775ee7SAntonio Huete Jimenez void (*decoder)(netdissect_options *, const u_char *, u_int) =
1958411677aeSAaron LI type == OFPST_DESC ? of10_desc_stats_reply_print :
1959411677aeSAaron LI type == OFPST_FLOW ? of10_flow_stats_reply_print :
1960411677aeSAaron LI type == OFPST_AGGREGATE ? of10_aggregate_stats_reply_print :
1961411677aeSAaron LI type == OFPST_TABLE ? of10_table_stats_reply_print :
1962411677aeSAaron LI type == OFPST_PORT ? of10_port_stats_reply_print :
1963411677aeSAaron LI type == OFPST_QUEUE ? of10_queue_stats_reply_print :
1964411677aeSAaron LI type == OFPST_VENDOR ? of10_vendor_data_print :
1965411677aeSAaron LI NULL;
1966*ed775ee7SAntonio Huete Jimenez if (decoder != NULL) {
1967*ed775ee7SAntonio Huete Jimenez decoder(ndo, cp, len);
1968*ed775ee7SAntonio Huete Jimenez return;
1969411677aeSAaron LI }
1970*ed775ee7SAntonio Huete Jimenez }
1971*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
1972411677aeSAaron LI }
1973411677aeSAaron LI
1974411677aeSAaron LI /* [OF10] Section 5.3.6 */
1975*ed775ee7SAntonio Huete Jimenez static void
of10_packet_out_print(netdissect_options * ndo,const u_char * cp,u_int len)1976411677aeSAaron LI of10_packet_out_print(netdissect_options *ndo,
1977*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
1978411677aeSAaron LI {
1979411677aeSAaron LI uint16_t actions_len;
1980411677aeSAaron LI
1981411677aeSAaron LI /* buffer_id */
1982*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t buffer_id 0x%08x", GET_BE_U_4(cp));
1983*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
1984411677aeSAaron LI /* in_port */
1985*ed775ee7SAntonio Huete Jimenez ND_PRINT(", in_port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
1986*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1987411677aeSAaron LI /* actions_len */
1988*ed775ee7SAntonio Huete Jimenez actions_len = GET_BE_U_2(cp);
1989*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
1990*ed775ee7SAntonio Huete Jimenez if (actions_len > len)
1991411677aeSAaron LI goto invalid;
1992411677aeSAaron LI /* actions */
1993*ed775ee7SAntonio Huete Jimenez of10_actions_print(ndo, "\n\t ", cp, actions_len);
1994*ed775ee7SAntonio Huete Jimenez OF_FWD(actions_len);
1995411677aeSAaron LI /* data */
1996*ed775ee7SAntonio Huete Jimenez of10_packet_data_print(ndo, cp, len);
1997*ed775ee7SAntonio Huete Jimenez return;
1998411677aeSAaron LI
1999411677aeSAaron LI invalid: /* skip the rest of the message body */
2000*ed775ee7SAntonio Huete Jimenez nd_print_invalid(ndo);
2001*ed775ee7SAntonio Huete Jimenez ND_TCHECK_LEN(cp, len);
2002411677aeSAaron LI }
2003411677aeSAaron LI
2004411677aeSAaron LI /* [OF10] Section 5.4.1 */
2005*ed775ee7SAntonio Huete Jimenez static void
of10_packet_in_print(netdissect_options * ndo,const u_char * cp,u_int len)2006411677aeSAaron LI of10_packet_in_print(netdissect_options *ndo,
2007*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
2008411677aeSAaron LI {
2009411677aeSAaron LI /* buffer_id */
2010*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t buffer_id %s",
2011*ed775ee7SAntonio Huete Jimenez tok2str(bufferid_str, "0x%08x", GET_BE_U_4(cp)));
2012*ed775ee7SAntonio Huete Jimenez OF_FWD(4);
2013411677aeSAaron LI /* total_len */
2014*ed775ee7SAntonio Huete Jimenez ND_PRINT(", total_len %u", GET_BE_U_2(cp));
2015*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
2016411677aeSAaron LI /* in_port */
2017*ed775ee7SAntonio Huete Jimenez ND_PRINT(", in_port %s", tok2str(ofpp_str, "%u", GET_BE_U_2(cp)));
2018*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
2019411677aeSAaron LI /* reason */
2020*ed775ee7SAntonio Huete Jimenez ND_PRINT(", reason %s",
2021*ed775ee7SAntonio Huete Jimenez tok2str(ofpr_str, "invalid (0x%02x)", GET_U_1(cp)));
2022*ed775ee7SAntonio Huete Jimenez OF_FWD(1);
2023411677aeSAaron LI /* pad */
2024*ed775ee7SAntonio Huete Jimenez /* Sometimes the last field, check bounds. */
2025*ed775ee7SAntonio Huete Jimenez OF_CHK_FWD(1);
2026411677aeSAaron LI /* data */
2027*ed775ee7SAntonio Huete Jimenez of10_packet_data_print(ndo, cp, len);
2028411677aeSAaron LI }
2029411677aeSAaron LI
2030411677aeSAaron LI /* [OF10] Section 5.4.2 */
2031*ed775ee7SAntonio Huete Jimenez static void
of10_flow_removed_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)2032411677aeSAaron LI of10_flow_removed_print(netdissect_options *ndo,
2033*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len _U_)
2034411677aeSAaron LI {
2035411677aeSAaron LI /* match */
2036*ed775ee7SAntonio Huete Jimenez of10_match_print(ndo, "\n\t ", cp);
2037*ed775ee7SAntonio Huete Jimenez cp += OF_MATCH_FIXLEN;
2038411677aeSAaron LI /* cookie */
2039*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t cookie 0x%016" PRIx64, GET_BE_U_8(cp));
2040411677aeSAaron LI cp += 8;
2041411677aeSAaron LI /* priority */
2042*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(cp))
2043*ed775ee7SAntonio Huete Jimenez ND_PRINT(", priority %u", GET_BE_U_2(cp));
2044411677aeSAaron LI cp += 2;
2045411677aeSAaron LI /* reason */
2046*ed775ee7SAntonio Huete Jimenez ND_PRINT(", reason %s",
2047*ed775ee7SAntonio Huete Jimenez tok2str(ofprr_str, "unknown (0x%02x)", GET_U_1(cp)));
2048411677aeSAaron LI cp += 1;
2049411677aeSAaron LI /* pad */
2050411677aeSAaron LI cp += 1;
2051411677aeSAaron LI /* duration_sec */
2052*ed775ee7SAntonio Huete Jimenez ND_PRINT(", duration_sec %u", GET_BE_U_4(cp));
2053411677aeSAaron LI cp += 4;
2054411677aeSAaron LI /* duration_nsec */
2055*ed775ee7SAntonio Huete Jimenez ND_PRINT(", duration_nsec %u", GET_BE_U_4(cp));
2056411677aeSAaron LI cp += 4;
2057411677aeSAaron LI /* idle_timeout */
2058*ed775ee7SAntonio Huete Jimenez if (GET_BE_U_2(cp))
2059*ed775ee7SAntonio Huete Jimenez ND_PRINT(", idle_timeout %u", GET_BE_U_2(cp));
2060411677aeSAaron LI cp += 2;
2061411677aeSAaron LI /* pad2 */
2062411677aeSAaron LI cp += 2;
2063411677aeSAaron LI /* packet_count */
2064*ed775ee7SAntonio Huete Jimenez ND_PRINT(", packet_count %" PRIu64, GET_BE_U_8(cp));
2065411677aeSAaron LI cp += 8;
2066411677aeSAaron LI /* byte_count */
2067*ed775ee7SAntonio Huete Jimenez ND_PRINT(", byte_count %" PRIu64, GET_BE_U_8(cp));
2068*ed775ee7SAntonio Huete Jimenez }
2069411677aeSAaron LI
2070*ed775ee7SAntonio Huete Jimenez /* [OF10] Section 5.4.3 */
2071*ed775ee7SAntonio Huete Jimenez static void
of10_port_status_print(netdissect_options * ndo,const u_char * cp,u_int len _U_)2072*ed775ee7SAntonio Huete Jimenez of10_port_status_print(netdissect_options *ndo,
2073*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len _U_)
2074*ed775ee7SAntonio Huete Jimenez {
2075*ed775ee7SAntonio Huete Jimenez /* reason */
2076*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t reason %s",
2077*ed775ee7SAntonio Huete Jimenez tok2str(ofppr_str, "invalid (0x%02x)", GET_U_1(cp)));
2078*ed775ee7SAntonio Huete Jimenez cp += 1;
2079*ed775ee7SAntonio Huete Jimenez /* pad */
2080*ed775ee7SAntonio Huete Jimenez /* No need to check bounds, more data follows. */
2081*ed775ee7SAntonio Huete Jimenez cp += 7;
2082*ed775ee7SAntonio Huete Jimenez /* desc */
2083*ed775ee7SAntonio Huete Jimenez of10_phy_port_print(ndo, cp);
2084411677aeSAaron LI }
2085411677aeSAaron LI
2086411677aeSAaron LI /* [OF10] Section 5.4.4 */
2087*ed775ee7SAntonio Huete Jimenez static void
of10_error_print(netdissect_options * ndo,const u_char * cp,u_int len)2088411677aeSAaron LI of10_error_print(netdissect_options *ndo,
2089*ed775ee7SAntonio Huete Jimenez const u_char *cp, u_int len)
2090411677aeSAaron LI {
2091*ed775ee7SAntonio Huete Jimenez uint16_t type, code;
2092411677aeSAaron LI const struct tok *code_str;
2093411677aeSAaron LI
2094411677aeSAaron LI /* type */
2095*ed775ee7SAntonio Huete Jimenez type = GET_BE_U_2(cp);
2096*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
2097*ed775ee7SAntonio Huete Jimenez ND_PRINT("\n\t type %s", tok2str(ofpet_str, "invalid (0x%04x)", type));
2098411677aeSAaron LI /* code */
2099*ed775ee7SAntonio Huete Jimenez code = GET_BE_U_2(cp);
2100*ed775ee7SAntonio Huete Jimenez OF_FWD(2);
2101*ed775ee7SAntonio Huete Jimenez code_str = uint2tokary(of10_ofpet2tokary, type);
2102*ed775ee7SAntonio Huete Jimenez if (code_str != NULL)
2103*ed775ee7SAntonio Huete Jimenez ND_PRINT(", code %s",
2104*ed775ee7SAntonio Huete Jimenez tok2str(code_str, "invalid (0x%04x)", code));
2105*ed775ee7SAntonio Huete Jimenez else
2106*ed775ee7SAntonio Huete Jimenez ND_PRINT(", code invalid (0x%04x)", code);
2107411677aeSAaron LI /* data */
2108*ed775ee7SAntonio Huete Jimenez of_data_print(ndo, cp, len);
2109411677aeSAaron LI }
2110411677aeSAaron LI
2111*ed775ee7SAntonio Huete Jimenez static const struct of_msgtypeinfo of10_msgtypeinfo[OFPT_MAX + 1] = {
2112*ed775ee7SAntonio Huete Jimenez /*
2113*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.5.1
2114*ed775ee7SAntonio Huete Jimenez * Variable-size data.
2115*ed775ee7SAntonio Huete Jimenez */
2116411677aeSAaron LI {
2117*ed775ee7SAntonio Huete Jimenez "HELLO", of_data_print,
2118*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, 0
2119*ed775ee7SAntonio Huete Jimenez },
2120*ed775ee7SAntonio Huete Jimenez /*
2121*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.4.4
2122*ed775ee7SAntonio Huete Jimenez * A fixed-size message body and variable-size data.
2123*ed775ee7SAntonio Huete Jimenez */
2124*ed775ee7SAntonio Huete Jimenez {
2125*ed775ee7SAntonio Huete Jimenez "ERROR", of10_error_print,
2126*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_ERROR_MSG_MINLEN
2127*ed775ee7SAntonio Huete Jimenez },
2128*ed775ee7SAntonio Huete Jimenez /*
2129*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.5.2
2130*ed775ee7SAntonio Huete Jimenez * Variable-size data.
2131*ed775ee7SAntonio Huete Jimenez */
2132*ed775ee7SAntonio Huete Jimenez {
2133*ed775ee7SAntonio Huete Jimenez "ECHO_REQUEST", of_data_print,
2134*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, 0
2135*ed775ee7SAntonio Huete Jimenez },
2136*ed775ee7SAntonio Huete Jimenez /*
2137*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.5.3
2138*ed775ee7SAntonio Huete Jimenez * Variable-size data.
2139*ed775ee7SAntonio Huete Jimenez */
2140*ed775ee7SAntonio Huete Jimenez {
2141*ed775ee7SAntonio Huete Jimenez "ECHO_REPLY", of_data_print,
2142*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, 0
2143*ed775ee7SAntonio Huete Jimenez },
2144*ed775ee7SAntonio Huete Jimenez /*
2145*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.5.4
2146*ed775ee7SAntonio Huete Jimenez * A fixed-size message body and variable-size data.
2147*ed775ee7SAntonio Huete Jimenez */
2148*ed775ee7SAntonio Huete Jimenez {
2149*ed775ee7SAntonio Huete Jimenez "VENDOR", of10_vendor_message_print,
2150*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_VENDOR_MINLEN
2151*ed775ee7SAntonio Huete Jimenez },
2152*ed775ee7SAntonio Huete Jimenez /*
2153*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.1
2154*ed775ee7SAntonio Huete Jimenez * No message body.
2155*ed775ee7SAntonio Huete Jimenez */
2156*ed775ee7SAntonio Huete Jimenez {
2157*ed775ee7SAntonio Huete Jimenez "FEATURES_REQUEST", NULL,
2158*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, 0
2159*ed775ee7SAntonio Huete Jimenez },
2160*ed775ee7SAntonio Huete Jimenez /*
2161*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.1
2162*ed775ee7SAntonio Huete Jimenez * A fixed-size message body and n * fixed-size data units.
2163*ed775ee7SAntonio Huete Jimenez */
2164*ed775ee7SAntonio Huete Jimenez {
2165*ed775ee7SAntonio Huete Jimenez "FEATURES_REPLY", of10_features_reply_print,
2166*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_FEATURES_REPLY_MINLEN
2167*ed775ee7SAntonio Huete Jimenez },
2168*ed775ee7SAntonio Huete Jimenez /*
2169*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.2
2170*ed775ee7SAntonio Huete Jimenez * No message body.
2171*ed775ee7SAntonio Huete Jimenez */
2172*ed775ee7SAntonio Huete Jimenez {
2173*ed775ee7SAntonio Huete Jimenez "GET_CONFIG_REQUEST", NULL,
2174*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, 0
2175*ed775ee7SAntonio Huete Jimenez },
2176*ed775ee7SAntonio Huete Jimenez /*
2177*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.2
2178*ed775ee7SAntonio Huete Jimenez * A fixed-size message body.
2179*ed775ee7SAntonio Huete Jimenez */
2180*ed775ee7SAntonio Huete Jimenez {
2181*ed775ee7SAntonio Huete Jimenez "GET_CONFIG_REPLY", of10_switch_config_msg_print,
2182*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, OF_SWITCH_CONFIG_FIXLEN
2183*ed775ee7SAntonio Huete Jimenez },
2184*ed775ee7SAntonio Huete Jimenez /*
2185*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.2
2186*ed775ee7SAntonio Huete Jimenez * A fixed-size message body.
2187*ed775ee7SAntonio Huete Jimenez */
2188*ed775ee7SAntonio Huete Jimenez {
2189*ed775ee7SAntonio Huete Jimenez "SET_CONFIG", of10_switch_config_msg_print,
2190*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, OF_SWITCH_CONFIG_FIXLEN
2191*ed775ee7SAntonio Huete Jimenez },
2192*ed775ee7SAntonio Huete Jimenez /*
2193*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.4.1
2194*ed775ee7SAntonio Huete Jimenez * A fixed-size message body and variable-size data.
2195*ed775ee7SAntonio Huete Jimenez * (The 2 mock octets count in OF_PACKET_IN_MINLEN only.)
2196*ed775ee7SAntonio Huete Jimenez */
2197*ed775ee7SAntonio Huete Jimenez {
2198*ed775ee7SAntonio Huete Jimenez "PACKET_IN", of10_packet_in_print,
2199*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_PACKET_IN_MINLEN - 2
2200*ed775ee7SAntonio Huete Jimenez },
2201*ed775ee7SAntonio Huete Jimenez /*
2202*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.4.2
2203*ed775ee7SAntonio Huete Jimenez * A fixed-size message body.
2204*ed775ee7SAntonio Huete Jimenez */
2205*ed775ee7SAntonio Huete Jimenez {
2206*ed775ee7SAntonio Huete Jimenez "FLOW_REMOVED", of10_flow_removed_print,
2207*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, OF_FLOW_REMOVED_FIXLEN
2208*ed775ee7SAntonio Huete Jimenez },
2209*ed775ee7SAntonio Huete Jimenez /*
2210*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.4.3
2211*ed775ee7SAntonio Huete Jimenez * A fixed-size message body.
2212*ed775ee7SAntonio Huete Jimenez */
2213*ed775ee7SAntonio Huete Jimenez {
2214*ed775ee7SAntonio Huete Jimenez "PORT_STATUS", of10_port_status_print,
2215*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, OF_PORT_STATUS_FIXLEN
2216*ed775ee7SAntonio Huete Jimenez },
2217*ed775ee7SAntonio Huete Jimenez /*
2218*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.6
2219*ed775ee7SAntonio Huete Jimenez * A fixed-size message body, n * variable-size data units and
2220*ed775ee7SAntonio Huete Jimenez * variable-size data.
2221*ed775ee7SAntonio Huete Jimenez */
2222*ed775ee7SAntonio Huete Jimenez {
2223*ed775ee7SAntonio Huete Jimenez "PACKET_OUT", of10_packet_out_print,
2224*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_PACKET_OUT_MINLEN
2225*ed775ee7SAntonio Huete Jimenez },
2226*ed775ee7SAntonio Huete Jimenez /*
2227*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.3
2228*ed775ee7SAntonio Huete Jimenez * A fixed-size message body and n * variable-size data units.
2229*ed775ee7SAntonio Huete Jimenez */
2230*ed775ee7SAntonio Huete Jimenez {
2231*ed775ee7SAntonio Huete Jimenez "FLOW_MOD", of10_flow_mod_print,
2232*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_FLOW_MOD_MINLEN
2233*ed775ee7SAntonio Huete Jimenez },
2234*ed775ee7SAntonio Huete Jimenez /*
2235*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.3
2236*ed775ee7SAntonio Huete Jimenez * A fixed-size message body.
2237*ed775ee7SAntonio Huete Jimenez */
2238*ed775ee7SAntonio Huete Jimenez {
2239*ed775ee7SAntonio Huete Jimenez "PORT_MOD", of10_port_mod_print,
2240*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, OF_PORT_MOD_FIXLEN
2241*ed775ee7SAntonio Huete Jimenez },
2242*ed775ee7SAntonio Huete Jimenez /*
2243*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.5
2244*ed775ee7SAntonio Huete Jimenez * A fixed-size message body and possibly more data of varying size
2245*ed775ee7SAntonio Huete Jimenez * and structure.
2246*ed775ee7SAntonio Huete Jimenez */
2247*ed775ee7SAntonio Huete Jimenez {
2248*ed775ee7SAntonio Huete Jimenez "STATS_REQUEST", of10_stats_request_print,
2249*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_STATS_REQUEST_MINLEN
2250*ed775ee7SAntonio Huete Jimenez },
2251*ed775ee7SAntonio Huete Jimenez /*
2252*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.5
2253*ed775ee7SAntonio Huete Jimenez * A fixed-size message body and possibly more data of varying size
2254*ed775ee7SAntonio Huete Jimenez * and structure.
2255*ed775ee7SAntonio Huete Jimenez */
2256*ed775ee7SAntonio Huete Jimenez {
2257*ed775ee7SAntonio Huete Jimenez "STATS_REPLY", of10_stats_reply_print,
2258*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_STATS_REPLY_MINLEN
2259*ed775ee7SAntonio Huete Jimenez },
2260*ed775ee7SAntonio Huete Jimenez /*
2261*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.7
2262*ed775ee7SAntonio Huete Jimenez * No message body.
2263*ed775ee7SAntonio Huete Jimenez */
2264*ed775ee7SAntonio Huete Jimenez {
2265*ed775ee7SAntonio Huete Jimenez "BARRIER_REQUEST", NULL,
2266*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, 0
2267*ed775ee7SAntonio Huete Jimenez },
2268*ed775ee7SAntonio Huete Jimenez /*
2269*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.7
2270*ed775ee7SAntonio Huete Jimenez * No message body.
2271*ed775ee7SAntonio Huete Jimenez */
2272*ed775ee7SAntonio Huete Jimenez {
2273*ed775ee7SAntonio Huete Jimenez "BARRIER_REPLY", NULL,
2274*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, 0
2275*ed775ee7SAntonio Huete Jimenez },
2276*ed775ee7SAntonio Huete Jimenez /*
2277*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.4
2278*ed775ee7SAntonio Huete Jimenez * A fixed-size message body.
2279*ed775ee7SAntonio Huete Jimenez */
2280*ed775ee7SAntonio Huete Jimenez {
2281*ed775ee7SAntonio Huete Jimenez "QUEUE_GET_CONFIG_REQUEST", of10_queue_get_config_request_print,
2282*ed775ee7SAntonio Huete Jimenez REQ_FIXLEN, OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN
2283*ed775ee7SAntonio Huete Jimenez },
2284*ed775ee7SAntonio Huete Jimenez /*
2285*ed775ee7SAntonio Huete Jimenez * [OF10] Section 5.3.4
2286*ed775ee7SAntonio Huete Jimenez * A fixed-size message body and n * variable-size data units.
2287*ed775ee7SAntonio Huete Jimenez */
2288*ed775ee7SAntonio Huete Jimenez {
2289*ed775ee7SAntonio Huete Jimenez "QUEUE_GET_CONFIG_REPLY", of10_queue_get_config_reply_print,
2290*ed775ee7SAntonio Huete Jimenez REQ_MINLEN, OF_QUEUE_GET_CONFIG_REPLY_MINLEN
2291*ed775ee7SAntonio Huete Jimenez },
2292*ed775ee7SAntonio Huete Jimenez };
2293411677aeSAaron LI
2294*ed775ee7SAntonio Huete Jimenez const struct of_msgtypeinfo *
of10_identify_msgtype(const uint8_t type)2295*ed775ee7SAntonio Huete Jimenez of10_identify_msgtype(const uint8_t type)
2296*ed775ee7SAntonio Huete Jimenez {
2297*ed775ee7SAntonio Huete Jimenez return type <= OFPT_MAX ? &of10_msgtypeinfo[type] : NULL;
2298411677aeSAaron LI }
2299