]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-dsa.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / print-dsa.c
index 3d142b28faf38c58d3fbb0bc5aad2127fa79b4fb..42d59461fd4856cdf4dad7f46964985c0f129af9 100644 (file)
@@ -21,9 +21,7 @@
 
 /* \summary: Marvell (Ethertype) Distributed Switch Architecture printer */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#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   |
 #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);
 }