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.
22 /* \summary: Marvell Extended Distributed Switch Architecture (MEDSA) printer */
28 #include "netdissect-stdinc.h"
30 #include "netdissect.h"
31 #include "ethertype.h"
32 #include "addrtoname.h"
37 * Marvell Extended Distributed Switch Archiecture.
39 * A Marvell propriatary header used for passing packets to/from
40 * specific ports of a switch. There is no open specification of this
41 * header, but is documented in the Marvell Switch data sheets. For
44 * https://lwn.net/Articles/302333/
48 nd_uint8_t tag_flags_dev
;
49 nd_uint8_t port_trunc_codehi_cfi
;
50 nd_uint8_t pri_vidhi_codelo
;
52 nd_uint16_t ether_type
;
55 /* Bytes 0 and 1 are reserved and should contain 0 */
56 #define TAG(medsa) (EXTRACT_U_1(medsa->tag_flags_dev) >> 6)
58 #define TAG_FROM_CPU 1
60 #define SRC_TAG(medsa) ((EXTRACT_U_1(medsa->tag_flags_dev) >> 5) & 0x01)
61 #define SRC_DEV(medsa) (EXTRACT_U_1(medsa->tag_flags_dev) & 0x1f)
62 #define SRC_PORT(medsa) ((EXTRACT_U_1(medsa->port_trunc_codehi_cfi) >> 3) & 0x01f)
63 #define TRUNK(medsa) ((EXTRACT_U_1(medsa->port_trunc_codehi_cfi) >> 2) & 0x01)
64 #define CODE(medsa) ((EXTRACT_U_1(medsa->port_trunc_codehi_cfi) & 0x06) | \
65 ((EXTRACT_U_1(medsa->pri_vidhi_codelo) >> 4) & 0x01))
67 #define CODE_IGMP_MLD 2
68 #define CODE_ARP_MIRROR 4
69 #define CFI(medsa) (EXTRACT_U_1(medsa->port_trunc_codehi_cfi) & 0x01)
70 #define PRI(medsa) (EXTRACT_U_1(medsa->pri_vidhi_codelo) >> 5)
71 #define VID(medsa) (((u_short)(EXTRACT_U_1(medsa->pri_vidhi_codelo) & 0xf) << 8 | \
72 EXTRACT_U_1(medsa->vidlo)))
74 static const struct tok tag_values
[] = {
75 { TAG_TO_CPU
, "To_CPU" },
76 { TAG_FROM_CPU
, "From_CPU" },
77 { TAG_FORWARD
, "Forward" },
81 static const struct tok code_values
[] = {
82 { CODE_BDPU
, "BDPU" },
83 { CODE_IGMP_MLD
, "IGMP/MLD" },
84 { CODE_ARP_MIRROR
, "APR_Mirror" },
89 medsa_print_full(netdissect_options
*ndo
,
90 const struct medsa_pkthdr
*medsa
,
93 u_char tag
= TAG(medsa
);
96 tok2str(tag_values
, "Unknown (%u)", tag
));
100 ND_PRINT(", %stagged", SRC_TAG(medsa
) ? "" : "un");
101 ND_PRINT(", dev.port:vlan %u.%u:%u",
102 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
));
105 tok2str(code_values
, "Unknown (%u)", CODE(medsa
)));
109 ND_PRINT(", pri %u: ", PRI(medsa
));
112 ND_PRINT(", %stagged", SRC_TAG(medsa
) ? "" : "un");
113 ND_PRINT(", dev.port:vlan %u.%u:%u",
114 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
));
119 ND_PRINT(", pri %u: ", PRI(medsa
));
122 ND_PRINT(", %stagged", SRC_TAG(medsa
) ? "" : "un");
124 ND_PRINT(", dev.trunk:vlan %u.%u:%u",
125 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
));
127 ND_PRINT(", dev.port:vlan %u.%u:%u",
128 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
));
133 ND_PRINT(", pri %u: ", PRI(medsa
));
136 ND_DEFAULTPRINT((const u_char
*)medsa
, caplen
);
142 medsa_print(netdissect_options
*ndo
,
143 const u_char
*bp
, u_int length
, u_int caplen
,
144 const struct lladdr_info
*src
, const struct lladdr_info
*dst
)
146 const struct medsa_pkthdr
*medsa
;
149 ndo
->ndo_protocol
= "medsa";
150 medsa
= (const struct medsa_pkthdr
*)bp
;
151 ND_TCHECK_SIZE(medsa
);
154 ND_PRINT("MEDSA %u.%u:%u: ",
155 SRC_DEV(medsa
), SRC_PORT(medsa
), VID(medsa
));
157 medsa_print_full(ndo
, medsa
, caplen
);
163 ether_type
= EXTRACT_BE_U_2(medsa
->ether_type
);
164 if (ether_type
<= MAX_ETHERNET_LENGTH_VAL
) {
165 /* Try to print the LLC-layer header & higher layers */
166 if (llc_print(ndo
, bp
, length
, caplen
, src
, dst
) < 0) {
167 /* packet type not known, print raw packet */
168 if (!ndo
->ndo_suppress_default_print
)
169 ND_DEFAULTPRINT(bp
, caplen
);
173 ND_PRINT("ethertype %s (0x%04x) ",
174 tok2str(ethertype_values
, "Unknown",
177 if (ethertype_print(ndo
, ether_type
, bp
, length
, caplen
, src
, dst
) == 0) {
178 /* ether_type not known, print raw packet */
180 ND_PRINT("ethertype %s (0x%04x) ",
181 tok2str(ethertype_values
, "Unknown",
185 if (!ndo
->ndo_suppress_default_print
)
186 ND_DEFAULTPRINT(bp
, caplen
);