summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/tcpdump/Makefile4
-rw-r--r--usr.sbin/tcpdump/interface.h5
-rw-r--r--usr.sbin/tcpdump/print-ether.c8
-rw-r--r--usr.sbin/tcpdump/print-slow.c269
4 files changed, 280 insertions, 6 deletions
diff --git a/usr.sbin/tcpdump/Makefile b/usr.sbin/tcpdump/Makefile
index f1c491b42ba..859711cbfb1 100644
--- a/usr.sbin/tcpdump/Makefile
+++ b/usr.sbin/tcpdump/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.51 2006/05/23 14:20:19 stevesk Exp $
+# $OpenBSD: Makefile,v 1.52 2008/10/16 12:57:01 mpf Exp $
#
# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
# The Regents of the University of California. All rights reserved.
@@ -46,7 +46,7 @@ SRCS= tcpdump.c addrtoname.c privsep.c privsep_fdpass.c privsep_pcap.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 \
+ print-802_11.c print-iapp.c print-mpls.c print-slow.c \
gmt2local.c savestr.c setsignal.c
# TCP OS Fingerprinting
diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h
index faa67284d3b..8a226682fd4 100644
--- a/usr.sbin/tcpdump/interface.h
+++ b/usr.sbin/tcpdump/interface.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: interface.h,v 1.56 2007/10/07 16:41:05 deraadt Exp $ */
+/* $OpenBSD: interface.h,v 1.57 2008/10/16 12:57:01 mpf 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.56 2007/10/07 16:41:05 deraadt Exp $ (LBL)
+ * @(#) $Id: interface.h,v 1.57 2008/10/16 12:57:01 mpf Exp $ (LBL)
*/
#ifndef tcpdump_interface_h
@@ -277,6 +277,7 @@ extern void etherip_print(const u_char *, u_int, 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);
+extern void slow_print(const u_char *, u_int);
#ifdef INET6
extern void ip6_print(const u_char *, int);
diff --git a/usr.sbin/tcpdump/print-ether.c b/usr.sbin/tcpdump/print-ether.c
index 37014d11b68..aad24160c78 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.23 2007/10/07 16:41:05 deraadt Exp $ */
+/* $OpenBSD: print-ether.c,v 1.24 2008/10/16 12:57:01 mpf Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -22,7 +22,7 @@
*/
#ifndef lint
static const char rcsid[] =
- "@(#) $Id: print-ether.c,v 1.23 2007/10/07 16:41:05 deraadt Exp $ (LBL)";
+ "@(#) $Id: print-ether.c,v 1.24 2008/10/16 12:57:01 mpf Exp $ (LBL)";
#endif
#include <sys/param.h>
@@ -250,6 +250,10 @@ recurse:
lldp_print(p, length);
return (1);
+ case ETHERTYPE_SLOW:
+ slow_print(p, length);
+ return (1);
+
case ETHERTYPE_LAT:
case ETHERTYPE_SCA:
case ETHERTYPE_MOPRC:
diff --git a/usr.sbin/tcpdump/print-slow.c b/usr.sbin/tcpdump/print-slow.c
new file mode 100644
index 00000000000..17d262818f6
--- /dev/null
+++ b/usr.sbin/tcpdump/print-slow.c
@@ -0,0 +1,269 @@
+/* $OpenBSD: print-slow.c,v 1.1 2008/10/16 12:57:01 mpf Exp $ */
+
+/*
+ * Copyright (c) 1998-2005 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+
+struct slow_common_header {
+ u_int8_t proto_subtype;
+ u_int8_t version;
+};
+
+#define SLOW_PROTO_LACP 1
+#define SLOW_PROTO_MARKER 2
+
+#define LACP_VERSION 1
+#define MARKER_VERSION 1
+
+static const struct tok slow_proto_values[] = {
+ { SLOW_PROTO_LACP, "LACP" },
+ { SLOW_PROTO_MARKER, "MARKER" },
+ { 0, NULL}
+};
+
+struct tlv_header_t {
+ u_int8_t type;
+ u_int8_t length;
+};
+
+#define LACP_TLV_TERMINATOR 0x00
+#define LACP_TLV_ACTOR_INFO 0x01
+#define LACP_TLV_PARTNER_INFO 0x02
+#define LACP_TLV_COLLECTOR_INFO 0x03
+
+#define MARKER_TLV_TERMINATOR 0x00
+#define MARKER_TLV_MARKER_INFO 0x01
+#define MARKER_TLV_MARKER_RESP 0x02
+
+static const struct tok slow_tlv_values[] = {
+ { (SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR, "Terminator"},
+ { (SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO, "Actor Information"},
+ { (SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO,
+ "Partner Information"},
+ { (SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO,
+ "Collector Information"},
+
+ { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_TERMINATOR, "Terminator"},
+ { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO,
+ "Marker Information"},
+ { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_RESP,
+ "Marker Response Information"},
+ { 0, NULL}
+};
+
+struct lacp_tlv_actor_partner_info_t {
+ u_int8_t sys_pri[2];
+ u_int8_t sys[ETHER_ADDR_LEN];
+ u_int8_t key[2];
+ u_int8_t port_pri[2];
+ u_int8_t port[2];
+ u_int8_t state;
+ u_int8_t pad[3];
+};
+
+#define ACTOR_PARTNER_BITS \
+"\020\1Activity\2Timeout\3Aggregation\4Synchronization\5Collecting\
+\6Distributing\7Default\10Expired"
+
+struct lacp_tlv_collector_info_t {
+ u_int8_t max_delay[2];
+ u_int8_t pad[12];
+};
+
+struct marker_tlv_marker_info_t {
+ u_int8_t req_port[2];
+ u_int8_t req_sys[ETHER_ADDR_LEN];
+ u_int8_t req_trans_id[4];
+ u_int8_t pad[2];
+};
+
+struct lacp_marker_tlv_terminator_t {
+ u_int8_t pad[50];
+};
+
+void
+slow_print(register const u_char *pptr, register u_int len)
+{
+
+ const struct slow_common_header *slow_com_header;
+ const struct tlv_header_t *tlv_header;
+ const u_char *tptr, *tlv_tptr;
+ u_int tlv_len, tlen, tlv_tlen;
+
+ union {
+ struct lacp_marker_tlv_terminator_t *marker_terminator;
+ struct lacp_tlv_actor_partner_info_t *actor_partner_info;
+ struct lacp_tlv_collector_info_t *collector_info;
+ struct marker_tlv_marker_info_t *marker_tlv_marker_info;
+ } tlv_ptr;
+
+ tptr = pptr;
+ slow_com_header = (const struct slow_common_header *)pptr;
+ TCHECK(*slow_com_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (slow_com_header->proto_subtype == SLOW_PROTO_LACP &&
+ slow_com_header->version != LACP_VERSION) {
+ printf("LACP version %u packet not supported",
+ slow_com_header->version);
+ return;
+ }
+ if (slow_com_header->proto_subtype == SLOW_PROTO_MARKER &&
+ slow_com_header->version != MARKER_VERSION) {
+ printf("MARKER version %u packet not supported",
+ slow_com_header->version);
+ return;
+ }
+
+ printf("%sv%u, length: %u",
+ tok2str(slow_proto_values, "unknown (%u)",
+ slow_com_header->proto_subtype), slow_com_header->version, len);
+
+ if (!vflag)
+ return;
+
+ /* ok they seem to want to know everything - lets fully decode it */
+ tlen = len - sizeof(struct slow_common_header);
+ tptr += sizeof(const struct slow_common_header);
+
+ while (tlen > 0) {
+ /* did we capture enough for fully decoding the tlv header ? */
+ TCHECK2(*tptr, sizeof(struct tlv_header_t));
+ tlv_header = (const struct tlv_header_t *)tptr;
+ tlv_len = tlv_header->length;
+
+ /* End of message */
+ if (tlv_header->type == LACP_TLV_TERMINATOR ||
+ tlv_header->type == MARKER_TLV_TERMINATOR)
+ return;
+
+ printf("\n\t%s TLV (0x%02x), length: %u",
+ tok2str(slow_tlv_values, "Unknown",
+ (slow_com_header->proto_subtype << 8) + tlv_header->type),
+ tlv_header->type, tlv_len);
+
+ if (tlv_len < sizeof(struct tlv_header_t) || tlv_len > tlen) {
+ printf("\n\tInvalid TLV length: %u", tlv_len);
+ return;
+ }
+
+ tlv_tptr = tptr + sizeof(struct tlv_header_t);
+ tlv_tlen = tlv_len - sizeof(struct tlv_header_t);
+
+ /* did we capture enough for fully decoding the tlv ? */
+ TCHECK2(*tptr, tlv_len);
+
+ switch((slow_com_header->proto_subtype << 8) +
+ tlv_header->type) {
+
+ /* those two TLVs have the same structure -> fall through */
+ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO):
+ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO):
+ tlv_ptr.actor_partner_info =
+ (struct lacp_tlv_actor_partner_info_t *)tlv_tptr;
+ if (tlv_tlen != sizeof(*tlv_ptr.actor_partner_info)) {
+ printf("\n\tInvalid partner/actor info length %u",
+ tlv_tlen);
+ break;
+ }
+
+ printf("\n\t System %s, System Priority %u, Key %u"
+ ", Port %u, Port Priority %u\n\t ",
+ etheraddr_string(tlv_ptr.actor_partner_info->sys),
+ EXTRACT_16BITS(tlv_ptr.actor_partner_info->sys_pri),
+ EXTRACT_16BITS(tlv_ptr.actor_partner_info->key),
+ EXTRACT_16BITS(tlv_ptr.actor_partner_info->port),
+ EXTRACT_16BITS(tlv_ptr.actor_partner_info->
+ port_pri));
+ printb("State", tlv_ptr.actor_partner_info->state,
+ ACTOR_PARTNER_BITS);
+ break;
+
+ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO):
+ tlv_ptr.collector_info =
+ (struct lacp_tlv_collector_info_t *)tlv_tptr;
+ if (tlv_tlen != sizeof(*tlv_ptr.collector_info)) {
+ printf("\n\tInvalid collector info length %u",
+ tlv_tlen);
+ break;
+ }
+
+ printf("\n\t Max Delay %u",
+ EXTRACT_16BITS(tlv_ptr.collector_info->max_delay));
+ break;
+
+ case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO):
+ case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_RESP):
+ tlv_ptr.marker_tlv_marker_info =
+ (struct marker_tlv_marker_info_t *)tlv_tptr;
+ if (tlv_tlen !=
+ sizeof(*tlv_ptr.marker_tlv_marker_info)) {
+ printf("\n\tInvalid marker info/resp length %u",
+ tlv_tlen);
+ break;
+ }
+
+ printf("\n\t Request System %s, Request Port %u,"
+ " Request Transaction ID 0x%08x",
+ etheraddr_string(tlv_ptr.marker_tlv_marker_info->
+ req_sys),
+ EXTRACT_16BITS(tlv_ptr.marker_tlv_marker_info->
+ req_port),
+ EXTRACT_32BITS(tlv_ptr.marker_tlv_marker_info->
+ req_trans_id));
+ break;
+
+ default:
+ if (vflag > 1)
+ printf("\n\t Unknown TLV type: 0x%x \n",
+ (slow_com_header->proto_subtype << 8) +
+ tlv_header->type);
+ break;
+ }
+
+ tptr += tlv_len;
+ tlen -= tlv_len;
+ }
+
+ return;
+trunc:
+ printf("\n\t[|slow]");
+}