diff options
author | 2006-03-28 15:48:33 +0000 | |
---|---|---|
committer | 2006-03-28 15:48:33 +0000 | |
commit | d7869ad73a59a677a0e4c21a160d18548b95b36a (patch) | |
tree | b4e44865e8dd82c1dc74bfc97764b5e0b7aa8623 /usr.sbin | |
parent | use clock_gettime if available. (diff) | |
download | wireguard-openbsd-d7869ad73a59a677a0e4c21a160d18548b95b36a.tar.xz wireguard-openbsd-d7869ad73a59a677a0e4c21a160d18548b95b36a.zip |
Add a simple printer for IEEE 802.1AB LLDP, the Link Layer Discovery
Protocol.
LLDP is used by some switch vendors as a replacement for the non-free
Cizzco Discovery Protocol (CDP) due to some Cisco patentry...
ok brad@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/tcpdump/Makefile | 4 | ||||
-rw-r--r-- | usr.sbin/tcpdump/afnum.h | 81 | ||||
-rw-r--r-- | usr.sbin/tcpdump/ethertype.h | 7 | ||||
-rw-r--r-- | usr.sbin/tcpdump/interface.h | 5 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-bgp.c | 27 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-ether.c | 8 | ||||
-rw-r--r-- | usr.sbin/tcpdump/print-lldp.c | 287 |
7 files changed, 387 insertions, 32 deletions
diff --git a/usr.sbin/tcpdump/Makefile b/usr.sbin/tcpdump/Makefile index 4591c373097..a086c1f762e 100644 --- a/usr.sbin/tcpdump/Makefile +++ b/usr.sbin/tcpdump/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.49 2005/11/22 11:36:12 reyk Exp $ +# $OpenBSD: Makefile,v 1.50 2006/03/28 15:48:33 reyk Exp $ # # Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 # The Regents of the University of California. All rights reserved. @@ -43,7 +43,7 @@ SRCS= tcpdump.c addrtoname.c privsep.c privsep_fdpass.c privsep_pcap.c \ print-ipsec.c print-ike.c print-raw.c print-l2tp.c print-mobile.c \ print-ip6.c print-ip6opts.c print-icmp6.c print-dhcp6.c print-frag6.c \ print-bgp.c print-ospf6.c print-ripng.c print-rt6.c print-stp.c \ - print-etherip.c print-lwres.c print-cdp.c print-pflog.c \ + print-etherip.c print-lwres.c print-lldp.c print-cdp.c print-pflog.c \ print-pfsync.c pf_print_state.c \ print-udpencap.c print-carp.c \ print-802_11.c print-iapp.c print-mpls.c \ diff --git a/usr.sbin/tcpdump/afnum.h b/usr.sbin/tcpdump/afnum.h new file mode 100644 index 00000000000..e2ea9201cdb --- /dev/null +++ b/usr.sbin/tcpdump/afnum.h @@ -0,0 +1,81 @@ +/* $OpenBSD: afnum.h,v 1.1 2006/03/28 15:48:33 reyk Exp $ */ + +/* + * Copyright (c) 2006 Reyk Floeter <reyk@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. + */ + +#ifndef _AFNUM_H +#define _AFNUM_H + +/* + * RFC3232 address family numbers + * see http://www.iana.org/assignments/address-family-numbers + */ +#define AFNUM_INET 1 +#define AFNUM_INET6 2 +#define AFNUM_NSAP 3 +#define AFNUM_HDLC 4 +#define AFNUM_BBN1822 5 +#define AFNUM_802 6 +#define AFNUM_E163 7 +#define AFNUM_E164 8 +#define AFNUM_F69 9 +#define AFNUM_X121 10 +#define AFNUM_IPX 11 +#define AFNUM_ATALK 12 +#define AFNUM_DECNET 13 +#define AFNUM_BANYAN 14 +#define AFNUM_E164NSAP 15 +#define AFNUM_DNS 16 +#define AFNUM_DN 17 +#define AFNUM_AS 18 +#define AFNUM_XTPINET 19 +#define AFNUM_XTPINET6 20 +#define AFNUM_XTP 21 +#define AFNUM_FCPORT 22 +#define AFNUM_FCNODE 23 +#define AFNUM_GWID 24 +#define AFNUM_MAX 24 +#define AFNUM_RESERVED 65535 + +#define AFNUM_NAME_STR { \ + "Reserved", \ + "IPv4", \ + "IPv6", \ + "NSAP", \ + "HDLC", \ + "BBN 1822", \ + "802", \ + "E.163", \ + "E.164", \ + "F.69", \ + "X.121", \ + "IPX", \ + "Appletalk", \ + "Decnet IV", \ + "Banyan Vines", \ + "E.164 with NSAP subaddress", \ + "DNS", \ + "AS Number", \ + "XTP over IPv4", \ + "XTP over IPv6", \ + "XTP native mode", \ + "Fibre Channel WWPN", \ + "Fibre Channel WWNN", \ + "GWID" \ +} + +#endif /* _AFNUM_H */ + diff --git a/usr.sbin/tcpdump/ethertype.h b/usr.sbin/tcpdump/ethertype.h index 042f292931f..d6fb99b96b2 100644 --- a/usr.sbin/tcpdump/ethertype.h +++ b/usr.sbin/tcpdump/ethertype.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ethertype.h,v 1.10 2005/04/24 21:17:18 brad Exp $ */ +/* $OpenBSD: ethertype.h,v 1.11 2006/03/28 15:48:33 reyk Exp $ */ /* * Copyright (c) 1993, 1994, 1996 @@ -20,7 +20,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /home/cvs/src/usr.sbin/tcpdump/ethertype.h,v 1.10 2005/04/24 21:17:18 brad Exp $ (LBL) + * @(#) $Header: /home/cvs/src/usr.sbin/tcpdump/ethertype.h,v 1.11 2006/03/28 15:48:33 reyk Exp $ (LBL) */ /* @@ -129,6 +129,9 @@ #ifndef ETHERTYPE_EAPOL #define ETHERTYPE_EAPOL 0x888e #endif +#ifndef ETHERTYPE_LLDP +#define ETHERTYPE_LLDP 0x88cc +#endif #ifndef ETHERTYPE_LOOPBACK #define ETHERTYPE_LOOPBACK 0x9000 #endif diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h index a60a590226e..7f874918216 100644 --- a/usr.sbin/tcpdump/interface.h +++ b/usr.sbin/tcpdump/interface.h @@ -1,4 +1,4 @@ -/* $OpenBSD: interface.h,v 1.51 2005/11/22 11:36:12 reyk Exp $ */ +/* $OpenBSD: interface.h,v 1.52 2006/03/28 15:48:33 reyk 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. * - * @(#) $Header: /home/cvs/src/usr.sbin/tcpdump/interface.h,v 1.51 2005/11/22 11:36:12 reyk Exp $ (LBL) + * @(#) $Header: /home/cvs/src/usr.sbin/tcpdump/interface.h,v 1.52 2006/03/28 15:48:33 reyk Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -273,6 +273,7 @@ extern void ether_print(const u_char *, u_int); extern void etherip_print(const u_char *, u_int, const u_char *); extern void ipcomp_print(const u_char *, u_int, const u_char *); extern void mpls_print(const u_char *, u_int); +extern void lldp_print(const u_char *, u_int); #ifdef INET6 extern void ip6_print(const u_char *, int); diff --git a/usr.sbin/tcpdump/print-bgp.c b/usr.sbin/tcpdump/print-bgp.c index 0f9a30a5bf0..b4688a81278 100644 --- a/usr.sbin/tcpdump/print-bgp.c +++ b/usr.sbin/tcpdump/print-bgp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: print-bgp.c,v 1.6 2005/06/14 17:57:21 moritz Exp $ */ +/* $OpenBSD: print-bgp.c,v 1.7 2006/03/28 15:48:34 reyk Exp $ */ /* * Copyright (C) 1999 WIDE Project. @@ -49,6 +49,7 @@ static const char rcsid[] = #include "interface.h" #include "addrtoname.h" #include "extract.h" +#include "afnum.h" struct bgp { u_int8_t bgp_marker[16]; @@ -204,29 +205,7 @@ static const char *bgpattr_nlri_safi[] = { #define BGP_COMMUNITY_NO_ADVERT 0xffffff02 #define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03 -/* RFC1700 address family numbers */ -#define AFNUM_INET 1 -#define AFNUM_INET6 2 -#define AFNUM_NSAP 3 -#define AFNUM_HDLC 4 -#define AFNUM_BBN1822 5 -#define AFNUM_802 6 -#define AFNUM_E163 7 -#define AFNUM_E164 8 -#define AFNUM_F69 9 -#define AFNUM_X121 10 -#define AFNUM_IPX 11 -#define AFNUM_ATALK 12 -#define AFNUM_DECNET 13 -#define AFNUM_BANYAN 14 -#define AFNUM_E164NSAP 15 - -static const char *afnumber[] = { - "Reserved", "IPv4", "IPv6", "NSAP", "HDLC", - "BBN 1822", "802", "E.163", "E.164", "F.69", - "X.121", "IPX", "Appletalk", "Decnet IV", "Banyan Vines", - "E.164 with NSAP subaddress", -}; +static const char *afnumber[] = AFNUM_NAME_STR; #define af_name(x) \ (((x) == 65535) ? afnumber[0] : \ num_or_str(afnumber, \ diff --git a/usr.sbin/tcpdump/print-ether.c b/usr.sbin/tcpdump/print-ether.c index d0db67dea31..3ac3dae0706 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.20 2005/10/08 19:45:15 canacar Exp $ */ +/* $OpenBSD: print-ether.c,v 1.21 2006/03/28 15:48:33 reyk Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/print-ether.c,v 1.20 2005/10/08 19:45:15 canacar Exp $ (LBL)"; + "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/print-ether.c,v 1.21 2006/03/28 15:48:33 reyk Exp $ (LBL)"; #endif #include <sys/param.h> @@ -240,6 +240,10 @@ recurse: mpls_print(p, length); return (1); + case ETHERTYPE_LLDP: + lldp_print(p, length); + return (1); + case ETHERTYPE_LAT: case ETHERTYPE_SCA: case ETHERTYPE_MOPRC: diff --git a/usr.sbin/tcpdump/print-lldp.c b/usr.sbin/tcpdump/print-lldp.c new file mode 100644 index 00000000000..38acdd4e5fc --- /dev/null +++ b/usr.sbin/tcpdump/print-lldp.c @@ -0,0 +1,287 @@ +/* $OpenBSD: print-lldp.c,v 1.1 2006/03/28 15:48:33 reyk Exp $ */ + +/* + * Copyright (c) 2006 Reyk Floeter <reyk@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. + */ + +#include <sys/param.h> +#include <sys/time.h> +#include <sys/socket.h> + +#include <net/if.h> + +#include <arpa/inet.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/if_ether.h> + +#include <ctype.h> +#include <stdio.h> +#include <string.h> + +#include "addrtoname.h" +#include "interface.h" +#include "afnum.h" + +enum { + LLDP_TLV_END = 0, + LLDP_TLV_CHASSIS_ID = 1, + LLDP_TLV_PORT_ID = 2, + LLDP_TLV_TTL = 3, + LLDP_TLV_PORT_DESCR = 4, + LLDP_TLV_SYSTEM_NAME = 5, + LLDP_TLV_SYSTEM_DESCR = 6, + LLDP_TLV_SYSTEM_CAP = 7, + LLDP_TLV_MANAGEMENT_ADDR = 8, + LLDP_TLV_ORG = 127 +}; + +enum { + LLDP_CHASSISID_SUBTYPE_CHASSIS = 1, + LLDP_CHASSISID_SUBTYPE_IFALIAS = 2, + LLDP_CHASSISID_SUBTYPE_PORT = 3, + LLDP_CHASSISID_SUBTYPE_LLADDR = 4, + LLDP_CHASSISID_SUBTYPE_ADDR = 5, + LLDP_CHASSISID_SUBTYPE_IFNAME = 6, + LLDP_CHASSISID_SUBTYPE_LOCAL = 7 +}; + +enum { + LLDP_PORTID_SUBTYPE_IFALIAS = 1, + LLDP_PORTID_SUBTYPE_PORT = 2, + LLDP_PORTID_SUBTYPE_LLADDR = 3, + LLDP_PORTID_SUBTYPE_ADDR = 4, + LLDP_PORTID_SUBTYPE_IFNAME = 5, + LLDP_PORTID_SUBTYPE_AGENTCID = 6, + LLDP_PORTID_SUBTYPE_LOCAL = 7 +}; + +#define LLDP_CAP_OTHER 0x01 +#define LLDP_CAP_REPEATER 0x02 +#define LLDP_CAP_BRIDGE 0x04 +#define LLDP_CAP_WLAN 0x08 +#define LLDP_CAP_ROUTER 0x10 +#define LLDP_CAP_TELEPHONE 0x20 +#define LLDP_CAP_DOCSIS 0x40 +#define LLDP_CAP_STATION 0x80 +#define LLDP_CAP_BITS \ + "\20\01OTHER\02REPEATER\03BRIDGE\04WLAN\05ROUTER\06TELEPHONE" \ + "\07DOCSIS\10STATION" + +enum { + LLDP_MGMT_IFACE_UNKNOWN = 1, + LLDP_MGMT_IFACE_IFINDEX = 2, + LLDP_MGMT_IFACE_SYSPORT = 3 +}; + +static const char *afnumber[] = AFNUM_NAME_STR; + +void +lldp_print_str(u_int8_t *str, int len) +{ + int i; + printf("\""); + for (i = 0; i < len; i++) + printf("%c", isprint(str[i]) ? str[i] : '.'); + printf("\""); +} + +void +lldp_print_id(int type, u_int8_t *ptr, int len) +{ + u_int8_t id; + u_int8_t *data; + + id = *(u_int8_t *)ptr; + len -= sizeof(u_int8_t); + data = ptr + sizeof(u_int8_t); + if (len <= 0) + return; + + if (type == LLDP_TLV_CHASSIS_ID) { + switch (id) { + case LLDP_CHASSISID_SUBTYPE_CHASSIS: + printf("chassis "); + lldp_print_str(data, len); + break; + case LLDP_CHASSISID_SUBTYPE_IFALIAS: + printf("ifalias"); + break; + case LLDP_CHASSISID_SUBTYPE_PORT: + printf("port"); + break; + case LLDP_CHASSISID_SUBTYPE_LLADDR: + printf("lladdr %s", + ether_ntoa((struct ether_addr *)data)); + break; + case LLDP_CHASSISID_SUBTYPE_ADDR: + printf("addr"); + break; + case LLDP_CHASSISID_SUBTYPE_IFNAME: + printf("ifname "); + lldp_print_str(data, len); + break; + case LLDP_CHASSISID_SUBTYPE_LOCAL: + printf("local "); + lldp_print_str(data, len); + break; + default: + printf("unknown 0x%02x", id); + break; + } + + } else if (type == LLDP_TLV_PORT_ID) { + switch (id) { + case LLDP_PORTID_SUBTYPE_IFALIAS: + printf("ifalias"); + break; + case LLDP_PORTID_SUBTYPE_PORT: + printf("port"); + break; + case LLDP_PORTID_SUBTYPE_LLADDR: + printf("lladdr %s", + ether_ntoa((struct ether_addr *)data)); + break; + case LLDP_PORTID_SUBTYPE_ADDR: + printf("addr"); + break; + case LLDP_PORTID_SUBTYPE_IFNAME: + printf("ifname "); + lldp_print_str(data, len); + break; + case LLDP_PORTID_SUBTYPE_AGENTCID: + printf("agentcid"); + break; + case LLDP_PORTID_SUBTYPE_LOCAL: + printf("local "); + lldp_print_str(data, len); + break; + default: + printf("unknown 0x%02x", id); + break; + } + } +} + +void +lldp_print(const u_char *p, u_int len) +{ + u_int16_t tlv; + u_int8_t *ptr = (u_int8_t *)p, v = 0; + int n, type, vlen, alen; + + printf("LLDP"); + +#define _ptrinc(_v) ptr += (_v); vlen -= (_v); + + for (n = 0; n < len;) { + TCHECK2(*ptr, sizeof(tlv)); + + tlv = ntohs(*(u_int16_t *)ptr); + type = (tlv & 0xfe00) >> 9; + vlen = tlv & 0x1ff; + n += vlen; + + ptr += sizeof(tlv); + TCHECK2(*ptr, vlen); + + switch (type) { + case LLDP_TLV_END: + goto done; + break; + + case LLDP_TLV_CHASSIS_ID: + printf(", Chassis ID: "); + lldp_print_id(type, ptr, vlen); + break; + + case LLDP_TLV_PORT_ID: + printf(", Port ID: "); + lldp_print_id(type, ptr, vlen); + break; + + case LLDP_TLV_TTL: + printf(", TTL: "); + TCHECK2(*ptr, 2); + printf("%ds", ntohs(*(u_int16_t *)ptr)); + break; + + case LLDP_TLV_PORT_DESCR: + printf(", Port Description: "); + lldp_print_str(ptr, vlen); + break; + + case LLDP_TLV_SYSTEM_NAME: + printf(", System Name: "); + lldp_print_str(ptr, vlen); + break; + + case LLDP_TLV_SYSTEM_DESCR: + printf(", System Description: "); + lldp_print_str(ptr, vlen); + break; + + case LLDP_TLV_SYSTEM_CAP: + printf(", System Capabilities:"); + TCHECK2(*ptr, 4); + printb(" available", ntohs(*(u_int16_t *)ptr), + LLDP_CAP_BITS); + _ptrinc(sizeof(u_int16_t)); + printb(" enabled", ntohs(*(u_int16_t *)ptr), + LLDP_CAP_BITS); + break; + + case LLDP_TLV_MANAGEMENT_ADDR: + printf(", Management Address:"); + TCHECK2(*ptr, 2); + alen = *ptr - sizeof(u_int8_t); + _ptrinc(sizeof(u_int8_t)); + v = *ptr; + _ptrinc(sizeof(u_int8_t)); + if (v <= AFNUM_MAX) + printf(" %s", afnumber[v]); + else + printf(" type %d", v); + TCHECK2(*ptr, alen); + switch (v) { + case AFNUM_INET: + if (alen != sizeof(struct in_addr)) + goto trunc; + printf(" %s", + inet_ntoa(*(struct in_addr*)ptr)); + break; + } + _ptrinc(alen); + v = *(u_int8_t *)ptr; + break; + + case LLDP_TLV_ORG: + printf(", Org Specific"); + break; + + default: + printf(", type %d length %d", type, vlen); + break; + } + ptr += vlen; + } + + done: + return; + + trunc: + printf(" [|LLDP]"); +} + |