2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 #include <tcpdump-stdinc.h>
28 #include "interface.h"
30 #include "ethertype.h"
31 #include "extract.h" /* must come after interface.h */
33 static const char tstr
[] = "[|MEDSA]";
36 * Marvell Extended Distributed Switch Archiecture.
38 * A Marvell propriatary header used for passing packets to/from
39 * specific ports of a switch. There is no open specification of this
40 * header, but is documented in the Marvell Switch data sheets. For
43 * https://lwn.net/Articles/302333/
50 /* Bytes 0 and 1 are reserved and should contain 0 */
51 #define TAG(medsa) (medsa->bytes[2] >> 6)
53 #define TAG_FROM_CPU 1
55 #define SRC_TAG(medsa) ((medsa->bytes[2] >> 5) & 0x01)
56 #define SRC_DEV(medsa) (medsa->bytes[2] & 0x1f)
57 #define SRC_PORT(medsa) ((medsa->bytes[3] >> 3) & 0x01f)
58 #define TRUNK(medsa) ((medsa->bytes[3] >> 2) & 0x01)
59 #define CODE(medsa) ((medsa->bytes[3] & 0x06) | \
60 ((medsa->bytes[4] >> 4) & 0x01))
62 #define CODE_IGMP_MLD 2
63 #define CODE_ARP_MIRROR 4
64 #define CFI(medsa) (medsa->bytes[3] & 0x01)
65 #define PRI(medsa) (medsa->bytes[4] >> 5)
66 #define VID(medsa) (((u_short)(medsa->bytes[4] & 0xf) << 8 | \
69 static const struct tok tag_values
[] = {
70 { TAG_TO_CPU
, "To_CPU" },
71 { TAG_FROM_CPU
, "From_CPU" },
72 { TAG_FORWARD
, "Forward" },
76 static const struct tok code_values
[] = {
77 { CODE_BDPU
, "BDPU" },
78 { CODE_IGMP_MLD
, "IGMP/MLD" },
79 { CODE_ARP_MIRROR
, "APR_Mirror" },
84 medsa_print_full(netdissect_options
*ndo
,
85 const struct medsa_pkthdr
*medsa
,
88 u_char tag
= TAG(medsa
);
91 tok2str(tag_values
, "Unknown (%u)", tag
)));
95 ND_PRINT((ndo
, ", %stagged", SRC_TAG(medsa
) ? "" : "un"));
96 ND_PRINT((ndo
, ", dev.port:vlan %d.%d:%d",
97 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
)));
99 ND_PRINT((ndo
, ", %s",
100 tok2str(code_values
, "Unknown (%u)", CODE(medsa
))));
102 ND_PRINT((ndo
, ", CFI"));
104 ND_PRINT((ndo
, ", pri %d: ", PRI(medsa
)));
107 ND_PRINT((ndo
, ", %stagged", SRC_TAG(medsa
) ? "" : "un"));
108 ND_PRINT((ndo
, ", dev.port:vlan %d.%d:%d",
109 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
)));
112 ND_PRINT((ndo
, ", CFI"));
114 ND_PRINT((ndo
, ", pri %d: ", PRI(medsa
)));
117 ND_PRINT((ndo
, ", %stagged", SRC_TAG(medsa
) ? "" : "un"));
119 ND_PRINT((ndo
, ", dev.trunk:vlan %d.%d:%d",
120 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
)));
122 ND_PRINT((ndo
, ", dev.port:vlan %d.%d:%d",
123 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
)));
126 ND_PRINT((ndo
, ", CFI"));
128 ND_PRINT((ndo
, ", pri %d: ", PRI(medsa
)));
131 ND_DEFAULTPRINT((const u_char
*)medsa
, caplen
);
137 medsa_print(netdissect_options
*ndo
,
138 const u_char
*bp
, u_int length
, u_int caplen
)
140 register const struct ether_header
*ep
;
141 const struct medsa_pkthdr
*medsa
;
144 medsa
= (const struct medsa_pkthdr
*)bp
;
145 ep
= (const struct ether_header
*)(bp
- sizeof(*ep
));
149 ND_PRINT((ndo
, "MEDSA %d.%d:%d: ",
150 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
)));
152 medsa_print_full(ndo
, medsa
, caplen
);
158 ether_type
= EXTRACT_16BITS(&medsa
->ether_type
);
159 if (ether_type
<= ETHERMTU
) {
160 /* Try to print the LLC-layer header & higher layers */
161 if (llc_print(ndo
, bp
, length
, caplen
, ESRC(ep
), EDST(ep
)) < 0) {
162 /* packet type not known, print raw packet */
163 if (!ndo
->ndo_suppress_default_print
)
164 ND_DEFAULTPRINT(bp
, caplen
);
168 ND_PRINT((ndo
, "ethertype %s (0x%04x) ",
169 tok2str(ethertype_values
, "Unknown",
173 if (ethertype_print(ndo
, ether_type
, bp
, length
, caplen
) == 0) {
174 /* ether_type not known, print raw packet */
176 ND_PRINT((ndo
, "ethertype %s (0x%04x) ",
177 tok2str(ethertype_values
, "Unknown",
181 if (!ndo
->ndo_suppress_default_print
)
182 ND_DEFAULTPRINT(bp
, caplen
);
187 ND_PRINT((ndo
, "%s", tstr
));