From 522382afefc85deafe49e0e95eb13e6cfa64e493 Mon Sep 17 00:00:00 2001 From: corubba Date: Mon, 10 Nov 2025 23:53:06 +0100 Subject: [PATCH] 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 | 131 ++++++++++++++++++++------------------------------- 1 file changed, 50 insertions(+), 81 deletions(-) diff --git a/print-slow.c b/print-slow.c index 6ce3e806d..466314e66 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" }, @@ -243,100 +235,41 @@ static void slow_marker_lacp_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; - break; - + case SLOW_PROTO_LACP: /* fall through */ 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_lacp_print(ndo, pptr, len, subtype); 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 +281,9 @@ slow_print(netdissect_options *ndo, ND_PRINT("\n\t\t packet is too short"); } +/* + * Print Link Aggregation Control Protocol and Marker protocol. (802.3ad / 802.1ax) + */ static void slow_marker_lacp_print(netdissect_options *ndo, const u_char *tptr, u_int tlen, @@ -355,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; @@ -364,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)) @@ -485,6 +441,9 @@ slow_marker_lacp_print(netdissect_options *ndo, 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 +477,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 +718,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);