diff options
author | remi <remi@cvs.openbsd.org> | 2020-04-15 20:19:26 +0000 |
---|---|---|
committer | remi <remi@cvs.openbsd.org> | 2020-04-15 20:19:26 +0000 |
commit | 84f96317352f10d4b9b15cf82b0052d5a4e6052c (patch) | |
tree | 9862627ad463d932c01155869c27a74dafaa01dc | |
parent | 78cdabc160e265f0fe16767dcaa9024b783c9043 (diff) |
add support for printing RfC 2332 NBMA Next Hop Resolution Protocol (NHRP)
ok dlg@
-rw-r--r-- | usr.sbin/tcpdump/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/tcpdump/interface.h | 5 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-ether.c | 9 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-gre.c | 8 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-nhrp.c | 287 |
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); +} |