summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2020-08-17 06:29:30 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2020-08-17 06:29:30 +0000
commit2cc3607d9db1bda1ac1a363aac04a9aa954f68ba (patch)
treef078d9925a20efb2a497d153e04db7c8e2be21cc /usr.sbin
parent34627e9b89b42ab6c574861b0e62ddd91bb55b5a (diff)
add initial support for handling geneve packets.
it's like vxlan, but different. the most interesting difference to vxlan is that the protocol adds support for adding optional metadata to packets (like nsh). this diff currently just skips that stuff and just handles the payload. for now.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/tcpdump/interface.h6
-rw-r--r--usr.sbin/tcpdump/print-gre.c99
-rw-r--r--usr.sbin/tcpdump/print-udp.c8
-rw-r--r--usr.sbin/tcpdump/tcpdump.86
-rw-r--r--usr.sbin/tcpdump/tcpdump.c4
5 files changed, 116 insertions, 7 deletions
diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h
index 2a68beddf51..602be405723 100644
--- a/usr.sbin/tcpdump/interface.h
+++ b/usr.sbin/tcpdump/interface.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: interface.h,v 1.85 2020/06/21 05:00:17 dlg Exp $ */
+/* $OpenBSD: interface.h,v 1.86 2020/08/17 06:29:29 dlg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -20,7 +20,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Id: interface.h,v 1.85 2020/06/21 05:00:17 dlg Exp $ (LBL)
+ * @(#) $Id: interface.h,v 1.86 2020/08/17 06:29:29 dlg Exp $ (LBL)
*/
#ifndef tcpdump_interface_h
@@ -66,6 +66,7 @@ extern char *device; /* as specified by -i */
#define PT_VXLAN 12 /* Virtual eXtensible Local Area Network */
#define PT_ERSPAN 13 /* GRE ERSPAN Type I or II */
#define PT_WIREGUARD 14 /* WireGuard tunnel */
+#define PT_GENEVE 15 /* Geneve */
#ifndef min
#define min(a,b) ((a)>(b)?(b):(a))
@@ -217,6 +218,7 @@ extern void ppp_ether_if_print(u_char *, const struct pcap_pkthdr *,
const u_char *);
extern void gre_print(const u_char *, u_int);
extern void vxlan_print(const u_char *, u_int);
+extern void geneve_print(const u_char *, u_int);
extern void nsh_print(const u_char *, u_int);
extern void nhrp_print(const u_char *, u_int);
extern void icmp_print(const u_char *, u_int, const u_char *);
diff --git a/usr.sbin/tcpdump/print-gre.c b/usr.sbin/tcpdump/print-gre.c
index 271039e8731..87aba555379 100644
--- a/usr.sbin/tcpdump/print-gre.c
+++ b/usr.sbin/tcpdump/print-gre.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-gre.c,v 1.31 2020/04/15 20:19:25 remi Exp $ */
+/* $OpenBSD: print-gre.c,v 1.32 2020/08/17 06:29:29 dlg Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -785,3 +785,100 @@ vxlan_print(const u_char *p, u_int length)
trunc:
printf(" [|vxlan]");
}
+
+/*
+ * Geneve: Generic Network Virtualization Encapsulation
+ * draft-ietf-nvo3-geneve-16
+ */
+
+struct geneve_header {
+ uint16_t flags;
+#define GENEVE_VER_SHIFT 14
+#define GENEVE_VER_MASK (0x3U << GENEVE_VER_SHIFT)
+#define GENEVE_VER_0 (0x0U << GENEVE_VER_SHIFT)
+#define GENEVE_OPT_LEN_SHIFT 8
+#define GENEVE_OPT_LEN_MASK (0x3fU << GENEVE_OPT_LEN_SHIFT)
+#define GENEVE_OPT_LEN_UNITS 4
+#define GENEVE_O 0x0080 /* Control packet */
+#define GENEVE_C 0x0040 /* Critical options present */
+ uint16_t protocol;
+ uint32_t vni;
+#define GENEVE_VNI_SHIFT 8
+#define GENEVE_VNI_MASK (0xffffffU << GENEVE_VNI_SHIFT)
+#define GENEVE_VNI_RESERVED (~GENEVE_VNI_MASK)
+};
+
+void
+geneve_print(const u_char *p, u_int length)
+{
+ const struct geneve_header *gh;
+ uint16_t flags, ver, optlen, proto;
+ uint32_t vni;
+ int l = snapend - p;
+
+ printf("geneve");
+
+ if (l < sizeof(*gh))
+ goto trunc;
+ if (length < sizeof(*gh)) {
+ printf(" ip truncated");
+ return;
+ }
+
+ gh = (const struct geneve_header *)p;
+
+ p += sizeof(*gh);
+ length -= sizeof(*gh);
+
+ flags = ntohs(gh->flags);
+ ver = flags & GENEVE_VER_MASK;
+ if (ver != GENEVE_VER_0) {
+ printf(" unknown version %u", ver >> GENEVE_VER_SHIFT);
+ return;
+ }
+
+ vni = (htonl(gh->vni) & GENEVE_VNI_MASK) >> GENEVE_VNI_SHIFT;
+ printf(" vni %u", vni);
+
+ if (flags & GENEVE_O)
+ printf(" Control");
+
+ if (flags & GENEVE_C)
+ printf(" Critical");
+
+ optlen = (flags & GENEVE_OPT_LEN_MASK) >> GENEVE_OPT_LEN_SHIFT;
+ optlen *= GENEVE_OPT_LEN_UNITS;
+
+ if (length < optlen)
+ goto trunc;
+
+ p += optlen;
+ length -= optlen;
+
+ printf(": ");
+
+ proto = ntohs(gh->protocol);
+ switch (proto) {
+ case ETHERTYPE_IP:
+ ip_print(p, length);
+ break;
+ case ETHERTYPE_IPV6:
+ ip6_print(p, length);
+ break;
+ case ETHERTYPE_MPLS:
+ case ETHERTYPE_MPLS_MCAST:
+ mpls_print(p, length);
+ break;
+ case ETHERTYPE_TRANSETHER:
+ ether_tryprint(p, length, 0);
+ break;
+
+ default:
+ printf("geneve-protocol-0x%x", proto);
+ break;
+ }
+
+ return;
+trunc:
+ printf(" [|geneve]");
+}
diff --git a/usr.sbin/tcpdump/print-udp.c b/usr.sbin/tcpdump/print-udp.c
index d581c924ba2..2ec86df5e79 100644
--- a/usr.sbin/tcpdump/print-udp.c
+++ b/usr.sbin/tcpdump/print-udp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-udp.c,v 1.55 2020/06/21 05:00:18 dlg Exp $ */
+/* $OpenBSD: print-udp.c,v 1.56 2020/08/17 06:29:29 dlg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
@@ -308,6 +308,7 @@ rtcp_print(const u_char *hdr, const u_char *ep)
#define GRE_PORT 4754
#define VXLAN_PORT 4789
#define VXLAN_GPE_PORT 4790
+#define GENEVE_PORT 6081
#define MULTICASTDNS_PORT 5353
#define MPLS_PORT 6635
@@ -466,6 +467,9 @@ udp_print(const u_char *bp, u_int length, const void *iph)
case PT_VXLAN:
vxlan_print(cp, length);
break;
+ case PT_GENEVE:
+ geneve_print(cp, length);
+ break;
case PT_MPLS:
mpls_print(cp, length);
break;
@@ -560,6 +564,8 @@ udp_print(const u_char *bp, u_int length, const void *iph)
gre_print(cp, length);
else if (ISPORT(VXLAN_PORT) || ISPORT(VXLAN_GPE_PORT))
vxlan_print(cp, length);
+ else if (ISPORT(GENEVE_PORT))
+ geneve_print(cp, length);
else if (ISPORT(MPLS_PORT))
mpls_print(cp, length);
else if (ISPORT(RIPNG_PORT))
diff --git a/usr.sbin/tcpdump/tcpdump.8 b/usr.sbin/tcpdump/tcpdump.8
index c0eaea3c676..37402e53a27 100644
--- a/usr.sbin/tcpdump/tcpdump.8
+++ b/usr.sbin/tcpdump/tcpdump.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tcpdump.8,v 1.110 2020/06/21 05:00:18 dlg Exp $
+.\" $OpenBSD: tcpdump.8,v 1.111 2020/08/17 06:29:29 dlg Exp $
.\"
.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996
.\" The Regents of the University of California. All rights reserved.
@@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.Dd $Mdocdate: June 21 2020 $
+.Dd $Mdocdate: August 17 2020 $
.Dt TCPDUMP 8
.Os
.Sh NAME
@@ -238,6 +238,8 @@ Currently known types are:
Cisco NetFlow protocol
.It Cm erspan
Cisco Encapsulated Remote Switch Port Analyzer (ERSPAN) over GRE
+.It Cm geneve
+Generic Network Virtualization Encapsulation
.It Cm gre
Generic Routing Encapsulation over UDP
.It Cm mpls
diff --git a/usr.sbin/tcpdump/tcpdump.c b/usr.sbin/tcpdump/tcpdump.c
index 02661758e39..bbdba4d4c48 100644
--- a/usr.sbin/tcpdump/tcpdump.c
+++ b/usr.sbin/tcpdump/tcpdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcpdump.c,v 1.93 2020/06/21 05:00:18 dlg Exp $ */
+/* $OpenBSD: tcpdump.c,v 1.94 2020/08/17 06:29:29 dlg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -365,6 +365,8 @@ main(int argc, char **argv)
packettype = PT_GRE;
else if (strcasecmp(optarg, "vxlan") == 0)
packettype = PT_VXLAN;
+ else if (strcasecmp(optarg, "geneve") == 0)
+ packettype = PT_GENEVE;
else if (strcasecmp(optarg, "erspan") == 0)
packettype = PT_ERSPAN;
else if (strcasecmp(optarg, "mpls") == 0)