2020 */
2121
2222/* \summary: Broadcom Ethernet switches tag (4 bytes) printer */
23+ // specification: https://www.tcpdump.org/linktypes/broadcom-switch-tag.html
2324
2425#include <config.h>
2526
3233
3334#define BRCM_TAG_LEN 4
3435#define BRCM_OPCODE_SHIFT 5
35- #define BRCM_OPCODE_MASK 0x7
36+ #define BRCM_EGRESS 0 // 0b000xxxxx
37+ #define BRCM_INGRESS 1 // 0b001xxxxx
3638
3739/* Ingress fields */
3840#define BRCM_IG_TC_SHIFT 2
4244#define BRCM_IG_DSTMAP_MASK 0x1ff
4345
4446/* Egress fields */
45- #define BRCM_EG_CID_MASK 0xff
46- #define BRCM_EG_RC_MASK 0xff
47- #define BRCM_EG_RC_RSVD (3 << 6)
47+ #define BRCM_EG_RC_RSVD7 (1 << 7)
48+ #define BRCM_EG_RC_RSVD6 (1 << 6)
4849#define BRCM_EG_RC_EXCEPTION (1 << 5)
4950#define BRCM_EG_RC_PROT_SNOOP (1 << 4)
5051#define BRCM_EG_RC_PROT_TERM (1 << 3)
5556#define BRCM_EG_TC_MASK 0x7
5657#define BRCM_EG_PID_MASK 0x1f
5758
59+ static const struct tok brcm_tag_opcodes [] = {
60+ { BRCM_EGRESS , "EG" },
61+ { BRCM_INGRESS , "IG" },
62+ { 0 , NULL }
63+ };
64+
5865static const struct tok brcm_tag_te_values [] = {
5966 { 0 , "None" },
6067 { 1 , "Untag" },
@@ -63,13 +70,28 @@ static const struct tok brcm_tag_te_values[] = {
6370 { 0 , NULL }
6471};
6572
66- static const struct tok brcm_tag_rc_values [] = {
67- { 1 , "mirror" },
68- { 2 , "MAC learning" },
69- { 4 , "switching" },
70- { 8 , "prot term" },
71- { 16 , "prot snoop" },
72- { 32 , "exception" },
73+ static const struct tok brcm_tag_rc_bm [] = {
74+ { BRCM_EG_RC_MIRROR , "mirror" },
75+ { BRCM_EG_RC_MAC_LEARN , "MAC learning" },
76+ { BRCM_EG_RC_SWITCH , "switching" },
77+ { BRCM_EG_RC_PROT_TERM , "prot term" },
78+ { BRCM_EG_RC_PROT_SNOOP , "prot snoop" },
79+ { BRCM_EG_RC_EXCEPTION , "exception" },
80+ { BRCM_EG_RC_RSVD6 , "reserved-6" },
81+ { BRCM_EG_RC_RSVD7 , "reserved-7" },
82+ { 0 , NULL }
83+ };
84+
85+ static const struct tok brcm_tag_port_bm [] = {
86+ { (1 << 0 ), "port 0" },
87+ { (1 << 1 ), "port 1" },
88+ { (1 << 2 ), "port 2" },
89+ { (1 << 3 ), "port 3" },
90+ { (1 << 4 ), "port 4" },
91+ { (1 << 5 ), "port 5" },
92+ { (1 << 6 ), "port 6" },
93+ { (1 << 7 ), "port 7" },
94+ { (1 << 8 ), "port 8" },
7395 { 0 , NULL }
7496};
7597
@@ -83,26 +105,30 @@ brcm_tag_print(netdissect_options *ndo, const u_char *bp)
83105 for (i = 0 ; i < BRCM_TAG_LEN ; i ++ )
84106 tag [i ] = GET_U_1 (bp + i );
85107
86- ND_PRINT ("BRCM tag OP: %s" , tag [0 ] ? "IG" : "EG" );
87- if (tag [0 ] & (1 << BRCM_OPCODE_SHIFT )) {
88- /* Ingress Broadcom tag */
89- ND_PRINT (", TC: %d" , (tag [1 ] >> BRCM_IG_TC_SHIFT ) &
108+ uint8_t opcode = tag [0 ] >> BRCM_OPCODE_SHIFT ;
109+ ND_PRINT ("BRCM tag OP: %s" , tok2str (brcm_tag_opcodes , NULL , opcode ));
110+ switch (opcode ) {
111+ case BRCM_INGRESS :
112+ ND_PRINT (", TC: %d" , (tag [0 ] >> BRCM_IG_TC_SHIFT ) &
90113 BRCM_IG_TC_MASK );
91114 ND_PRINT (", TE: %s" ,
92115 tok2str (brcm_tag_te_values , "unknown" ,
93- (tag [1 ] & BRCM_IG_TE_MASK )));
116+ (tag [0 ] & BRCM_IG_TE_MASK )));
94117 ND_PRINT (", TS: %d" , tag [1 ] >> BRCM_IG_TS_SHIFT );
95- dst_map = (uint16_t )tag [2 ] << 8 | tag [3 ];
96- ND_PRINT (", DST map: 0x%04x" , dst_map & BRCM_IG_DSTMAP_MASK );
97- } else {
98- /* Egress Broadcom tag */
118+ dst_map = ((uint16_t )tag [2 ] << 8 | tag [3 ]) & BRCM_IG_DSTMAP_MASK ;
119+ ND_PRINT (", DST map: [%s]" ,
120+ bittok2str (brcm_tag_port_bm , "none" , dst_map ));
121+ break ;
122+ case BRCM_EGRESS :
99123 ND_PRINT (", CID: %d" , tag [1 ]);
100- ND_PRINT (", RC: %s " , tok2str ( brcm_tag_rc_values ,
101- "reserved " , tag [2 ]));
124+ ND_PRINT (", RC: [%s] " , bittok2str ( brcm_tag_rc_bm ,
125+ "none " , tag [2 ]));
102126 ND_PRINT (", TC: %d" , (tag [3 ] >> BRCM_EG_TC_SHIFT ) &
103127 BRCM_EG_TC_MASK );
104128 ND_PRINT (", port: %d" , tag [3 ] & BRCM_EG_PID_MASK );
129+ break ;
105130 }
131+
106132 ND_PRINT (", " );
107133}
108134
0 commit comments