From 2c7f188ff13d932e408da5ff5324aeebe71486cc Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Wed, 30 Sep 2020 14:41:45 +0100 Subject: [PATCH] OpenFlow 1.3: Get OFPT_HELLO right. Decode the optional trailing data and update two tests. --- openflow.h | 7 +++ print-openflow-1.3.c | 87 +++++++++++++++++++++++++++++++++++++- print-openflow.c | 7 --- tests/of13_ericsson-v.out | 2 +- tests/of13_ericsson-vv.out | 3 +- 5 files changed, 95 insertions(+), 11 deletions(-) diff --git a/openflow.h b/openflow.h index 1234da5d..c9c04c36 100644 --- a/openflow.h +++ b/openflow.h @@ -41,6 +41,13 @@ len -= (n); \ } +#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 + #define OF_HEADER_FIXLEN 8U #define ONF_EXP_ONF 0x4f4e4600 diff --git a/print-openflow-1.3.c b/print-openflow-1.3.c index 9832373d..b4f7e354 100644 --- a/print-openflow-1.3.c +++ b/print-openflow-1.3.c @@ -108,6 +108,12 @@ static const struct tok ofpt_str[] = { { 0, NULL } }; +#define OFPHET_VERSIONBITMAP 1U +static const struct tok ofphet_str[] = { + { OFPHET_VERSIONBITMAP, "VERSIONBITMAP" }, + { 0, NULL } +}; + #define OFPP_MAX 0xffffff00U #define OFPP_IN_PORT 0xfffffff8U #define OFPP_TABLE 0xfffffff9U @@ -130,6 +136,24 @@ static const struct tok ofpp_str[] = { { 0, NULL } }; +#define OF_BIT_VER_1_0 (1U << (OF_VER_1_0 - 1)) +#define OF_BIT_VER_1_1 (1U << (OF_VER_1_1 - 1)) +#define OF_BIT_VER_1_2 (1U << (OF_VER_1_2 - 1)) +#define OF_BIT_VER_1_3 (1U << (OF_VER_1_3 - 1)) +#define OF_BIT_VER_1_4 (1U << (OF_VER_1_4 - 1)) +#define OF_BIT_VER_1_5 (1U << (OF_VER_1_5 - 1)) +static const struct tok ofverbm_str[] = { + { OF_BIT_VER_1_0, "1.0" }, + { OF_BIT_VER_1_1, "1.1" }, + { OF_BIT_VER_1_2, "1.2" }, + { OF_BIT_VER_1_3, "1.3" }, + { OF_BIT_VER_1_4, "1.4" }, + { OF_BIT_VER_1_5, "1.5" }, + { 0, NULL } +}; +#define OF_BIT_VER_U (~(OF_BIT_VER_1_0 | OF_BIT_VER_1_1 | OF_BIT_VER_1_2 | \ + OF_BIT_VER_1_3 | OF_BIT_VER_1_4 | OF_BIT_VER_1_5)) + #define OFPET_HELLO_FAILED 0U #define OFPET_BAD_REQUEST 1U #define OFPET_BAD_ACTION 2U @@ -448,6 +472,7 @@ static const struct tok ofptffc_str[] = { }; /* lengths (fixed or minimal) of particular protocol structures */ +#define OF_HELLO_ELEM_MINSIZE 4U #define OF_ERROR_MSG_MINLEN 12U #define OF_QUEUE_GET_CONFIG_REQUEST_FIXLEN 16U @@ -458,6 +483,60 @@ of13_msgtype_str(const uint8_t type) return tok2str(ofpt_str, "invalid (0x%02x)", type); } +/* [OF13] Section 7.5.1 */ +static void +of13_hello_elements_print(netdissect_options *ndo, + const u_char *cp, u_int len) +{ + while (len) { + uint16_t type, bmlen; + + if (len < OF_HELLO_ELEM_MINSIZE) + goto invalid; + /* type */ + type = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT("\n\t type %s", + tok2str(ofphet_str, "unknown (0x%04x)", type)); + /* length */ + bmlen = GET_BE_U_2(cp); + OF_FWD(2); + ND_PRINT(", length %u", bmlen); + /* cp is OF_HELLO_ELEM_MINSIZE bytes in */ + if (bmlen < OF_HELLO_ELEM_MINSIZE || + bmlen > OF_HELLO_ELEM_MINSIZE + len) + goto invalid; + switch (type) { + case OFPHET_VERSIONBITMAP: + /* + * The specification obviously overprovisions the space + * for version bitmaps in this element ("ofp versions + * 32 to 63 are encoded in the second bitmap and so + * on"). Keep this code simple for now and recognize + * only a single bitmap with no padding. + */ + if (bmlen == OF_HELLO_ELEM_MINSIZE + 4) { + uint32_t bitmap = GET_BE_U_4(cp); + ND_PRINT(", bitmap 0x%08x", bitmap); + of_bitmap_print(ndo, ofverbm_str, bitmap, + OF_BIT_VER_U); + } else { + ND_PRINT(" (bogus)"); + ND_TCHECK_LEN(cp, bmlen - OF_HELLO_ELEM_MINSIZE); + } + break; + default: + ND_TCHECK_LEN(cp, bmlen - OF_HELLO_ELEM_MINSIZE); + } + OF_FWD(bmlen - OF_HELLO_ELEM_MINSIZE); + } + return; + +invalid: + nd_print_invalid(ndo); + ND_TCHECK_LEN(cp, len); +} + /* [OF13] Section A.4.4 */ static void of13_error_print(netdissect_options *ndo, @@ -528,7 +607,6 @@ of13_message_print(netdissect_options *ndo, return; /* OpenFlow header and variable-size data. */ - case OFPT_HELLO: /* [OF13] Section A.5.1 */ case OFPT_ECHO_REQUEST: /* [OF13] Section A.5.2 */ case OFPT_ECHO_REPLY: /* [OF13] Section A.5.3 */ if (ndo->ndo_vflag < 1) @@ -536,6 +614,13 @@ of13_message_print(netdissect_options *ndo, of_data_print(ndo, cp, len); return; + /* OpenFlow header and n * variable-size data units. */ + case OFPT_HELLO: /* [OF13] Section A.5.1 */ + if (ndo->ndo_vflag < 1) + break; + of13_hello_elements_print(ndo, cp, len); + return; + /* OpenFlow header, fixed-size message body and variable-size data. */ case OFPT_ERROR: if (len < OF_ERROR_MSG_MINLEN - OF_HEADER_FIXLEN) diff --git a/print-openflow.c b/print-openflow.c index 699ebe88..73c783d3 100644 --- a/print-openflow.c +++ b/print-openflow.c @@ -45,13 +45,6 @@ #include "oui.h" -#define OF_VER_1_0 0x01 -#define OF_VER_1_1 0x02 -#define OF_VER_1_2 0x03 -#define OF_VER_1_3 0x04 -#define OF_VER_1_4 0x05 -#define OF_VER_1_5 0x06 - static const struct tok ofver_str[] = { { OF_VER_1_0, "1.0" }, { OF_VER_1_1, "1.1" }, diff --git a/tests/of13_ericsson-v.out b/tests/of13_ericsson-v.out index 115598ad..27e70228 100644 --- a/tests/of13_ericsson-v.out +++ b/tests/of13_ericsson-v.out @@ -85,7 +85,7 @@ 33 20:23:03.674363 IP (tos 0x0, ttl 64, id 5825, offset 0, flags [DF], proto TCP (6), length 68) 127.0.0.1.6633 > 127.0.0.1.37123: Flags [P.], cksum 0xfe38 (incorrect -> 0xc315), seq 16:32, ack 9, win 94, options [nop,nop,TS val 683431 ecr 683336], length 16: OpenFlow version 1.3, type HELLO, length 16, xid 0x00000161 - data (8 octets) + type VERSIONBITMAP, length 8, bitmap 0x00000015 (1.0, 1.2, 1.4) 34 20:23:03.711246 IP (tos 0x0, ttl 64, id 544, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.37123 > 127.0.0.1.6633: Flags [.], cksum 0xfe28 (incorrect -> 0xc84b), ack 32, win 86, options [nop,nop,TS val 683441 ecr 683431], length 0 35 09:18:28.508689 IP (tos 0x0, ttl 64, id 8726, offset 0, flags [DF], proto TCP (6), length 60) diff --git a/tests/of13_ericsson-vv.out b/tests/of13_ericsson-vv.out index c6a6873c..6bc54a93 100644 --- a/tests/of13_ericsson-vv.out +++ b/tests/of13_ericsson-vv.out @@ -122,8 +122,7 @@ 33 20:23:03.674363 IP (tos 0x0, ttl 64, id 5825, offset 0, flags [DF], proto TCP (6), length 68) 127.0.0.1.6633 > 127.0.0.1.37123: Flags [P.], cksum 0xfe38 (incorrect -> 0xc315), seq 16:32, ack 9, win 94, options [nop,nop,TS val 683431 ecr 683336], length 16: OpenFlow version 1.3, type HELLO, length 16, xid 0x00000161 - data (8 octets) - 0x0000: 0001 0008 0000 0015 ........ + type VERSIONBITMAP, length 8, bitmap 0x00000015 (1.0, 1.2, 1.4) 34 20:23:03.711246 IP (tos 0x0, ttl 64, id 544, offset 0, flags [DF], proto TCP (6), length 52) 127.0.0.1.37123 > 127.0.0.1.6633: Flags [.], cksum 0xfe28 (incorrect -> 0xc84b), seq 9, ack 32, win 86, options [nop,nop,TS val 683441 ecr 683431], length 0 35 09:18:28.508689 IP (tos 0x0, ttl 64, id 8726, offset 0, flags [DF], proto TCP (6), length 60)