From 5f4b040e9186a640061d4bbd7371ceb91ed1476e Mon Sep 17 00:00:00 2001 From: corubba Date: Mon, 20 Oct 2025 01:24:34 +0200 Subject: [PATCH 1/2] slow: Move version handling to subtype functions Limit the access of the `slow_print` function to the subtype field, which is the only field the slow protocol defines. This means moving the version stuff for LACP and Marker to their own dedicated functions. The output is kept mostly the same as before, which is why there is no change to the test data. The only deliberate change is replacing the "version not supported" message with printing the packet data verbatim. --- print-slow.c | 183 +++++++++++++++++++++++++++++---------------------- 1 file changed, 105 insertions(+), 78 deletions(-) diff --git a/print-slow.c b/print-slow.c index 6ce3e806d..99f300866 100644 --- a/print-slow.c +++ b/print-slow.c @@ -39,14 +39,6 @@ #define LACP_VERSION 1 #define MARKER_VERSION 1 -static const struct tok slow_proto_values[] = { - { SLOW_PROTO_LACP, "LACP" }, - { SLOW_PROTO_MARKER, "MARKER" }, - { SLOW_PROTO_OAM, "OAM" }, - { SLOW_PROTO_OSSP, "OSSP" }, - { 0, NULL} -}; - static const struct tok slow_oam_flag_values[] = { { 0x0001, "Link Fault" }, { 0x0002, "Dying Gasp" }, @@ -239,104 +231,49 @@ struct lacp_marker_tlv_terminator_t { nd_byte pad[50]; }; -static void slow_marker_lacp_print(netdissect_options *, const u_char *, u_int, u_int); +static void slow_lacp_print(netdissect_options *, const u_char *, u_int); +static void slow_marker_print(netdissect_options *, const u_char *, u_int); static void slow_oam_print(netdissect_options *, const u_char *, u_int); static void slow_ossp_print(netdissect_options *, const u_char *, u_int); +/* + * Print Slow Protocol. (802.3 Annex 57A) + */ void slow_print(netdissect_options *ndo, const u_char *pptr, u_int len) { - int print_version; u_int subtype; ndo->ndo_protocol = "slow"; + if (len < 1) goto tooshort; subtype = GET_U_1(pptr); + len -= 1; + pptr += 1; - /* - * Sanity checking of the header. - */ switch (subtype) { case SLOW_PROTO_LACP: - if (len < 2) - goto tooshort; - if (GET_U_1(pptr + 1) != LACP_VERSION) { - ND_PRINT("LACP version %u packet not supported", - GET_U_1(pptr + 1)); - return; - } - print_version = 1; + slow_lacp_print(ndo, pptr, len); break; case SLOW_PROTO_MARKER: - if (len < 2) - goto tooshort; - if (GET_U_1(pptr + 1) != MARKER_VERSION) { - ND_PRINT("MARKER version %u packet not supported", - GET_U_1(pptr + 1)); - return; - } - print_version = 1; + slow_marker_print(ndo, pptr, len); break; case SLOW_PROTO_OAM: - case SLOW_PROTO_OSSP: - print_version = 0; - break; - - default: - /* print basic information and exit */ - print_version = -1; - break; - } - - if (print_version == 1) { - ND_PRINT("%sv%u, length %u", - tok2str(slow_proto_values, "unknown (%u)", subtype), - GET_U_1((pptr + 1)), - len); - } else { - /* some slow protos don't have a version number in the header */ - ND_PRINT("%s, length %u", - tok2str(slow_proto_values, "unknown (%u)", subtype), - len); - } - - /* unrecognized subtype */ - if (print_version == -1) { - print_unknown_data(ndo, pptr, "\n\t", len); - return; - } - - if (!ndo->ndo_vflag) - return; - - switch (subtype) { - default: /* should not happen */ + slow_oam_print(ndo, pptr, len); break; case SLOW_PROTO_OSSP: - /* skip subtype */ - len -= 1; - pptr += 1; slow_ossp_print(ndo, pptr, len); break; - case SLOW_PROTO_OAM: - /* skip subtype */ - len -= 1; - pptr += 1; - slow_oam_print(ndo, pptr, len); - break; - - case SLOW_PROTO_LACP: /* LACP and MARKER share the same semantics */ - case SLOW_PROTO_MARKER: - /* skip subtype and version */ - len -= 2; - pptr += 2; - slow_marker_lacp_print(ndo, pptr, len, subtype); + default: + ND_PRINT("unknown (%u), length %u", subtype, len + 1); + if (ndo->ndo_vflag) + print_unknown_data(ndo, pptr, "\n\t", len); break; } return; @@ -348,6 +285,9 @@ slow_print(netdissect_options *ndo, ND_PRINT("\n\t\t packet is too short"); } +/* + * Common tlv logic for LACPv1 and Marker. + */ static void slow_marker_lacp_print(netdissect_options *ndo, const u_char *tptr, u_int tlen, @@ -485,6 +425,83 @@ slow_marker_lacp_print(netdissect_options *ndo, ND_PRINT("\n\t\t packet is too short"); } +/* + * Print Link Aggregation Control Protocol. (802.3ad / 802.1AX) + */ +static void +slow_lacp_print(netdissect_options *ndo, + const u_char *tptr, u_int tlen) +{ + u_int version; + + if (tlen < 1) + goto tooshort; + + version = GET_U_1(tptr); + tlen -= 1; + tptr += 1; + + ND_PRINT("LACPv%u, length %u", version, tlen + 2); + + if (!ndo->ndo_vflag) + return; + + switch (version) { + case LACP_VERSION: + slow_marker_lacp_print(ndo, tptr, tlen, SLOW_PROTO_LACP); + break; + + /* TODO LACPv2 */ + + default: + print_unknown_data(ndo, tptr, "\n\t", tlen); + break; + } + return; + +tooshort: + ND_PRINT("\n\t\t packet is too short"); +} + +/* + * Print Marker protocol. (802.3ad / 802.1ax) + */ +static void +slow_marker_print(netdissect_options *ndo, + const u_char *tptr, u_int tlen) +{ + u_int version; + + if (tlen < 1) + goto tooshort; + + version = GET_U_1(tptr); + tlen -= 1; + tptr += 1; + + ND_PRINT("MARKERv%u, length %u", version, tlen + 2); + + if (!ndo->ndo_vflag) + return; + + switch (version) { + case MARKER_VERSION: + slow_marker_lacp_print(ndo, tptr, tlen, SLOW_PROTO_MARKER); + break; + + default: + print_unknown_data(ndo, tptr, "\n\t", tlen); + break; + } + return; + +tooshort: + ND_PRINT("\n\t\t packet is too short"); +} + +/* + * Print Operations, Administration, and Maintenance. (802.3) + */ static void slow_oam_print(netdissect_options *ndo, const u_char *tptr, u_int tlen) @@ -518,6 +535,11 @@ slow_oam_print(netdissect_options *ndo, const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl; } tlv; + ND_PRINT("OAM, length %u", tlen + 1); + + if (!ndo->ndo_vflag) + return; + ptr.slow_oam_common_header = (const struct slow_oam_common_header_t *)tptr; if (tlen < sizeof(*ptr.slow_oam_common_header)) goto tooshort; @@ -754,6 +776,11 @@ slow_ossp_print(netdissect_options *ndo, { uint32_t oui; + ND_PRINT("OSSP, length %u", tlen + 1); + + if (!ndo->ndo_vflag) + return; + ND_ICHECKMSG_U("length", tlen, <, 3); oui = GET_BE_U_3(tptr); From 15ada8db398b6d9654a1d44c903f6f68e3ca04ee Mon Sep 17 00:00:00 2001 From: corubba Date: Mon, 20 Oct 2025 22:44:23 +0200 Subject: [PATCH 2/2] fixup! slow: Move version handling to subtype functions Consolidate the subtype-functions into the common function. --- print-slow.c | 108 ++++++++++++--------------------------------------- 1 file changed, 25 insertions(+), 83 deletions(-) diff --git a/print-slow.c b/print-slow.c index 99f300866..466314e66 100644 --- a/print-slow.c +++ b/print-slow.c @@ -231,8 +231,7 @@ struct lacp_marker_tlv_terminator_t { nd_byte pad[50]; }; -static void slow_lacp_print(netdissect_options *, const u_char *, u_int); -static void slow_marker_print(netdissect_options *, const u_char *, u_int); +static void slow_marker_lacp_print(netdissect_options *, const u_char *, u_int, u_int); static void slow_oam_print(netdissect_options *, const u_char *, u_int); static void slow_ossp_print(netdissect_options *, const u_char *, u_int); @@ -254,12 +253,9 @@ slow_print(netdissect_options *ndo, pptr += 1; switch (subtype) { - case SLOW_PROTO_LACP: - slow_lacp_print(ndo, pptr, len); - break; - + case SLOW_PROTO_LACP: /* fall through */ case SLOW_PROTO_MARKER: - slow_marker_print(ndo, pptr, len); + slow_marker_lacp_print(ndo, pptr, len, subtype); break; case SLOW_PROTO_OAM: @@ -286,7 +282,7 @@ slow_print(netdissect_options *ndo, } /* - * Common tlv logic for LACPv1 and Marker. + * Print Link Aggregation Control Protocol and Marker protocol. (802.3ad / 802.1ax) */ static void slow_marker_lacp_print(netdissect_options *ndo, @@ -295,7 +291,7 @@ slow_marker_lacp_print(netdissect_options *ndo, { const struct tlv_header_t *tlv_header; const u_char *tlv_tptr; - u_int tlv_type, tlv_len, tlv_tlen; + u_int tlv_type, tlv_len, tlv_tlen, version; union { const struct lacp_marker_tlv_terminator_t *lacp_marker_tlv_terminator; @@ -304,6 +300,26 @@ slow_marker_lacp_print(netdissect_options *ndo, const struct marker_tlv_marker_info_t *marker_tlv_marker_info; } tlv_ptr; + if (tlen < 1) + goto tooshort; + + version = GET_U_1(tptr); + tlen -= 1; + tptr += 1; + + ND_PRINT("%sv%u, length %u", + proto_subtype == SLOW_PROTO_LACP ? "LACP" : "MARKER", + version, tlen + 2); + + if (!ndo->ndo_vflag) + return; + + if ((proto_subtype == SLOW_PROTO_LACP && version != LACP_VERSION) + || (proto_subtype == SLOW_PROTO_MARKER && version != MARKER_VERSION)) { + print_unknown_data(ndo, tptr, "\n\t", tlen); + return; + } + while(tlen != 0) { /* is the packet big enough to include the tlv header ? */ if (tlen < sizeof(struct tlv_header_t)) @@ -425,80 +441,6 @@ slow_marker_lacp_print(netdissect_options *ndo, ND_PRINT("\n\t\t packet is too short"); } -/* - * Print Link Aggregation Control Protocol. (802.3ad / 802.1AX) - */ -static void -slow_lacp_print(netdissect_options *ndo, - const u_char *tptr, u_int tlen) -{ - u_int version; - - if (tlen < 1) - goto tooshort; - - version = GET_U_1(tptr); - tlen -= 1; - tptr += 1; - - ND_PRINT("LACPv%u, length %u", version, tlen + 2); - - if (!ndo->ndo_vflag) - return; - - switch (version) { - case LACP_VERSION: - slow_marker_lacp_print(ndo, tptr, tlen, SLOW_PROTO_LACP); - break; - - /* TODO LACPv2 */ - - default: - print_unknown_data(ndo, tptr, "\n\t", tlen); - break; - } - return; - -tooshort: - ND_PRINT("\n\t\t packet is too short"); -} - -/* - * Print Marker protocol. (802.3ad / 802.1ax) - */ -static void -slow_marker_print(netdissect_options *ndo, - const u_char *tptr, u_int tlen) -{ - u_int version; - - if (tlen < 1) - goto tooshort; - - version = GET_U_1(tptr); - tlen -= 1; - tptr += 1; - - ND_PRINT("MARKERv%u, length %u", version, tlen + 2); - - if (!ndo->ndo_vflag) - return; - - switch (version) { - case MARKER_VERSION: - slow_marker_lacp_print(ndo, tptr, tlen, SLOW_PROTO_MARKER); - break; - - default: - print_unknown_data(ndo, tptr, "\n\t", tlen); - break; - } - return; - -tooshort: - ND_PRINT("\n\t\t packet is too short"); -} - /* * Print Operations, Administration, and Maintenance. (802.3) */