summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorremi <remi@cvs.openbsd.org>2020-04-15 20:19:26 +0000
committerremi <remi@cvs.openbsd.org>2020-04-15 20:19:26 +0000
commit84f96317352f10d4b9b15cf82b0052d5a4e6052c (patch)
tree9862627ad463d932c01155869c27a74dafaa01dc
parent78cdabc160e265f0fe16767dcaa9024b783c9043 (diff)
add support for printing RfC 2332 NBMA Next Hop Resolution Protocol (NHRP)
ok dlg@
-rw-r--r--usr.sbin/tcpdump/Makefile4
-rw-r--r--usr.sbin/tcpdump/interface.h5
-rw-r--r--usr.sbin/tcpdump/print-ether.c9
-rw-r--r--usr.sbin/tcpdump/print-gre.c8
-rw-r--r--usr.sbin/tcpdump/print-nhrp.c287
5 files changed, 307 insertions, 6 deletions
diff --git a/usr.sbin/tcpdump/Makefile b/usr.sbin/tcpdump/Makefile
index 99eb058c1f3..d566d3ab653 100644
--- a/usr.sbin/tcpdump/Makefile
+++ b/usr.sbin/tcpdump/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.64 2019/12/03 01:43:33 dlg Exp $
+# $OpenBSD: Makefile,v 1.65 2020/04/15 20:19:25 remi Exp $
#
# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
# The Regents of the University of California. All rights reserved.
@@ -48,7 +48,7 @@ SRCS= tcpdump.c addrtoname.c privsep.c privsep_fdpass.c privsep_pcap.c \
print-bgp.c print-ospf6.c print-ripng.c print-rt6.c print-stp.c \
print-etherip.c print-lwres.c print-lldp.c print-cdp.c print-pflog.c \
print-pfsync.c pf_print_state.c print-ofp.c ofp_map.c \
- print-udpencap.c print-carp.c \
+ print-udpencap.c print-carp.c print-nhrp.c \
print-802_11.c print-iapp.c print-mpls.c print-slow.c print-usbpcap.c \
gmt2local.c savestr.c setsignal.c in_cksum.c
diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h
index df226098e9c..5836e64ce12 100644
--- a/usr.sbin/tcpdump/interface.h
+++ b/usr.sbin/tcpdump/interface.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: interface.h,v 1.83 2019/12/03 01:43:33 dlg Exp $ */
+/* $OpenBSD: interface.h,v 1.84 2020/04/15 20:19:25 remi 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.83 2019/12/03 01:43:33 dlg Exp $ (LBL)
+ * @(#) $Id: interface.h,v 1.84 2020/04/15 20:19:25 remi Exp $ (LBL)
*/
#ifndef tcpdump_interface_h
@@ -217,6 +217,7 @@ extern void ppp_ether_if_print(u_char *, const struct pcap_pkthdr *,
extern void gre_print(const u_char *, u_int);
extern void vxlan_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 *);
extern void ieee802_11_if_print(u_char *, const struct pcap_pkthdr *,
const u_char *);
diff --git a/usr.sbin/tcpdump/print-ether.c b/usr.sbin/tcpdump/print-ether.c
index 773fbb828fa..6e960c3bf36 100644
--- a/usr.sbin/tcpdump/print-ether.c
+++ b/usr.sbin/tcpdump/print-ether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-ether.c,v 1.37 2020/01/24 22:46:36 procter Exp $ */
+/* $OpenBSD: print-ether.c,v 1.38 2020/04/15 20:19:25 remi Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -303,6 +303,13 @@ recurse:
ether_pbb_print(p, length, caplen);
return (1);
+#ifndef ETHERTYPE_NHRP
+#define ETHERTYPE_NHRP 0x2001
+#endif
+ case ETHERTYPE_NHRP:
+ nhrp_print(p, length);
+ return (1);
+
#ifdef PPP
case ETHERTYPE_PPPOEDISC:
case ETHERTYPE_PPPOE:
diff --git a/usr.sbin/tcpdump/print-gre.c b/usr.sbin/tcpdump/print-gre.c
index 35f32a9ddab..271039e8731 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.30 2020/01/24 22:46:36 procter Exp $ */
+/* $OpenBSD: print-gre.c,v 1.31 2020/04/15 20:19:25 remi Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -289,6 +289,12 @@ gre_print_0(const u_char *p, u_int length)
case 0x2000:
cdp_print(p, length, l, 0);
break;
+#ifndef ETHERTYPE_NHRP
+#define ETHERTYPE_NHRP 0x2001
+#endif
+ case ETHERTYPE_NHRP:
+ nhrp_print(p, length);
+ break;
default:
printf("unknown-proto-%04x", proto);
}
diff --git a/usr.sbin/tcpdump/print-nhrp.c b/usr.sbin/tcpdump/print-nhrp.c
new file mode 100644
index 00000000000..f8b8bd620e4
--- /dev/null
+++ b/usr.sbin/tcpdump/print-nhrp.c
@@ -0,0 +1,287 @@
+/* $OpenBSD: print-nhrp.c,v 1.1 2020/04/15 20:19:25 remi Exp $ */
+
+/*
+ * Copyright (c) 2020 Remi Locherer <remi@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * RFC 2332 NBMA Next Hop Resolution Protocol (NHRP)
+ */
+
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+
+#include <net/ethertypes.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "addrtoname.h"
+#include "afnum.h"
+#include "interface.h"
+#include "extract.h"
+
+#define NHRP_VER_RFC2332 1
+
+#define NHRP_PKG_RESOLUTION_REQUEST 1
+#define NHRP_PKG_RESOLUTION_REPLY 2
+#define NHRP_PKG_REGISTRATION_REQUEST 3
+#define NHRP_PKG_REGISTRATION_REPLY 4
+#define NHRP_PKG_PURGE_REQUEST 5
+#define NHRP_PKG_PURGE_REPLY 6
+#define NHRP_PKG_ERROR_INDICATION 7
+
+
+struct nhrp_header {
+ /* fixed header part */
+ u_int16_t afn; /* link layer address */
+ u_int16_t pro_type; /* protocol type (short form) */
+ u_int8_t pro_snap[5]; /* protocol type (long form) */
+ u_int8_t hopcnt; /* hop count */
+ u_int16_t pktsz; /* length of the NHRP packet (octets) */
+ u_int16_t chksum; /* IP checksum over the entier packet */
+ u_int16_t extoff; /* extension offset */
+ u_int8_t op_version; /* version of address mapping and
+ management protocol */
+ u_int8_t op_type; /* NHRP packet type */
+ u_int8_t shtl; /* type and length of src NBMA addr */
+ u_int8_t sstl; /* type and length of src NBMA
+ subaddress */
+ /* mandatory header part */
+ u_int8_t spl; /* src proto len */
+ u_int8_t dpl; /* dst proto len */
+ u_int16_t flags; /* flags */
+ union {
+ u_int32_t id; /* request id */
+ struct { /* error code */
+ u_int16_t code;
+ u_int16_t offset;
+ } err;
+ } u;
+};
+
+struct nhrp_cie {
+ /* client information entrie */
+ u_int8_t code;
+ u_int8_t plen;
+ u_int16_t unused;
+ u_int16_t mtu;
+ u_int16_t htime;
+ u_int8_t cli_addr_tl;
+ u_int8_t cli_saddr_tl;
+ u_int8_t cli_proto_tl;
+ u_int8_t pref;
+};
+
+static const u_char * nhrp_print_cie(const u_char *, u_int16_t, u_int16_t);
+
+
+void
+nhrp_print(const u_char *p, u_int length)
+{
+ struct nhrp_header *hdr;
+ const u_char *nhrpext, *nhrpend;
+
+ printf("NHRP: ");
+
+ if ((snapend - p) < sizeof(*hdr))
+ goto trunc;
+
+ hdr = (struct nhrp_header *)p;
+
+ if (hdr->op_version != NHRP_VER_RFC2332) {
+ printf("unknown-version-%02x", hdr->op_version);
+ return;
+
+ }
+
+ nhrpext = p + EXTRACT_16BITS(&hdr->extoff);
+ nhrpend = p + EXTRACT_16BITS(&hdr->pktsz);
+
+ switch (hdr->op_type) {
+ case NHRP_PKG_RESOLUTION_REQUEST:
+ printf("res request, ");
+ break;
+ case NHRP_PKG_RESOLUTION_REPLY:
+ printf("res reply, ");
+ break;
+ case NHRP_PKG_REGISTRATION_REQUEST:
+ printf("reg request, ");
+ break;
+ case NHRP_PKG_REGISTRATION_REPLY:
+ printf("reg reply, ");
+ break;
+ case NHRP_PKG_PURGE_REQUEST:
+ printf("purge request, ");
+ break;
+ case NHRP_PKG_PURGE_REPLY:
+ printf("purge reply, ");
+ break;
+ case NHRP_PKG_ERROR_INDICATION:
+ printf("error %u", hdr->u.err.code);
+ return;
+ default:
+ printf("unknown-op-type-%04x, ", hdr->op_type);
+ break;
+ }
+
+ printf("id %u", EXTRACT_32BITS(&hdr->u.id));
+
+ if (vflag) {
+ printf(", hopcnt %u", hdr->hopcnt);
+
+ /* most significat bit must be 0 */
+ if (hdr->shtl & 0x80)
+ printf(" (shtl bit 7 set)");
+
+ /* check 2nd most significant bit */
+ if (hdr->shtl & 0x40)
+ printf(" (nbma E.154)");
+ }
+
+ p += sizeof(*hdr);
+ if ((snapend - p) < hdr->shtl)
+ goto trunc;
+
+ if (hdr->shtl) {
+ switch (EXTRACT_16BITS(&hdr->afn)) {
+ case AFNUM_INET:
+ printf(", src nbma %s", ipaddr_string(p));
+ break;
+ case AFNUM_INET6:
+ printf(", src nbma %s", ip6addr_string(p));
+ break;
+ case AFNUM_802:
+ printf(", src nbma %s", etheraddr_string(p));
+ break;
+ default:
+ printf(", unknown-nbma-addr-family-%04x",
+ EXTRACT_16BITS(&hdr->afn));
+ break;
+ }
+ }
+
+ p += hdr->shtl;
+ if ((snapend - p) < (hdr->spl + hdr->dpl))
+ goto trunc;
+
+ switch (EXTRACT_16BITS(&hdr->pro_type)) {
+ case ETHERTYPE_IP:
+ printf(", %s -> %s",
+ ipaddr_string(p),
+ ipaddr_string(p + hdr->spl));
+ break;
+ case ETHERTYPE_IPV6:
+ printf(", %s -> %s",
+ ip6addr_string(p),
+ ip6addr_string(p + hdr->spl));
+ break;
+ default:
+ printf(", proto type %04x",
+ EXTRACT_16BITS(&hdr->pro_type));
+ break;
+ }
+
+ p += hdr->spl + hdr->dpl;
+
+ do {
+ p = nhrp_print_cie(p, hdr->afn, hdr->pro_type);
+ if (p == 0)
+ goto trunc;
+ } while ((hdr->extoff && (p < nhrpext)) ||
+ ((!hdr->extoff && (p < nhrpend))));
+
+ return;
+
+trunc:
+ printf(" [|nhrp]");
+
+}
+
+static const u_char *
+nhrp_print_cie(const u_char *data, u_int16_t afn, u_int16_t pro_type)
+{
+ struct nhrp_cie *cie;
+ int family, type;
+
+ if ((snapend - data) < sizeof(*cie))
+ return (0);
+
+ cie = (struct nhrp_cie *)data;
+
+ family = EXTRACT_16BITS(&afn);
+ type = EXTRACT_16BITS(&pro_type);
+
+ printf(" (code %d", cie->code);
+ if (vflag)
+ printf(", pl %d, mtu %d, htime %d, pref %d", cie->plen,
+ EXTRACT_16BITS(&cie->mtu), EXTRACT_16BITS(&cie->htime),
+ cie->pref);
+
+ /* check 2nd most significant bit */
+ if (cie->cli_addr_tl & 0x40)
+ printf(", nbma E.154");
+
+ data += sizeof(*cie);
+ if ((snapend - data) < cie->cli_addr_tl)
+ return (0);
+
+ if (cie->cli_addr_tl) {
+ switch (family) {
+ case AFNUM_INET:
+ printf(", nbma %s", ipaddr_string(data));
+ break;
+ case AFNUM_INET6:
+ printf(", nbma %s", ip6addr_string(data));
+ break;
+ case AFNUM_802:
+ printf(", nbma %s", etheraddr_string(data));
+ break;
+ default:
+ printf(", unknown-nbma-addr-family-%04x", family);
+ break;
+ }
+ }
+ if (cie->cli_saddr_tl)
+ printf(", unknown-nbma-saddr-family");
+
+ data += cie->cli_addr_tl + cie->cli_saddr_tl;
+ if ((snapend - data) < cie->cli_proto_tl)
+ return (0);
+
+ if (cie->cli_proto_tl) {
+ switch (type) {
+ case ETHERTYPE_IP:
+ printf(", proto %s", ipaddr_string(data));
+ break;
+ case ETHERTYPE_IPV6:
+ printf(", proto %s", ip6addr_string(data));
+ break;
+ default:
+ printf(", unknown-proto-family-%04x", type);
+ break;
+ }
+ }
+
+ printf(")");
+
+ return (data + cie->cli_proto_tl);
+}