Commit Graph

42 Commits

Author SHA1 Message Date
Denis Ovsienko
e379a5690f OpenFlow: Process message types via declarations.
Introduce struct of_msgtypeinfo and convert all the case blocks in
of10_message_print() and of13_message_print() together with ofpt_str[]
and the associated wrapper functions into array elements of this type.

Convert the code remaining of both functions into a short generic
of_message_print() function.

Refer to the latest OpenFlow 1.3 PDF and update comments to use section
numbers from that document.
2020-10-08 15:55:29 +01:00
Denis Ovsienko
853e9dccef OpenFlow 1.3: Recognise 5 more messages types.
Also add new OUIs and experimenter IDs for OFPT_EXPERIMENTER. Update
two tests.
2020-10-02 12:52:48 +01:00
Denis Ovsienko
3b46f347ca OpenFlow: Use bittok2str(), fix OF1.0 port status.
of_bitmap_print() used to have its own bitmap printing code, which would
yield a single closing parenthesis when none of the assigned tokens
matched (that was a bug, althought not triggered by any of the existing
tests). Simplify the function to use bittok2str() instead, then observe
some changes in OpenFlow 1.0 tests output. Apparently, the old code
implemented "match any" for multiple-bit tokens, and bittok2str() now
implements "match all".

However, in that protocol encoding bitmap tokens are always single-bit,
so examine the OFPPS_ props closer and realize that the "state" field of
the physical port structure includes both a tiny bitmap and a tiny code
point. Leave comments to clarify that, update the props and the printing
code. Update output for four tests.
2020-10-01 17:08:45 +01:00
Denis Ovsienko
2c7f188ff1 OpenFlow 1.3: Get OFPT_HELLO right.
Decode the optional trailing data and update two tests.
2020-09-30 14:53:37 +01:00
Denis Ovsienko
e17e42550a OpenFlow: Make one more function shared.
Rename of10_bitmap_print() to of_bitmap_print() and make it available
from print-openflow.c.
2020-09-30 14:53:37 +01:00
Denis Ovsienko
2bddf3b1f7 OpenFlow: Fix a compiler error on Windows. [skip travis]
print-openflow.c(110): error C2081: 'u_int16_t': name in formal
parameter list illegal
2020-09-28 14:29:13 +01:00
Denis Ovsienko
bdac249ee0 OpenFlow 1.3: Add initial partial support.
This code processes only the simplest message types (9 out of the 30
defined).

Add a test from [1], which comes from [2], which comes from a
contributor in Ericsson (Zoltán Lajos Kis).

1: https://wiki.wireshark.org/SampleCaptures#OpenFlow
2: https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9283
2020-09-28 13:58:12 +01:00
Denis Ovsienko
afb9acd6bc OpenFlow: Improve the common header dissection.
of_header_print() printed any version as "unknown", always printed the
type in hex only and printed the length with no remarks. If the header
was not good enough to proceed, openflow_print() would just print
"(invalid)" after it and be done with it.

Introduce of10_msgtype_str(). Rename of10_header_body_print() to
of10_message_print() and unburden it of all common header details. Add a
registry of all known OpenFlow version numbers. Merge of_header_print()
into openflow_print() and take the header apart one field at a time with
the captured and the declared lengths in mind, and indicate any anomalies
in version, type and length independently. Try to print the transaction
ID too before giving up on the header.

Among other changes, the header now shows the type as "unknown" when the
decoder does not know which types are valid for the version, and as
"invalid" when the type is definitely not valid for the version. Update
two tests.
2020-09-28 13:58:12 +01:00
Denis Ovsienko
8bd8cb7c59 OpenFlow: Rename and move a function.
Rename of10_data_print() to of_data_print(), move it to print-openflow.c
and declare it in openflow.h.
2020-09-28 13:58:12 +01:00
Denis Ovsienko
424961546a Introduce and use ND_LONGJMP_FROM_TCHECK.
Apply this to the 4 the recently converted protocols.

HOW TO USE:

Define this in a print-*.c file before including netdissect.h to make
all its ND_TCHECK*() instances longjmp(). Only do this after verifying
that every ND_TCHECK*() in the file is correct and that in every
possible case it is safe to call longjmp() without incurring resource
leaks or any other problems. If it is not safe or feasible to convert
whole file, consider converting one function at a time.
2020-09-27 21:45:46 +01:00
Denis Ovsienko
2e63bc0ec1 OpenFlow: Add an overshoot guard back.
In openflow_print() terminate the loop if the downstream code managed
to run off the TCP payload end without running off the packet buffer
end (that's how the pointers worked before commit ad69daa2, but I got
the recent conversion to a decrementing unsigned length wrong in commit
4e2e9c24). Expand the comment further.

