13c602fabSXin LI /* 23c602fabSXin LI * This module implements decoding of OpenFlow protocol version 1.0 (wire 33c602fabSXin LI * protocol 0x01). The decoder implements terse (default), detailed (-v) and 43c602fabSXin LI * full (-vv) output formats and, as much as each format implies, detects and 53c602fabSXin LI * tries to work around sizing anomalies inside the messages. The decoder marks 63c602fabSXin LI * up bogus values of selected message fields and decodes partially captured 73c602fabSXin LI * messages up to the snapshot end. It is based on the specification below: 83c602fabSXin LI * 93c602fabSXin LI * [OF10] http://www.openflow.org/documents/openflow-spec-v1.0.0.pdf 103c602fabSXin LI * 11*8bdc5a62SPatrick Kelsey * Most functions in this file take 3 arguments into account: 12*8bdc5a62SPatrick Kelsey * * cp -- the pointer to the first octet to decode 13*8bdc5a62SPatrick Kelsey * * len -- the length of the current structure as declared on the wire 14*8bdc5a62SPatrick Kelsey * * ep -- the pointer to the end of the captured frame 15*8bdc5a62SPatrick Kelsey * They return either the pointer to the next not-yet-decoded part of the frame 16*8bdc5a62SPatrick Kelsey * or the value of ep, which means the current frame processing is over as it 17*8bdc5a62SPatrick Kelsey * has been fully decoded or is malformed or truncated. This way it is possible 18*8bdc5a62SPatrick Kelsey * to chain and nest such functions uniformly to decode an OF1.0 message, which 19*8bdc5a62SPatrick Kelsey * consists of several layers of nested structures. 20*8bdc5a62SPatrick Kelsey * 213c602fabSXin LI * Decoding of Ethernet frames nested in OFPT_PACKET_IN and OFPT_PACKET_OUT 223c602fabSXin LI * messages is done only when the verbosity level set by command-line argument 233c602fabSXin LI * is "-vvv" or higher. In that case the verbosity level is temporarily 243c602fabSXin LI * decremented by 3 during the nested frame decoding. For example, running 253c602fabSXin LI * tcpdump with "-vvvv" will do full decoding of OpenFlow and "-v" decoding of 263c602fabSXin LI * the nested frames. 273c602fabSXin LI * 28*8bdc5a62SPatrick Kelsey * Partial decoding of Big Switch Networks vendor extensions is done after the 29*8bdc5a62SPatrick Kelsey * oftest (OpenFlow Testing Framework) and Loxigen (library generator) source 30*8bdc5a62SPatrick Kelsey * code. 31*8bdc5a62SPatrick Kelsey * 323c602fabSXin LI * 333c602fabSXin LI * Copyright (c) 2013 The TCPDUMP project 343c602fabSXin LI * All rights reserved. 353c602fabSXin LI * 363c602fabSXin LI * Redistribution and use in source and binary forms, with or without 373c602fabSXin LI * modification, are permitted provided that the following conditions 383c602fabSXin LI * are met: 393c602fabSXin LI * 1. Redistributions of source code must retain the above copyright 403c602fabSXin LI * notice, this list of conditions and the following disclaimer. 413c602fabSXin LI * 2. Redistributions in binary form must reproduce the above copyright 423c602fabSXin LI * notice, this list of conditions and the following disclaimer in the 433c602fabSXin LI * documentation and/or other materials provided with the distribution. 443c602fabSXin LI * 453c602fabSXin LI * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 463c602fabSXin LI * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 473c602fabSXin LI * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 483c602fabSXin LI * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 493c602fabSXin LI * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 503c602fabSXin LI * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 513c602fabSXin LI * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 523c602fabSXin LI * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 533c602fabSXin LI * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 543c602fabSXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 553c602fabSXin LI * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 563c602fabSXin LI * POSSIBILITY OF SUCH DAMAGE. 573c602fabSXin LI */ 583c602fabSXin LI 593c602fabSXin LI #define NETDISSECT_REWORKED 603c602fabSXin LI #ifdef HAVE_CONFIG_H 613c602fabSXin LI #include "config.h" 623c602fabSXin LI #endif 633c602fabSXin LI 643c602fabSXin LI #include <tcpdump-stdinc.h> 653c602fabSXin LI 663c602fabSXin LI #include "interface.h" 673c602fabSXin LI #include "extract.h" 683c602fabSXin LI #include "addrtoname.h" 693c602fabSXin LI #include "ether.h" 703c602fabSXin LI #include "ethertype.h" 713c602fabSXin LI #include "ipproto.h" 72*8bdc5a62SPatrick Kelsey #include "oui.h" 733c602fabSXin LI #include "openflow.h" 743c602fabSXin LI 753c602fabSXin LI static const char tstr[] = " [|openflow]"; 763c602fabSXin LI static const char cstr[] = " (corrupt)"; 773c602fabSXin LI 783c602fabSXin LI #define OFPT_HELLO 0x00 793c602fabSXin LI #define OFPT_ERROR 0x01 803c602fabSXin LI #define OFPT_ECHO_REQUEST 0x02 813c602fabSXin LI #define OFPT_ECHO_REPLY 0x03 823c602fabSXin LI #define OFPT_VENDOR 0x04 833c602fabSXin LI #define OFPT_FEATURES_REQUEST 0x05 843c602fabSXin LI #define OFPT_FEATURES_REPLY 0x06 853c602fabSXin LI #define OFPT_GET_CONFIG_REQUEST 0x07 863c602fabSXin LI #define OFPT_GET_CONFIG_REPLY 0x08 873c602fabSXin LI #define OFPT_SET_CONFIG 0x09 883c602fabSXin LI #define OFPT_PACKET_IN 0x0a 893c602fabSXin LI #define OFPT_FLOW_REMOVED 0x0b 903c602fabSXin LI #define OFPT_PORT_STATUS 0x0c 913c602fabSXin LI #define OFPT_PACKET_OUT 0x0d 923c602fabSXin LI #define OFPT_FLOW_MOD 0x0e 933c602fabSXin LI #define OFPT_PORT_MOD 0x0f 943c602fabSXin LI #define OFPT_STATS_REQUEST 0x10 953c602fabSXin LI #define OFPT_STATS_REPLY 0x11 963c602fabSXin LI #define OFPT_BARRIER_REQUEST 0x12 973c602fabSXin LI #define OFPT_BARRIER_REPLY 0x13 983c602fabSXin LI #define OFPT_QUEUE_GET_CONFIG_REQUEST 0x14 993c602fabSXin LI #define OFPT_QUEUE_GET_CONFIG_REPLY 0x15 1003c602fabSXin LI static const struct tok ofpt_str[] = { 1013c602fabSXin LI { OFPT_HELLO, "HELLO" }, 1023c602fabSXin LI { OFPT_ERROR, "ERROR" }, 1033c602fabSXin LI { OFPT_ECHO_REQUEST, "ECHO_REQUEST" }, 1043c602fabSXin LI { OFPT_ECHO_REPLY, "ECHO_REPLY" }, 1053c602fabSXin LI { OFPT_VENDOR, "VENDOR" }, 1063c602fabSXin LI { OFPT_FEATURES_REQUEST, "FEATURES_REQUEST" }, 1073c602fabSXin LI { OFPT_FEATURES_REPLY, "FEATURES_REPLY" }, 1083c602fabSXin LI { OFPT_GET_CONFIG_REQUEST, "GET_CONFIG_REQUEST" }, 1093c602fabSXin LI { OFPT_GET_CONFIG_REPLY, "GET_CONFIG_REPLY" }, 1103c602fabSXin LI { OFPT_SET_CONFIG, "SET_CONFIG" }, 1113c602fabSXin LI { OFPT_PACKET_IN, "PACKET_IN" }, 1123c602fabSXin LI { OFPT_FLOW_REMOVED, "FLOW_REMOVED" }, 1133c602fabSXin LI { OFPT_PORT_STATUS, "PORT_STATUS" }, 1143c602fabSXin LI { OFPT_PACKET_OUT, "PACKET_OUT" }, 1153c602fabSXin LI { OFPT_FLOW_MOD, "FLOW_MOD" }, 1163c602fabSXin LI { OFPT_PORT_MOD, "PORT_MOD" }, 1173c602fabSXin LI { OFPT_STATS_REQUEST, "STATS_REQUEST" }, 1183c602fabSXin LI { OFPT_STATS_REPLY, "STATS_REPLY" }, 1193c602fabSXin LI { OFPT_BARRIER_REQUEST, "BARRIER_REQUEST" }, 1203c602fabSXin LI { OFPT_BARRIER_REPLY, "BARRIER_REPLY" }, 1213c602fabSXin LI { OFPT_QUEUE_GET_CONFIG_REQUEST, "QUEUE_GET_CONFIG_REQUEST" }, 1223c602fabSXin LI { OFPT_QUEUE_GET_CONFIG_REPLY, "QUEUE_GET_CONFIG_REPLY" }, 1233c602fabSXin LI { 0, NULL } 1243c602fabSXin LI }; 1253c602fabSXin LI 1263c602fabSXin LI #define OFPPC_PORT_DOWN (1 << 0) 1273c602fabSXin LI #define OFPPC_NO_STP (1 << 1) 1283c602fabSXin LI #define OFPPC_NO_RECV (1 << 2) 1293c602fabSXin LI #define OFPPC_NO_RECV_STP (1 << 3) 1303c602fabSXin LI #define OFPPC_NO_FLOOD (1 << 4) 1313c602fabSXin LI #define OFPPC_NO_FWD (1 << 5) 1323c602fabSXin LI #define OFPPC_NO_PACKET_IN (1 << 6) 1333c602fabSXin LI static const struct tok ofppc_bm[] = { 1343c602fabSXin LI { OFPPC_PORT_DOWN, "PORT_DOWN" }, 1353c602fabSXin LI { OFPPC_NO_STP, "NO_STP" }, 1363c602fabSXin LI { OFPPC_NO_RECV, "NO_RECV" }, 1373c602fabSXin LI { OFPPC_NO_RECV_STP, "NO_RECV_STP" }, 1383c602fabSXin LI { OFPPC_NO_FLOOD, "NO_FLOOD" }, 1393c602fabSXin LI { OFPPC_NO_FWD, "NO_FWD" }, 1403c602fabSXin LI { OFPPC_NO_PACKET_IN, "NO_PACKET_IN" }, 1413c602fabSXin LI { 0, NULL } 1423c602fabSXin LI }; 1433c602fabSXin LI #define OFPPC_U (~(OFPPC_PORT_DOWN | OFPPC_NO_STP | OFPPC_NO_RECV | \ 1443c602fabSXin LI OFPPC_NO_RECV_STP | OFPPC_NO_FLOOD | OFPPC_NO_FWD | \ 1453c602fabSXin LI OFPPC_NO_PACKET_IN)) 1463c602fabSXin LI 1473c602fabSXin LI #define OFPPS_LINK_DOWN (1 << 0) 1483c602fabSXin LI #define OFPPS_STP_LISTEN (0 << 8) 1493c602fabSXin LI #define OFPPS_STP_LEARN (1 << 8) 1503c602fabSXin LI #define OFPPS_STP_FORWARD (2 << 8) 1513c602fabSXin LI #define OFPPS_STP_BLOCK (3 << 8) 1523c602fabSXin LI #define OFPPS_STP_MASK (3 << 8) 1533c602fabSXin LI static const struct tok ofpps_bm[] = { 1543c602fabSXin LI { OFPPS_LINK_DOWN, "LINK_DOWN" }, 1553c602fabSXin LI { OFPPS_STP_LISTEN, "STP_LISTEN" }, 1563c602fabSXin LI { OFPPS_STP_LEARN, "STP_LEARN" }, 1573c602fabSXin LI { OFPPS_STP_FORWARD, "STP_FORWARD" }, 1583c602fabSXin LI { OFPPS_STP_BLOCK, "STP_BLOCK" }, 1593c602fabSXin LI { 0, NULL } 1603c602fabSXin LI }; 1613c602fabSXin LI #define OFPPS_U (~(OFPPS_LINK_DOWN | OFPPS_STP_LISTEN | OFPPS_STP_LEARN | \ 1623c602fabSXin LI OFPPS_STP_FORWARD | OFPPS_STP_BLOCK)) 1633c602fabSXin LI 1643c602fabSXin LI #define OFPP_MAX 0xff00 1653c602fabSXin LI #define OFPP_IN_PORT 0xfff8 1663c602fabSXin LI #define OFPP_TABLE 0xfff9 1673c602fabSXin LI #define OFPP_NORMAL 0xfffa 1683c602fabSXin LI #define OFPP_FLOOD 0xfffb 1693c602fabSXin LI #define OFPP_ALL 0xfffc 1703c602fabSXin LI #define OFPP_CONTROLLER 0xfffd 1713c602fabSXin LI #define OFPP_LOCAL 0xfffe 1723c602fabSXin LI #define OFPP_NONE 0xffff 1733c602fabSXin LI static const struct tok ofpp_str[] = { 1743c602fabSXin LI { OFPP_MAX, "MAX" }, 1753c602fabSXin LI { OFPP_IN_PORT, "IN_PORT" }, 1763c602fabSXin LI { OFPP_TABLE, "TABLE" }, 1773c602fabSXin LI { OFPP_NORMAL, "NORMAL" }, 1783c602fabSXin LI { OFPP_FLOOD, "FLOOD" }, 1793c602fabSXin LI { OFPP_ALL, "ALL" }, 1803c602fabSXin LI { OFPP_CONTROLLER, "CONTROLLER" }, 1813c602fabSXin LI { OFPP_LOCAL, "LOCAL" }, 1823c602fabSXin LI { OFPP_NONE, "NONE" }, 1833c602fabSXin LI { 0, NULL } 1843c602fabSXin LI }; 1853c602fabSXin LI 1863c602fabSXin LI #define OFPPF_10MB_HD (1 << 0) 1873c602fabSXin LI #define OFPPF_10MB_FD (1 << 1) 1883c602fabSXin LI #define OFPPF_100MB_HD (1 << 2) 1893c602fabSXin LI #define OFPPF_100MB_FD (1 << 3) 1903c602fabSXin LI #define OFPPF_1GB_HD (1 << 4) 1913c602fabSXin LI #define OFPPF_1GB_FD (1 << 5) 1923c602fabSXin LI #define OFPPF_10GB_FD (1 << 6) 1933c602fabSXin LI #define OFPPF_COPPER (1 << 7) 1943c602fabSXin LI #define OFPPF_FIBER (1 << 8) 1953c602fabSXin LI #define OFPPF_AUTONEG (1 << 9) 1963c602fabSXin LI #define OFPPF_PAUSE (1 << 10) 1973c602fabSXin LI #define OFPPF_PAUSE_ASYM (1 << 11) 1983c602fabSXin LI static const struct tok ofppf_bm[] = { 1993c602fabSXin LI { OFPPF_10MB_HD, "10MB_HD" }, 2003c602fabSXin LI { OFPPF_10MB_FD, "10MB_FD" }, 2013c602fabSXin LI { OFPPF_100MB_HD, "100MB_HD" }, 2023c602fabSXin LI { OFPPF_100MB_FD, "100MB_FD" }, 2033c602fabSXin LI { OFPPF_1GB_HD, "1GB_HD" }, 2043c602fabSXin LI { OFPPF_1GB_FD, "1GB_FD" }, 2053c602fabSXin LI { OFPPF_10GB_FD, "10GB_FD" }, 2063c602fabSXin LI { OFPPF_COPPER, "COPPER" }, 2073c602fabSXin LI { OFPPF_FIBER, "FIBER" }, 2083c602fabSXin LI { OFPPF_AUTONEG, "AUTONEG" }, 2093c602fabSXin LI { OFPPF_PAUSE, "PAUSE" }, 2103c602fabSXin LI { OFPPF_PAUSE_ASYM, "PAUSE_ASYM" }, 2113c602fabSXin LI { 0, NULL } 2123c602fabSXin LI }; 2133c602fabSXin LI #define OFPPF_U (~(OFPPF_10MB_HD | OFPPF_10MB_FD | OFPPF_100MB_HD | \ 2143c602fabSXin LI OFPPF_100MB_FD | OFPPF_1GB_HD | OFPPF_1GB_FD | \ 2153c602fabSXin LI OFPPF_10GB_FD | OFPPF_COPPER | OFPPF_FIBER | \ 2163c602fabSXin LI OFPPF_AUTONEG | OFPPF_PAUSE | OFPPF_PAUSE_ASYM)) 2173c602fabSXin LI 2183c602fabSXin LI #define OFPQT_NONE 0x0000 2193c602fabSXin LI #define OFPQT_MIN_RATE 0x0001 2203c602fabSXin LI static const struct tok ofpqt_str[] = { 2213c602fabSXin LI { OFPQT_NONE, "NONE" }, 2223c602fabSXin LI { OFPQT_MIN_RATE, "MIN_RATE" }, 2233c602fabSXin LI { 0, NULL } 2243c602fabSXin LI }; 2253c602fabSXin LI 2263c602fabSXin LI #define OFPFW_IN_PORT (1 << 0) 2273c602fabSXin LI #define OFPFW_DL_VLAN (1 << 1) 2283c602fabSXin LI #define OFPFW_DL_SRC (1 << 2) 2293c602fabSXin LI #define OFPFW_DL_DST (1 << 3) 2303c602fabSXin LI #define OFPFW_DL_TYPE (1 << 4) 2313c602fabSXin LI #define OFPFW_NW_PROTO (1 << 5) 2323c602fabSXin LI #define OFPFW_TP_SRC (1 << 6) 2333c602fabSXin LI #define OFPFW_TP_DST (1 << 7) 2343c602fabSXin LI #define OFPFW_NW_SRC_SHIFT 8 2353c602fabSXin LI #define OFPFW_NW_SRC_BITS 6 2363c602fabSXin LI #define OFPFW_NW_SRC_MASK (((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT) 2373c602fabSXin LI #define OFPFW_NW_DST_SHIFT 14 2383c602fabSXin LI #define OFPFW_NW_DST_BITS 6 2393c602fabSXin LI #define OFPFW_NW_DST_MASK (((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT) 2403c602fabSXin LI #define OFPFW_DL_VLAN_PCP (1 << 20) 2413c602fabSXin LI #define OFPFW_NW_TOS (1 << 21) 2423c602fabSXin LI #define OFPFW_ALL ((1 << 22) - 1) 2433c602fabSXin LI static const struct tok ofpfw_bm[] = { 2443c602fabSXin LI { OFPFW_IN_PORT, "IN_PORT" }, 2453c602fabSXin LI { OFPFW_DL_VLAN, "DL_VLAN" }, 2463c602fabSXin LI { OFPFW_DL_SRC, "DL_SRC" }, 2473c602fabSXin LI { OFPFW_DL_DST, "DL_DST" }, 2483c602fabSXin LI { OFPFW_DL_TYPE, "DL_TYPE" }, 2493c602fabSXin LI { OFPFW_NW_PROTO, "NW_PROTO" }, 2503c602fabSXin LI { OFPFW_TP_SRC, "TP_SRC" }, 2513c602fabSXin LI { OFPFW_TP_DST, "TP_DST" }, 2523c602fabSXin LI { OFPFW_DL_VLAN_PCP, "DL_VLAN_PCP" }, 2533c602fabSXin LI { OFPFW_NW_TOS, "NW_TOS" }, 2543c602fabSXin LI { 0, NULL } 2553c602fabSXin LI }; 2563c602fabSXin LI /* The above array does not include bits 8~13 (OFPFW_NW_SRC_*) and 14~19 2573c602fabSXin LI * (OFPFW_NW_DST_*), which are not a part of the bitmap and require decoding 2583c602fabSXin LI * other than that of tok2str(). The macro below includes these bits such that 2593c602fabSXin LI * they are not reported as bogus in the decoding. */ 2603c602fabSXin LI #define OFPFW_U (~(OFPFW_ALL)) 2613c602fabSXin LI 2623c602fabSXin LI #define OFPAT_OUTPUT 0x0000 2633c602fabSXin LI #define OFPAT_SET_VLAN_VID 0x0001 2643c602fabSXin LI #define OFPAT_SET_VLAN_PCP 0x0002 2653c602fabSXin LI #define OFPAT_STRIP_VLAN 0x0003 2663c602fabSXin LI #define OFPAT_SET_DL_SRC 0x0004 2673c602fabSXin LI #define OFPAT_SET_DL_DST 0x0005 2683c602fabSXin LI #define OFPAT_SET_NW_SRC 0x0006 2693c602fabSXin LI #define OFPAT_SET_NW_DST 0x0007 2703c602fabSXin LI #define OFPAT_SET_NW_TOS 0x0008 2713c602fabSXin LI #define OFPAT_SET_TP_SRC 0x0009 2723c602fabSXin LI #define OFPAT_SET_TP_DST 0x000a 2733c602fabSXin LI #define OFPAT_ENQUEUE 0x000b 2743c602fabSXin LI #define OFPAT_VENDOR 0xffff 2753c602fabSXin LI static const struct tok ofpat_str[] = { 2763c602fabSXin LI { OFPAT_OUTPUT, "OUTPUT" }, 2773c602fabSXin LI { OFPAT_SET_VLAN_VID, "SET_VLAN_VID" }, 2783c602fabSXin LI { OFPAT_SET_VLAN_PCP, "SET_VLAN_PCP" }, 2793c602fabSXin LI { OFPAT_STRIP_VLAN, "STRIP_VLAN" }, 2803c602fabSXin LI { OFPAT_SET_DL_SRC, "SET_DL_SRC" }, 2813c602fabSXin LI { OFPAT_SET_DL_DST, "SET_DL_DST" }, 2823c602fabSXin LI { OFPAT_SET_NW_SRC, "SET_NW_SRC" }, 2833c602fabSXin LI { OFPAT_SET_NW_DST, "SET_NW_DST" }, 2843c602fabSXin LI { OFPAT_SET_NW_TOS, "SET_NW_TOS" }, 2853c602fabSXin LI { OFPAT_SET_TP_SRC, "SET_TP_SRC" }, 2863c602fabSXin LI { OFPAT_SET_TP_DST, "SET_TP_DST" }, 2873c602fabSXin LI { OFPAT_ENQUEUE, "ENQUEUE" }, 2883c602fabSXin LI { OFPAT_VENDOR, "VENDOR" }, 2893c602fabSXin LI { 0, NULL } 2903c602fabSXin LI }; 2913c602fabSXin LI 2923c602fabSXin LI /* bit-shifted, w/o vendor action */ 2933c602fabSXin LI static const struct tok ofpat_bm[] = { 2943c602fabSXin LI { 1 << OFPAT_OUTPUT, "OUTPUT" }, 2953c602fabSXin LI { 1 << OFPAT_SET_VLAN_VID, "SET_VLAN_VID" }, 2963c602fabSXin LI { 1 << OFPAT_SET_VLAN_PCP, "SET_VLAN_PCP" }, 2973c602fabSXin LI { 1 << OFPAT_STRIP_VLAN, "STRIP_VLAN" }, 2983c602fabSXin LI { 1 << OFPAT_SET_DL_SRC, "SET_DL_SRC" }, 2993c602fabSXin LI { 1 << OFPAT_SET_DL_DST, "SET_DL_DST" }, 3003c602fabSXin LI { 1 << OFPAT_SET_NW_SRC, "SET_NW_SRC" }, 3013c602fabSXin LI { 1 << OFPAT_SET_NW_DST, "SET_NW_DST" }, 3023c602fabSXin LI { 1 << OFPAT_SET_NW_TOS, "SET_NW_TOS" }, 3033c602fabSXin LI { 1 << OFPAT_SET_TP_SRC, "SET_TP_SRC" }, 3043c602fabSXin LI { 1 << OFPAT_SET_TP_DST, "SET_TP_DST" }, 3053c602fabSXin LI { 1 << OFPAT_ENQUEUE, "ENQUEUE" }, 3063c602fabSXin LI { 0, NULL } 3073c602fabSXin LI }; 3083c602fabSXin LI #define OFPAT_U (~(1 << OFPAT_OUTPUT | 1 << OFPAT_SET_VLAN_VID | \ 3093c602fabSXin LI 1 << OFPAT_SET_VLAN_PCP | 1 << OFPAT_STRIP_VLAN | \ 3103c602fabSXin LI 1 << OFPAT_SET_DL_SRC | 1 << OFPAT_SET_DL_DST | \ 3113c602fabSXin LI 1 << OFPAT_SET_NW_SRC | 1 << OFPAT_SET_NW_DST | \ 3123c602fabSXin LI 1 << OFPAT_SET_NW_TOS | 1 << OFPAT_SET_TP_SRC | \ 3133c602fabSXin LI 1 << OFPAT_SET_TP_DST | 1 << OFPAT_ENQUEUE)) 3143c602fabSXin LI 3153c602fabSXin LI #define OFPC_FLOW_STATS (1 << 0) 3163c602fabSXin LI #define OFPC_TABLE_STATS (1 << 1) 3173c602fabSXin LI #define OFPC_PORT_STATS (1 << 2) 3183c602fabSXin LI #define OFPC_STP (1 << 3) 3193c602fabSXin LI #define OFPC_RESERVED (1 << 4) 3203c602fabSXin LI #define OFPC_IP_REASM (1 << 5) 3213c602fabSXin LI #define OFPC_QUEUE_STATS (1 << 6) 3223c602fabSXin LI #define OFPC_ARP_MATCH_IP (1 << 7) 3233c602fabSXin LI static const struct tok ofp_capabilities_bm[] = { 3243c602fabSXin LI { OFPC_FLOW_STATS, "FLOW_STATS" }, 3253c602fabSXin LI { OFPC_TABLE_STATS, "TABLE_STATS" }, 3263c602fabSXin LI { OFPC_PORT_STATS, "PORT_STATS" }, 3273c602fabSXin LI { OFPC_STP, "STP" }, 3283c602fabSXin LI { OFPC_RESERVED, "RESERVED" }, /* not in the mask below */ 3293c602fabSXin LI { OFPC_IP_REASM, "IP_REASM" }, 3303c602fabSXin LI { OFPC_QUEUE_STATS, "QUEUE_STATS" }, 3313c602fabSXin LI { OFPC_ARP_MATCH_IP, "ARP_MATCH_IP" }, 3323c602fabSXin LI { 0, NULL } 3333c602fabSXin LI }; 3343c602fabSXin LI #define OFPCAP_U (~(OFPC_FLOW_STATS | OFPC_TABLE_STATS | OFPC_PORT_STATS | \ 3353c602fabSXin LI OFPC_STP | OFPC_IP_REASM | OFPC_QUEUE_STATS | \ 3363c602fabSXin LI OFPC_ARP_MATCH_IP)) 3373c602fabSXin LI 3383c602fabSXin LI #define OFPC_FRAG_NORMAL 0x0000 3393c602fabSXin LI #define OFPC_FRAG_DROP 0x0001 3403c602fabSXin LI #define OFPC_FRAG_REASM 0x0002 3413c602fabSXin LI #define OFPC_FRAG_MASK 0x0003 3423c602fabSXin LI static const struct tok ofp_config_str[] = { 3433c602fabSXin LI { OFPC_FRAG_NORMAL, "FRAG_NORMAL" }, 3443c602fabSXin LI { OFPC_FRAG_DROP, "FRAG_DROP" }, 3453c602fabSXin LI { OFPC_FRAG_REASM, "FRAG_REASM" }, 3463c602fabSXin LI { 0, NULL } 3473c602fabSXin LI }; 3483c602fabSXin LI 3493c602fabSXin LI #define OFPFC_ADD 0x0000 3503c602fabSXin LI #define OFPFC_MODIFY 0x0001 3513c602fabSXin LI #define OFPFC_MODIFY_STRICT 0x0002 3523c602fabSXin LI #define OFPFC_DELETE 0x0003 3533c602fabSXin LI #define OFPFC_DELETE_STRICT 0x0004 3543c602fabSXin LI static const struct tok ofpfc_str[] = { 3553c602fabSXin LI { OFPFC_ADD, "ADD" }, 3563c602fabSXin LI { OFPFC_MODIFY, "MODIFY" }, 3573c602fabSXin LI { OFPFC_MODIFY_STRICT, "MODIFY_STRICT" }, 3583c602fabSXin LI { OFPFC_DELETE, "DELETE" }, 3593c602fabSXin LI { OFPFC_DELETE_STRICT, "DELETE_STRICT" }, 3603c602fabSXin LI { 0, NULL } 3613c602fabSXin LI }; 3623c602fabSXin LI 3633c602fabSXin LI static const struct tok bufferid_str[] = { 3643c602fabSXin LI { 0xffffffff, "NONE" }, 3653c602fabSXin LI { 0, NULL } 3663c602fabSXin LI }; 3673c602fabSXin LI 3683c602fabSXin LI #define OFPFF_SEND_FLOW_REM (1 << 0) 3693c602fabSXin LI #define OFPFF_CHECK_OVERLAP (1 << 1) 3703c602fabSXin LI #define OFPFF_EMERG (1 << 2) 3713c602fabSXin LI static const struct tok ofpff_bm[] = { 3723c602fabSXin LI { OFPFF_SEND_FLOW_REM, "SEND_FLOW_REM" }, 3733c602fabSXin LI { OFPFF_CHECK_OVERLAP, "CHECK_OVERLAP" }, 3743c602fabSXin LI { OFPFF_EMERG, "EMERG" }, 3753c602fabSXin LI { 0, NULL } 3763c602fabSXin LI }; 3773c602fabSXin LI #define OFPFF_U (~(OFPFF_SEND_FLOW_REM | OFPFF_CHECK_OVERLAP | OFPFF_EMERG)) 3783c602fabSXin LI 3793c602fabSXin LI #define OFPST_DESC 0x0000 3803c602fabSXin LI #define OFPST_FLOW 0x0001 3813c602fabSXin LI #define OFPST_AGGREGATE 0x0002 3823c602fabSXin LI #define OFPST_TABLE 0x0003 3833c602fabSXin LI #define OFPST_PORT 0x0004 3843c602fabSXin LI #define OFPST_QUEUE 0x0005 3853c602fabSXin LI #define OFPST_VENDOR 0xffff 3863c602fabSXin LI static const struct tok ofpst_str[] = { 3873c602fabSXin LI { OFPST_DESC, "DESC" }, 3883c602fabSXin LI { OFPST_FLOW, "FLOW" }, 3893c602fabSXin LI { OFPST_AGGREGATE, "AGGREGATE" }, 3903c602fabSXin LI { OFPST_TABLE, "TABLE" }, 3913c602fabSXin LI { OFPST_PORT, "PORT" }, 3923c602fabSXin LI { OFPST_QUEUE, "QUEUE" }, 3933c602fabSXin LI { OFPST_VENDOR, "VENDOR" }, 3943c602fabSXin LI { 0, NULL } 3953c602fabSXin LI }; 3963c602fabSXin LI 3973c602fabSXin LI static const struct tok tableid_str[] = { 3983c602fabSXin LI { 0xfe, "EMERG" }, 3993c602fabSXin LI { 0xff, "ALL" }, 4003c602fabSXin LI { 0, NULL } 4013c602fabSXin LI }; 4023c602fabSXin LI 4033c602fabSXin LI #define OFPQ_ALL 0xffffffff 4043c602fabSXin LI static const struct tok ofpq_str[] = { 4053c602fabSXin LI { OFPQ_ALL, "ALL" }, 4063c602fabSXin LI { 0, NULL } 4073c602fabSXin LI }; 4083c602fabSXin LI 4093c602fabSXin LI #define OFPSF_REPLY_MORE 0x0001 4103c602fabSXin LI static const struct tok ofpsf_reply_bm[] = { 4113c602fabSXin LI { OFPSF_REPLY_MORE, "MORE" }, 4123c602fabSXin LI { 0, NULL } 4133c602fabSXin LI }; 4143c602fabSXin LI #define OFPSF_REPLY_U (~(OFPSF_REPLY_MORE)) 4153c602fabSXin LI 4163c602fabSXin LI #define OFPR_NO_MATCH 0x00 4173c602fabSXin LI #define OFPR_ACTION 0x01 4183c602fabSXin LI static const struct tok ofpr_str[] = { 4193c602fabSXin LI { OFPR_NO_MATCH, "NO_MATCH" }, 4203c602fabSXin LI { OFPR_ACTION, "ACTION" }, 4213c602fabSXin LI { 0, NULL } 4223c602fabSXin LI }; 4233c602fabSXin LI 4243c602fabSXin LI #define OFPRR_IDLE_TIMEOUT 0x00 4253c602fabSXin LI #define OFPRR_HARD_TIMEOUT 0x01 4263c602fabSXin LI #define OFPRR_DELETE 0x02 4273c602fabSXin LI static const struct tok ofprr_str[] = { 4283c602fabSXin LI { OFPRR_IDLE_TIMEOUT, "IDLE_TIMEOUT" }, 4293c602fabSXin LI { OFPRR_HARD_TIMEOUT, "HARD_TIMEOUT" }, 4303c602fabSXin LI { OFPRR_DELETE, "DELETE" }, 4313c602fabSXin LI { 0, NULL } 4323c602fabSXin LI }; 4333c602fabSXin LI 4343c602fabSXin LI #define OFPPR_ADD 0x00 4353c602fabSXin LI #define OFPPR_DELETE 0x01 4363c602fabSXin LI #define OFPPR_MODIFY 0x02 4373c602fabSXin LI static const struct tok ofppr_str[] = { 4383c602fabSXin LI { OFPPR_ADD, "ADD" }, 4393c602fabSXin LI { OFPPR_DELETE, "DELETE" }, 4403c602fabSXin LI { OFPPR_MODIFY, "MODIFY" }, 4413c602fabSXin LI { 0, NULL } 4423c602fabSXin LI }; 4433c602fabSXin LI 4443c602fabSXin LI #define OFPET_HELLO_FAILED 0x0000 4453c602fabSXin LI #define OFPET_BAD_REQUEST 0x0001 4463c602fabSXin LI #define OFPET_BAD_ACTION 0x0002 4473c602fabSXin LI #define OFPET_FLOW_MOD_FAILED 0x0003 4483c602fabSXin LI #define OFPET_PORT_MOD_FAILED 0x0004 4493c602fabSXin LI #define OFPET_QUEUE_OP_FAILED 0x0005 4503c602fabSXin LI static const struct tok ofpet_str[] = { 4513c602fabSXin LI { OFPET_HELLO_FAILED, "HELLO_FAILED" }, 4523c602fabSXin LI { OFPET_BAD_REQUEST, "BAD_REQUEST" }, 4533c602fabSXin LI { OFPET_BAD_ACTION, "BAD_ACTION" }, 4543c602fabSXin LI { OFPET_FLOW_MOD_FAILED, "FLOW_MOD_FAILED" }, 4553c602fabSXin LI { OFPET_PORT_MOD_FAILED, "PORT_MOD_FAILED" }, 4563c602fabSXin LI { OFPET_QUEUE_OP_FAILED, "QUEUE_OP_FAILED" }, 4573c602fabSXin LI { 0, NULL } 4583c602fabSXin LI }; 4593c602fabSXin LI 4603c602fabSXin LI #define OFPHFC_INCOMPATIBLE 0x0000 4613c602fabSXin LI #define OFPHFC_EPERM 0x0001 4623c602fabSXin LI static const struct tok ofphfc_str[] = { 4633c602fabSXin LI { OFPHFC_INCOMPATIBLE, "INCOMPATIBLE" }, 4643c602fabSXin LI { OFPHFC_EPERM, "EPERM" }, 4653c602fabSXin LI { 0, NULL } 4663c602fabSXin LI }; 4673c602fabSXin LI 4683c602fabSXin LI #define OFPBRC_BAD_VERSION 0x0000 4693c602fabSXin LI #define OFPBRC_BAD_TYPE 0x0001 4703c602fabSXin LI #define OFPBRC_BAD_STAT 0x0002 4713c602fabSXin LI #define OFPBRC_BAD_VENDOR 0x0003 4723c602fabSXin LI #define OFPBRC_BAD_SUBTYPE 0x0004 4733c602fabSXin LI #define OFPBRC_EPERM 0x0005 4743c602fabSXin LI #define OFPBRC_BAD_LEN 0x0006 4753c602fabSXin LI #define OFPBRC_BUFFER_EMPTY 0x0007 4763c602fabSXin LI #define OFPBRC_BUFFER_UNKNOWN 0x0008 4773c602fabSXin LI static const struct tok ofpbrc_str[] = { 4783c602fabSXin LI { OFPBRC_BAD_VERSION, "BAD_VERSION" }, 4793c602fabSXin LI { OFPBRC_BAD_TYPE, "BAD_TYPE" }, 4803c602fabSXin LI { OFPBRC_BAD_STAT, "BAD_STAT" }, 4813c602fabSXin LI { OFPBRC_BAD_VENDOR, "BAD_VENDOR" }, 4823c602fabSXin LI { OFPBRC_BAD_SUBTYPE, "BAD_SUBTYPE" }, 4833c602fabSXin LI { OFPBRC_EPERM, "EPERM" }, 4843c602fabSXin LI { OFPBRC_BAD_LEN, "BAD_LEN" }, 4853c602fabSXin LI { OFPBRC_BUFFER_EMPTY, "BUFFER_EMPTY" }, 4863c602fabSXin LI { OFPBRC_BUFFER_UNKNOWN, "BUFFER_UNKNOWN" }, 4873c602fabSXin LI { 0, NULL } 4883c602fabSXin LI }; 4893c602fabSXin LI 4903c602fabSXin LI #define OFPBAC_BAD_TYPE 0x0000 4913c602fabSXin LI #define OFPBAC_BAD_LEN 0x0001 4923c602fabSXin LI #define OFPBAC_BAD_VENDOR 0x0002 4933c602fabSXin LI #define OFPBAC_BAD_VENDOR_TYPE 0x0003 4943c602fabSXin LI #define OFPBAC_BAD_OUT_PORT 0x0004 4953c602fabSXin LI #define OFPBAC_BAD_ARGUMENT 0x0005 4963c602fabSXin LI #define OFPBAC_EPERM 0x0006 4973c602fabSXin LI #define OFPBAC_TOO_MANY 0x0007 4983c602fabSXin LI #define OFPBAC_BAD_QUEUE 0x0008 4993c602fabSXin LI static const struct tok ofpbac_str[] = { 5003c602fabSXin LI { OFPBAC_BAD_TYPE, "BAD_TYPE" }, 5013c602fabSXin LI { OFPBAC_BAD_LEN, "BAD_LEN" }, 5023c602fabSXin LI { OFPBAC_BAD_VENDOR, "BAD_VENDOR" }, 5033c602fabSXin LI { OFPBAC_BAD_VENDOR_TYPE, "BAD_VENDOR_TYPE" }, 5043c602fabSXin LI { OFPBAC_BAD_OUT_PORT, "BAD_OUT_PORT" }, 5053c602fabSXin LI { OFPBAC_BAD_ARGUMENT, "BAD_ARGUMENT" }, 5063c602fabSXin LI { OFPBAC_EPERM, "EPERM" }, 5073c602fabSXin LI { OFPBAC_TOO_MANY, "TOO_MANY" }, 5083c602fabSXin LI { OFPBAC_BAD_QUEUE, "BAD_QUEUE" }, 5093c602fabSXin LI { 0, NULL } 5103c602fabSXin LI }; 5113c602fabSXin LI 5123c602fabSXin LI #define OFPFMFC_ALL_TABLES_FULL 0x0000 5133c602fabSXin LI #define OFPFMFC_OVERLAP 0x0001 5143c602fabSXin LI #define OFPFMFC_EPERM 0x0002 5153c602fabSXin LI #define OFPFMFC_BAD_EMERG_TIMEOUT 0x0003 5163c602fabSXin LI #define OFPFMFC_BAD_COMMAND 0x0004 5173c602fabSXin LI #define OFPFMFC_UNSUPPORTED 0x0005 5183c602fabSXin LI static const struct tok ofpfmfc_str[] = { 5193c602fabSXin LI { OFPFMFC_ALL_TABLES_FULL, "ALL_TABLES_FULL" }, 5203c602fabSXin LI { OFPFMFC_OVERLAP, "OVERLAP" }, 5213c602fabSXin LI { OFPFMFC_EPERM, "EPERM" }, 5223c602fabSXin LI { OFPFMFC_BAD_EMERG_TIMEOUT, "BAD_EMERG_TIMEOUT" }, 5233c602fabSXin LI { OFPFMFC_BAD_COMMAND, "BAD_COMMAND" }, 5243c602fabSXin LI { OFPFMFC_UNSUPPORTED, "UNSUPPORTED" }, 5253c602fabSXin LI { 0, NULL } 5263c602fabSXin LI }; 5273c602fabSXin LI 5283c602fabSXin LI #define OFPPMFC_BAD_PORT 0x0000 5293c602fabSXin LI #define OFPPMFC_BAD_HW_ADDR 0x0001 5303c602fabSXin LI static const struct tok ofppmfc_str[] = { 5313c602fabSXin LI { OFPPMFC_BAD_PORT, "BAD_PORT" }, 5323c602fabSXin LI { OFPPMFC_BAD_HW_ADDR, "BAD_HW_ADDR" }, 5333c602fabSXin LI { 0, NULL } 5343c602fabSXin LI }; 5353c602fabSXin LI 5363c602fabSXin LI #define OFPQOFC_BAD_PORT 0x0000 5373c602fabSXin LI #define OFPQOFC_BAD_QUEUE 0x0001 5383c602fabSXin LI #define OFPQOFC_EPERM 0x0002 5393c602fabSXin LI static const struct tok ofpqofc_str[] = { 5403c602fabSXin LI { OFPQOFC_BAD_PORT, "BAD_PORT" }, 5413c602fabSXin LI { OFPQOFC_BAD_QUEUE, "BAD_QUEUE" }, 5423c602fabSXin LI { OFPQOFC_EPERM, "EPERM" }, 5433c602fabSXin LI { 0, NULL } 5443c602fabSXin LI }; 5453c602fabSXin LI 5463c602fabSXin LI static const struct tok empty_str[] = { 5473c602fabSXin LI { 0, NULL } 5483c602fabSXin LI }; 5493c602fabSXin LI 5503c602fabSXin LI /* lengths (fixed or minimal) of particular protocol structures */ 5513c602fabSXin LI #define OF_SWITCH_CONFIG_LEN 12 5523c602fabSXin LI #define OF_PHY_PORT_LEN 48 5533c602fabSXin LI #define OF_SWITCH_FEATURES_LEN 32 5543c602fabSXin LI #define OF_PORT_STATUS_LEN 64 5553c602fabSXin LI #define OF_PORT_MOD_LEN 32 5563c602fabSXin LI #define OF_PACKET_IN_LEN 20 5573c602fabSXin LI #define OF_ACTION_OUTPUT_LEN 8 5583c602fabSXin LI #define OF_ACTION_VLAN_VID_LEN 8 5593c602fabSXin LI #define OF_ACTION_VLAN_PCP_LEN 8 5603c602fabSXin LI #define OF_ACTION_DL_ADDR_LEN 16 5613c602fabSXin LI #define OF_ACTION_NW_ADDR_LEN 8 5623c602fabSXin LI #define OF_ACTION_TP_PORT_LEN 8 5633c602fabSXin LI #define OF_ACTION_NW_TOS_LEN 8 5643c602fabSXin LI #define OF_ACTION_VENDOR_HEADER_LEN 8 5653c602fabSXin LI #define OF_ACTION_HEADER_LEN 8 5663c602fabSXin LI #define OF_PACKET_OUT_LEN 16 5673c602fabSXin LI #define OF_MATCH_LEN 40 5683c602fabSXin LI #define OF_FLOW_MOD_LEN 72 5693c602fabSXin LI #define OF_FLOW_REMOVED_LEN 88 5703c602fabSXin LI #define OF_ERROR_MSG_LEN 12 5713c602fabSXin LI #define OF_STATS_REQUEST_LEN 12 5723c602fabSXin LI #define OF_STATS_REPLY_LEN 12 5733c602fabSXin LI #define OF_DESC_STATS_LEN 1056 5743c602fabSXin LI #define OF_FLOW_STATS_REQUEST_LEN 44 5753c602fabSXin LI #define OF_FLOW_STATS_LEN 88 5763c602fabSXin LI #define OF_AGGREGATE_STATS_REQUEST_LEN 44 5773c602fabSXin LI #define OF_AGGREGATE_STATS_REPLY_LEN 24 5783c602fabSXin LI #define OF_TABLE_STATS_LEN 64 5793c602fabSXin LI #define OF_PORT_STATS_REQUEST_LEN 8 5803c602fabSXin LI #define OF_PORT_STATS_LEN 104 5813c602fabSXin LI #define OF_VENDOR_HEADER_LEN 12 5823c602fabSXin LI #define OF_QUEUE_PROP_HEADER_LEN 8 5833c602fabSXin LI #define OF_QUEUE_PROP_MIN_RATE_LEN 16 5843c602fabSXin LI #define OF_PACKET_QUEUE_LEN 8 5853c602fabSXin LI #define OF_QUEUE_GET_CONFIG_REQUEST_LEN 12 5863c602fabSXin LI #define OF_QUEUE_GET_CONFIG_REPLY_LEN 16 5873c602fabSXin LI #define OF_ACTION_ENQUEUE_LEN 16 5883c602fabSXin LI #define OF_QUEUE_STATS_REQUEST_LEN 8 5893c602fabSXin LI #define OF_QUEUE_STATS_LEN 32 5903c602fabSXin LI 5913c602fabSXin LI /* miscellaneous constants from [OF10] */ 5923c602fabSXin LI #define OFP_MAX_TABLE_NAME_LEN 32 5933c602fabSXin LI #define OFP_MAX_PORT_NAME_LEN 16 5943c602fabSXin LI #define DESC_STR_LEN 256 5953c602fabSXin LI #define SERIAL_NUM_LEN 32 5963c602fabSXin LI #define OFP_VLAN_NONE 0xffff 5973c602fabSXin LI 598*8bdc5a62SPatrick Kelsey /* vendor extensions */ 599*8bdc5a62SPatrick Kelsey #define BSN_SET_IP_MASK 0 600*8bdc5a62SPatrick Kelsey #define BSN_GET_IP_MASK_REQUEST 1 601*8bdc5a62SPatrick Kelsey #define BSN_GET_IP_MASK_REPLY 2 602*8bdc5a62SPatrick Kelsey #define BSN_SET_MIRRORING 3 603*8bdc5a62SPatrick Kelsey #define BSN_GET_MIRRORING_REQUEST 4 604*8bdc5a62SPatrick Kelsey #define BSN_GET_MIRRORING_REPLY 5 605*8bdc5a62SPatrick Kelsey #define BSN_SHELL_COMMAND 6 606*8bdc5a62SPatrick Kelsey #define BSN_SHELL_OUTPUT 7 607*8bdc5a62SPatrick Kelsey #define BSN_SHELL_STATUS 8 608*8bdc5a62SPatrick Kelsey #define BSN_GET_INTERFACES_REQUEST 9 609*8bdc5a62SPatrick Kelsey #define BSN_GET_INTERFACES_REPLY 10 610*8bdc5a62SPatrick Kelsey #define BSN_SET_PKTIN_SUPPRESSION_REQUEST 11 611*8bdc5a62SPatrick Kelsey #define BSN_SET_L2_TABLE_REQUEST 12 612*8bdc5a62SPatrick Kelsey #define BSN_GET_L2_TABLE_REQUEST 13 613*8bdc5a62SPatrick Kelsey #define BSN_GET_L2_TABLE_REPLY 14 614*8bdc5a62SPatrick Kelsey #define BSN_VIRTUAL_PORT_CREATE_REQUEST 15 615*8bdc5a62SPatrick Kelsey #define BSN_VIRTUAL_PORT_CREATE_REPLY 16 616*8bdc5a62SPatrick Kelsey #define BSN_VIRTUAL_PORT_REMOVE_REQUEST 17 617*8bdc5a62SPatrick Kelsey #define BSN_BW_ENABLE_SET_REQUEST 18 618*8bdc5a62SPatrick Kelsey #define BSN_BW_ENABLE_GET_REQUEST 19 619*8bdc5a62SPatrick Kelsey #define BSN_BW_ENABLE_GET_REPLY 20 620*8bdc5a62SPatrick Kelsey #define BSN_BW_CLEAR_DATA_REQUEST 21 621*8bdc5a62SPatrick Kelsey #define BSN_BW_CLEAR_DATA_REPLY 22 622*8bdc5a62SPatrick Kelsey #define BSN_BW_ENABLE_SET_REPLY 23 623*8bdc5a62SPatrick Kelsey #define BSN_SET_L2_TABLE_REPLY 24 624*8bdc5a62SPatrick Kelsey #define BSN_SET_PKTIN_SUPPRESSION_REPLY 25 625*8bdc5a62SPatrick Kelsey #define BSN_VIRTUAL_PORT_REMOVE_REPLY 26 626*8bdc5a62SPatrick Kelsey #define BSN_HYBRID_GET_REQUEST 27 627*8bdc5a62SPatrick Kelsey #define BSN_HYBRID_GET_REPLY 28 628*8bdc5a62SPatrick Kelsey /* 29 */ 629*8bdc5a62SPatrick Kelsey /* 30 */ 630*8bdc5a62SPatrick Kelsey #define BSN_PDU_TX_REQUEST 31 631*8bdc5a62SPatrick Kelsey #define BSN_PDU_TX_REPLY 32 632*8bdc5a62SPatrick Kelsey #define BSN_PDU_RX_REQUEST 33 633*8bdc5a62SPatrick Kelsey #define BSN_PDU_RX_REPLY 34 634*8bdc5a62SPatrick Kelsey #define BSN_PDU_RX_TIMEOUT 35 635*8bdc5a62SPatrick Kelsey 636*8bdc5a62SPatrick Kelsey static const struct tok bsn_subtype_str[] = { 637*8bdc5a62SPatrick Kelsey { BSN_SET_IP_MASK, "SET_IP_MASK" }, 638*8bdc5a62SPatrick Kelsey { BSN_GET_IP_MASK_REQUEST, "GET_IP_MASK_REQUEST" }, 639*8bdc5a62SPatrick Kelsey { BSN_GET_IP_MASK_REPLY, "GET_IP_MASK_REPLY" }, 640*8bdc5a62SPatrick Kelsey { BSN_SET_MIRRORING, "SET_MIRRORING" }, 641*8bdc5a62SPatrick Kelsey { BSN_GET_MIRRORING_REQUEST, "GET_MIRRORING_REQUEST" }, 642*8bdc5a62SPatrick Kelsey { BSN_GET_MIRRORING_REPLY, "GET_MIRRORING_REPLY" }, 643*8bdc5a62SPatrick Kelsey { BSN_SHELL_COMMAND, "SHELL_COMMAND" }, 644*8bdc5a62SPatrick Kelsey { BSN_SHELL_OUTPUT, "SHELL_OUTPUT" }, 645*8bdc5a62SPatrick Kelsey { BSN_SHELL_STATUS, "SHELL_STATUS" }, 646*8bdc5a62SPatrick Kelsey { BSN_GET_INTERFACES_REQUEST, "GET_INTERFACES_REQUEST" }, 647*8bdc5a62SPatrick Kelsey { BSN_GET_INTERFACES_REPLY, "GET_INTERFACES_REPLY" }, 648*8bdc5a62SPatrick Kelsey { BSN_SET_PKTIN_SUPPRESSION_REQUEST, "SET_PKTIN_SUPPRESSION_REQUEST" }, 649*8bdc5a62SPatrick Kelsey { BSN_SET_L2_TABLE_REQUEST, "SET_L2_TABLE_REQUEST" }, 650*8bdc5a62SPatrick Kelsey { BSN_GET_L2_TABLE_REQUEST, "GET_L2_TABLE_REQUEST" }, 651*8bdc5a62SPatrick Kelsey { BSN_GET_L2_TABLE_REPLY, "GET_L2_TABLE_REPLY" }, 652*8bdc5a62SPatrick Kelsey { BSN_VIRTUAL_PORT_CREATE_REQUEST, "VIRTUAL_PORT_CREATE_REQUEST" }, 653*8bdc5a62SPatrick Kelsey { BSN_VIRTUAL_PORT_CREATE_REPLY, "VIRTUAL_PORT_CREATE_REPLY" }, 654*8bdc5a62SPatrick Kelsey { BSN_VIRTUAL_PORT_REMOVE_REQUEST, "VIRTUAL_PORT_REMOVE_REQUEST" }, 655*8bdc5a62SPatrick Kelsey { BSN_BW_ENABLE_SET_REQUEST, "BW_ENABLE_SET_REQUEST" }, 656*8bdc5a62SPatrick Kelsey { BSN_BW_ENABLE_GET_REQUEST, "BW_ENABLE_GET_REQUEST" }, 657*8bdc5a62SPatrick Kelsey { BSN_BW_ENABLE_GET_REPLY, "BW_ENABLE_GET_REPLY" }, 658*8bdc5a62SPatrick Kelsey { BSN_BW_CLEAR_DATA_REQUEST, "BW_CLEAR_DATA_REQUEST" }, 659*8bdc5a62SPatrick Kelsey { BSN_BW_CLEAR_DATA_REPLY, "BW_CLEAR_DATA_REPLY" }, 660*8bdc5a62SPatrick Kelsey { BSN_BW_ENABLE_SET_REPLY, "BW_ENABLE_SET_REPLY" }, 661*8bdc5a62SPatrick Kelsey { BSN_SET_L2_TABLE_REPLY, "SET_L2_TABLE_REPLY" }, 662*8bdc5a62SPatrick Kelsey { BSN_SET_PKTIN_SUPPRESSION_REPLY, "SET_PKTIN_SUPPRESSION_REPLY" }, 663*8bdc5a62SPatrick Kelsey { BSN_VIRTUAL_PORT_REMOVE_REPLY, "VIRTUAL_PORT_REMOVE_REPLY" }, 664*8bdc5a62SPatrick Kelsey { BSN_HYBRID_GET_REQUEST, "HYBRID_GET_REQUEST" }, 665*8bdc5a62SPatrick Kelsey { BSN_HYBRID_GET_REPLY, "HYBRID_GET_REPLY" }, 666*8bdc5a62SPatrick Kelsey { BSN_PDU_TX_REQUEST, "PDU_TX_REQUEST" }, 667*8bdc5a62SPatrick Kelsey { BSN_PDU_TX_REPLY, "PDU_TX_REPLY" }, 668*8bdc5a62SPatrick Kelsey { BSN_PDU_RX_REQUEST, "PDU_RX_REQUEST" }, 669*8bdc5a62SPatrick Kelsey { BSN_PDU_RX_REPLY, "PDU_RX_REPLY" }, 670*8bdc5a62SPatrick Kelsey { BSN_PDU_RX_TIMEOUT, "PDU_RX_TIMEOUT" }, 671*8bdc5a62SPatrick Kelsey { 0, NULL } 672*8bdc5a62SPatrick Kelsey }; 673*8bdc5a62SPatrick Kelsey 674*8bdc5a62SPatrick Kelsey #define BSN_ACTION_MIRROR 1 675*8bdc5a62SPatrick Kelsey #define BSN_ACTION_SET_TUNNEL_DST 2 676*8bdc5a62SPatrick Kelsey /* 3 */ 677*8bdc5a62SPatrick Kelsey #define BSN_ACTION_CHECKSUM 4 678*8bdc5a62SPatrick Kelsey 679*8bdc5a62SPatrick Kelsey static const struct tok bsn_action_subtype_str[] = { 680*8bdc5a62SPatrick Kelsey { BSN_ACTION_MIRROR, "MIRROR" }, 681*8bdc5a62SPatrick Kelsey { BSN_ACTION_SET_TUNNEL_DST, "SET_TUNNEL_DST" }, 682*8bdc5a62SPatrick Kelsey { BSN_ACTION_CHECKSUM, "CHECKSUM" }, 683*8bdc5a62SPatrick Kelsey { 0, NULL } 684*8bdc5a62SPatrick Kelsey }; 685*8bdc5a62SPatrick Kelsey 686*8bdc5a62SPatrick Kelsey static const struct tok bsn_mirror_copy_stage_str[] = { 687*8bdc5a62SPatrick Kelsey { 0, "INGRESS" }, 688*8bdc5a62SPatrick Kelsey { 1, "EGRESS" }, 689*8bdc5a62SPatrick Kelsey { 0, NULL }, 690*8bdc5a62SPatrick Kelsey }; 691*8bdc5a62SPatrick Kelsey 692*8bdc5a62SPatrick Kelsey static const struct tok bsn_onoff_str[] = { 693*8bdc5a62SPatrick Kelsey { 0, "OFF" }, 694*8bdc5a62SPatrick Kelsey { 1, "ON" }, 695*8bdc5a62SPatrick Kelsey { 0, NULL }, 696*8bdc5a62SPatrick Kelsey }; 697*8bdc5a62SPatrick Kelsey 6983c602fabSXin LI static const char * 699*8bdc5a62SPatrick Kelsey vlan_str(const uint16_t vid) 700*8bdc5a62SPatrick Kelsey { 7013c602fabSXin LI static char buf[sizeof("65535 (bogus)")]; 7023c602fabSXin LI const char *fmt; 7033c602fabSXin LI 7043c602fabSXin LI if (vid == OFP_VLAN_NONE) 7053c602fabSXin LI return "NONE"; 7063c602fabSXin LI fmt = (vid > 0 && vid < 0x0fff) ? "%u" : "%u (bogus)"; 7073c602fabSXin LI snprintf(buf, sizeof(buf), fmt, vid); 7083c602fabSXin LI return buf; 7093c602fabSXin LI } 7103c602fabSXin LI 7113c602fabSXin LI static const char * 712*8bdc5a62SPatrick Kelsey pcp_str(const uint8_t pcp) 713*8bdc5a62SPatrick Kelsey { 7143c602fabSXin LI static char buf[sizeof("255 (bogus)")]; 7153c602fabSXin LI snprintf(buf, sizeof(buf), pcp <= 7 ? "%u" : "%u (bogus)", pcp); 7163c602fabSXin LI return buf; 7173c602fabSXin LI } 7183c602fabSXin LI 7193c602fabSXin LI static void 7203c602fabSXin LI of10_bitmap_print(netdissect_options *ndo, 721*8bdc5a62SPatrick Kelsey const struct tok *t, const uint32_t v, const uint32_t u) 722*8bdc5a62SPatrick Kelsey { 7233c602fabSXin LI const char *sep = " ("; 7243c602fabSXin LI 7253c602fabSXin LI if (v == 0) 7263c602fabSXin LI return; 7273c602fabSXin LI /* assigned bits */ 7283c602fabSXin LI for (; t->s != NULL; t++) 7293c602fabSXin LI if (v & t->v) { 7303c602fabSXin LI ND_PRINT((ndo, "%s%s", sep, t->s)); 7313c602fabSXin LI sep = ", "; 7323c602fabSXin LI } 7333c602fabSXin LI /* unassigned bits? */ 7343c602fabSXin LI ND_PRINT((ndo, v & u ? ") (bogus)" : ")")); 7353c602fabSXin LI } 7363c602fabSXin LI 7373c602fabSXin LI static const u_char * 7383c602fabSXin LI of10_data_print(netdissect_options *ndo, 739*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 740*8bdc5a62SPatrick Kelsey { 7413c602fabSXin LI if (len == 0) 7423c602fabSXin LI return cp; 7433c602fabSXin LI /* data */ 7443c602fabSXin LI ND_PRINT((ndo, "\n\t data (%u octets)", len)); 7453c602fabSXin LI ND_TCHECK2(*cp, len); 7463c602fabSXin LI if (ndo->ndo_vflag >= 2) 7473c602fabSXin LI hex_and_ascii_print(ndo, "\n\t ", cp, len); 7483c602fabSXin LI return cp + len; 7493c602fabSXin LI 7503c602fabSXin LI trunc: 7513c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 7523c602fabSXin LI return ep; 7533c602fabSXin LI } 7543c602fabSXin LI 7553c602fabSXin LI static const u_char * 756*8bdc5a62SPatrick Kelsey of10_bsn_message_print(netdissect_options *ndo, 757*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 758*8bdc5a62SPatrick Kelsey { 759*8bdc5a62SPatrick Kelsey const u_char *cp0 = cp; 760*8bdc5a62SPatrick Kelsey uint32_t subtype; 761*8bdc5a62SPatrick Kelsey 762*8bdc5a62SPatrick Kelsey if (len < 4) 763*8bdc5a62SPatrick Kelsey goto corrupt; 764*8bdc5a62SPatrick Kelsey /* subtype */ 765*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 766*8bdc5a62SPatrick Kelsey subtype = EXTRACT_32BITS(cp); 767*8bdc5a62SPatrick Kelsey cp += 4; 768*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "\n\t subtype %s", tok2str(bsn_subtype_str, "unknown (0x%08x)", subtype))); 769*8bdc5a62SPatrick Kelsey switch (subtype) { 770*8bdc5a62SPatrick Kelsey case BSN_GET_IP_MASK_REQUEST: 771*8bdc5a62SPatrick Kelsey /* 772*8bdc5a62SPatrick Kelsey * 0 1 2 3 773*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 774*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 775*8bdc5a62SPatrick Kelsey * | subtype | 776*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 777*8bdc5a62SPatrick Kelsey * | index | pad | 778*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 779*8bdc5a62SPatrick Kelsey * | pad | 780*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 781*8bdc5a62SPatrick Kelsey * 782*8bdc5a62SPatrick Kelsey */ 783*8bdc5a62SPatrick Kelsey if (len != 12) 784*8bdc5a62SPatrick Kelsey goto corrupt; 785*8bdc5a62SPatrick Kelsey /* index */ 786*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 1); 787*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", index %u", *cp)); 788*8bdc5a62SPatrick Kelsey cp += 1; 789*8bdc5a62SPatrick Kelsey /* pad */ 790*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 7); 791*8bdc5a62SPatrick Kelsey cp += 7; 792*8bdc5a62SPatrick Kelsey break; 793*8bdc5a62SPatrick Kelsey case BSN_SET_IP_MASK: 794*8bdc5a62SPatrick Kelsey case BSN_GET_IP_MASK_REPLY: 795*8bdc5a62SPatrick Kelsey /* 796*8bdc5a62SPatrick Kelsey * 0 1 2 3 797*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 798*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 799*8bdc5a62SPatrick Kelsey * | subtype | 800*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 801*8bdc5a62SPatrick Kelsey * | index | pad | 802*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 803*8bdc5a62SPatrick Kelsey * | mask | 804*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 805*8bdc5a62SPatrick Kelsey * 806*8bdc5a62SPatrick Kelsey */ 807*8bdc5a62SPatrick Kelsey if (len != 12) 808*8bdc5a62SPatrick Kelsey goto corrupt; 809*8bdc5a62SPatrick Kelsey /* index */ 810*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 1); 811*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", index %u", *cp)); 812*8bdc5a62SPatrick Kelsey cp += 1; 813*8bdc5a62SPatrick Kelsey /* pad */ 814*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 3); 815*8bdc5a62SPatrick Kelsey cp += 3; 816*8bdc5a62SPatrick Kelsey /* mask */ 817*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 818*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", mask %s", ipaddr_string(ndo, cp))); 819*8bdc5a62SPatrick Kelsey cp += 4; 820*8bdc5a62SPatrick Kelsey break; 821*8bdc5a62SPatrick Kelsey case BSN_SET_MIRRORING: 822*8bdc5a62SPatrick Kelsey case BSN_GET_MIRRORING_REQUEST: 823*8bdc5a62SPatrick Kelsey case BSN_GET_MIRRORING_REPLY: 824*8bdc5a62SPatrick Kelsey /* 825*8bdc5a62SPatrick Kelsey * 0 1 2 3 826*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 827*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 828*8bdc5a62SPatrick Kelsey * | subtype | 829*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 830*8bdc5a62SPatrick Kelsey * | report m. p. | pad | 831*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 832*8bdc5a62SPatrick Kelsey * 833*8bdc5a62SPatrick Kelsey */ 834*8bdc5a62SPatrick Kelsey if (len != 8) 835*8bdc5a62SPatrick Kelsey goto corrupt; 836*8bdc5a62SPatrick Kelsey /* report_mirror_ports */ 837*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 1); 838*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", report_mirror_ports %s", tok2str(bsn_onoff_str, "bogus (%u)", *cp))); 839*8bdc5a62SPatrick Kelsey cp += 1; 840*8bdc5a62SPatrick Kelsey /* pad */ 841*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 3); 842*8bdc5a62SPatrick Kelsey cp += 3; 843*8bdc5a62SPatrick Kelsey break; 844*8bdc5a62SPatrick Kelsey case BSN_GET_INTERFACES_REQUEST: 845*8bdc5a62SPatrick Kelsey case BSN_GET_L2_TABLE_REQUEST: 846*8bdc5a62SPatrick Kelsey case BSN_BW_ENABLE_GET_REQUEST: 847*8bdc5a62SPatrick Kelsey case BSN_BW_CLEAR_DATA_REQUEST: 848*8bdc5a62SPatrick Kelsey case BSN_HYBRID_GET_REQUEST: 849*8bdc5a62SPatrick Kelsey /* 850*8bdc5a62SPatrick Kelsey * 0 1 2 3 851*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 852*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 853*8bdc5a62SPatrick Kelsey * | subtype | 854*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 855*8bdc5a62SPatrick Kelsey * 856*8bdc5a62SPatrick Kelsey */ 857*8bdc5a62SPatrick Kelsey if (len != 4) 858*8bdc5a62SPatrick Kelsey goto corrupt; 859*8bdc5a62SPatrick Kelsey break; 860*8bdc5a62SPatrick Kelsey case BSN_VIRTUAL_PORT_REMOVE_REQUEST: 861*8bdc5a62SPatrick Kelsey /* 862*8bdc5a62SPatrick Kelsey * 0 1 2 3 863*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 864*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 865*8bdc5a62SPatrick Kelsey * | subtype | 866*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 867*8bdc5a62SPatrick Kelsey * | vport_no | 868*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 869*8bdc5a62SPatrick Kelsey * 870*8bdc5a62SPatrick Kelsey */ 871*8bdc5a62SPatrick Kelsey if (len != 8) 872*8bdc5a62SPatrick Kelsey goto corrupt; 873*8bdc5a62SPatrick Kelsey /* vport_no */ 874*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 875*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", vport_no %u", EXTRACT_32BITS(cp))); 876*8bdc5a62SPatrick Kelsey cp += 4; 877*8bdc5a62SPatrick Kelsey break; 878*8bdc5a62SPatrick Kelsey case BSN_SHELL_COMMAND: 879*8bdc5a62SPatrick Kelsey /* 880*8bdc5a62SPatrick Kelsey * 0 1 2 3 881*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 882*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 883*8bdc5a62SPatrick Kelsey * | subtype | 884*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 885*8bdc5a62SPatrick Kelsey * | service | 886*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 887*8bdc5a62SPatrick Kelsey * | data ... 888*8bdc5a62SPatrick Kelsey * +---------------+---------------+-------- 889*8bdc5a62SPatrick Kelsey * 890*8bdc5a62SPatrick Kelsey */ 891*8bdc5a62SPatrick Kelsey if (len < 8) 892*8bdc5a62SPatrick Kelsey goto corrupt; 893*8bdc5a62SPatrick Kelsey /* service */ 894*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 895*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", service %u", EXTRACT_32BITS(cp))); 896*8bdc5a62SPatrick Kelsey cp += 4; 897*8bdc5a62SPatrick Kelsey /* data */ 898*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", data '")); 899*8bdc5a62SPatrick Kelsey if (fn_printn(ndo, cp, len - 8, ep)) { 900*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "'")); 901*8bdc5a62SPatrick Kelsey goto trunc; 902*8bdc5a62SPatrick Kelsey } 903*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "'")); 904*8bdc5a62SPatrick Kelsey cp += len - 8; 905*8bdc5a62SPatrick Kelsey break; 906*8bdc5a62SPatrick Kelsey case BSN_SHELL_OUTPUT: 907*8bdc5a62SPatrick Kelsey /* 908*8bdc5a62SPatrick Kelsey * 0 1 2 3 909*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 910*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 911*8bdc5a62SPatrick Kelsey * | subtype | 912*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 913*8bdc5a62SPatrick Kelsey * | data ... 914*8bdc5a62SPatrick Kelsey * +---------------+---------------+-------- 915*8bdc5a62SPatrick Kelsey * 916*8bdc5a62SPatrick Kelsey */ 917*8bdc5a62SPatrick Kelsey /* already checked that len >= 4 */ 918*8bdc5a62SPatrick Kelsey /* data */ 919*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", data '")); 920*8bdc5a62SPatrick Kelsey if (fn_printn(ndo, cp, len - 4, ep)) { 921*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "'")); 922*8bdc5a62SPatrick Kelsey goto trunc; 923*8bdc5a62SPatrick Kelsey } 924*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "'")); 925*8bdc5a62SPatrick Kelsey cp += len - 4; 926*8bdc5a62SPatrick Kelsey break; 927*8bdc5a62SPatrick Kelsey case BSN_SHELL_STATUS: 928*8bdc5a62SPatrick Kelsey /* 929*8bdc5a62SPatrick Kelsey * 0 1 2 3 930*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 931*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 932*8bdc5a62SPatrick Kelsey * | subtype | 933*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 934*8bdc5a62SPatrick Kelsey * | status | 935*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 936*8bdc5a62SPatrick Kelsey * 937*8bdc5a62SPatrick Kelsey */ 938*8bdc5a62SPatrick Kelsey if (len != 8) 939*8bdc5a62SPatrick Kelsey goto corrupt; 940*8bdc5a62SPatrick Kelsey /* status */ 941*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 942*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", status 0x%08x", EXTRACT_32BITS(cp))); 943*8bdc5a62SPatrick Kelsey cp += 4; 944*8bdc5a62SPatrick Kelsey break; 945*8bdc5a62SPatrick Kelsey default: 946*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, len - 4); 947*8bdc5a62SPatrick Kelsey cp += len - 4; 948*8bdc5a62SPatrick Kelsey } 949*8bdc5a62SPatrick Kelsey return cp; 950*8bdc5a62SPatrick Kelsey 951*8bdc5a62SPatrick Kelsey corrupt: /* skip the undersized data */ 952*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "%s", cstr)); 953*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp0, len); 954*8bdc5a62SPatrick Kelsey return cp0 + len; 955*8bdc5a62SPatrick Kelsey trunc: 956*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "%s", tstr)); 957*8bdc5a62SPatrick Kelsey return ep; 958*8bdc5a62SPatrick Kelsey } 959*8bdc5a62SPatrick Kelsey 960*8bdc5a62SPatrick Kelsey static const u_char * 961*8bdc5a62SPatrick Kelsey of10_bsn_actions_print(netdissect_options *ndo, 962*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 963*8bdc5a62SPatrick Kelsey { 964*8bdc5a62SPatrick Kelsey const u_char *cp0 = cp; 965*8bdc5a62SPatrick Kelsey uint32_t subtype, vlan_tag; 966*8bdc5a62SPatrick Kelsey 967*8bdc5a62SPatrick Kelsey if (len < 4) 968*8bdc5a62SPatrick Kelsey goto corrupt; 969*8bdc5a62SPatrick Kelsey /* subtype */ 970*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 971*8bdc5a62SPatrick Kelsey subtype = EXTRACT_32BITS(cp); 972*8bdc5a62SPatrick Kelsey cp += 4; 973*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "\n\t subtype %s", tok2str(bsn_action_subtype_str, "unknown (0x%08x)", subtype))); 974*8bdc5a62SPatrick Kelsey switch (subtype) { 975*8bdc5a62SPatrick Kelsey case BSN_ACTION_MIRROR: 976*8bdc5a62SPatrick Kelsey /* 977*8bdc5a62SPatrick Kelsey * 0 1 2 3 978*8bdc5a62SPatrick Kelsey * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 979*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 980*8bdc5a62SPatrick Kelsey * | subtype | 981*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 982*8bdc5a62SPatrick Kelsey * | dest_port | 983*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 984*8bdc5a62SPatrick Kelsey * | vlan_tag | 985*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 986*8bdc5a62SPatrick Kelsey * | copy_stage | pad | 987*8bdc5a62SPatrick Kelsey * +---------------+---------------+---------------+---------------+ 988*8bdc5a62SPatrick Kelsey * 989*8bdc5a62SPatrick Kelsey */ 990*8bdc5a62SPatrick Kelsey if (len != 16) 991*8bdc5a62SPatrick Kelsey goto corrupt; 992*8bdc5a62SPatrick Kelsey /* dest_port */ 993*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 994*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", dest_port %u", EXTRACT_32BITS(cp))); 995*8bdc5a62SPatrick Kelsey cp += 4; 996*8bdc5a62SPatrick Kelsey /* vlan_tag */ 997*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 998*8bdc5a62SPatrick Kelsey vlan_tag = EXTRACT_32BITS(cp); 999*8bdc5a62SPatrick Kelsey cp += 4; 1000*8bdc5a62SPatrick Kelsey switch (vlan_tag >> 16) { 1001*8bdc5a62SPatrick Kelsey case 0: 1002*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", vlan_tag none")); 1003*8bdc5a62SPatrick Kelsey break; 1004*8bdc5a62SPatrick Kelsey case ETHERTYPE_8021Q: 1005*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", vlan_tag 802.1Q (%s)", ieee8021q_tci_string(vlan_tag & 0xffff))); 1006*8bdc5a62SPatrick Kelsey break; 1007*8bdc5a62SPatrick Kelsey default: 1008*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", vlan_tag unknown (0x%04x)", vlan_tag >> 16)); 1009*8bdc5a62SPatrick Kelsey } 1010*8bdc5a62SPatrick Kelsey /* copy_stage */ 1011*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 1); 1012*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", copy_stage %s", tok2str(bsn_mirror_copy_stage_str, "unknown (%u)", *cp))); 1013*8bdc5a62SPatrick Kelsey cp += 1; 1014*8bdc5a62SPatrick Kelsey /* pad */ 1015*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 3); 1016*8bdc5a62SPatrick Kelsey cp += 3; 1017*8bdc5a62SPatrick Kelsey break; 1018*8bdc5a62SPatrick Kelsey default: 1019*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, len - 4); 1020*8bdc5a62SPatrick Kelsey cp += len - 4; 1021*8bdc5a62SPatrick Kelsey } 1022*8bdc5a62SPatrick Kelsey 1023*8bdc5a62SPatrick Kelsey return cp; 1024*8bdc5a62SPatrick Kelsey 1025*8bdc5a62SPatrick Kelsey corrupt: 1026*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "%s", cstr)); 1027*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp0, len); 1028*8bdc5a62SPatrick Kelsey return cp0 + len; 1029*8bdc5a62SPatrick Kelsey trunc: 1030*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "%s", tstr)); 1031*8bdc5a62SPatrick Kelsey return ep; 1032*8bdc5a62SPatrick Kelsey } 1033*8bdc5a62SPatrick Kelsey 1034*8bdc5a62SPatrick Kelsey static const u_char * 1035*8bdc5a62SPatrick Kelsey of10_vendor_action_print(netdissect_options *ndo, 1036*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 1037*8bdc5a62SPatrick Kelsey { 1038*8bdc5a62SPatrick Kelsey uint32_t vendor; 1039*8bdc5a62SPatrick Kelsey const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, const u_int); 1040*8bdc5a62SPatrick Kelsey 10413c602fabSXin LI if (len < 4) 10423c602fabSXin LI goto corrupt; 10433c602fabSXin LI /* vendor */ 10443c602fabSXin LI ND_TCHECK2(*cp, 4); 1045*8bdc5a62SPatrick Kelsey vendor = EXTRACT_32BITS(cp); 10463c602fabSXin LI cp += 4; 1047*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor))); 1048*8bdc5a62SPatrick Kelsey /* data */ 1049*8bdc5a62SPatrick Kelsey decoder = 1050*8bdc5a62SPatrick Kelsey vendor == OUI_BSN ? of10_bsn_actions_print : 1051*8bdc5a62SPatrick Kelsey of10_data_print; 1052*8bdc5a62SPatrick Kelsey return decoder(ndo, cp, ep, len - 4); 1053*8bdc5a62SPatrick Kelsey 1054*8bdc5a62SPatrick Kelsey corrupt: /* skip the undersized data */ 1055*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "%s", cstr)); 1056*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, len); 1057*8bdc5a62SPatrick Kelsey return cp + len; 1058*8bdc5a62SPatrick Kelsey trunc: 1059*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "%s", tstr)); 1060*8bdc5a62SPatrick Kelsey return ep; 1061*8bdc5a62SPatrick Kelsey } 1062*8bdc5a62SPatrick Kelsey 1063*8bdc5a62SPatrick Kelsey static const u_char * 1064*8bdc5a62SPatrick Kelsey of10_vendor_message_print(netdissect_options *ndo, 1065*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 1066*8bdc5a62SPatrick Kelsey { 1067*8bdc5a62SPatrick Kelsey uint32_t vendor; 1068*8bdc5a62SPatrick Kelsey const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, u_int); 1069*8bdc5a62SPatrick Kelsey 1070*8bdc5a62SPatrick Kelsey if (len < 4) 1071*8bdc5a62SPatrick Kelsey goto corrupt; 1072*8bdc5a62SPatrick Kelsey /* vendor */ 1073*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 1074*8bdc5a62SPatrick Kelsey vendor = EXTRACT_32BITS(cp); 1075*8bdc5a62SPatrick Kelsey cp += 4; 1076*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor))); 1077*8bdc5a62SPatrick Kelsey /* data */ 1078*8bdc5a62SPatrick Kelsey decoder = 1079*8bdc5a62SPatrick Kelsey vendor == OUI_BSN ? of10_bsn_message_print : 1080*8bdc5a62SPatrick Kelsey of10_data_print; 1081*8bdc5a62SPatrick Kelsey return decoder(ndo, cp, ep, len - 4); 1082*8bdc5a62SPatrick Kelsey 1083*8bdc5a62SPatrick Kelsey corrupt: /* skip the undersized data */ 1084*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "%s", cstr)); 1085*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, len); 1086*8bdc5a62SPatrick Kelsey return cp + len; 1087*8bdc5a62SPatrick Kelsey trunc: 1088*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, "%s", tstr)); 1089*8bdc5a62SPatrick Kelsey return ep; 1090*8bdc5a62SPatrick Kelsey } 1091*8bdc5a62SPatrick Kelsey 1092*8bdc5a62SPatrick Kelsey /* Vendor ID is mandatory, data is optional. */ 1093*8bdc5a62SPatrick Kelsey static const u_char * 1094*8bdc5a62SPatrick Kelsey of10_vendor_data_print(netdissect_options *ndo, 1095*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 1096*8bdc5a62SPatrick Kelsey { 1097*8bdc5a62SPatrick Kelsey uint32_t vendor; 1098*8bdc5a62SPatrick Kelsey 1099*8bdc5a62SPatrick Kelsey if (len < 4) 1100*8bdc5a62SPatrick Kelsey goto corrupt; 1101*8bdc5a62SPatrick Kelsey /* vendor */ 1102*8bdc5a62SPatrick Kelsey ND_TCHECK2(*cp, 4); 1103*8bdc5a62SPatrick Kelsey vendor = EXTRACT_32BITS(cp); 1104*8bdc5a62SPatrick Kelsey cp += 4; 1105*8bdc5a62SPatrick Kelsey ND_PRINT((ndo, ", vendor 0x%08x (%s)", vendor, of_vendor_name(vendor))); 11063c602fabSXin LI /* data */ 11073c602fabSXin LI return of10_data_print(ndo, cp, ep, len - 4); 11083c602fabSXin LI 11093c602fabSXin LI corrupt: /* skip the undersized data */ 11103c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 11113c602fabSXin LI ND_TCHECK2(*cp, len); 11123c602fabSXin LI return cp + len; 11133c602fabSXin LI trunc: 11143c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 11153c602fabSXin LI return ep; 11163c602fabSXin LI } 11173c602fabSXin LI 11183c602fabSXin LI static const u_char * 11193c602fabSXin LI of10_packet_data_print(netdissect_options *ndo, 1120*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 1121*8bdc5a62SPatrick Kelsey { 11223c602fabSXin LI if (len == 0) 11233c602fabSXin LI return cp; 11243c602fabSXin LI /* data */ 11253c602fabSXin LI ND_PRINT((ndo, "\n\t data (%u octets)", len)); 11263c602fabSXin LI if (ndo->ndo_vflag < 3) 11273c602fabSXin LI return cp + len; 11283c602fabSXin LI ND_TCHECK2(*cp, len); 11293c602fabSXin LI ndo->ndo_vflag -= 3; 11303c602fabSXin LI ND_PRINT((ndo, ", frame decoding below\n")); 11313c602fabSXin LI ether_print(ndo, cp, len, ndo->ndo_snapend - cp, NULL, NULL); 11323c602fabSXin LI ndo->ndo_vflag += 3; 11333c602fabSXin LI return cp + len; 11343c602fabSXin LI 11353c602fabSXin LI trunc: 11363c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 11373c602fabSXin LI return ep; 11383c602fabSXin LI } 11393c602fabSXin LI 11403c602fabSXin LI /* [OF10] Section 5.2.1 */ 11413c602fabSXin LI static const u_char * 11423c602fabSXin LI of10_phy_ports_print(netdissect_options *ndo, 1143*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, u_int len) 1144*8bdc5a62SPatrick Kelsey { 11453c602fabSXin LI const u_char *cp0 = cp; 11463c602fabSXin LI const u_int len0 = len; 11473c602fabSXin LI 11483c602fabSXin LI while (len) { 11493c602fabSXin LI if (len < OF_PHY_PORT_LEN) 11503c602fabSXin LI goto corrupt; 11513c602fabSXin LI /* port_no */ 11523c602fabSXin LI ND_TCHECK2(*cp, 2); 11533c602fabSXin LI ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 11543c602fabSXin LI cp += 2; 11553c602fabSXin LI /* hw_addr */ 11563c602fabSXin LI ND_TCHECK2(*cp, ETHER_ADDR_LEN); 11573c602fabSXin LI ND_PRINT((ndo, ", hw_addr %s", etheraddr_string(ndo, cp))); 11583c602fabSXin LI cp += ETHER_ADDR_LEN; 11593c602fabSXin LI /* name */ 11603c602fabSXin LI ND_TCHECK2(*cp, OFP_MAX_PORT_NAME_LEN); 11613c602fabSXin LI ND_PRINT((ndo, ", name '")); 11623c602fabSXin LI fn_print(ndo, cp, cp + OFP_MAX_PORT_NAME_LEN); 11633c602fabSXin LI ND_PRINT((ndo, "'")); 11643c602fabSXin LI cp += OFP_MAX_PORT_NAME_LEN; 11653c602fabSXin LI 11663c602fabSXin LI if (ndo->ndo_vflag < 2) { 11673c602fabSXin LI ND_TCHECK2(*cp, 24); 11683c602fabSXin LI cp += 24; 11693c602fabSXin LI goto next_port; 11703c602fabSXin LI } 11713c602fabSXin LI /* config */ 11723c602fabSXin LI ND_TCHECK2(*cp, 4); 11733c602fabSXin LI ND_PRINT((ndo, "\n\t config 0x%08x", EXTRACT_32BITS(cp))); 11743c602fabSXin LI of10_bitmap_print(ndo, ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U); 11753c602fabSXin LI cp += 4; 11763c602fabSXin LI /* state */ 11773c602fabSXin LI ND_TCHECK2(*cp, 4); 11783c602fabSXin LI ND_PRINT((ndo, "\n\t state 0x%08x", EXTRACT_32BITS(cp))); 11793c602fabSXin LI of10_bitmap_print(ndo, ofpps_bm, EXTRACT_32BITS(cp), OFPPS_U); 11803c602fabSXin LI cp += 4; 11813c602fabSXin LI /* curr */ 11823c602fabSXin LI ND_TCHECK2(*cp, 4); 11833c602fabSXin LI ND_PRINT((ndo, "\n\t curr 0x%08x", EXTRACT_32BITS(cp))); 11843c602fabSXin LI of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); 11853c602fabSXin LI cp += 4; 11863c602fabSXin LI /* advertised */ 11873c602fabSXin LI ND_TCHECK2(*cp, 4); 11883c602fabSXin LI ND_PRINT((ndo, "\n\t advertised 0x%08x", EXTRACT_32BITS(cp))); 11893c602fabSXin LI of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); 11903c602fabSXin LI cp += 4; 11913c602fabSXin LI /* supported */ 11923c602fabSXin LI ND_TCHECK2(*cp, 4); 11933c602fabSXin LI ND_PRINT((ndo, "\n\t supported 0x%08x", EXTRACT_32BITS(cp))); 11943c602fabSXin LI of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); 11953c602fabSXin LI cp += 4; 11963c602fabSXin LI /* peer */ 11973c602fabSXin LI ND_TCHECK2(*cp, 4); 11983c602fabSXin LI ND_PRINT((ndo, "\n\t peer 0x%08x", EXTRACT_32BITS(cp))); 11993c602fabSXin LI of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); 12003c602fabSXin LI cp += 4; 12013c602fabSXin LI next_port: 12023c602fabSXin LI len -= OF_PHY_PORT_LEN; 12033c602fabSXin LI } /* while */ 12043c602fabSXin LI return cp; 12053c602fabSXin LI 12063c602fabSXin LI corrupt: /* skip the undersized trailing data */ 12073c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 12083c602fabSXin LI ND_TCHECK2(*cp0, len0); 12093c602fabSXin LI return cp0 + len0; 12103c602fabSXin LI trunc: 12113c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 12123c602fabSXin LI return ep; 12133c602fabSXin LI } 12143c602fabSXin LI 12153c602fabSXin LI /* [OF10] Section 5.2.2 */ 12163c602fabSXin LI static const u_char * 12173c602fabSXin LI of10_queue_props_print(netdissect_options *ndo, 1218*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, u_int len) 1219*8bdc5a62SPatrick Kelsey { 12203c602fabSXin LI const u_char *cp0 = cp; 12213c602fabSXin LI const u_int len0 = len; 12223c602fabSXin LI uint16_t property, plen, rate; 12233c602fabSXin LI 12243c602fabSXin LI while (len) { 12253c602fabSXin LI u_char plen_bogus = 0, skip = 0; 12263c602fabSXin LI 12273c602fabSXin LI if (len < OF_QUEUE_PROP_HEADER_LEN) 12283c602fabSXin LI goto corrupt; 12293c602fabSXin LI /* property */ 12303c602fabSXin LI ND_TCHECK2(*cp, 2); 12313c602fabSXin LI property = EXTRACT_16BITS(cp); 12323c602fabSXin LI cp += 2; 12333c602fabSXin LI ND_PRINT((ndo, "\n\t property %s", tok2str(ofpqt_str, "invalid (0x%04x)", property))); 12343c602fabSXin LI /* len */ 12353c602fabSXin LI ND_TCHECK2(*cp, 2); 12363c602fabSXin LI plen = EXTRACT_16BITS(cp); 12373c602fabSXin LI cp += 2; 12383c602fabSXin LI ND_PRINT((ndo, ", len %u", plen)); 12393c602fabSXin LI if (plen < OF_QUEUE_PROP_HEADER_LEN || plen > len) 12403c602fabSXin LI goto corrupt; 12413c602fabSXin LI /* pad */ 12423c602fabSXin LI ND_TCHECK2(*cp, 4); 12433c602fabSXin LI cp += 4; 12443c602fabSXin LI /* property-specific constraints and decoding */ 12453c602fabSXin LI switch (property) { 12463c602fabSXin LI case OFPQT_NONE: 12473c602fabSXin LI plen_bogus = plen != OF_QUEUE_PROP_HEADER_LEN; 12483c602fabSXin LI break; 12493c602fabSXin LI case OFPQT_MIN_RATE: 12503c602fabSXin LI plen_bogus = plen != OF_QUEUE_PROP_MIN_RATE_LEN; 12513c602fabSXin LI break; 12523c602fabSXin LI default: 12533c602fabSXin LI skip = 1; 12543c602fabSXin LI } 12553c602fabSXin LI if (plen_bogus) { 12563c602fabSXin LI ND_PRINT((ndo, " (bogus)")); 12573c602fabSXin LI skip = 1; 12583c602fabSXin LI } 12593c602fabSXin LI if (skip) { 12603c602fabSXin LI ND_TCHECK2(*cp, plen - 4); 12613c602fabSXin LI cp += plen - 4; 12623c602fabSXin LI goto next_property; 12633c602fabSXin LI } 12643c602fabSXin LI if (property == OFPQT_MIN_RATE) { /* the only case of property decoding */ 12653c602fabSXin LI /* rate */ 12663c602fabSXin LI ND_TCHECK2(*cp, 2); 12673c602fabSXin LI rate = EXTRACT_16BITS(cp); 12683c602fabSXin LI cp += 2; 12693c602fabSXin LI if (rate > 1000) 12703c602fabSXin LI ND_PRINT((ndo, ", rate disabled")); 12713c602fabSXin LI else 12723c602fabSXin LI ND_PRINT((ndo, ", rate %u.%u%%", rate / 10, rate % 10)); 12733c602fabSXin LI /* pad */ 12743c602fabSXin LI ND_TCHECK2(*cp, 6); 12753c602fabSXin LI cp += 6; 12763c602fabSXin LI } 12773c602fabSXin LI next_property: 12783c602fabSXin LI len -= plen; 12793c602fabSXin LI } /* while */ 12803c602fabSXin LI return cp; 12813c602fabSXin LI 12823c602fabSXin LI corrupt: /* skip the rest of queue properties */ 12833c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 12843c602fabSXin LI ND_TCHECK2(*cp0, len0); 12853c602fabSXin LI return cp0 + len0; 12863c602fabSXin LI trunc: 12873c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 12883c602fabSXin LI return ep; 12893c602fabSXin LI } 12903c602fabSXin LI 12913c602fabSXin LI /* ibid */ 12923c602fabSXin LI static const u_char * 12933c602fabSXin LI of10_queues_print(netdissect_options *ndo, 1294*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, u_int len) 1295*8bdc5a62SPatrick Kelsey { 12963c602fabSXin LI const u_char *cp0 = cp; 12973c602fabSXin LI const u_int len0 = len; 12983c602fabSXin LI uint16_t desclen; 12993c602fabSXin LI 13003c602fabSXin LI while (len) { 13013c602fabSXin LI if (len < OF_PACKET_QUEUE_LEN) 13023c602fabSXin LI goto corrupt; 13033c602fabSXin LI /* queue_id */ 13043c602fabSXin LI ND_TCHECK2(*cp, 4); 13053c602fabSXin LI ND_PRINT((ndo, "\n\t queue_id %u", EXTRACT_32BITS(cp))); 13063c602fabSXin LI cp += 4; 13073c602fabSXin LI /* len */ 13083c602fabSXin LI ND_TCHECK2(*cp, 2); 13093c602fabSXin LI desclen = EXTRACT_16BITS(cp); 13103c602fabSXin LI cp += 2; 13113c602fabSXin LI ND_PRINT((ndo, ", len %u", desclen)); 13123c602fabSXin LI if (desclen < OF_PACKET_QUEUE_LEN || desclen > len) 13133c602fabSXin LI goto corrupt; 13143c602fabSXin LI /* pad */ 13153c602fabSXin LI ND_TCHECK2(*cp, 2); 13163c602fabSXin LI cp += 2; 13173c602fabSXin LI /* properties */ 13183c602fabSXin LI if (ndo->ndo_vflag < 2) { 13193c602fabSXin LI ND_TCHECK2(*cp, desclen - OF_PACKET_QUEUE_LEN); 13203c602fabSXin LI cp += desclen - OF_PACKET_QUEUE_LEN; 13213c602fabSXin LI goto next_queue; 13223c602fabSXin LI } 13233c602fabSXin LI if (ep == (cp = of10_queue_props_print(ndo, cp, ep, desclen - OF_PACKET_QUEUE_LEN))) 13243c602fabSXin LI return ep; /* end of snapshot */ 13253c602fabSXin LI next_queue: 13263c602fabSXin LI len -= desclen; 13273c602fabSXin LI } /* while */ 13283c602fabSXin LI return cp; 13293c602fabSXin LI 13303c602fabSXin LI corrupt: /* skip the rest of queues */ 13313c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 13323c602fabSXin LI ND_TCHECK2(*cp0, len0); 13333c602fabSXin LI return cp0 + len0; 13343c602fabSXin LI trunc: 13353c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 13363c602fabSXin LI return ep; 13373c602fabSXin LI } 13383c602fabSXin LI 13393c602fabSXin LI /* [OF10] Section 5.2.3 */ 13403c602fabSXin LI static const u_char * 13413c602fabSXin LI of10_match_print(netdissect_options *ndo, 1342*8bdc5a62SPatrick Kelsey const char *pfx, const u_char *cp, const u_char *ep) 1343*8bdc5a62SPatrick Kelsey { 13443c602fabSXin LI uint32_t wildcards; 13453c602fabSXin LI uint16_t dl_type; 13463c602fabSXin LI uint8_t nw_proto; 13473c602fabSXin LI u_char nw_bits; 13483c602fabSXin LI const char *field_name; 13493c602fabSXin LI 13503c602fabSXin LI /* wildcards */ 13513c602fabSXin LI ND_TCHECK2(*cp, 4); 13523c602fabSXin LI wildcards = EXTRACT_32BITS(cp); 13533c602fabSXin LI if (wildcards & OFPFW_U) 13543c602fabSXin LI ND_PRINT((ndo, "%swildcards 0x%08x (bogus)", pfx, wildcards)); 13553c602fabSXin LI cp += 4; 13563c602fabSXin LI /* in_port */ 13573c602fabSXin LI ND_TCHECK2(*cp, 2); 13583c602fabSXin LI if (! (wildcards & OFPFW_IN_PORT)) 13593c602fabSXin LI ND_PRINT((ndo, "%smatch in_port %s", pfx, tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 13603c602fabSXin LI cp += 2; 13613c602fabSXin LI /* dl_src */ 13623c602fabSXin LI ND_TCHECK2(*cp, ETHER_ADDR_LEN); 13633c602fabSXin LI if (! (wildcards & OFPFW_DL_SRC)) 13643c602fabSXin LI ND_PRINT((ndo, "%smatch dl_src %s", pfx, etheraddr_string(ndo, cp))); 13653c602fabSXin LI cp += ETHER_ADDR_LEN; 13663c602fabSXin LI /* dl_dst */ 13673c602fabSXin LI ND_TCHECK2(*cp, ETHER_ADDR_LEN); 13683c602fabSXin LI if (! (wildcards & OFPFW_DL_DST)) 13693c602fabSXin LI ND_PRINT((ndo, "%smatch dl_dst %s", pfx, etheraddr_string(ndo, cp))); 13703c602fabSXin LI cp += ETHER_ADDR_LEN; 13713c602fabSXin LI /* dl_vlan */ 13723c602fabSXin LI ND_TCHECK2(*cp, 2); 13733c602fabSXin LI if (! (wildcards & OFPFW_DL_VLAN)) 13743c602fabSXin LI ND_PRINT((ndo, "%smatch dl_vlan %s", pfx, vlan_str(EXTRACT_16BITS(cp)))); 13753c602fabSXin LI cp += 2; 13763c602fabSXin LI /* dl_vlan_pcp */ 13773c602fabSXin LI ND_TCHECK2(*cp, 1); 13783c602fabSXin LI if (! (wildcards & OFPFW_DL_VLAN_PCP)) 13793c602fabSXin LI ND_PRINT((ndo, "%smatch dl_vlan_pcp %s", pfx, pcp_str(*cp))); 13803c602fabSXin LI cp += 1; 13813c602fabSXin LI /* pad1 */ 13823c602fabSXin LI ND_TCHECK2(*cp, 1); 13833c602fabSXin LI cp += 1; 13843c602fabSXin LI /* dl_type */ 13853c602fabSXin LI ND_TCHECK2(*cp, 2); 13863c602fabSXin LI dl_type = EXTRACT_16BITS(cp); 13873c602fabSXin LI cp += 2; 13883c602fabSXin LI if (! (wildcards & OFPFW_DL_TYPE)) 13893c602fabSXin LI ND_PRINT((ndo, "%smatch dl_type 0x%04x", pfx, dl_type)); 13903c602fabSXin LI /* nw_tos */ 13913c602fabSXin LI ND_TCHECK2(*cp, 1); 13923c602fabSXin LI if (! (wildcards & OFPFW_NW_TOS)) 13933c602fabSXin LI ND_PRINT((ndo, "%smatch nw_tos 0x%02x", pfx, *cp)); 13943c602fabSXin LI cp += 1; 13953c602fabSXin LI /* nw_proto */ 13963c602fabSXin LI ND_TCHECK2(*cp, 1); 13973c602fabSXin LI nw_proto = *cp; 13983c602fabSXin LI cp += 1; 13993c602fabSXin LI if (! (wildcards & OFPFW_NW_PROTO)) { 14003c602fabSXin LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_ARP 14013c602fabSXin LI ? "arp_opcode" : "nw_proto"; 14023c602fabSXin LI ND_PRINT((ndo, "%smatch %s %u", pfx, field_name, nw_proto)); 14033c602fabSXin LI } 14043c602fabSXin LI /* pad2 */ 14053c602fabSXin LI ND_TCHECK2(*cp, 2); 14063c602fabSXin LI cp += 2; 14073c602fabSXin LI /* nw_src */ 14083c602fabSXin LI ND_TCHECK2(*cp, 4); 14093c602fabSXin LI nw_bits = (wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT; 14103c602fabSXin LI if (nw_bits < 32) 14113c602fabSXin LI ND_PRINT((ndo, "%smatch nw_src %s/%u", pfx, ipaddr_string(ndo, cp), 32 - nw_bits)); 14123c602fabSXin LI cp += 4; 14133c602fabSXin LI /* nw_dst */ 14143c602fabSXin LI ND_TCHECK2(*cp, 4); 14153c602fabSXin LI nw_bits = (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT; 14163c602fabSXin LI if (nw_bits < 32) 14173c602fabSXin LI ND_PRINT((ndo, "%smatch nw_dst %s/%u", pfx, ipaddr_string(ndo, cp), 32 - nw_bits)); 14183c602fabSXin LI cp += 4; 14193c602fabSXin LI /* tp_src */ 14203c602fabSXin LI ND_TCHECK2(*cp, 2); 14213c602fabSXin LI if (! (wildcards & OFPFW_TP_SRC)) { 14223c602fabSXin LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP 14233c602fabSXin LI && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP 14243c602fabSXin LI ? "icmp_type" : "tp_src"; 14253c602fabSXin LI ND_PRINT((ndo, "%smatch %s %u", pfx, field_name, EXTRACT_16BITS(cp))); 14263c602fabSXin LI } 14273c602fabSXin LI cp += 2; 14283c602fabSXin LI /* tp_dst */ 14293c602fabSXin LI ND_TCHECK2(*cp, 2); 14303c602fabSXin LI if (! (wildcards & OFPFW_TP_DST)) { 14313c602fabSXin LI field_name = ! (wildcards & OFPFW_DL_TYPE) && dl_type == ETHERTYPE_IP 14323c602fabSXin LI && ! (wildcards & OFPFW_NW_PROTO) && nw_proto == IPPROTO_ICMP 14333c602fabSXin LI ? "icmp_code" : "tp_dst"; 14343c602fabSXin LI ND_PRINT((ndo, "%smatch %s %u", pfx, field_name, EXTRACT_16BITS(cp))); 14353c602fabSXin LI } 14363c602fabSXin LI return cp + 2; 14373c602fabSXin LI 14383c602fabSXin LI trunc: 14393c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 14403c602fabSXin LI return ep; 14413c602fabSXin LI } 14423c602fabSXin LI 14433c602fabSXin LI /* [OF10] Section 5.2.4 */ 14443c602fabSXin LI static const u_char * 14453c602fabSXin LI of10_actions_print(netdissect_options *ndo, 14463c602fabSXin LI const char *pfx, const u_char *cp, const u_char *ep, 1447*8bdc5a62SPatrick Kelsey u_int len) 1448*8bdc5a62SPatrick Kelsey { 14493c602fabSXin LI const u_char *cp0 = cp; 14503c602fabSXin LI const u_int len0 = len; 14513c602fabSXin LI uint16_t type, alen, output_port; 14523c602fabSXin LI 14533c602fabSXin LI while (len) { 14543c602fabSXin LI u_char alen_bogus = 0, skip = 0; 14553c602fabSXin LI 14563c602fabSXin LI if (len < OF_ACTION_HEADER_LEN) 14573c602fabSXin LI goto corrupt; 14583c602fabSXin LI /* type */ 14593c602fabSXin LI ND_TCHECK2(*cp, 2); 14603c602fabSXin LI type = EXTRACT_16BITS(cp); 14613c602fabSXin LI cp += 2; 14623c602fabSXin LI ND_PRINT((ndo, "%saction type %s", pfx, tok2str(ofpat_str, "invalid (0x%04x)", type))); 14633c602fabSXin LI /* length */ 14643c602fabSXin LI ND_TCHECK2(*cp, 2); 14653c602fabSXin LI alen = EXTRACT_16BITS(cp); 14663c602fabSXin LI cp += 2; 14673c602fabSXin LI ND_PRINT((ndo, ", len %u", alen)); 14683c602fabSXin LI /* On action size underrun/overrun skip the rest of the action list. */ 14693c602fabSXin LI if (alen < OF_ACTION_HEADER_LEN || alen > len) 14703c602fabSXin LI goto corrupt; 14713c602fabSXin LI /* On action size inappropriate for the given type or invalid type just skip 14723c602fabSXin LI * the current action, as the basic length constraint has been met. */ 14733c602fabSXin LI switch (type) { 14743c602fabSXin LI case OFPAT_OUTPUT: 14753c602fabSXin LI case OFPAT_SET_VLAN_VID: 14763c602fabSXin LI case OFPAT_SET_VLAN_PCP: 14773c602fabSXin LI case OFPAT_STRIP_VLAN: 14783c602fabSXin LI case OFPAT_SET_NW_SRC: 14793c602fabSXin LI case OFPAT_SET_NW_DST: 14803c602fabSXin LI case OFPAT_SET_NW_TOS: 14813c602fabSXin LI case OFPAT_SET_TP_SRC: 14823c602fabSXin LI case OFPAT_SET_TP_DST: 14833c602fabSXin LI alen_bogus = alen != 8; 14843c602fabSXin LI break; 14853c602fabSXin LI case OFPAT_SET_DL_SRC: 14863c602fabSXin LI case OFPAT_SET_DL_DST: 14873c602fabSXin LI case OFPAT_ENQUEUE: 14883c602fabSXin LI alen_bogus = alen != 16; 14893c602fabSXin LI break; 14903c602fabSXin LI case OFPAT_VENDOR: 14913c602fabSXin LI alen_bogus = alen % 8 != 0; /* already >= 8 so far */ 14923c602fabSXin LI break; 14933c602fabSXin LI default: 14943c602fabSXin LI skip = 1; 14953c602fabSXin LI } 14963c602fabSXin LI if (alen_bogus) { 14973c602fabSXin LI ND_PRINT((ndo, " (bogus)")); 14983c602fabSXin LI skip = 1; 14993c602fabSXin LI } 15003c602fabSXin LI if (skip) { 15013c602fabSXin LI ND_TCHECK2(*cp, alen - 4); 15023c602fabSXin LI cp += alen - 4; 15033c602fabSXin LI goto next_action; 15043c602fabSXin LI } 15053c602fabSXin LI /* OK to decode the rest of the action structure */ 15063c602fabSXin LI switch (type) { 15073c602fabSXin LI case OFPAT_OUTPUT: 15083c602fabSXin LI /* port */ 15093c602fabSXin LI ND_TCHECK2(*cp, 2); 15103c602fabSXin LI output_port = EXTRACT_16BITS(cp); 15113c602fabSXin LI cp += 2; 15123c602fabSXin LI ND_PRINT((ndo, ", port %s", tok2str(ofpp_str, "%u", output_port))); 15133c602fabSXin LI /* max_len */ 15143c602fabSXin LI ND_TCHECK2(*cp, 2); 15153c602fabSXin LI if (output_port == OFPP_CONTROLLER) 15163c602fabSXin LI ND_PRINT((ndo, ", max_len %u", EXTRACT_16BITS(cp))); 15173c602fabSXin LI cp += 2; 15183c602fabSXin LI break; 15193c602fabSXin LI case OFPAT_SET_VLAN_VID: 15203c602fabSXin LI /* vlan_vid */ 15213c602fabSXin LI ND_TCHECK2(*cp, 2); 15223c602fabSXin LI ND_PRINT((ndo, ", vlan_vid %s", vlan_str(EXTRACT_16BITS(cp)))); 15233c602fabSXin LI cp += 2; 15243c602fabSXin LI /* pad */ 15253c602fabSXin LI ND_TCHECK2(*cp, 2); 15263c602fabSXin LI cp += 2; 15273c602fabSXin LI break; 15283c602fabSXin LI case OFPAT_SET_VLAN_PCP: 15293c602fabSXin LI /* vlan_pcp */ 15303c602fabSXin LI ND_TCHECK2(*cp, 1); 15313c602fabSXin LI ND_PRINT((ndo, ", vlan_pcp %s", pcp_str(*cp))); 15323c602fabSXin LI cp += 1; 15333c602fabSXin LI /* pad */ 15343c602fabSXin LI ND_TCHECK2(*cp, 3); 15353c602fabSXin LI cp += 3; 15363c602fabSXin LI break; 15373c602fabSXin LI case OFPAT_SET_DL_SRC: 15383c602fabSXin LI case OFPAT_SET_DL_DST: 15393c602fabSXin LI /* dl_addr */ 15403c602fabSXin LI ND_TCHECK2(*cp, ETHER_ADDR_LEN); 15413c602fabSXin LI ND_PRINT((ndo, ", dl_addr %s", etheraddr_string(ndo, cp))); 15423c602fabSXin LI cp += ETHER_ADDR_LEN; 15433c602fabSXin LI /* pad */ 15443c602fabSXin LI ND_TCHECK2(*cp, 6); 15453c602fabSXin LI cp += 6; 15463c602fabSXin LI break; 15473c602fabSXin LI case OFPAT_SET_NW_SRC: 15483c602fabSXin LI case OFPAT_SET_NW_DST: 15493c602fabSXin LI /* nw_addr */ 15503c602fabSXin LI ND_TCHECK2(*cp, 4); 15513c602fabSXin LI ND_PRINT((ndo, ", nw_addr %s", ipaddr_string(ndo, cp))); 15523c602fabSXin LI cp += 4; 15533c602fabSXin LI break; 15543c602fabSXin LI case OFPAT_SET_NW_TOS: 15553c602fabSXin LI /* nw_tos */ 15563c602fabSXin LI ND_TCHECK2(*cp, 1); 15573c602fabSXin LI ND_PRINT((ndo, ", nw_tos 0x%02x", *cp)); 15583c602fabSXin LI cp += 1; 15593c602fabSXin LI /* pad */ 15603c602fabSXin LI ND_TCHECK2(*cp, 3); 15613c602fabSXin LI cp += 3; 15623c602fabSXin LI break; 15633c602fabSXin LI case OFPAT_SET_TP_SRC: 15643c602fabSXin LI case OFPAT_SET_TP_DST: 15653c602fabSXin LI /* nw_tos */ 15663c602fabSXin LI ND_TCHECK2(*cp, 2); 15673c602fabSXin LI ND_PRINT((ndo, ", tp_port %u", EXTRACT_16BITS(cp))); 15683c602fabSXin LI cp += 2; 15693c602fabSXin LI /* pad */ 15703c602fabSXin LI ND_TCHECK2(*cp, 2); 15713c602fabSXin LI cp += 2; 15723c602fabSXin LI break; 15733c602fabSXin LI case OFPAT_ENQUEUE: 15743c602fabSXin LI /* port */ 15753c602fabSXin LI ND_TCHECK2(*cp, 2); 15763c602fabSXin LI ND_PRINT((ndo, ", port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 15773c602fabSXin LI cp += 2; 15783c602fabSXin LI /* pad */ 15793c602fabSXin LI ND_TCHECK2(*cp, 6); 15803c602fabSXin LI cp += 6; 15813c602fabSXin LI /* queue_id */ 15823c602fabSXin LI ND_TCHECK2(*cp, 4); 15833c602fabSXin LI ND_PRINT((ndo, ", queue_id %s", tok2str(ofpq_str, "%u", EXTRACT_32BITS(cp)))); 15843c602fabSXin LI cp += 4; 15853c602fabSXin LI break; 15863c602fabSXin LI case OFPAT_VENDOR: 1587*8bdc5a62SPatrick Kelsey if (ep == (cp = of10_vendor_action_print(ndo, cp, ep, alen - 4))) 15883c602fabSXin LI return ep; /* end of snapshot */ 15893c602fabSXin LI break; 15903c602fabSXin LI case OFPAT_STRIP_VLAN: 15913c602fabSXin LI /* pad */ 15923c602fabSXin LI ND_TCHECK2(*cp, 4); 15933c602fabSXin LI cp += 4; 15943c602fabSXin LI break; 15953c602fabSXin LI } /* switch */ 15963c602fabSXin LI next_action: 15973c602fabSXin LI len -= alen; 15983c602fabSXin LI } /* while */ 15993c602fabSXin LI return cp; 16003c602fabSXin LI 16013c602fabSXin LI corrupt: /* skip the rest of actions */ 16023c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 16033c602fabSXin LI ND_TCHECK2(*cp0, len0); 16043c602fabSXin LI return cp0 + len0; 16053c602fabSXin LI trunc: 16063c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 16073c602fabSXin LI return ep; 16083c602fabSXin LI } 16093c602fabSXin LI 16103c602fabSXin LI /* [OF10] Section 5.3.1 */ 16113c602fabSXin LI static const u_char * 16123c602fabSXin LI of10_features_reply_print(netdissect_options *ndo, 1613*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 1614*8bdc5a62SPatrick Kelsey { 16153c602fabSXin LI /* datapath_id */ 16163c602fabSXin LI ND_TCHECK2(*cp, 8); 16173c602fabSXin LI ND_PRINT((ndo, "\n\t dpid 0x%016" PRIx64, EXTRACT_64BITS(cp))); 16183c602fabSXin LI cp += 8; 16193c602fabSXin LI /* n_buffers */ 16203c602fabSXin LI ND_TCHECK2(*cp, 4); 16213c602fabSXin LI ND_PRINT((ndo, ", n_buffers %u", EXTRACT_32BITS(cp))); 16223c602fabSXin LI cp += 4; 16233c602fabSXin LI /* n_tables */ 16243c602fabSXin LI ND_TCHECK2(*cp, 1); 16253c602fabSXin LI ND_PRINT((ndo, ", n_tables %u", *cp)); 16263c602fabSXin LI cp += 1; 16273c602fabSXin LI /* pad */ 16283c602fabSXin LI ND_TCHECK2(*cp, 3); 16293c602fabSXin LI cp += 3; 16303c602fabSXin LI /* capabilities */ 16313c602fabSXin LI ND_TCHECK2(*cp, 4); 16323c602fabSXin LI ND_PRINT((ndo, "\n\t capabilities 0x%08x", EXTRACT_32BITS(cp))); 16333c602fabSXin LI of10_bitmap_print(ndo, ofp_capabilities_bm, EXTRACT_32BITS(cp), OFPCAP_U); 16343c602fabSXin LI cp += 4; 16353c602fabSXin LI /* actions */ 16363c602fabSXin LI ND_TCHECK2(*cp, 4); 16373c602fabSXin LI ND_PRINT((ndo, "\n\t actions 0x%08x", EXTRACT_32BITS(cp))); 16383c602fabSXin LI of10_bitmap_print(ndo, ofpat_bm, EXTRACT_32BITS(cp), OFPAT_U); 16393c602fabSXin LI cp += 4; 16403c602fabSXin LI /* ports */ 16413c602fabSXin LI return of10_phy_ports_print(ndo, cp, ep, len - OF_SWITCH_FEATURES_LEN); 16423c602fabSXin LI 16433c602fabSXin LI trunc: 16443c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 16453c602fabSXin LI return ep; 16463c602fabSXin LI } 16473c602fabSXin LI 16483c602fabSXin LI /* [OF10] Section 5.3.3 */ 16493c602fabSXin LI static const u_char * 16503c602fabSXin LI of10_flow_mod_print(netdissect_options *ndo, 1651*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 1652*8bdc5a62SPatrick Kelsey { 16533c602fabSXin LI uint16_t command; 16543c602fabSXin LI 16553c602fabSXin LI /* match */ 16563c602fabSXin LI if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) 16573c602fabSXin LI return ep; /* end of snapshot */ 16583c602fabSXin LI /* cookie */ 16593c602fabSXin LI ND_TCHECK2(*cp, 8); 16603c602fabSXin LI ND_PRINT((ndo, "\n\t cookie 0x%016" PRIx64, EXTRACT_64BITS(cp))); 16613c602fabSXin LI cp += 8; 16623c602fabSXin LI /* command */ 16633c602fabSXin LI ND_TCHECK2(*cp, 2); 16643c602fabSXin LI command = EXTRACT_16BITS(cp); 16653c602fabSXin LI ND_PRINT((ndo, ", command %s", tok2str(ofpfc_str, "invalid (0x%04x)", command))); 16663c602fabSXin LI cp += 2; 16673c602fabSXin LI /* idle_timeout */ 16683c602fabSXin LI ND_TCHECK2(*cp, 2); 16693c602fabSXin LI if (EXTRACT_16BITS(cp)) 16703c602fabSXin LI ND_PRINT((ndo, ", idle_timeout %u", EXTRACT_16BITS(cp))); 16713c602fabSXin LI cp += 2; 16723c602fabSXin LI /* hard_timeout */ 16733c602fabSXin LI ND_TCHECK2(*cp, 2); 16743c602fabSXin LI if (EXTRACT_16BITS(cp)) 16753c602fabSXin LI ND_PRINT((ndo, ", hard_timeout %u", EXTRACT_16BITS(cp))); 16763c602fabSXin LI cp += 2; 16773c602fabSXin LI /* priority */ 16783c602fabSXin LI ND_TCHECK2(*cp, 2); 16793c602fabSXin LI if (EXTRACT_16BITS(cp)) 16803c602fabSXin LI ND_PRINT((ndo, ", priority %u", EXTRACT_16BITS(cp))); 16813c602fabSXin LI cp += 2; 16823c602fabSXin LI /* buffer_id */ 16833c602fabSXin LI ND_TCHECK2(*cp, 4); 16843c602fabSXin LI if (command == OFPFC_ADD || command == OFPFC_MODIFY || 16853c602fabSXin LI command == OFPFC_MODIFY_STRICT) 16863c602fabSXin LI ND_PRINT((ndo, ", buffer_id %s", tok2str(bufferid_str, "0x%08x", EXTRACT_32BITS(cp)))); 16873c602fabSXin LI cp += 4; 16883c602fabSXin LI /* out_port */ 16893c602fabSXin LI ND_TCHECK2(*cp, 2); 16903c602fabSXin LI if (command == OFPFC_DELETE || command == OFPFC_DELETE_STRICT) 16913c602fabSXin LI ND_PRINT((ndo, ", out_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 16923c602fabSXin LI cp += 2; 16933c602fabSXin LI /* flags */ 16943c602fabSXin LI ND_TCHECK2(*cp, 2); 16953c602fabSXin LI ND_PRINT((ndo, ", flags 0x%04x", EXTRACT_16BITS(cp))); 16963c602fabSXin LI of10_bitmap_print(ndo, ofpff_bm, EXTRACT_16BITS(cp), OFPFF_U); 16973c602fabSXin LI cp += 2; 16983c602fabSXin LI /* actions */ 16993c602fabSXin LI return of10_actions_print(ndo, "\n\t ", cp, ep, len - OF_FLOW_MOD_LEN); 17003c602fabSXin LI 17013c602fabSXin LI trunc: 17023c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 17033c602fabSXin LI return ep; 17043c602fabSXin LI } 17053c602fabSXin LI 17063c602fabSXin LI /* ibid */ 17073c602fabSXin LI static const u_char * 17083c602fabSXin LI of10_port_mod_print(netdissect_options *ndo, 1709*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep) 1710*8bdc5a62SPatrick Kelsey { 17113c602fabSXin LI /* port_no */ 17123c602fabSXin LI ND_TCHECK2(*cp, 2); 17133c602fabSXin LI ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 17143c602fabSXin LI cp += 2; 17153c602fabSXin LI /* hw_addr */ 17163c602fabSXin LI ND_TCHECK2(*cp, ETHER_ADDR_LEN); 17173c602fabSXin LI ND_PRINT((ndo, ", hw_addr %s", etheraddr_string(ndo, cp))); 17183c602fabSXin LI cp += ETHER_ADDR_LEN; 17193c602fabSXin LI /* config */ 17203c602fabSXin LI ND_TCHECK2(*cp, 4); 17213c602fabSXin LI ND_PRINT((ndo, "\n\t config 0x%08x", EXTRACT_32BITS(cp))); 17223c602fabSXin LI of10_bitmap_print(ndo, ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U); 17233c602fabSXin LI cp += 4; 17243c602fabSXin LI /* mask */ 17253c602fabSXin LI ND_TCHECK2(*cp, 4); 17263c602fabSXin LI ND_PRINT((ndo, "\n\t mask 0x%08x", EXTRACT_32BITS(cp))); 17273c602fabSXin LI of10_bitmap_print(ndo, ofppc_bm, EXTRACT_32BITS(cp), OFPPC_U); 17283c602fabSXin LI cp += 4; 17293c602fabSXin LI /* advertise */ 17303c602fabSXin LI ND_TCHECK2(*cp, 4); 17313c602fabSXin LI ND_PRINT((ndo, "\n\t advertise 0x%08x", EXTRACT_32BITS(cp))); 17323c602fabSXin LI of10_bitmap_print(ndo, ofppf_bm, EXTRACT_32BITS(cp), OFPPF_U); 17333c602fabSXin LI cp += 4; 17343c602fabSXin LI /* pad */ 17353c602fabSXin LI ND_TCHECK2(*cp, 4); 17363c602fabSXin LI return cp + 4; 17373c602fabSXin LI 17383c602fabSXin LI trunc: 17393c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 17403c602fabSXin LI return ep; 17413c602fabSXin LI } 17423c602fabSXin LI 17433c602fabSXin LI /* [OF10] Section 5.3.5 */ 17443c602fabSXin LI static const u_char * 17453c602fabSXin LI of10_stats_request_print(netdissect_options *ndo, 1746*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, u_int len) 1747*8bdc5a62SPatrick Kelsey { 17483c602fabSXin LI const u_char *cp0 = cp; 17493c602fabSXin LI const u_int len0 = len; 17503c602fabSXin LI uint16_t type; 17513c602fabSXin LI 17523c602fabSXin LI /* type */ 17533c602fabSXin LI ND_TCHECK2(*cp, 2); 17543c602fabSXin LI type = EXTRACT_16BITS(cp); 17553c602fabSXin LI cp += 2; 17563c602fabSXin LI ND_PRINT((ndo, "\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type))); 17573c602fabSXin LI /* flags */ 17583c602fabSXin LI ND_TCHECK2(*cp, 2); 17593c602fabSXin LI ND_PRINT((ndo, ", flags 0x%04x", EXTRACT_16BITS(cp))); 17603c602fabSXin LI if (EXTRACT_16BITS(cp)) 17613c602fabSXin LI ND_PRINT((ndo, " (bogus)")); 17623c602fabSXin LI cp += 2; 17633c602fabSXin LI /* type-specific body of one of fixed lengths */ 17643c602fabSXin LI len -= OF_STATS_REQUEST_LEN; 17653c602fabSXin LI switch(type) { 17663c602fabSXin LI case OFPST_DESC: 17673c602fabSXin LI case OFPST_TABLE: 17683c602fabSXin LI if (len) 17693c602fabSXin LI goto corrupt; 17703c602fabSXin LI return cp; 17713c602fabSXin LI case OFPST_FLOW: 17723c602fabSXin LI case OFPST_AGGREGATE: 17733c602fabSXin LI if (len != OF_FLOW_STATS_REQUEST_LEN) 17743c602fabSXin LI goto corrupt; 17753c602fabSXin LI /* match */ 17763c602fabSXin LI if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) 17773c602fabSXin LI return ep; /* end of snapshot */ 17783c602fabSXin LI /* table_id */ 17793c602fabSXin LI ND_TCHECK2(*cp, 1); 17803c602fabSXin LI ND_PRINT((ndo, "\n\t table_id %s", tok2str(tableid_str, "%u", *cp))); 17813c602fabSXin LI cp += 1; 17823c602fabSXin LI /* pad */ 17833c602fabSXin LI ND_TCHECK2(*cp, 1); 17843c602fabSXin LI cp += 1; 17853c602fabSXin LI /* out_port */ 17863c602fabSXin LI ND_TCHECK2(*cp, 2); 17873c602fabSXin LI ND_PRINT((ndo, ", out_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 17883c602fabSXin LI return cp + 2; 17893c602fabSXin LI case OFPST_PORT: 17903c602fabSXin LI if (len != OF_PORT_STATS_REQUEST_LEN) 17913c602fabSXin LI goto corrupt; 17923c602fabSXin LI /* port_no */ 17933c602fabSXin LI ND_TCHECK2(*cp, 2); 17943c602fabSXin LI ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 17953c602fabSXin LI cp += 2; 17963c602fabSXin LI /* pad */ 17973c602fabSXin LI ND_TCHECK2(*cp, 6); 17983c602fabSXin LI return cp + 6; 17993c602fabSXin LI case OFPST_QUEUE: 18003c602fabSXin LI if (len != OF_QUEUE_STATS_REQUEST_LEN) 18013c602fabSXin LI goto corrupt; 18023c602fabSXin LI /* port_no */ 18033c602fabSXin LI ND_TCHECK2(*cp, 2); 18043c602fabSXin LI ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 18053c602fabSXin LI cp += 2; 18063c602fabSXin LI /* pad */ 18073c602fabSXin LI ND_TCHECK2(*cp, 2); 18083c602fabSXin LI cp += 2; 18093c602fabSXin LI /* queue_id */ 18103c602fabSXin LI ND_TCHECK2(*cp, 4); 18113c602fabSXin LI ND_PRINT((ndo, ", queue_id %s", tok2str(ofpq_str, "%u", EXTRACT_32BITS(cp)))); 18123c602fabSXin LI return cp + 4; 18133c602fabSXin LI case OFPST_VENDOR: 18143c602fabSXin LI return of10_vendor_data_print(ndo, cp, ep, len); 18153c602fabSXin LI } 18163c602fabSXin LI return cp; 18173c602fabSXin LI 18183c602fabSXin LI corrupt: /* skip the message body */ 18193c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 18203c602fabSXin LI ND_TCHECK2(*cp0, len0); 18213c602fabSXin LI return cp0 + len0; 18223c602fabSXin LI trunc: 18233c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 18243c602fabSXin LI return ep; 18253c602fabSXin LI } 18263c602fabSXin LI 18273c602fabSXin LI /* ibid */ 18283c602fabSXin LI static const u_char * 18293c602fabSXin LI of10_desc_stats_reply_print(netdissect_options *ndo, 1830*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 1831*8bdc5a62SPatrick Kelsey { 18323c602fabSXin LI if (len != OF_DESC_STATS_LEN) 18333c602fabSXin LI goto corrupt; 18343c602fabSXin LI /* mfr_desc */ 18353c602fabSXin LI ND_TCHECK2(*cp, DESC_STR_LEN); 18363c602fabSXin LI ND_PRINT((ndo, "\n\t mfr_desc '")); 18373c602fabSXin LI fn_print(ndo, cp, cp + DESC_STR_LEN); 18383c602fabSXin LI ND_PRINT((ndo, "'")); 18393c602fabSXin LI cp += DESC_STR_LEN; 18403c602fabSXin LI /* hw_desc */ 18413c602fabSXin LI ND_TCHECK2(*cp, DESC_STR_LEN); 18423c602fabSXin LI ND_PRINT((ndo, "\n\t hw_desc '")); 18433c602fabSXin LI fn_print(ndo, cp, cp + DESC_STR_LEN); 18443c602fabSXin LI ND_PRINT((ndo, "'")); 18453c602fabSXin LI cp += DESC_STR_LEN; 18463c602fabSXin LI /* sw_desc */ 18473c602fabSXin LI ND_TCHECK2(*cp, DESC_STR_LEN); 18483c602fabSXin LI ND_PRINT((ndo, "\n\t sw_desc '")); 18493c602fabSXin LI fn_print(ndo, cp, cp + DESC_STR_LEN); 18503c602fabSXin LI ND_PRINT((ndo, "'")); 18513c602fabSXin LI cp += DESC_STR_LEN; 18523c602fabSXin LI /* serial_num */ 18533c602fabSXin LI ND_TCHECK2(*cp, SERIAL_NUM_LEN); 18543c602fabSXin LI ND_PRINT((ndo, "\n\t serial_num '")); 18553c602fabSXin LI fn_print(ndo, cp, cp + SERIAL_NUM_LEN); 18563c602fabSXin LI ND_PRINT((ndo, "'")); 18573c602fabSXin LI cp += SERIAL_NUM_LEN; 18583c602fabSXin LI /* dp_desc */ 18593c602fabSXin LI ND_TCHECK2(*cp, DESC_STR_LEN); 18603c602fabSXin LI ND_PRINT((ndo, "\n\t dp_desc '")); 18613c602fabSXin LI fn_print(ndo, cp, cp + DESC_STR_LEN); 18623c602fabSXin LI ND_PRINT((ndo, "'")); 18633c602fabSXin LI return cp + DESC_STR_LEN; 18643c602fabSXin LI 18653c602fabSXin LI corrupt: /* skip the message body */ 18663c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 18673c602fabSXin LI ND_TCHECK2(*cp, len); 18683c602fabSXin LI return cp + len; 18693c602fabSXin LI trunc: 18703c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 18713c602fabSXin LI return ep; 18723c602fabSXin LI } 18733c602fabSXin LI 18743c602fabSXin LI /* ibid */ 18753c602fabSXin LI static const u_char * 18763c602fabSXin LI of10_flow_stats_reply_print(netdissect_options *ndo, 1877*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, u_int len) 1878*8bdc5a62SPatrick Kelsey { 18793c602fabSXin LI const u_char *cp0 = cp; 18803c602fabSXin LI const u_int len0 = len; 18813c602fabSXin LI uint16_t entry_len; 18823c602fabSXin LI 18833c602fabSXin LI while (len) { 18843c602fabSXin LI if (len < OF_FLOW_STATS_LEN) 18853c602fabSXin LI goto corrupt; 18863c602fabSXin LI /* length */ 18873c602fabSXin LI ND_TCHECK2(*cp, 2); 18883c602fabSXin LI entry_len = EXTRACT_16BITS(cp); 18893c602fabSXin LI ND_PRINT((ndo, "\n\t length %u", entry_len)); 18903c602fabSXin LI if (entry_len < OF_FLOW_STATS_LEN || entry_len > len) 18913c602fabSXin LI goto corrupt; 18923c602fabSXin LI cp += 2; 18933c602fabSXin LI /* table_id */ 18943c602fabSXin LI ND_TCHECK2(*cp, 1); 18953c602fabSXin LI ND_PRINT((ndo, ", table_id %s", tok2str(tableid_str, "%u", *cp))); 18963c602fabSXin LI cp += 1; 18973c602fabSXin LI /* pad */ 18983c602fabSXin LI ND_TCHECK2(*cp, 1); 18993c602fabSXin LI cp += 1; 19003c602fabSXin LI /* match */ 19013c602fabSXin LI if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) 19023c602fabSXin LI return ep; /* end of snapshot */ 19033c602fabSXin LI /* duration_sec */ 19043c602fabSXin LI ND_TCHECK2(*cp, 4); 19053c602fabSXin LI ND_PRINT((ndo, "\n\t duration_sec %u", EXTRACT_32BITS(cp))); 19063c602fabSXin LI cp += 4; 19073c602fabSXin LI /* duration_nsec */ 19083c602fabSXin LI ND_TCHECK2(*cp, 4); 19093c602fabSXin LI ND_PRINT((ndo, ", duration_nsec %u", EXTRACT_32BITS(cp))); 19103c602fabSXin LI cp += 4; 19113c602fabSXin LI /* priority */ 19123c602fabSXin LI ND_TCHECK2(*cp, 2); 19133c602fabSXin LI ND_PRINT((ndo, ", priority %u", EXTRACT_16BITS(cp))); 19143c602fabSXin LI cp += 2; 19153c602fabSXin LI /* idle_timeout */ 19163c602fabSXin LI ND_TCHECK2(*cp, 2); 19173c602fabSXin LI ND_PRINT((ndo, ", idle_timeout %u", EXTRACT_16BITS(cp))); 19183c602fabSXin LI cp += 2; 19193c602fabSXin LI /* hard_timeout */ 19203c602fabSXin LI ND_TCHECK2(*cp, 2); 19213c602fabSXin LI ND_PRINT((ndo, ", hard_timeout %u", EXTRACT_16BITS(cp))); 19223c602fabSXin LI cp += 2; 19233c602fabSXin LI /* pad2 */ 19243c602fabSXin LI ND_TCHECK2(*cp, 6); 19253c602fabSXin LI cp += 6; 19263c602fabSXin LI /* cookie */ 19273c602fabSXin LI ND_TCHECK2(*cp, 8); 19283c602fabSXin LI ND_PRINT((ndo, ", cookie 0x%016" PRIx64, EXTRACT_64BITS(cp))); 19293c602fabSXin LI cp += 8; 19303c602fabSXin LI /* packet_count */ 19313c602fabSXin LI ND_TCHECK2(*cp, 8); 19323c602fabSXin LI ND_PRINT((ndo, ", packet_count %" PRIu64, EXTRACT_64BITS(cp))); 19333c602fabSXin LI cp += 8; 19343c602fabSXin LI /* byte_count */ 19353c602fabSXin LI ND_TCHECK2(*cp, 8); 19363c602fabSXin LI ND_PRINT((ndo, ", byte_count %" PRIu64, EXTRACT_64BITS(cp))); 19373c602fabSXin LI cp += 8; 19383c602fabSXin LI /* actions */ 19393c602fabSXin LI if (ep == (cp = of10_actions_print(ndo, "\n\t ", cp, ep, entry_len - OF_FLOW_STATS_LEN))) 19403c602fabSXin LI return ep; /* end of snapshot */ 19413c602fabSXin LI 19423c602fabSXin LI len -= entry_len; 19433c602fabSXin LI } /* while */ 19443c602fabSXin LI return cp; 19453c602fabSXin LI 19463c602fabSXin LI corrupt: /* skip the rest of flow statistics entries */ 19473c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 19483c602fabSXin LI ND_TCHECK2(*cp0, len0); 19493c602fabSXin LI return cp0 + len0; 19503c602fabSXin LI trunc: 19513c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 19523c602fabSXin LI return ep; 19533c602fabSXin LI } 19543c602fabSXin LI 19553c602fabSXin LI /* ibid */ 19563c602fabSXin LI static const u_char * 19573c602fabSXin LI of10_aggregate_stats_reply_print(netdissect_options *ndo, 19583c602fabSXin LI const u_char *cp, const u_char *ep, 1959*8bdc5a62SPatrick Kelsey const u_int len) 1960*8bdc5a62SPatrick Kelsey { 19613c602fabSXin LI if (len != OF_AGGREGATE_STATS_REPLY_LEN) 19623c602fabSXin LI goto corrupt; 19633c602fabSXin LI /* packet_count */ 19643c602fabSXin LI ND_TCHECK2(*cp, 8); 19653c602fabSXin LI ND_PRINT((ndo, "\n\t packet_count %" PRIu64, EXTRACT_64BITS(cp))); 19663c602fabSXin LI cp += 8; 19673c602fabSXin LI /* byte_count */ 19683c602fabSXin LI ND_TCHECK2(*cp, 8); 19693c602fabSXin LI ND_PRINT((ndo, ", byte_count %" PRIu64, EXTRACT_64BITS(cp))); 19703c602fabSXin LI cp += 8; 19713c602fabSXin LI /* flow_count */ 19723c602fabSXin LI ND_TCHECK2(*cp, 4); 19733c602fabSXin LI ND_PRINT((ndo, ", flow_count %u", EXTRACT_32BITS(cp))); 19743c602fabSXin LI cp += 4; 19753c602fabSXin LI /* pad */ 19763c602fabSXin LI ND_TCHECK2(*cp, 4); 19773c602fabSXin LI return cp + 4; 19783c602fabSXin LI 19793c602fabSXin LI corrupt: /* skip the message body */ 19803c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 19813c602fabSXin LI ND_TCHECK2(*cp, len); 19823c602fabSXin LI return cp + len; 19833c602fabSXin LI trunc: 19843c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 19853c602fabSXin LI return ep; 19863c602fabSXin LI } 19873c602fabSXin LI 19883c602fabSXin LI /* ibid */ 19893c602fabSXin LI static const u_char * 19903c602fabSXin LI of10_table_stats_reply_print(netdissect_options *ndo, 1991*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, u_int len) 1992*8bdc5a62SPatrick Kelsey { 19933c602fabSXin LI const u_char *cp0 = cp; 19943c602fabSXin LI const u_int len0 = len; 19953c602fabSXin LI 19963c602fabSXin LI while (len) { 19973c602fabSXin LI if (len < OF_TABLE_STATS_LEN) 19983c602fabSXin LI goto corrupt; 19993c602fabSXin LI /* table_id */ 20003c602fabSXin LI ND_TCHECK2(*cp, 1); 20013c602fabSXin LI ND_PRINT((ndo, "\n\t table_id %s", tok2str(tableid_str, "%u", *cp))); 20023c602fabSXin LI cp += 1; 20033c602fabSXin LI /* pad */ 20043c602fabSXin LI ND_TCHECK2(*cp, 3); 20053c602fabSXin LI cp += 3; 20063c602fabSXin LI /* name */ 20073c602fabSXin LI ND_TCHECK2(*cp, OFP_MAX_TABLE_NAME_LEN); 20083c602fabSXin LI ND_PRINT((ndo, ", name '")); 20093c602fabSXin LI fn_print(ndo, cp, cp + OFP_MAX_TABLE_NAME_LEN); 20103c602fabSXin LI ND_PRINT((ndo, "'")); 20113c602fabSXin LI cp += OFP_MAX_TABLE_NAME_LEN; 20123c602fabSXin LI /* wildcards */ 20133c602fabSXin LI ND_TCHECK2(*cp, 4); 20143c602fabSXin LI ND_PRINT((ndo, "\n\t wildcards 0x%08x", EXTRACT_32BITS(cp))); 20153c602fabSXin LI of10_bitmap_print(ndo, ofpfw_bm, EXTRACT_32BITS(cp), OFPFW_U); 20163c602fabSXin LI cp += 4; 20173c602fabSXin LI /* max_entries */ 20183c602fabSXin LI ND_TCHECK2(*cp, 4); 20193c602fabSXin LI ND_PRINT((ndo, "\n\t max_entries %u", EXTRACT_32BITS(cp))); 20203c602fabSXin LI cp += 4; 20213c602fabSXin LI /* active_count */ 20223c602fabSXin LI ND_TCHECK2(*cp, 4); 20233c602fabSXin LI ND_PRINT((ndo, ", active_count %u", EXTRACT_32BITS(cp))); 20243c602fabSXin LI cp += 4; 20253c602fabSXin LI /* lookup_count */ 20263c602fabSXin LI ND_TCHECK2(*cp, 8); 20273c602fabSXin LI ND_PRINT((ndo, ", lookup_count %" PRIu64, EXTRACT_64BITS(cp))); 20283c602fabSXin LI cp += 8; 20293c602fabSXin LI /* matched_count */ 20303c602fabSXin LI ND_TCHECK2(*cp, 8); 20313c602fabSXin LI ND_PRINT((ndo, ", matched_count %" PRIu64, EXTRACT_64BITS(cp))); 20323c602fabSXin LI cp += 8; 20333c602fabSXin LI 20343c602fabSXin LI len -= OF_TABLE_STATS_LEN; 20353c602fabSXin LI } /* while */ 20363c602fabSXin LI return cp; 20373c602fabSXin LI 20383c602fabSXin LI corrupt: /* skip the undersized trailing data */ 20393c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 20403c602fabSXin LI ND_TCHECK2(*cp0, len0); 20413c602fabSXin LI return cp0 + len0; 20423c602fabSXin LI trunc: 20433c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 20443c602fabSXin LI return ep; 20453c602fabSXin LI } 20463c602fabSXin LI 20473c602fabSXin LI /* ibid */ 20483c602fabSXin LI static const u_char * 20493c602fabSXin LI of10_port_stats_reply_print(netdissect_options *ndo, 2050*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, u_int len) 2051*8bdc5a62SPatrick Kelsey { 20523c602fabSXin LI const u_char *cp0 = cp; 20533c602fabSXin LI const u_int len0 = len; 20543c602fabSXin LI 20553c602fabSXin LI while (len) { 20563c602fabSXin LI if (len < OF_PORT_STATS_LEN) 20573c602fabSXin LI goto corrupt; 20583c602fabSXin LI /* port_no */ 20593c602fabSXin LI ND_TCHECK2(*cp, 2); 20603c602fabSXin LI ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 20613c602fabSXin LI cp += 2; 20623c602fabSXin LI if (ndo->ndo_vflag < 2) { 20633c602fabSXin LI ND_TCHECK2(*cp, OF_PORT_STATS_LEN - 2); 20643c602fabSXin LI cp += OF_PORT_STATS_LEN - 2; 20653c602fabSXin LI goto next_port; 20663c602fabSXin LI } 20673c602fabSXin LI /* pad */ 20683c602fabSXin LI ND_TCHECK2(*cp, 6); 20693c602fabSXin LI cp += 6; 20703c602fabSXin LI /* rx_packets */ 20713c602fabSXin LI ND_TCHECK2(*cp, 8); 20723c602fabSXin LI ND_PRINT((ndo, ", rx_packets %" PRIu64, EXTRACT_64BITS(cp))); 20733c602fabSXin LI cp += 8; 20743c602fabSXin LI /* tx_packets */ 20753c602fabSXin LI ND_TCHECK2(*cp, 8); 20763c602fabSXin LI ND_PRINT((ndo, ", tx_packets %" PRIu64, EXTRACT_64BITS(cp))); 20773c602fabSXin LI cp += 8; 20783c602fabSXin LI /* rx_bytes */ 20793c602fabSXin LI ND_TCHECK2(*cp, 8); 20803c602fabSXin LI ND_PRINT((ndo, ", rx_bytes %" PRIu64, EXTRACT_64BITS(cp))); 20813c602fabSXin LI cp += 8; 20823c602fabSXin LI /* tx_bytes */ 20833c602fabSXin LI ND_TCHECK2(*cp, 8); 20843c602fabSXin LI ND_PRINT((ndo, ", tx_bytes %" PRIu64, EXTRACT_64BITS(cp))); 20853c602fabSXin LI cp += 8; 20863c602fabSXin LI /* rx_dropped */ 20873c602fabSXin LI ND_TCHECK2(*cp, 8); 20883c602fabSXin LI ND_PRINT((ndo, ", rx_dropped %" PRIu64, EXTRACT_64BITS(cp))); 20893c602fabSXin LI cp += 8; 20903c602fabSXin LI /* tx_dropped */ 20913c602fabSXin LI ND_TCHECK2(*cp, 8); 20923c602fabSXin LI ND_PRINT((ndo, ", tx_dropped %" PRIu64, EXTRACT_64BITS(cp))); 20933c602fabSXin LI cp += 8; 20943c602fabSXin LI /* rx_errors */ 20953c602fabSXin LI ND_TCHECK2(*cp, 8); 20963c602fabSXin LI ND_PRINT((ndo, ", rx_errors %" PRIu64, EXTRACT_64BITS(cp))); 20973c602fabSXin LI cp += 8; 20983c602fabSXin LI /* tx_errors */ 20993c602fabSXin LI ND_TCHECK2(*cp, 8); 21003c602fabSXin LI ND_PRINT((ndo, ", tx_errors %" PRIu64, EXTRACT_64BITS(cp))); 21013c602fabSXin LI cp += 8; 21023c602fabSXin LI /* rx_frame_err */ 21033c602fabSXin LI ND_TCHECK2(*cp, 8); 21043c602fabSXin LI ND_PRINT((ndo, ", rx_frame_err %" PRIu64, EXTRACT_64BITS(cp))); 21053c602fabSXin LI cp += 8; 21063c602fabSXin LI /* rx_over_err */ 21073c602fabSXin LI ND_TCHECK2(*cp, 8); 21083c602fabSXin LI ND_PRINT((ndo, ", rx_over_err %" PRIu64, EXTRACT_64BITS(cp))); 21093c602fabSXin LI cp += 8; 21103c602fabSXin LI /* rx_crc_err */ 21113c602fabSXin LI ND_TCHECK2(*cp, 8); 21123c602fabSXin LI ND_PRINT((ndo, ", rx_crc_err %" PRIu64, EXTRACT_64BITS(cp))); 21133c602fabSXin LI cp += 8; 21143c602fabSXin LI /* collisions */ 21153c602fabSXin LI ND_TCHECK2(*cp, 8); 21163c602fabSXin LI ND_PRINT((ndo, ", collisions %" PRIu64, EXTRACT_64BITS(cp))); 21173c602fabSXin LI cp += 8; 21183c602fabSXin LI next_port: 21193c602fabSXin LI len -= OF_PORT_STATS_LEN; 21203c602fabSXin LI } /* while */ 21213c602fabSXin LI return cp; 21223c602fabSXin LI 21233c602fabSXin LI corrupt: /* skip the undersized trailing data */ 21243c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 21253c602fabSXin LI ND_TCHECK2(*cp0, len0); 21263c602fabSXin LI return cp0 + len0; 21273c602fabSXin LI trunc: 21283c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 21293c602fabSXin LI return ep; 21303c602fabSXin LI } 21313c602fabSXin LI 21323c602fabSXin LI /* ibid */ 21333c602fabSXin LI static const u_char * 21343c602fabSXin LI of10_queue_stats_reply_print(netdissect_options *ndo, 2135*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, u_int len) 2136*8bdc5a62SPatrick Kelsey { 21373c602fabSXin LI const u_char *cp0 = cp; 21383c602fabSXin LI const u_int len0 = len; 21393c602fabSXin LI 21403c602fabSXin LI while (len) { 21413c602fabSXin LI if (len < OF_QUEUE_STATS_LEN) 21423c602fabSXin LI goto corrupt; 21433c602fabSXin LI /* port_no */ 21443c602fabSXin LI ND_TCHECK2(*cp, 2); 21453c602fabSXin LI ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 21463c602fabSXin LI cp += 2; 21473c602fabSXin LI /* pad */ 21483c602fabSXin LI ND_TCHECK2(*cp, 2); 21493c602fabSXin LI cp += 2; 21503c602fabSXin LI /* queue_id */ 21513c602fabSXin LI ND_TCHECK2(*cp, 4); 21523c602fabSXin LI ND_PRINT((ndo, ", queue_id %u", EXTRACT_32BITS(cp))); 21533c602fabSXin LI cp += 4; 21543c602fabSXin LI /* tx_bytes */ 21553c602fabSXin LI ND_TCHECK2(*cp, 8); 21563c602fabSXin LI ND_PRINT((ndo, ", tx_bytes %" PRIu64, EXTRACT_64BITS(cp))); 21573c602fabSXin LI cp += 8; 21583c602fabSXin LI /* tx_packets */ 21593c602fabSXin LI ND_TCHECK2(*cp, 8); 21603c602fabSXin LI ND_PRINT((ndo, ", tx_packets %" PRIu64, EXTRACT_64BITS(cp))); 21613c602fabSXin LI cp += 8; 21623c602fabSXin LI /* tx_errors */ 21633c602fabSXin LI ND_TCHECK2(*cp, 8); 21643c602fabSXin LI ND_PRINT((ndo, ", tx_errors %" PRIu64, EXTRACT_64BITS(cp))); 21653c602fabSXin LI cp += 8; 21663c602fabSXin LI 21673c602fabSXin LI len -= OF_QUEUE_STATS_LEN; 21683c602fabSXin LI } /* while */ 21693c602fabSXin LI return cp; 21703c602fabSXin LI 21713c602fabSXin LI corrupt: /* skip the undersized trailing data */ 21723c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 21733c602fabSXin LI ND_TCHECK2(*cp0, len0); 21743c602fabSXin LI return cp0 + len0; 21753c602fabSXin LI trunc: 21763c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 21773c602fabSXin LI return ep; 21783c602fabSXin LI } 21793c602fabSXin LI 21803c602fabSXin LI /* ibid */ 21813c602fabSXin LI static const u_char * 21823c602fabSXin LI of10_stats_reply_print(netdissect_options *ndo, 2183*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 2184*8bdc5a62SPatrick Kelsey { 21853c602fabSXin LI const u_char *cp0 = cp; 21863c602fabSXin LI uint16_t type; 21873c602fabSXin LI 21883c602fabSXin LI /* type */ 21893c602fabSXin LI ND_TCHECK2(*cp, 2); 21903c602fabSXin LI type = EXTRACT_16BITS(cp); 21913c602fabSXin LI ND_PRINT((ndo, "\n\t type %s", tok2str(ofpst_str, "invalid (0x%04x)", type))); 21923c602fabSXin LI cp += 2; 21933c602fabSXin LI /* flags */ 21943c602fabSXin LI ND_TCHECK2(*cp, 2); 21953c602fabSXin LI ND_PRINT((ndo, ", flags 0x%04x", EXTRACT_16BITS(cp))); 21963c602fabSXin LI of10_bitmap_print(ndo, ofpsf_reply_bm, EXTRACT_16BITS(cp), OFPSF_REPLY_U); 21973c602fabSXin LI cp += 2; 21983c602fabSXin LI 21993c602fabSXin LI if (ndo->ndo_vflag > 0) { 22003c602fabSXin LI const u_char *(*decoder)(netdissect_options *, const u_char *, const u_char *, u_int) = 22013c602fabSXin LI type == OFPST_DESC ? of10_desc_stats_reply_print : 22023c602fabSXin LI type == OFPST_FLOW ? of10_flow_stats_reply_print : 22033c602fabSXin LI type == OFPST_AGGREGATE ? of10_aggregate_stats_reply_print : 22043c602fabSXin LI type == OFPST_TABLE ? of10_table_stats_reply_print : 22053c602fabSXin LI type == OFPST_PORT ? of10_port_stats_reply_print : 22063c602fabSXin LI type == OFPST_QUEUE ? of10_queue_stats_reply_print : 22073c602fabSXin LI type == OFPST_VENDOR ? of10_vendor_data_print : 22083c602fabSXin LI NULL; 22093c602fabSXin LI if (decoder != NULL) 22103c602fabSXin LI return decoder(ndo, cp, ep, len - OF_STATS_REPLY_LEN); 22113c602fabSXin LI } 22123c602fabSXin LI ND_TCHECK2(*cp0, len); 22133c602fabSXin LI return cp0 + len; 22143c602fabSXin LI 22153c602fabSXin LI trunc: 22163c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 22173c602fabSXin LI return ep; 22183c602fabSXin LI } 22193c602fabSXin LI 22203c602fabSXin LI /* [OF10] Section 5.3.6 */ 22213c602fabSXin LI static const u_char * 22223c602fabSXin LI of10_packet_out_print(netdissect_options *ndo, 2223*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 2224*8bdc5a62SPatrick Kelsey { 22253c602fabSXin LI const u_char *cp0 = cp; 22263c602fabSXin LI const u_int len0 = len; 22273c602fabSXin LI uint16_t actions_len; 22283c602fabSXin LI 22293c602fabSXin LI /* buffer_id */ 22303c602fabSXin LI ND_TCHECK2(*cp, 4); 22313c602fabSXin LI ND_PRINT((ndo, "\n\t buffer_id 0x%08x", EXTRACT_32BITS(cp))); 22323c602fabSXin LI cp += 4; 22333c602fabSXin LI /* in_port */ 22343c602fabSXin LI ND_TCHECK2(*cp, 2); 22353c602fabSXin LI ND_PRINT((ndo, ", in_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 22363c602fabSXin LI cp += 2; 22373c602fabSXin LI /* actions_len */ 22383c602fabSXin LI ND_TCHECK2(*cp, 2); 22393c602fabSXin LI actions_len = EXTRACT_16BITS(cp); 22403c602fabSXin LI cp += 2; 22413c602fabSXin LI if (actions_len > len - OF_PACKET_OUT_LEN) 22423c602fabSXin LI goto corrupt; 22433c602fabSXin LI /* actions */ 22443c602fabSXin LI if (ep == (cp = of10_actions_print(ndo, "\n\t ", cp, ep, actions_len))) 22453c602fabSXin LI return ep; /* end of snapshot */ 22463c602fabSXin LI /* data */ 22473c602fabSXin LI return of10_packet_data_print(ndo, cp, ep, len - OF_PACKET_OUT_LEN - actions_len); 22483c602fabSXin LI 22493c602fabSXin LI corrupt: /* skip the rest of the message body */ 22503c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 22513c602fabSXin LI ND_TCHECK2(*cp0, len0); 22523c602fabSXin LI return cp0 + len0; 22533c602fabSXin LI trunc: 22543c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 22553c602fabSXin LI return ep; 22563c602fabSXin LI } 22573c602fabSXin LI 22583c602fabSXin LI /* [OF10] Section 5.4.1 */ 22593c602fabSXin LI static const u_char * 22603c602fabSXin LI of10_packet_in_print(netdissect_options *ndo, 2261*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 2262*8bdc5a62SPatrick Kelsey { 22633c602fabSXin LI /* buffer_id */ 22643c602fabSXin LI ND_TCHECK2(*cp, 4); 22653c602fabSXin LI ND_PRINT((ndo, "\n\t buffer_id %s", tok2str(bufferid_str, "0x%08x", EXTRACT_32BITS(cp)))); 22663c602fabSXin LI cp += 4; 22673c602fabSXin LI /* total_len */ 22683c602fabSXin LI ND_TCHECK2(*cp, 2); 22693c602fabSXin LI ND_PRINT((ndo, ", total_len %u", EXTRACT_16BITS(cp))); 22703c602fabSXin LI cp += 2; 22713c602fabSXin LI /* in_port */ 22723c602fabSXin LI ND_TCHECK2(*cp, 2); 22733c602fabSXin LI ND_PRINT((ndo, ", in_port %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 22743c602fabSXin LI cp += 2; 22753c602fabSXin LI /* reason */ 22763c602fabSXin LI ND_TCHECK2(*cp, 1); 22773c602fabSXin LI ND_PRINT((ndo, ", reason %s", tok2str(ofpr_str, "invalid (0x%02x)", *cp))); 22783c602fabSXin LI cp += 1; 22793c602fabSXin LI /* pad */ 22803c602fabSXin LI ND_TCHECK2(*cp, 1); 22813c602fabSXin LI cp += 1; 22823c602fabSXin LI /* data */ 22833c602fabSXin LI /* 2 mock octets count in OF_PACKET_IN_LEN but not in len */ 22843c602fabSXin LI return of10_packet_data_print(ndo, cp, ep, len - (OF_PACKET_IN_LEN - 2)); 22853c602fabSXin LI 22863c602fabSXin LI trunc: 22873c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 22883c602fabSXin LI return ep; 22893c602fabSXin LI } 22903c602fabSXin LI 22913c602fabSXin LI /* [OF10] Section 5.4.2 */ 22923c602fabSXin LI static const u_char * 22933c602fabSXin LI of10_flow_removed_print(netdissect_options *ndo, 2294*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep) 2295*8bdc5a62SPatrick Kelsey { 22963c602fabSXin LI /* match */ 22973c602fabSXin LI if (ep == (cp = of10_match_print(ndo, "\n\t ", cp, ep))) 22983c602fabSXin LI return ep; /* end of snapshot */ 22993c602fabSXin LI /* cookie */ 23003c602fabSXin LI ND_TCHECK2(*cp, 8); 23013c602fabSXin LI ND_PRINT((ndo, "\n\t cookie 0x%016" PRIx64, EXTRACT_64BITS(cp))); 23023c602fabSXin LI cp += 8; 23033c602fabSXin LI /* priority */ 23043c602fabSXin LI ND_TCHECK2(*cp, 2); 23053c602fabSXin LI if (EXTRACT_16BITS(cp)) 23063c602fabSXin LI ND_PRINT((ndo, ", priority %u", EXTRACT_16BITS(cp))); 23073c602fabSXin LI cp += 2; 23083c602fabSXin LI /* reason */ 23093c602fabSXin LI ND_TCHECK2(*cp, 1); 23103c602fabSXin LI ND_PRINT((ndo, ", reason %s", tok2str(ofprr_str, "unknown (0x%02x)", *cp))); 23113c602fabSXin LI cp += 1; 23123c602fabSXin LI /* pad */ 23133c602fabSXin LI ND_TCHECK2(*cp, 1); 23143c602fabSXin LI cp += 1; 23153c602fabSXin LI /* duration_sec */ 23163c602fabSXin LI ND_TCHECK2(*cp, 4); 23173c602fabSXin LI ND_PRINT((ndo, ", duration_sec %u", EXTRACT_32BITS(cp))); 23183c602fabSXin LI cp += 4; 23193c602fabSXin LI /* duration_nsec */ 23203c602fabSXin LI ND_TCHECK2(*cp, 4); 23213c602fabSXin LI ND_PRINT((ndo, ", duration_nsec %u", EXTRACT_32BITS(cp))); 23223c602fabSXin LI cp += 4; 23233c602fabSXin LI /* idle_timeout */ 23243c602fabSXin LI ND_TCHECK2(*cp, 2); 23253c602fabSXin LI if (EXTRACT_16BITS(cp)) 23263c602fabSXin LI ND_PRINT((ndo, ", idle_timeout %u", EXTRACT_16BITS(cp))); 23273c602fabSXin LI cp += 2; 23283c602fabSXin LI /* pad2 */ 23293c602fabSXin LI ND_TCHECK2(*cp, 2); 23303c602fabSXin LI cp += 2; 23313c602fabSXin LI /* packet_count */ 23323c602fabSXin LI ND_TCHECK2(*cp, 8); 23333c602fabSXin LI ND_PRINT((ndo, ", packet_count %" PRIu64, EXTRACT_64BITS(cp))); 23343c602fabSXin LI cp += 8; 23353c602fabSXin LI /* byte_count */ 23363c602fabSXin LI ND_TCHECK2(*cp, 8); 23373c602fabSXin LI ND_PRINT((ndo, ", byte_count %" PRIu64, EXTRACT_64BITS(cp))); 23383c602fabSXin LI return cp + 8; 23393c602fabSXin LI 23403c602fabSXin LI trunc: 23413c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 23423c602fabSXin LI return ep; 23433c602fabSXin LI } 23443c602fabSXin LI 23453c602fabSXin LI /* [OF10] Section 5.4.4 */ 23463c602fabSXin LI static const u_char * 23473c602fabSXin LI of10_error_print(netdissect_options *ndo, 2348*8bdc5a62SPatrick Kelsey const u_char *cp, const u_char *ep, const u_int len) 2349*8bdc5a62SPatrick Kelsey { 23503c602fabSXin LI uint16_t type; 23513c602fabSXin LI const struct tok *code_str; 23523c602fabSXin LI 23533c602fabSXin LI /* type */ 23543c602fabSXin LI ND_TCHECK2(*cp, 2); 23553c602fabSXin LI type = EXTRACT_16BITS(cp); 23563c602fabSXin LI cp += 2; 23573c602fabSXin LI ND_PRINT((ndo, "\n\t type %s", tok2str(ofpet_str, "invalid (0x%04x)", type))); 23583c602fabSXin LI /* code */ 23593c602fabSXin LI ND_TCHECK2(*cp, 2); 23603c602fabSXin LI code_str = 23613c602fabSXin LI type == OFPET_HELLO_FAILED ? ofphfc_str : 23623c602fabSXin LI type == OFPET_BAD_REQUEST ? ofpbrc_str : 23633c602fabSXin LI type == OFPET_BAD_ACTION ? ofpbac_str : 23643c602fabSXin LI type == OFPET_FLOW_MOD_FAILED ? ofpfmfc_str : 23653c602fabSXin LI type == OFPET_PORT_MOD_FAILED ? ofppmfc_str : 23663c602fabSXin LI type == OFPET_QUEUE_OP_FAILED ? ofpqofc_str : 23673c602fabSXin LI empty_str; 23683c602fabSXin LI ND_PRINT((ndo, ", code %s", tok2str(code_str, "invalid (0x%04x)", EXTRACT_16BITS(cp)))); 23693c602fabSXin LI cp += 2; 23703c602fabSXin LI /* data */ 23713c602fabSXin LI return of10_data_print(ndo, cp, ep, len - OF_ERROR_MSG_LEN); 23723c602fabSXin LI 23733c602fabSXin LI trunc: 23743c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 23753c602fabSXin LI return ep; 23763c602fabSXin LI } 23773c602fabSXin LI 23783c602fabSXin LI const u_char * 23793c602fabSXin LI of10_header_body_print(netdissect_options *ndo, 23803c602fabSXin LI const u_char *cp, const u_char *ep, const uint8_t type, 2381*8bdc5a62SPatrick Kelsey const uint16_t len, const uint32_t xid) 2382*8bdc5a62SPatrick Kelsey { 23833c602fabSXin LI const u_char *cp0 = cp; 23843c602fabSXin LI const u_int len0 = len; 23853c602fabSXin LI /* Thus far message length is not less than the basic header size, but most 23863c602fabSXin LI * message types have additional assorted constraints on the length. Wherever 23873c602fabSXin LI * possible, check that message length meets the constraint, in remaining 23883c602fabSXin LI * cases check that the length is OK to begin decoding and leave any final 23893c602fabSXin LI * verification up to a lower-layer function. When the current message is 23903c602fabSXin LI * corrupt, proceed to the next message. */ 23913c602fabSXin LI 23923c602fabSXin LI /* [OF10] Section 5.1 */ 23933c602fabSXin LI ND_PRINT((ndo, "\n\tversion 1.0, type %s, length %u, xid 0x%08x", 23943c602fabSXin LI tok2str(ofpt_str, "invalid (0x%02x)", type), len, xid)); 23953c602fabSXin LI switch (type) { 23963c602fabSXin LI /* OpenFlow header only. */ 23973c602fabSXin LI case OFPT_FEATURES_REQUEST: /* [OF10] Section 5.3.1 */ 23983c602fabSXin LI case OFPT_GET_CONFIG_REQUEST: /* [OF10] Section 5.3.2 */ 23993c602fabSXin LI case OFPT_BARRIER_REQUEST: /* [OF10] Section 5.3.7 */ 24003c602fabSXin LI case OFPT_BARRIER_REPLY: /* ibid */ 24013c602fabSXin LI if (len != OF_HEADER_LEN) 24023c602fabSXin LI goto corrupt; 24033c602fabSXin LI break; 24043c602fabSXin LI 24053c602fabSXin LI /* OpenFlow header and fixed-size message body. */ 24063c602fabSXin LI case OFPT_SET_CONFIG: /* [OF10] Section 5.3.2 */ 24073c602fabSXin LI case OFPT_GET_CONFIG_REPLY: /* ibid */ 24083c602fabSXin LI if (len != OF_SWITCH_CONFIG_LEN) 24093c602fabSXin LI goto corrupt; 24103c602fabSXin LI if (ndo->ndo_vflag < 1) 24113c602fabSXin LI goto next_message; 24123c602fabSXin LI /* flags */ 24133c602fabSXin LI ND_TCHECK2(*cp, 2); 24143c602fabSXin LI ND_PRINT((ndo, "\n\t flags %s", tok2str(ofp_config_str, "invalid (0x%04x)", EXTRACT_16BITS(cp)))); 24153c602fabSXin LI cp += 2; 24163c602fabSXin LI /* miss_send_len */ 24173c602fabSXin LI ND_TCHECK2(*cp, 2); 24183c602fabSXin LI ND_PRINT((ndo, ", miss_send_len %u", EXTRACT_16BITS(cp))); 24193c602fabSXin LI return cp + 2; 24203c602fabSXin LI case OFPT_PORT_MOD: 24213c602fabSXin LI if (len != OF_PORT_MOD_LEN) 24223c602fabSXin LI goto corrupt; 24233c602fabSXin LI if (ndo->ndo_vflag < 1) 24243c602fabSXin LI goto next_message; 24253c602fabSXin LI return of10_port_mod_print(ndo, cp, ep); 24263c602fabSXin LI case OFPT_QUEUE_GET_CONFIG_REQUEST: /* [OF10] Section 5.3.4 */ 24273c602fabSXin LI if (len != OF_QUEUE_GET_CONFIG_REQUEST_LEN) 24283c602fabSXin LI goto corrupt; 24293c602fabSXin LI if (ndo->ndo_vflag < 1) 24303c602fabSXin LI goto next_message; 24313c602fabSXin LI /* port */ 24323c602fabSXin LI ND_TCHECK2(*cp, 2); 24333c602fabSXin LI ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 24343c602fabSXin LI cp += 2; 24353c602fabSXin LI /* pad */ 24363c602fabSXin LI ND_TCHECK2(*cp, 2); 24373c602fabSXin LI return cp + 2; 24383c602fabSXin LI case OFPT_FLOW_REMOVED: 24393c602fabSXin LI if (len != OF_FLOW_REMOVED_LEN) 24403c602fabSXin LI goto corrupt; 24413c602fabSXin LI if (ndo->ndo_vflag < 1) 24423c602fabSXin LI goto next_message; 24433c602fabSXin LI return of10_flow_removed_print(ndo, cp, ep); 24443c602fabSXin LI case OFPT_PORT_STATUS: /* [OF10] Section 5.4.3 */ 24453c602fabSXin LI if (len != OF_PORT_STATUS_LEN) 24463c602fabSXin LI goto corrupt; 24473c602fabSXin LI if (ndo->ndo_vflag < 1) 24483c602fabSXin LI goto next_message; 24493c602fabSXin LI /* reason */ 24503c602fabSXin LI ND_TCHECK2(*cp, 1); 24513c602fabSXin LI ND_PRINT((ndo, "\n\t reason %s", tok2str(ofppr_str, "invalid (0x%02x)", *cp))); 24523c602fabSXin LI cp += 1; 24533c602fabSXin LI /* pad */ 24543c602fabSXin LI ND_TCHECK2(*cp, 7); 24553c602fabSXin LI cp += 7; 24563c602fabSXin LI /* desc */ 24573c602fabSXin LI return of10_phy_ports_print(ndo, cp, ep, OF_PHY_PORT_LEN); 24583c602fabSXin LI 24593c602fabSXin LI /* OpenFlow header, fixed-size message body and n * fixed-size data units. */ 24603c602fabSXin LI case OFPT_FEATURES_REPLY: 24613c602fabSXin LI if (len < OF_SWITCH_FEATURES_LEN) 24623c602fabSXin LI goto corrupt; 24633c602fabSXin LI if (ndo->ndo_vflag < 1) 24643c602fabSXin LI goto next_message; 24653c602fabSXin LI return of10_features_reply_print(ndo, cp, ep, len); 24663c602fabSXin LI 24673c602fabSXin LI /* OpenFlow header and variable-size data. */ 24683c602fabSXin LI case OFPT_HELLO: /* [OF10] Section 5.5.1 */ 24693c602fabSXin LI case OFPT_ECHO_REQUEST: /* [OF10] Section 5.5.2 */ 24703c602fabSXin LI case OFPT_ECHO_REPLY: /* [OF10] Section 5.5.3 */ 24713c602fabSXin LI if (ndo->ndo_vflag < 1) 24723c602fabSXin LI goto next_message; 24733c602fabSXin LI return of10_data_print(ndo, cp, ep, len - OF_HEADER_LEN); 24743c602fabSXin LI 24753c602fabSXin LI /* OpenFlow header, fixed-size message body and variable-size data. */ 24763c602fabSXin LI case OFPT_ERROR: 24773c602fabSXin LI if (len < OF_ERROR_MSG_LEN) 24783c602fabSXin LI goto corrupt; 24793c602fabSXin LI if (ndo->ndo_vflag < 1) 24803c602fabSXin LI goto next_message; 24813c602fabSXin LI return of10_error_print(ndo, cp, ep, len); 24823c602fabSXin LI case OFPT_VENDOR: 24833c602fabSXin LI /* [OF10] Section 5.5.4 */ 24843c602fabSXin LI if (len < OF_VENDOR_HEADER_LEN) 24853c602fabSXin LI goto corrupt; 24863c602fabSXin LI if (ndo->ndo_vflag < 1) 24873c602fabSXin LI goto next_message; 2488*8bdc5a62SPatrick Kelsey return of10_vendor_message_print(ndo, cp, ep, len - OF_HEADER_LEN); 24893c602fabSXin LI case OFPT_PACKET_IN: 24903c602fabSXin LI /* 2 mock octets count in OF_PACKET_IN_LEN but not in len */ 24913c602fabSXin LI if (len < OF_PACKET_IN_LEN - 2) 24923c602fabSXin LI goto corrupt; 24933c602fabSXin LI if (ndo->ndo_vflag < 1) 24943c602fabSXin LI goto next_message; 24953c602fabSXin LI return of10_packet_in_print(ndo, cp, ep, len); 24963c602fabSXin LI 24973c602fabSXin LI /* a. OpenFlow header. */ 24983c602fabSXin LI /* b. OpenFlow header and one of the fixed-size message bodies. */ 24993c602fabSXin LI /* c. OpenFlow header, fixed-size message body and variable-size data. */ 25003c602fabSXin LI case OFPT_STATS_REQUEST: 25013c602fabSXin LI if (len < OF_STATS_REQUEST_LEN) 25023c602fabSXin LI goto corrupt; 25033c602fabSXin LI if (ndo->ndo_vflag < 1) 25043c602fabSXin LI goto next_message; 25053c602fabSXin LI return of10_stats_request_print(ndo, cp, ep, len); 25063c602fabSXin LI 25073c602fabSXin LI /* a. OpenFlow header and fixed-size message body. */ 25083c602fabSXin LI /* b. OpenFlow header and n * fixed-size data units. */ 25093c602fabSXin LI /* c. OpenFlow header and n * variable-size data units. */ 25103c602fabSXin LI /* d. OpenFlow header, fixed-size message body and variable-size data. */ 25113c602fabSXin LI case OFPT_STATS_REPLY: 25123c602fabSXin LI if (len < OF_STATS_REPLY_LEN) 25133c602fabSXin LI goto corrupt; 25143c602fabSXin LI if (ndo->ndo_vflag < 1) 25153c602fabSXin LI goto next_message; 25163c602fabSXin LI return of10_stats_reply_print(ndo, cp, ep, len); 25173c602fabSXin LI 25183c602fabSXin LI /* OpenFlow header and n * variable-size data units and variable-size data. */ 25193c602fabSXin LI case OFPT_PACKET_OUT: 25203c602fabSXin LI if (len < OF_PACKET_OUT_LEN) 25213c602fabSXin LI goto corrupt; 25223c602fabSXin LI if (ndo->ndo_vflag < 1) 25233c602fabSXin LI goto next_message; 25243c602fabSXin LI return of10_packet_out_print(ndo, cp, ep, len); 25253c602fabSXin LI 25263c602fabSXin LI /* OpenFlow header, fixed-size message body and n * variable-size data units. */ 25273c602fabSXin LI case OFPT_FLOW_MOD: 25283c602fabSXin LI if (len < OF_FLOW_MOD_LEN) 25293c602fabSXin LI goto corrupt; 25303c602fabSXin LI if (ndo->ndo_vflag < 1) 25313c602fabSXin LI goto next_message; 25323c602fabSXin LI return of10_flow_mod_print(ndo, cp, ep, len); 25333c602fabSXin LI 25343c602fabSXin LI /* OpenFlow header, fixed-size message body and n * variable-size data units. */ 25353c602fabSXin LI case OFPT_QUEUE_GET_CONFIG_REPLY: /* [OF10] Section 5.3.4 */ 25363c602fabSXin LI if (len < OF_QUEUE_GET_CONFIG_REPLY_LEN) 25373c602fabSXin LI goto corrupt; 25383c602fabSXin LI if (ndo->ndo_vflag < 1) 25393c602fabSXin LI goto next_message; 25403c602fabSXin LI /* port */ 25413c602fabSXin LI ND_TCHECK2(*cp, 2); 25423c602fabSXin LI ND_PRINT((ndo, "\n\t port_no %s", tok2str(ofpp_str, "%u", EXTRACT_16BITS(cp)))); 25433c602fabSXin LI cp += 2; 25443c602fabSXin LI /* pad */ 25453c602fabSXin LI ND_TCHECK2(*cp, 6); 25463c602fabSXin LI cp += 6; 25473c602fabSXin LI /* queues */ 25483c602fabSXin LI return of10_queues_print(ndo, cp, ep, len - OF_QUEUE_GET_CONFIG_REPLY_LEN); 25493c602fabSXin LI } /* switch (type) */ 25503c602fabSXin LI goto next_message; 25513c602fabSXin LI 25523c602fabSXin LI corrupt: /* skip the message body */ 25533c602fabSXin LI ND_PRINT((ndo, "%s", cstr)); 25543c602fabSXin LI next_message: 25553c602fabSXin LI ND_TCHECK2(*cp0, len0 - OF_HEADER_LEN); 25563c602fabSXin LI return cp0 + len0 - OF_HEADER_LEN; 25573c602fabSXin LI trunc: 25583c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 25593c602fabSXin LI return ep; 25603c602fabSXin LI } 2561