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