Declare OF_HEADER_FIXLEN as unsigned to squelch a signedness warning.
2020-09-27 20:36:14 +01:00
Denis Ovsienko
4e2e9c244a 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 18:58:45 +01:00
Denis Ovsienko
afed055715 OpenFlow: Reorganize the length macros. [skip ci]
Lose unused items, lose _HEADER_ in all names except the common OpenFlow
header, always spell _REQUEST_ and _REPLY_ where they belong, spell
either _MINLEN or _FIXLEN everywhere. Denote the 2 mock octets once
again.
2020-09-24 18:58:45 +01:00
Denis Ovsienko
07ee811374 OpenFlow 1.0: Fix queue properties decoding.
In of10_queue_props_print() the "skip" branch tested and skipped 4 bytes
too many, so a malformed queue property would likely result in an odd
truncation or incorrect decoding of subsequent data (this is based on
code analysis only).

Get the offset and the size right and add a comment to explain it. Add
and update other comments to clarify a few similar subtleties that are
easy to get wrong.
2020-09-24 18:58:45 +01:00
Francois-Xavier Le Bail
abc8c2d61c Remove many (762) now redundant ND_TCHECK_n() calls
ND_TCHECK_n(e), n in { 1, 2, 3, 4, 8 }.

They are redundant because they are followed by a GET_.*_n(e) call,
same n, same e, which do the bounds check.

Remove unused 'trunc' labels and most associated codes.

Update the outputs of some tests accordingly.
2020-09-06 20:22:29 +02:00
Francois-Xavier Le Bail
ee68aa3646 Use the new GET_ macros instead of the EXTRACT_ ones
The exceptions are currently:
Some EXTRACT_ in print-juniper.c, not used on packet buffer pointer.
An EXTRACT_BE_U_3 in addrtoname.c, not always used on packet buffer
pointer.
2019-03-26 21:06:24 +01:00
Francois-Xavier Le Bail
77a49fcb6e Add the nd_print_invalid() function
It prints " (invalid)", used for malformed or corrupted packets.

Moreover:
Update CONTRIBUTING.
2018-09-11 13:09:05 +02:00
Francois-Xavier Le Bail
ba8936b39b Print truncations with nd_print_trunc() instead of tstr[] strings
Remove the tstr[] strings.
Update the output of some tests accordingly.

Moreover:
Add or update some ndo_protocol fields.
2018-05-04 13:47:49 +02:00
Francois-Xavier Le Bail
546558eabd Add the ndo_protocol field in the netdissect_options structure
Update this field in printer entry functions.
It will be used for some printings.
2018-03-16 19:44:47 +01:00
Francois-Xavier Le Bail
ad69daa2e4 OpenFlow: Fix the uses of the pointer to the end of current packet
Must be based on packet header caplen.
2018-03-01 16:39:38 +01:00
Guy Harris
fb2479d733 Always include <config.h> rather than "config.h".
This can prevent bizarre failures if, for example, you've done a
configuration in the top-level source directory, leaving behind one
config.h file, and then do an out-of-tree build in another directory,
with different configuration options.  This way, we always pick up the
same config.h, in the build directory.
2018-01-21 12:27:28 -08:00
Francois-Xavier Le Bail
513f782ae1 Use quoted include netdissect-stdinc.h instead of angle-bracketed one 2018-01-21 10:28:15 +01:00
Francois-Xavier Le Bail
e2982e7f6f Update ND_PRINT() as a variadic macro 2018-01-07 13:36:41 +01:00
Francois-Xavier Le Bail
84ef17ac0e Replace ND_TTEST2()/ND_TCHECK2() macros by macros using pointers (1/n)
ND_TTEST2(var, l)  -> ND_TTEST_LEN(p, l)
ND_TCHECK2(var, l) -> ND_TCHECK_LEN(p, l)
2017-12-11 22:11:01 +01:00
Francois-Xavier Le Bail
3a7639e545 Use more the EXTRACT_U_1() macro (49/n)
Assignment, *(p)
2017-12-09 09:56:29 +01:00
Francois-Xavier Le Bail
39c8c55aa9 Use more ND_TCHECK_n()/ND_TTEST_n() macros 2017-11-24 22:48:55 +01:00
Francois-Xavier Le Bail
da20bc56d6 Rename EXTRACT_ macros
Now all the macros have a name meaning a count in bytes.

With _S_: signed, _U_: unsigned

e.g.:
EXTRACT_BE_32BITS -> EXTRACT_BE_U_4
EXTRACT_LE_32BITS -> EXTRACT_LE_U_4
...
EXTRACT_BE_INT32 -> EXTRACT_BE_S_4

