]> The Tcpdump Group git mirrors - tcpdump/commitdiff
gre, erspan: add an ERSPAN dissector and have the GRE dissector call it.
authorGuy Harris <[email protected]>
Wed, 7 Jun 2023 22:20:16 +0000 (15:20 -0700)
committerGuy Harris <[email protected]>
Wed, 7 Jun 2023 22:20:16 +0000 (15:20 -0700)
This is from the OpenBSD tcpdump.

Fixes #1040.

Sort the .c list in CMakeLists.txt while we're at it.

CMakeLists.txt
Makefile.in
netdissect.h
print-erspan.c [new file with mode: 0644]
print-gre.c

index 1dea8d27027f45a6a43c543e1a70f654c11f08b4..5b6fdcdcffc42019555d3747397fe0011e2e0065 100644 (file)
@@ -1066,8 +1066,8 @@ set(NETDISSECT_SOURCE_LIST_C
     netdissect.c
     netdissect-alloc.c
     nlpid.c
-    oui.c
     ntp.c
+    oui.c
     parsenfsfh.c
     print.c
     print-802_11.c
@@ -1109,6 +1109,7 @@ set(NETDISSECT_SOURCE_LIST_C
     print-egp.c
     print-eigrp.c
     print-enc.c
+    print-erspan.c
     print-esp.c
     print-ether.c
     print-fddi.c
index 80f5bc825b205fd4328c039acbc2cb027cb1fd5e..4c07a80ff9179e90079ea97cd619b21c8f7af020 100644 (file)
@@ -131,6 +131,7 @@ LIBNETDISSECT_SRC=\
        print-egp.c \
        print-eigrp.c \
        print-enc.c \
+       print-erspan.c \
        print-esp.c \
        print-ether.c \
        print-fddi.c \
index a359824c57f22502378b16467d93a4c2afb2bf00..4f917eebb1eeb25ba86d9f3b8bde013e3aa31b11 100644 (file)
@@ -631,6 +631,7 @@ extern void eap_print(netdissect_options *, const u_char *, u_int);
 extern void eapol_print(netdissect_options *, const u_char *);
 extern void egp_print(netdissect_options *, const u_char *, u_int);
 extern void eigrp_print(netdissect_options *, const u_char *, u_int);
+extern void erspan_print(netdissect_options *, uint16_t, const u_char *, u_int);
 extern void esp_print(netdissect_options *, const u_char *, u_int, const u_char *, u_int, int, u_int);
 extern u_int ether_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), const u_char *);
 extern u_int ether_switch_tag_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), u_int);
