summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2006-03-28 15:48:33 +0000
committerreyk <reyk@openbsd.org>2006-03-28 15:48:33 +0000
commitd7869ad73a59a677a0e4c21a160d18548b95b36a (patch)
treeb4e44865e8dd82c1dc74bfc97764b5e0b7aa8623 /usr.sbin
parentuse clock_gettime if available. (diff)
downloadwireguard-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/Makefile4
-rw-r--r--usr.sbin/tcpdump/afnum.h81
-rw-r--r--usr.sbin/tcpdump/ethertype.h7
-rw-r--r--usr.sbin/tcpdump/interface.h5
-rw-r--r--usr.sbin/tcpdump/print-bgp.c27
-rw-r--r--usr.sbin/tcpdump/print-ether.c8
-rw-r--r--usr.sbin/tcpdump/print-lldp.c287
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]");
+}
+