and have:
EXTRACT_8BITS -> EXTRACT_U_1
EXTRACT_INT8  -> EXTRACT_S_1
2017-11-22 23:54:09 +01:00
Francois-Xavier Le Bail
577621026d Rename EXTRACT_nBITS() macros to EXTRACT_BE_nBITS()
It indicates clearly that these macros are used to extract big-endian
integral values.
2017-11-18 13:56:40 +01:00
Francois-Xavier Le Bail
b38f324af9 Add a summary comment in all other printers
Moreover:
Remove some redundant comments
Update some summary comments
Update the specification URL for ATA over Ethernet (AoE) protocol
2016-08-15 22:42:38 +02:00
Francois-Xavier Le Bail
436ced3bd8 Change istr[] (for invalid string) to be global 2016-01-28 14:24:19 +01:00
Francois-Xavier Le Bail
99c91c3aec Rename 'tcpdump-stdinc.h' to 'netdissect-stdinc.h'
Get the full log via: git log --follow netdissect-stdinc.h
2015-09-10 08:50:40 +02:00
Francois-Xavier Le Bail
3fb4560e1e Rename cstr[] to istr[] like invalid string
Moreover:
Hamonise the output for error messages
Add istr[] in print-babel.c
2015-09-06 20:47:42 +02:00
Francois-Xavier Le Bail
7ea344d76a Use the word 'invalid' for 'malformed' or 'corrupted' packets
An invalid packet could be:
1) built malformed originally by the sender or a fuzz tester,
2) became corrupted in transit.
2015-09-06 13:44:54 +02:00
Francois-Xavier Le Bail
c1c3c77463 Printers must include 'netdissect.h', not 'interface.h' 2015-09-05 23:35:58 +02:00
Denis Ovsienko
38700c7f24 dismiss NETDISSECT_REWORKED macro
The purpose of this macro was to enable the file-by-file switch to NDO,
after which only tcpdump.c had a use of it and the definitions guarded
by it. Update tcpdump.c not to require them any more and dismiss the
unused definitions.
2015-03-22 10:06:15 +00:00
Denis Ovsienko
60a835d80f clean K&R style up in function declarations a bit
The function body should have its opening brace on the next line.
2015-03-05 10:35:03 +00:00
Denis Ovsienko
94b4c01e1d OpenFlow: add vendor name printing
The new function goes into print-openflow.c as vendor name decoding is
the same in all versions of OpenFlow (although in 1.0 it is "vendor"
and in subsequent versions it is "experimenter"). The mapping is from:

https://rs.opennetworking.org/wiki/display/PUBLIC/ONF+Registry
2014-12-13 18:06:04 +00:00
Denis Ovsienko
5663cdab5e NDOize OpenFlow, IEEE slow and telnet decoders 2014-03-17 19:18:47 +04:00
Denis Ovsienko
d8acd8f5d0 make consistent use of the "tstr" idiom
For each decoder that has more than one instance of truncation signaling
and prints the same string in each instance make sure that the string is
declared as "static const char tstr[]" right after the initial includes
block. Where necessary, replace fputs(s, stdout) with equivalent
printf("%s", s).
2013-12-26 18:19:50 +04:00
Guy Harris
a6c16ed8ab Fix build issues with the OpenFlow printer on some systems.
Don't assume we have <stdint.h>.  Instead, use the AC_TYPE_ macros to
ensure we have the C99 intN_t and uintN_t types; we already include
<inttypes.h> in tcpdump-stdinc.h iff we have it.

Get rid of the structure declarations in openflow-1.0.h, as they have
zero-length arrays (not supported by all the compilers people might be
using) and as

	1) they're only used in sizeof()

and

	2) after each one there's an assertion to check that sizeof()
returns a specific numerical value

so, instead, just #define various _LEN items to those numerical values
and use them.

Add an openflow.h header with a #define for the length of the basic
header, and move the declaration of of10_header_body_print() there.
2013-06-23 14:03:38 -07:00
Denis Ovsienko
fd35562d7e add OpenFlow 1.0 decoder (no SSL)
The new file openflow-1.0.h is a verbatim copy of the file openflow.h
from the openflow-1.0.0.tar.gz distribution. The new file
print-openflow-1.0.c contains a set of functions for OpenFlow 1.0 (wire
protocol 0x01) decoding. Of these functions only
of10_header_body_print() is exported and used by the minimal OpenFlow
decoder.

It is intended that future (1.1, 1.2, 1.3.0) OpenFlow version decoders
are implemented the same way (in modules of their own), since different
versions of OpenFlow specification reuse the same symbols for different
numeric values. This way, print-openflow-1.1.c would include
openflow-1.1.h and so on.

The new test case "of10_p3295-vv" was produced using a Pica8 P-3295
switch and Trema controller running a purpose-built sample application.
2013-05-29 13:03:23 +04:00
Denis Ovsienko
ceeea95918 add minimal OpenFlow decoding framework
This change registers OpenFlow TCP port number and adds processing of
respective packets with openflow_print(), a new function that
understands the minimal OpenFlow header format and can iterate over
messages within a snapshot that starts with the header.
2013-05-29 13:03:23 +04:00