]> The Tcpdump Group git mirrors - tcpdump/blob - print-erspan.c
gre, erspan: add an ERSPAN dissector and have the GRE dissector call it.
[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 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include "netdissect-stdinc.h"
40
41 #define ND_LONGJMP_FROM_TCHECK
42 #include "netdissect.h"
43 #include "extract.h"
44
45 #define ERSPAN2_VER_SHIFT 28
46 #define ERSPAN2_VER_MASK (0xfU << ERSPAN2_VER_SHIFT)
47 #define ERSPAN2_VER (0x1U << ERSPAN2_VER_SHIFT)
48 #define ERSPAN2_VLAN_SHIFT 16
49 #define ERSPAN2_VLAN_MASK (0xfffU << ERSPAN2_VLAN_SHIFT)
50 #define ERSPAN2_COS_SHIFT 13
51 #define ERSPAN2_COS_MASK (0x7U << ERSPAN2_COS_SHIFT)
52 #define ERSPAN2_EN_SHIFT 11
53 #define ERSPAN2_EN_MASK (0x3U << ERSPAN2_EN_SHIFT)
54 #define ERSPAN2_EN_NONE (0x0U << ERSPAN2_EN_SHIFT)
55 #define ERSPAN2_EN_ISL (0x1U << ERSPAN2_EN_SHIFT)
56 #define ERSPAN2_EN_DOT1Q (0x2U << ERSPAN2_EN_SHIFT)
57 #define ERSPAN2_EN_VLAN (0x3U << ERSPAN2_EN_SHIFT)
58 #define ERSPAN2_T_SHIFT 10
59 #define ERSPAN2_T_MASK (0x1U << ERSPAN2_T_SHIFT)
60 #define ERSPAN2_SID_SHIFT 0
61 #define ERSPAN2_SID_MASK (0x3ffU << ERSPAN2_SID_SHIFT)
62
63 #define ERSPAN2_INDEX_SHIFT 0
64 #define ERSPAN2_INDEX_MASK (0xfffffU << ERSPAN2_INDEX_SHIFT)
65
66 /*
67 * XXX - eh?
68 */
69 #define GRE_SP 0x1000 /* sequence# present */
70
71 void
72 erspan_print(netdissect_options *ndo, uint16_t flags, const u_char *bp, u_int len)
73 {
74 uint32_t hdr, ver, vlan, cos, en, sid, index;
75
76 ndo->ndo_protocol = "erspan";
77 nd_print_protocol(ndo);
78
79 if (!(flags & GRE_SP)) {
80 ND_PRINT(" I: ");
81 ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
82 return;
83 }
84
85 ND_ICHECK_U(len, <, 4);
86 hdr = GET_BE_U_4(bp);
87 bp += 4;
88 len -= 4;
89
90 ver = hdr & ERSPAN2_VER_MASK;
91 if (ver != ERSPAN2_VER) {
92 ver >>= ERSPAN2_VER_SHIFT;
93 ND_PRINT(" erspan-unknown-version-%x", ver);
94 return;
95 }
96
97 if (ndo->ndo_vflag)
98 ND_PRINT(" II");
99
100 sid = (hdr & ERSPAN2_SID_MASK) >> ERSPAN2_SID_SHIFT;
101 ND_PRINT(" session %u", sid);
102
103 en = hdr & ERSPAN2_EN_MASK;
104 vlan = (hdr & ERSPAN2_VLAN_MASK) >> ERSPAN2_VLAN_SHIFT;
105 switch (en) {
106 case ERSPAN2_EN_NONE:
107 break;
108 case ERSPAN2_EN_ISL:
109 ND_PRINT(" isl %u", vlan);
110 break;
111 case ERSPAN2_EN_DOT1Q:
112 ND_PRINT(" vlan %u", vlan);
113 break;
114 case ERSPAN2_EN_VLAN:
115 ND_PRINT(" vlan payload");
116 break;
117 }
118
119 if (ndo->ndo_vflag) {
120 cos = (hdr & ERSPAN2_COS_MASK) >> ERSPAN2_COS_SHIFT;
121 ND_PRINT(" cos %u", cos);
122
123 if (hdr & ERSPAN2_T_MASK)
124 ND_PRINT(" truncated");
125 }
126
127 ND_ICHECK_U(len, <, 4);
128 hdr = GET_BE_U_4(bp);
129 bp += 4;
130 len -= 4;
131
132 if (ndo->ndo_vflag) {
133 index = (hdr & ERSPAN2_INDEX_MASK) >> ERSPAN2_INDEX_SHIFT;
134 ND_PRINT(" index %u", index);
135 }
136
137 ND_PRINT(": ");
138 ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
139 return;
140
141 invalid:
142 nd_print_invalid(ndo);
143 }