X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/59c57f40fe6548ba92d46f02b2a4122a704f8691..HEAD:/print-dsa.c?ds=inline diff --git a/print-dsa.c b/print-dsa.c index 3d142b28..42d59461 100644 --- a/print-dsa.c +++ b/print-dsa.c @@ -21,9 +21,7 @@ /* \summary: Marvell (Ethertype) Distributed Switch Architecture printer */ -#ifdef HAVE_CONFIG_H #include -#endif #include "netdissect-stdinc.h" @@ -35,7 +33,7 @@ /* * Format of (Ethertyped or not) DSA tagged frames: * - * 7 6 5 4 3 2 1 0 + * 7 6 5 4 3 2 1 0 * . . . . . . . . . * 0 +---+---+---+---+---+---+---+---+ * | Ether Destination Address | @@ -83,11 +81,10 @@ #define DSA_RX_SNIFF(tag) TOK(tag, 1, 0x04, 2) #define DSA_CFI(tag) TOK(tag, 1, 0x01, 0) #define DSA_PRI(tag) TOK(tag, 2, 0xe0, 5) -#define DSA_VID(tag) ((u_short)((TOK(tag, 2, 0xe0, 5) << 8) | (TOK(tag, 3, 0xff, 0)))) +#define DSA_VID(tag) ((u_short)((TOK(tag, 2, 0x0f, 0) << 8) | (TOK(tag, 3, 0xff, 0)))) #define DSA_CODE(tag) ((TOK(tag, 1, 0x06, 1) << 1) | TOK(tag, 2, 0x10, 4)) #define EDSA_LEN 8 -#define EDSA_ETYPE(tag) ((u_short)((TOK(tag, 0, 0xff, 0) << 8) | (TOK(tag, 1, 0xff, 0)))) static const struct tok dsa_mode_values[] = { { DSA_MODE_TO_CPU, "To CPU" }, @@ -107,129 +104,114 @@ static const struct tok dsa_code_values[] = { { 0, NULL } }; -static u_int -dsa_if_print_full(netdissect_options *ndo, const struct pcap_pkthdr *h, - const u_char *p, u_int taglen) +static void +tag_common_print(netdissect_options *ndo, const u_char *p) { - const u_char *edsa, *dsa; - int eflag, ret; - - if (h->caplen < 12 + taglen) { - nd_print_trunc(ndo); - return (h->caplen); - } - - if (h->len < 12 + taglen) { - nd_print_trunc(ndo); - return (h->len); - } - - if (taglen == EDSA_LEN) { - edsa = p + 12; - dsa = edsa + 4; - } else { - edsa = NULL; - dsa = p + 12; - } - if (ndo->ndo_eflag) { - ND_PRINT("%s > %s, ", - etheraddr_string(ndo, p + 6), - etheraddr_string(ndo, p)); - - if (edsa) { - ND_PRINT("Marvell EDSA ethertype 0x%04x (%s), ", EDSA_ETYPE(edsa), - tok2str(ethertype_values, "unregistered", EDSA_ETYPE(edsa))); - ND_PRINT("rsvd %u %u, ", edsa[2], edsa[3]); - } else { - ND_PRINT("Marvell DSA "); - } + ND_PRINT("mode %s, ", tok2str(dsa_mode_values, "unknown", DSA_MODE(p))); - ND_PRINT("mode %s, ", tok2str(dsa_mode_values, "unknown", DSA_MODE(dsa))); - - switch (DSA_MODE(dsa)) { + switch (DSA_MODE(p)) { case DSA_MODE_FORWARD: - ND_PRINT("dev %u, %s %u, ", DSA_DEV(dsa), - DSA_TRUNK(dsa) ? "trunk" : "port", DSA_PORT(dsa)); + ND_PRINT("dev %u, %s %u, ", DSA_DEV(p), + DSA_TRUNK(p) ? "trunk" : "port", DSA_PORT(p)); break; case DSA_MODE_FROM_CPU: ND_PRINT("target dev %u, port %u, ", - DSA_DEV(dsa), DSA_PORT(dsa)); + DSA_DEV(p), DSA_PORT(p)); break; case DSA_MODE_TO_CPU: ND_PRINT("source dev %u, port %u, ", - DSA_DEV(dsa), DSA_PORT(dsa)); + DSA_DEV(p), DSA_PORT(p)); ND_PRINT("code %s, ", - tok2str(dsa_code_values, "reserved", DSA_CODE(dsa))); + tok2str(dsa_code_values, "reserved", DSA_CODE(p))); break; case DSA_MODE_TO_SNIFFER: ND_PRINT("source dev %u, port %u, ", - DSA_DEV(dsa), DSA_PORT(dsa)); + DSA_DEV(p), DSA_PORT(p)); ND_PRINT("%s sniff, ", - DSA_RX_SNIFF(dsa) ? "ingress" : "egress"); + DSA_RX_SNIFF(p) ? "ingress" : "egress"); break; default: break; } - ND_PRINT("%s, ", DSA_TAGGED(dsa) ? "tagged" : "untagged"); - ND_PRINT("%s", DSA_CFI(dsa) ? "CFI, " : ""); - ND_PRINT("VID %u, ", DSA_VID(dsa)); - ND_PRINT("FPri %u, ", DSA_PRI(dsa)); + ND_PRINT("%s, ", DSA_TAGGED(p) ? "tagged" : "untagged"); + ND_PRINT("%s", DSA_CFI(p) ? "CFI, " : ""); + ND_PRINT("VID %u, ", DSA_VID(p)); + ND_PRINT("FPri %u, ", DSA_PRI(p)); } else { - if (edsa) { - ND_PRINT("EDSA 0x%04x, ", EDSA_ETYPE(edsa)); - } else { - ND_PRINT("DSA "); - } - - switch (DSA_MODE(dsa)) { + switch (DSA_MODE(p)) { case DSA_MODE_FORWARD: ND_PRINT("Forward %s %u.%u, ", - DSA_TRUNK(dsa) ? "trunk" : "port", - DSA_DEV(dsa), DSA_PORT(dsa)); + DSA_TRUNK(p) ? "trunk" : "port", + DSA_DEV(p), DSA_PORT(p)); break; case DSA_MODE_FROM_CPU: ND_PRINT("CPU > port %u.%u, ", - DSA_DEV(dsa), DSA_PORT(dsa)); + DSA_DEV(p), DSA_PORT(p)); break; case DSA_MODE_TO_CPU: ND_PRINT("port %u.%u > CPU, ", - DSA_DEV(dsa), DSA_PORT(dsa)); + DSA_DEV(p), DSA_PORT(p)); break; case DSA_MODE_TO_SNIFFER: ND_PRINT("port %u.%u > %s Sniffer, ", - DSA_DEV(dsa), DSA_PORT(dsa), - DSA_RX_SNIFF(dsa) ? "Rx" : "Tx"); + DSA_DEV(p), DSA_PORT(p), + DSA_RX_SNIFF(p) ? "Rx" : "Tx"); break; default: break; } - ND_PRINT("VLAN %u%c, ", DSA_VID(dsa), DSA_TAGGED(dsa) ? 't' : 'u'); + ND_PRINT("VLAN %u%c, ", DSA_VID(p), DSA_TAGGED(p) ? 't' : 'u'); } +} + +static void +dsa_tag_print(netdissect_options *ndo, const u_char *bp) +{ + if (ndo->ndo_eflag) + ND_PRINT("Marvell DSA "); + else + ND_PRINT("DSA "); + tag_common_print(ndo, bp); +} - eflag = ndo->ndo_eflag; - ndo->ndo_eflag = 0; - ret = ether_hdr_len_print(ndo, p, h->len, h->caplen, NULL, NULL, - 12 + taglen + 2); - ndo->ndo_eflag = eflag; +static void +edsa_tag_print(netdissect_options *ndo, const u_char *bp) +{ + const u_char *p = bp; + uint16_t edsa_etype; - return ret; + edsa_etype = GET_BE_U_2(p); + if (ndo->ndo_eflag) { + ND_PRINT("Marvell EDSA ethertype 0x%04x (%s), ", edsa_etype, + tok2str(ethertype_values, "Unknown", edsa_etype)); + ND_PRINT("rsvd %u %u, ", GET_U_1(p + 2), GET_U_1(p + 3)); + } else + ND_PRINT("EDSA 0x%04x, ", edsa_etype); + p += 4; + tag_common_print(ndo, p); } -u_int +void dsa_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - ndo->ndo_protocol = "dsa"; + u_int caplen = h->caplen; + u_int length = h->len; - return dsa_if_print_full(ndo, h, p, DSA_LEN); + ndo->ndo_protocol = "dsa"; + ndo->ndo_ll_hdr_len += + ether_switch_tag_print(ndo, p, length, caplen, dsa_tag_print, DSA_LEN); } -u_int +void edsa_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { - ndo->ndo_protocol = "edsa"; + u_int caplen = h->caplen; + u_int length = h->len; - return dsa_if_print_full(ndo, h, p, EDSA_LEN); + ndo->ndo_protocol = "edsa"; + ndo->ndo_ll_hdr_len += + ether_switch_tag_print(ndo, p, length, caplen, edsa_tag_print, EDSA_LEN); }