diff --git a/print-erspan.c b/print-erspan.c
new file mode 100644 (file)
index 0000000..3bcf0ac
--- /dev/null
@@ -0,0 +1,143 @@
+/*     $OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $     */
+
+/*
+ * Copyright (c) 2002 Jason L. Wright ([email protected])
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* \summary: Cisco ERSPAN printer */
+
+/*
+ * Specifications: I-D draft-foschiano-erspan-03.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "netdissect-stdinc.h"
+
+#define ND_LONGJMP_FROM_TCHECK
+#include "netdissect.h"
+#include "extract.h"
+
+#define ERSPAN2_VER_SHIFT      28
+#define ERSPAN2_VER_MASK       (0xfU << ERSPAN2_VER_SHIFT)
+#define ERSPAN2_VER            (0x1U << ERSPAN2_VER_SHIFT)
+#define ERSPAN2_VLAN_SHIFT     16
+#define ERSPAN2_VLAN_MASK      (0xfffU << ERSPAN2_VLAN_SHIFT)
+#define ERSPAN2_COS_SHIFT      13
+#define ERSPAN2_COS_MASK       (0x7U << ERSPAN2_COS_SHIFT)
+#define ERSPAN2_EN_SHIFT       11
+#define ERSPAN2_EN_MASK                (0x3U << ERSPAN2_EN_SHIFT)
+#define ERSPAN2_EN_NONE                (0x0U << ERSPAN2_EN_SHIFT)
+#define ERSPAN2_EN_ISL         (0x1U << ERSPAN2_EN_SHIFT)
+#define ERSPAN2_EN_DOT1Q       (0x2U << ERSPAN2_EN_SHIFT)
+#define ERSPAN2_EN_VLAN                (0x3U << ERSPAN2_EN_SHIFT)
+#define ERSPAN2_T_SHIFT                10
+#define ERSPAN2_T_MASK         (0x1U << ERSPAN2_T_SHIFT)
+#define ERSPAN2_SID_SHIFT      0
+#define ERSPAN2_SID_MASK       (0x3ffU << ERSPAN2_SID_SHIFT)
+
+#define ERSPAN2_INDEX_SHIFT    0
+#define ERSPAN2_INDEX_MASK     (0xfffffU << ERSPAN2_INDEX_SHIFT)
+
+/*
+ * XXX - eh?
+ */
+#define        GRE_SP          0x1000          /* sequence# present */
+
+void
+erspan_print(netdissect_options *ndo, uint16_t flags, const u_char *bp, u_int len)
+{
+       uint32_t hdr, ver, vlan, cos, en, sid, index;
+
+       ndo->ndo_protocol = "erspan";
+       nd_print_protocol(ndo);
+
+       if (!(flags & GRE_SP)) {
+               ND_PRINT(" I: ");
+               ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
+               return;
+       }
+
+       ND_ICHECK_U(len, <, 4);
+       hdr = GET_BE_U_4(bp);
+       bp += 4;
+       len -= 4;
+
+       ver = hdr & ERSPAN2_VER_MASK;
+       if (ver != ERSPAN2_VER) {
+               ver >>= ERSPAN2_VER_SHIFT;
+               ND_PRINT(" erspan-unknown-version-%x", ver);
+               return;
+       }
+
+       if (ndo->ndo_vflag)
+               ND_PRINT(" II");
+
+       sid = (hdr & ERSPAN2_SID_MASK) >> ERSPAN2_SID_SHIFT;
+       ND_PRINT(" session %u", sid);
+
+       en = hdr & ERSPAN2_EN_MASK;
+       vlan = (hdr & ERSPAN2_VLAN_MASK) >> ERSPAN2_VLAN_SHIFT;
+       switch (en) {
+       case ERSPAN2_EN_NONE:
+               break;
+       case ERSPAN2_EN_ISL:
+               ND_PRINT(" isl %u", vlan);
+               break;
+       case ERSPAN2_EN_DOT1Q:
+               ND_PRINT(" vlan %u", vlan);
+               break;
+       case ERSPAN2_EN_VLAN:
+               ND_PRINT(" vlan payload");
+               break;
+       }
+
+       if (ndo->ndo_vflag) {
+               cos = (hdr & ERSPAN2_COS_MASK) >> ERSPAN2_COS_SHIFT;
+               ND_PRINT(" cos %u", cos);
+
+               if (hdr & ERSPAN2_T_MASK)
+                       ND_PRINT(" truncated");
+       }
+
+       ND_ICHECK_U(len, <, 4);
+       hdr = GET_BE_U_4(bp);
+       bp += 4;
+       len -= 4;
+
+       if (ndo->ndo_vflag) {
+               index = (hdr & ERSPAN2_INDEX_MASK) >> ERSPAN2_INDEX_SHIFT;
+               ND_PRINT(" index %u", index);
+       }
+
+       ND_PRINT(": ");
+       ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
+       return;
+
+invalid:
+       nd_print_invalid(ndo);
+}
index 25c6ac2f5566e684c57a6e88a4b726e1cf207923..04b030f85310b645dec202c12f896cfa46c020ca 100644 (file)
@@ -86,7 +86,9 @@ static const struct tok gre_flag_values[] = {
  */
 #define GRE_CDP                        0x2000  /* Cisco Discovery Protocol */
 #define GRE_NHRP               0x2001  /* Next Hop Resolution Protocol */
+#define GRE_ERSPAN_III         0x22eb
 #define GRE_WCCP               0x883e  /* Web Cache C* Protocol */
+#define GRE_ERSPAN_I_II                0x88be
 
 struct wccp_redirect {
        nd_uint8_t      flags;
@@ -308,6 +310,9 @@ gre_print_0(netdissect_options *ndo, const u_char *bp, u_int length)
        case ETHERTYPE_NSH:
                nsh_print(ndo, bp, len);
                break;
+       case GRE_ERSPAN_I_II:
+               erspan_print(ndo, flags, bp, len);
+               break;
        case GRE_CDP:
                cdp_print(ndo, bp, len);
                break;