summaryrefslogtreecommitdiffstats
path: root/usr.sbin/tcpdump/print-gre.c
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2019-12-02 22:32:01 +0000
committerdlg <dlg@openbsd.org>2019-12-02 22:32:01 +0000
commita0ced5ee57147aec322f94f83c1e32aeea4f3e6d (patch)
treedd3456d7d580d9b07f00d26603084817581c261d /usr.sbin/tcpdump/print-gre.c
parentTweak previous, using fputs here was fine (diff)
downloadwireguard-openbsd-a0ced5ee57147aec322f94f83c1e32aeea4f3e6d.tar.xz
wireguard-openbsd-a0ced5ee57147aec322f94f83c1e32aeea4f3e6d.zip
add support for VXLAN-GPE as per draft-ietf-nvo3-vxlan-gpe-08.
it's nicely backwards compatible, so we can use the same code for both vxlan and vxlan-gpe.
Diffstat (limited to 'usr.sbin/tcpdump/print-gre.c')
-rw-r--r--usr.sbin/tcpdump/print-gre.c111
1 files changed, 79 insertions, 32 deletions
diff --git a/usr.sbin/tcpdump/print-gre.c b/usr.sbin/tcpdump/print-gre.c
index 542f73dcf0c..954d62f9786 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.27 2019/05/26 22:42:42 dlg Exp $ */
+/* $OpenBSD: print-gre.c,v 1.28 2019/12/02 22:32:01 dlg Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -666,10 +666,30 @@ gre_sre_asn_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len)
}
}
+/*
+ * - RFC 7348 Virtual eXtensible Local Area Network (VXLAN)
+ * - draft-ietf-nvo3-vxlan-gpe-08 Generic Protocol Extension for VXLAN
+ */
+
struct vxlan_header {
uint16_t flags;
-#define VXLAN_I 0x0800
- uint16_t proto;
+#define VXLAN_VER 0x3000 /* GPE */
+#define VXLAN_VER_0 0x0000
+#define VXLAN_I 0x0800 /* Instance Bit */
+#define VXLAN_P 0x0400 /* GPE Next Protocol */
+#define VXLAN_B 0x0200 /* GPE BUM Traffic */
+#define VXLAN_O 0x0100 /* GPE OAM Flag */
+ uint8_t reserved;
+ uint8_t next_proto; /* GPE */
+#define VXLAN_PROTO_RESERVED 0x00
+#define VXLAN_PROTO_IPV4 0x01
+#define VXLAN_PROTO_IPV6 0x02
+#define VXLAN_PROTO_ETHERNET 0x03
+#define VXLAN_PROTO_NSH 0x04
+#define VXLAN_PROTO_MPLS 0x05
+#define VXLAN_PROTO_VBNG 0x07
+#define VXLAN_PROTO_GBP 0x80
+#define VXLAN_PROTO_IOAM 0x82
uint32_t vni;
#define VXLAN_VNI_SHIFT 8
#define VXLAN_VNI_MASK (0xffffffU << VXLAN_VNI_SHIFT)
@@ -680,49 +700,76 @@ void
vxlan_print(const u_char *p, u_int length)
{
const struct vxlan_header *vh;
- uint16_t flags, proto;
- uint32_t vni;
- size_t l;
+ uint16_t flags, ver;
+ uint8_t proto = VXLAN_PROTO_ETHERNET;
+ int l = snapend - p;
- l = snapend - p;
- if (l < sizeof(*vh)) {
- printf("[|vxlan]");
+ printf("VXLAN");
+
+ if (l < sizeof(*vh))
+ goto trunc;
+ if (length < sizeof(*vh)) {
+ printf(" ip truncated");
return;
}
+
vh = (const struct vxlan_header *)p;
+ p += sizeof(*vh);
+ length -= sizeof(*vh);
+
flags = ntohs(vh->flags);
- if (flags & ~VXLAN_I) {
- printf("vxlan-invalid-flags %04x", flags);
+ ver = flags & VXLAN_VER;
+ if (ver != VXLAN_VER_0) {
+ printf(" unknown version %u", ver >> 12);
return;
}
- proto = ntohs(vh->proto);
- if (proto != 0) {
- printf("vxlan-invalid-proto %04x", proto);
- return;
+ if (flags & VXLAN_I) {
+ uint32_t vni = (htonl(vh->vni) & VXLAN_VNI_MASK) >>
+ VXLAN_VNI_SHIFT;
+ printf(" vni %u", vni >> VXLAN_VNI_SHIFT);
}
- vni = ntohl(vh->vni);
- if (flags & VXLAN_I) {
- if (vni & VXLAN_VNI_RESERVED) {
- printf("vxlan-vni-reserved %02x",
- vni & VXLAN_VNI_RESERVED);
- return;
- }
+ if (flags & VXLAN_P)
+ proto = vh->next_proto;
- printf("vxlan %u: ", vni >> VXLAN_VNI_SHIFT);
- } else {
- if (vh->vni != 0) {
- printf("vxlan-invalid-vni %08x\n", vni);
- return;
- }
+ if (flags & VXLAN_B)
+ printf(" BUM");
- printf("vxlan: ");
+ if (flags & VXLAN_O) {
+ printf(" OAM (proto 0x%x, len %u)", proto, length);
+ return;
}
- p += sizeof(*vh);
- length -= sizeof(*vh);
+ printf(": ");
+
+ switch (proto) {
+ case VXLAN_PROTO_RESERVED:
+ printf("Reserved");
+ break;
+ case VXLAN_PROTO_IPV4:
+ ip_print(p, length);
+ break;
+ case VXLAN_PROTO_IPV6:
+ ip6_print(p, length);
+ break;
+ case VXLAN_PROTO_ETHERNET:
+ ether_tryprint(p, length, 0);
+ break;
+ case VXLAN_PROTO_NSH:
+ printf("NSH");
+ break;
+ case VXLAN_PROTO_MPLS:
+ mpls_print(p, length);
+ break;
+
+ default:
+ printf("Unassigned proto 0x%x", proto);
+ break;
+ }
- ether_tryprint(p, length, 0);
+ return;
+trunc:
+ printf(" [|vxlan]");
}