]>
The Tcpdump Group git mirrors - tcpdump/blob - print-erspan.c
1 /* $OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $ */
4 * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
29 /* \summary: Cisco ERSPAN printer */
32 * Specifications: I-D draft-foschiano-erspan-03.
37 #include "netdissect-stdinc.h"
39 #define ND_LONGJMP_FROM_TCHECK
40 #include "netdissect.h"
47 #define ERSPAN2_VER_SHIFT 28
48 #define ERSPAN2_VER_MASK (0xfU << ERSPAN2_VER_SHIFT)
49 #define ERSPAN2_VER (0x1U << ERSPAN2_VER_SHIFT)
50 #define ERSPAN2_VLAN_SHIFT 16
51 #define ERSPAN2_VLAN_MASK (0xfffU << ERSPAN2_VLAN_SHIFT)
52 #define ERSPAN2_COS_SHIFT 13
53 #define ERSPAN2_COS_MASK (0x7U << ERSPAN2_COS_SHIFT)
54 #define ERSPAN2_EN_SHIFT 11
55 #define ERSPAN2_EN_MASK (0x3U << ERSPAN2_EN_SHIFT)
56 #define ERSPAN2_EN_NONE (0x0U << ERSPAN2_EN_SHIFT)
57 #define ERSPAN2_EN_ISL (0x1U << ERSPAN2_EN_SHIFT)
58 #define ERSPAN2_EN_DOT1Q (0x2U << ERSPAN2_EN_SHIFT)
59 #define ERSPAN2_EN_VLAN (0x3U << ERSPAN2_EN_SHIFT)
60 #define ERSPAN2_T_SHIFT 10
61 #define ERSPAN2_T_MASK (0x1U << ERSPAN2_T_SHIFT)
62 #define ERSPAN2_SID_SHIFT 0
63 #define ERSPAN2_SID_MASK (0x3ffU << ERSPAN2_SID_SHIFT)
65 #define ERSPAN2_INDEX_SHIFT 0
66 #define ERSPAN2_INDEX_MASK (0xfffffU << ERSPAN2_INDEX_SHIFT)
69 erspan_i_ii_print(netdissect_options
*ndo
, uint16_t flags
, const u_char
*bp
, u_int len
)
71 uint32_t hdr
, ver
, vlan
, cos
, en
, sid
, index
;
73 ndo
->ndo_protocol
= "erspan";
74 nd_print_protocol(ndo
);
76 if (!(flags
& GRE_SP
)) {
78 * ERSPAN Type I; no header, just a raw Ethernet frame.
81 ether_print(ndo
, bp
, len
, ND_BYTES_AVAILABLE_AFTER(bp
), NULL
, NULL
);
88 ND_ICHECK_U(len
, <, 4);
93 ver
= hdr
& ERSPAN2_VER_MASK
;
94 if (ver
!= ERSPAN2_VER
) {
98 ver
>>= ERSPAN2_VER_SHIFT
;
99 ND_PRINT(" erspan-unknown-version-%x", ver
);
106 sid
= (hdr
& ERSPAN2_SID_MASK
) >> ERSPAN2_SID_SHIFT
;
107 ND_PRINT(" session %u", sid
);
109 en
= hdr
& ERSPAN2_EN_MASK
;
110 vlan
= (hdr
& ERSPAN2_VLAN_MASK
) >> ERSPAN2_VLAN_SHIFT
;
112 case ERSPAN2_EN_NONE
:
115 ND_PRINT(" isl %u", vlan
);
117 case ERSPAN2_EN_DOT1Q
:
118 ND_PRINT(" vlan %u", vlan
);
120 case ERSPAN2_EN_VLAN
:
121 ND_PRINT(" vlan payload");
125 if (ndo
->ndo_vflag
) {
126 cos
= (hdr
& ERSPAN2_COS_MASK
) >> ERSPAN2_COS_SHIFT
;
127 ND_PRINT(" cos %u", cos
);
129 if (hdr
& ERSPAN2_T_MASK
)
130 ND_PRINT(" truncated");
133 ND_ICHECK_U(len
, <, 4);
134 hdr
= GET_BE_U_4(bp
);
138 if (ndo
->ndo_vflag
) {
139 index
= (hdr
& ERSPAN2_INDEX_MASK
) >> ERSPAN2_INDEX_SHIFT
;
140 ND_PRINT(" index %u", index
);
144 ether_print(ndo
, bp
, len
, ND_BYTES_AVAILABLE_AFTER(bp
), NULL
, NULL
);
148 nd_print_invalid(ndo
);
154 #define ERSPAN3_VER_SHIFT 28
155 #define ERSPAN3_VER_MASK (0xfU << ERSPAN3_VER_SHIFT)
156 #define ERSPAN3_VER (0x2U << ERSPAN3_VER_SHIFT)
157 #define ERSPAN3_VLAN_SHIFT 16
158 #define ERSPAN3_VLAN_MASK (0xfffU << ERSPAN3_VLAN_SHIFT)
159 #define ERSPAN3_COS_SHIFT 13
160 #define ERSPAN3_COS_MASK (0x7U << ERSPAN3_COS_SHIFT)
161 #define ERSPAN3_BSO_SHIFT 11
162 #define ERSPAN3_BSO_MASK (0x3U << ERSPAN3_BSO_SHIFT)
163 #define ERSPAN3_BSO_GOOD_UNKNOWN 0x0U
164 #define ERSPAN3_BSO_BAD 0x3U
165 #define ERSPAN3_BSO_SHORT 0x1U
166 #define ERSPAN3_BSO_OVERSIZED 0x2U
167 #define ERSPAN3_T_SHIFT 10
168 #define ERSPAN3_T_MASK (0x1U << ERSPAN3_T_SHIFT)
169 #define ERSPAN3_SID_SHIFT 0
170 #define ERSPAN3_SID_MASK (0x3ffU << ERSPAN3_SID_SHIFT)
171 #define ERSPAN3_P_SHIFT 15
172 #define ERSPAN3_P_MASK (0x1U << ERSPAN3_P_SHIFT)
173 #define ERSPAN3_FT_SHIFT 10
174 #define ERSPAN3_FT_MASK (0x1fU << ERSPAN3_FT_SHIFT)
175 #define ERSPAN3_FT_ETHERNET 0
176 #define ERSPAN3_FT_IP 2
177 #define ERSPAN3_HW_ID_SHIFT 4
178 #define ERSPAN3_HW_ID_MASK (0x3fU << ERSPAN3_HW_ID_SHIFT)
179 #define ERSPAN3_D_SHIFT 3
180 #define ERSPAN3_D_MASK (0x1U << ERSPAN3_D_SHIFT)
181 #define ERSPAN3_GRA_SHIFT 1
182 #define ERSPAN3_GRA_MASK (0x3U << ERSPAN3_GRA_SHIFT)
183 #define ERSPAN3_O_SHIFT 0
184 #define ERSPAN3_O_MASK (0x1U << ERSPAN3_O_SHIFT)
186 static const struct tok erspan3_bso_values
[] = {
187 { ERSPAN3_BSO_GOOD_UNKNOWN
, "Good/unknown" },
188 { ERSPAN3_BSO_BAD
, "Bad" },
189 { ERSPAN3_BSO_SHORT
, "Short" },
190 { ERSPAN3_BSO_OVERSIZED
, "Oversized" },
194 static const struct tok erspan3_ft_values
[] = {
195 { ERSPAN3_FT_ETHERNET
, "Ethernet" },
196 { ERSPAN3_FT_IP
, "IP" },
201 erspan_iii_print(netdissect_options
*ndo
, const u_char
*bp
, u_int len
)
203 uint32_t hdr
, hdr2
, ver
, cos
, sid
, ft
;
205 ndo
->ndo_protocol
= "erspan";
206 nd_print_protocol(ndo
);
209 * We do not check the GRE flags; ERSPAN Type III always
210 * has an ERSPAN header.
212 ND_ICHECK_U(len
, <, 4);
213 hdr
= GET_BE_U_4(bp
);
217 ver
= hdr
& ERSPAN3_VER_MASK
;
218 if (ver
!= ERSPAN3_VER
) {
222 ver
>>= ERSPAN3_VER_SHIFT
;
223 ND_PRINT(" erspan-unknown-version-%x", ver
);
230 sid
= (hdr
& ERSPAN3_SID_MASK
) >> ERSPAN3_SID_SHIFT
;
231 ND_PRINT(" session %u", sid
);
234 tok2str(erspan3_bso_values
, "unknown %x",
235 (hdr
& ERSPAN3_BSO_MASK
) >> ERSPAN3_BSO_SHIFT
));
237 if (ndo
->ndo_vflag
) {
238 cos
= (hdr
& ERSPAN3_COS_MASK
) >> ERSPAN3_COS_SHIFT
;
239 ND_PRINT(" cos %u", cos
);
241 if (hdr
& ERSPAN3_T_MASK
)
242 ND_PRINT(" truncated");
246 ND_ICHECK_U(len
, <, 4);
252 ND_ICHECK_U(len
, <, 2);
257 /* Additional fields */
258 ND_ICHECK_U(len
, <, 2);
259 hdr2
= GET_BE_U_2(bp
);
263 ft
= (hdr2
& ERSPAN3_FT_MASK
) >> ERSPAN3_FT_SHIFT
;
265 tok2str(erspan3_ft_values
, "unknown %x", ft
));
268 /* Do we have the platform-specific header? */
269 if (hdr2
& ERSPAN3_O_MASK
) {
271 ND_ICHECK_U(len
, <, 8);
281 case ERSPAN3_FT_ETHERNET
:
282 ether_print(ndo
, bp
, len
, ND_BYTES_AVAILABLE_AFTER(bp
), NULL
, NULL
);
286 ND_PRINT("Frame type unknown");
292 nd_print_invalid(ndo
);