]> The Tcpdump Group git mirrors - tcpdump/blob - print-erspan.c
31795a5399f00b67a46292ed8ebfd40042c0f753
[tcpdump] / print-erspan.c
1 /* $OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $ */
2
3 /*
4 * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
15 *
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.
27 */
28
29 /* \summary: Cisco ERSPAN printer */
30
31 /*
32 * Specifications: I-D draft-foschiano-erspan-03.
33 */
34
35 #include <config.h>
36
37 #include "netdissect-stdinc.h"
38
39 #define ND_LONGJMP_FROM_TCHECK
40 #include "netdissect.h"
41 #include "extract.h"
42 #include "gre.h"
43
44 #define ERSPAN2_VER_SHIFT 28
45 #define ERSPAN2_VER_MASK (0xfU << ERSPAN2_VER_SHIFT)
46 #define ERSPAN2_VER (0x1U << ERSPAN2_VER_SHIFT)
47 #define ERSPAN2_VLAN_SHIFT 16
48 #define ERSPAN2_VLAN_MASK (0xfffU << ERSPAN2_VLAN_SHIFT)
49 #define ERSPAN2_COS_SHIFT 13
50 #define ERSPAN2_COS_MASK (0x7U << ERSPAN2_COS_SHIFT)
51 #define ERSPAN2_EN_SHIFT 11
52 #define ERSPAN2_EN_MASK (0x3U << ERSPAN2_EN_SHIFT)
53 #define ERSPAN2_EN_NONE (0x0U << ERSPAN2_EN_SHIFT)
54 #define ERSPAN2_EN_ISL (0x1U << ERSPAN2_EN_SHIFT)
55 #define ERSPAN2_EN_DOT1Q (0x2U << ERSPAN2_EN_SHIFT)
56 #define ERSPAN2_EN_VLAN (0x3U << ERSPAN2_EN_SHIFT)
57 #define ERSPAN2_T_SHIFT 10
58 #define ERSPAN2_T_MASK (0x1U << ERSPAN2_T_SHIFT)
59 #define ERSPAN2_SID_SHIFT 0
60 #define ERSPAN2_SID_MASK (0x3ffU << ERSPAN2_SID_SHIFT)
61
62 #define ERSPAN2_INDEX_SHIFT 0
63 #define ERSPAN2_INDEX_MASK (0xfffffU << ERSPAN2_INDEX_SHIFT)
64
65 void
66 erspan_print(netdissect_options *ndo, uint16_t flags, const u_char *bp, u_int len)
67 {
68 uint32_t hdr, ver, vlan, cos, en, sid, index;
69
70 ndo->ndo_protocol = "erspan";
71 nd_print_protocol(ndo);
72
73 if (!(flags & GRE_SP)) {
74 ND_PRINT(" type1: ");
75 ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
76 return;
77 }
78
79 ND_ICHECK_U(len, <, 4);
80 hdr = GET_BE_U_4(bp);
81 bp += 4;
82 len -= 4;
83
84 ver = hdr & ERSPAN2_VER_MASK;
85 if (ver != ERSPAN2_VER) {
86 ver >>= ERSPAN2_VER_SHIFT;
87 ND_PRINT(" erspan-unknown-version-%x", ver);
88 return;
89 }
90
91 if (ndo->ndo_vflag)
92 ND_PRINT(" type2");
93
94 sid = (hdr & ERSPAN2_SID_MASK) >> ERSPAN2_SID_SHIFT;
95 ND_PRINT(" session %u", sid);
96
97 en = hdr & ERSPAN2_EN_MASK;
98 vlan = (hdr & ERSPAN2_VLAN_MASK) >> ERSPAN2_VLAN_SHIFT;
99 switch (en) {
100 case ERSPAN2_EN_NONE:
101 break;
102 case ERSPAN2_EN_ISL:
103 ND_PRINT(" isl %u", vlan);
104 break;
105 case ERSPAN2_EN_DOT1Q:
106 ND_PRINT(" vlan %u", vlan);
107 break;
108 case ERSPAN2_EN_VLAN:
109 ND_PRINT(" vlan payload");
110 break;
111 }
112
113 if (ndo->ndo_vflag) {
114 cos = (hdr & ERSPAN2_COS_MASK) >> ERSPAN2_COS_SHIFT;
115 ND_PRINT(" cos %u", cos);
116
117 if (hdr & ERSPAN2_T_MASK)
118 ND_PRINT(" truncated");
119 }
120
121 ND_ICHECK_U(len, <, 4);
122 hdr = GET_BE_U_4(bp);
123 bp += 4;
124 len -= 4;
125
126 if (ndo->ndo_vflag) {
127 index = (hdr & ERSPAN2_INDEX_MASK) >> ERSPAN2_INDEX_SHIFT;
128 ND_PRINT(" index %u", index);
129 }
130
131 ND_PRINT(": ");
132 ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
133 return;
134
135 invalid:
136 nd_print_invalid(ndo);
137 }