2013-06-26 22:06:47 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2013 The TCPDUMP project
|
|
|
|
* All rights reserved.
|
2013-06-26 14:10:07 +08:00
|
|
|
*
|
2013-06-26 22:06:47 +08:00
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
2013-06-26 14:10:07 +08:00
|
|
|
*
|
2013-06-26 22:06:47 +08:00
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
2013-06-26 14:10:07 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* OpenFlow: protocol between controller and datapath. */
|
|
|
|
|
2014-04-03 20:02:07 +08:00
|
|
|
/* for netdissect_options */
|
|
|
|
#include "netdissect.h"
|
|
|
|
|
OpenFlow: Modernize packet parsing style.
Most OpenFlow functions operated on the (cp, ep, len) tuple, returned a
pointer to tell the calling function where to decode next (which was not
a good idea because the calling functions had the values of cp and len in
the first place) and set the pointer to ep to indicate truncated data.
Change them to use the (cp, len) tuple, to be void and to use nd_trunc().
Update the header comment to explain this new convention.
Now if a low-level function gets an offset wrong, as in the bug recently
fixed in of10_queue_props_print(), and manages to return, the error will
not propagate into the calling function, which will be able to continue
the decoding.
Since cp does not have to be current anymore when the [void] function
returns, remove a number of cp increments just before the return.
Introduce OF_FWD(), which modifies both cp and len in sync, and
OF_CHK_FWD(), which also does a bounds check, and use these macros
instead of incrementing cp directly in every function that has both cp
and len arguments. Update the code to account for len that is
decrementing as cp is incrementing.
Commit ad69daa2 was fine for its time, but the introduction of the GET
macros had made it obsolete. Instead of reintroducing ep back merge
of_header_body_print() into openflow_print() to simplify the handling of
pointers, sizes and error conditions, all in the style above.
While at it, subtract OF_HEADER_FIXLEN from the declared OpenFlow message
length before passing it to of10_header_body_print() and make the latter
the only function that has to know about the common header size (clarify
it in the comment). This and the sufficiently current cp and len
disencumber the following functions of type-specific length calculations:
of10_features_reply_print(), of10_flow_mod_print(),
of10_stats_request_print(), of10_stats_reply_print(),
of10_packet_out_print(), of10_packet_in_print() and of10_error_print().
The resulting code in most cases addresses the not yet processed part of
the declared structure with just cp and len: nextfunc(ndo, cp, len) and
ND_TCHECK_LEN(cp, len) do the right thing regardless of how far the
current decoder has made it into the current structure. This makes all
the cp0 and len0 snapshot variables obsolete, so remove them too.
Update a test case output: the missing closing quote now correctly means
that the snapshot end is inside the "data" field of a BSN_SHELL_COMMAND
vendor message, not after it.
2020-09-24 00:02:44 +08:00
|
|
|
#define OF_FWD(n) { \
|
|
|
|
cp += (n); \
|
|
|
|
len -= (n); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define OF_CHK_FWD(n) { \
|
|
|
|
ND_TCHECK_LEN(cp, (n)); \
|
|
|
|
cp += (n); \
|
|
|
|
len -= (n); \
|
|
|
|
}
|
|
|
|
|
2020-09-30 21:41:45 +08:00
|
|
|
#define OF_VER_1_0 0x01U
|
|
|
|
#define OF_VER_1_1 0x02U
|
|
|
|
#define OF_VER_1_2 0x03U
|
|
|
|
#define OF_VER_1_3 0x04U
|
|
|
|
#define OF_VER_1_4 0x05U
|
|
|
|
#define OF_VER_1_5 0x06U
|
|
|
|
|
2020-09-28 03:24:13 +08:00
|
|
|
#define OF_HEADER_FIXLEN 8U
|
2013-06-26 14:10:07 +08:00
|
|
|
|
2014-12-12 07:49:30 +08:00
|
|
|
#define ONF_EXP_ONF 0x4f4e4600
|
|
|
|
#define ONF_EXP_BUTE 0xff000001
|
|
|
|
#define ONF_EXP_NOVIFLOW 0xff000002
|
|
|
|
#define ONF_EXP_L3 0xff000003
|
|
|
|
#define ONF_EXP_L4L7 0xff000004
|
|
|
|
#define ONF_EXP_WMOB 0xff000005
|
|
|
|
#define ONF_EXP_FABS 0xff000006
|
|
|
|
#define ONF_EXP_OTRANS 0xff000007
|
2020-10-02 19:52:48 +08:00
|
|
|
#define ONF_EXP_NBLNCTU 0xff000008
|
|
|
|
#define ONF_EXP_MPCE 0xff000009
|
|
|
|
#define ONF_EXP_MPLSTPSPTN 0xff00000a
|
2014-12-12 07:49:30 +08:00
|
|
|
extern const struct tok onf_exp_str[];
|
|
|
|
|
2020-09-27 05:54:23 +08:00
|
|
|
extern const char * of_vendor_name(const uint32_t);
|
2020-09-30 19:56:43 +08:00
|
|
|
extern void of_bitmap_print(netdissect_options *ndo,
|
|
|
|
const struct tok *, const uint32_t, const uint32_t);
|
2020-09-27 05:54:23 +08:00
|
|
|
extern void of_data_print(netdissect_options *ndo,
|
|
|
|
const u_char *, const u_int);
|
|
|
|
|
2013-06-26 14:10:07 +08:00
|
|
|
/*
|
2020-09-28 06:07:40 +08:00
|
|
|
* Routines to handle various versions of OpenFlow.
|
2013-06-26 14:10:07 +08:00
|
|
|
*/
|
2020-09-28 06:07:40 +08:00
|
|
|
|
2020-10-05 07:54:33 +08:00
|
|
|
struct of_msgtypeinfo {
|
|
|
|
/* Should not be NULL. */
|
|
|
|
const char *name;
|
|
|
|
/* May be NULL to mean "message body printing is not implemented". */
|
|
|
|
void (*decoder)(netdissect_options *ndo, const u_char *, const u_int);
|
|
|
|
enum {
|
|
|
|
REQ_NONE, /* Message body length may be anything. */
|
|
|
|
REQ_FIXLEN, /* Message body length must be == req_value. */
|
|
|
|
REQ_MINLEN, /* Message body length must be >= req_value. */
|
|
|
|
} req_what;
|
|
|
|
uint16_t req_value;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const struct of_msgtypeinfo *of10_identify_msgtype(const uint8_t);
|
|
|
|
extern const struct of_msgtypeinfo *of13_identify_msgtype(const uint8_t);
|