Skip to content

Commit e0787e5

Browse files
committed
gre, erspan: add an ERSPAN dissector and have the GRE dissector call it.
This is from the OpenBSD tcpdump. Fixes #1040. Sort the .c list in CMakeLists.txt while we're at it.
1 parent c6b4ee6 commit e0787e5

File tree

5 files changed

+152
-1
lines changed

5 files changed

+152
-1
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1066,8 +1066,8 @@ set(NETDISSECT_SOURCE_LIST_C
10661066
netdissect.c
10671067
netdissect-alloc.c
10681068
nlpid.c
1069-
oui.c
10701069
ntp.c
1070+
oui.c
10711071
parsenfsfh.c
10721072
print.c
10731073
print-802_11.c
@@ -1109,6 +1109,7 @@ set(NETDISSECT_SOURCE_LIST_C
11091109
print-egp.c
11101110
print-eigrp.c
11111111
print-enc.c
1112+
print-erspan.c
11121113
print-esp.c
11131114
print-ether.c
11141115
print-fddi.c

Makefile.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ LIBNETDISSECT_SRC=\
131131
print-egp.c \
132132
print-eigrp.c \
133133
print-enc.c \
134+
print-erspan.c \
134135
print-esp.c \
135136
print-ether.c \
136137
print-fddi.c \

netdissect.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,7 @@ extern void eap_print(netdissect_options *, const u_char *, u_int);
631631
extern void eapol_print(netdissect_options *, const u_char *);
632632
extern void egp_print(netdissect_options *, const u_char *, u_int);
633633
extern void eigrp_print(netdissect_options *, const u_char *, u_int);
634+
extern void erspan_print(netdissect_options *, uint16_t, const u_char *, u_int);
634635
extern void esp_print(netdissect_options *, const u_char *, u_int, const u_char *, u_int, int, u_int);
635636
extern u_int ether_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), const u_char *);
636637
extern u_int ether_switch_tag_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), u_int);

print-erspan.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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 ([email protected])
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+
}

print-gre.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@ static const struct tok gre_flag_values[] = {
8686
*/
8787
#define GRE_CDP 0x2000 /* Cisco Discovery Protocol */
8888
#define GRE_NHRP 0x2001 /* Next Hop Resolution Protocol */
89+
#define GRE_ERSPAN_III 0x22eb
8990
#define GRE_WCCP 0x883e /* Web Cache C* Protocol */
91+
#define GRE_ERSPAN_I_II 0x88be
9092

9193
struct wccp_redirect {
9294
nd_uint8_t flags;
@@ -308,6 +310,9 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length)
308310
case ETHERTYPE_NSH:
309311
nsh_print(ndo, bp, len);
310312
break;
313+
case GRE_ERSPAN_I_II:
314+
erspan_print(ndo, flags, bp, len);
315+
break;
311316
case GRE_CDP:
312317
cdp_print(ndo, bp, len);
313318
break;

0 commit comments

Comments
 (0)