From: hannes Date: Sun, 10 Jul 2005 14:41:34 +0000 (+0000) Subject: add support for the IEEE slow protocols LACP, MARKER as per 802.3ad X-Git-Tag: tcpdump-4.0.0~371 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/c56e09a204cc3b00c41845f1d3ea7693bcef7496 add support for the IEEE slow protocols LACP, MARKER as per 802.3ad --- diff --git a/FILES b/FILES index ebd02cbd..73e29197 100644 --- a/FILES +++ b/FILES @@ -188,6 +188,7 @@ print-sctp.c print-sip.c print-sl.c print-sll.c +print-slow.c print-smb.c print-snmp.c print-stp.c diff --git a/Makefile.in b/Makefile.in index edd83280..9cdf4098 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,7 +17,7 @@ # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # -# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.294 2005-05-20 21:02:29 hannes Exp $ (LBL) +# @(#) $Header: /tcpdump/master/tcpdump/Makefile.in,v 1.295 2005-07-10 14:44:50 hannes Exp $ (LBL) # # Various configurable paths (remember to edit Makefile.in, not Makefile) @@ -84,7 +84,7 @@ CSRC = addrtoname.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c \ print-pflog.c print-pgm.c print-pim.c print-ppp.c print-pppoe.c \ print-pptp.c print-radius.c print-raw.c print-rip.c \ print-rsvp.c print-rx.c print-sctp.c print-sip.c print-sl.c print-sll.c \ - print-snmp.c print-stp.c print-sunatm.c print-sunrpc.c \ + print-slow.c print-snmp.c print-stp.c print-sunatm.c print-sunrpc.c \ print-symantec.c print-syslog.c print-tcp.c print-telnet.c print-tftp.c \ print-timed.c print-token.c print-udp.c print-vjc.c print-vrrp.c \ print-wb.c print-zephyr.c setsignal.c tcpdump.c util.c diff --git a/ethertype.h b/ethertype.h index 6e93be9f..4f85202b 100644 --- a/ethertype.h +++ b/ethertype.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.24 2004-10-07 16:04:07 hannes Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.25 2005-07-10 14:49:48 hannes Exp $ (LBL) */ /* @@ -109,6 +109,9 @@ #ifndef ETHERTYPE_PPP #define ETHERTYPE_PPP 0x880b #endif +#ifndef ETHERTYPE_SLOW +#define ETHERTYPE_SLOW 0x8809 +#endif #ifndef ETHERTYPE_MPLS #define ETHERTYPE_MPLS 0x8847 #endif diff --git a/interface.h b/interface.h index 66639b06..605c8a46 100644 --- a/interface.h +++ b/interface.h @@ -18,7 +18,7 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.257 2005-07-07 01:22:15 guy Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.258 2005-07-10 14:41:35 hannes Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -285,6 +285,7 @@ extern const char *nt_errstr(u_int32_t); extern void print_data(const unsigned char *, int); extern void l2tp_print(const u_char *, u_int); extern void vrrp_print(const u_char *, u_int, int); +extern void slow_print(const u_char *, u_int); extern void pgm_print(const u_char *, u_int, const u_char *); extern void cdp_print(const u_char *, u_int, u_int); extern void stp_print(const u_char *, u_int); diff --git a/print-ether.c b/print-ether.c index ace88877..13c06174 100644 --- a/print-ether.c +++ b/print-ether.c @@ -20,7 +20,7 @@ */ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.98 2005-07-07 01:22:17 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.99 2005-07-10 14:41:34 hannes Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -65,6 +65,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_AARP, "Appletalk ARP" }, { ETHERTYPE_IPX, "IPX" }, { ETHERTYPE_PPP, "PPP" }, + { ETHERTYPE_SLOW, "Slow Protocols" }, { ETHERTYPE_PPPOED, "PPPoE D" }, { ETHERTYPE_PPPOES, "PPPoE S" }, { ETHERTYPE_EAPOL, "EAPOL" }, @@ -295,6 +296,10 @@ ether_encap_print(u_short ether_type, const u_char *p, } return (1); + case ETHERTYPE_SLOW: + slow_print(p, length); + return (1); + case ETHERTYPE_LOOPBACK: return (1); diff --git a/print-slow.c b/print-slow.c new file mode 100644 index 00000000..4038b9ec --- /dev/null +++ b/print-slow.c @@ -0,0 +1,264 @@ +/* + * 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) + */ + +#ifndef lint +static const char rcsid[] _U_ = + "@(#) $Header: /tcpdump/master/tcpdump/print-slow.c,v 1.1 2005-07-10 14:41:34 hannes Exp $"; +#endif + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include +#include + +#include "interface.h" +#include "extract.h" +#include "addrtoname.h" +#include "ether.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 + +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"}, + { 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]; +}; + +static const struct tok lacp_tlv_actor_partner_info_state_values[] = { + { 0x01, "Activity"}, + { 0x02, "Timeout"}, + { 0x04, "Aggregation"}, + { 0x08, "Synchronization"}, + { 0x10, "Collecting"}, + { 0x20, "Distributing"}, + { 0x40, "Default"}, + { 0x80, "Expired"}, + { 0, NULL} +}; + +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 { + const struct lacp_marker_tlv_terminator_t *lacp_marker_tlv_terminator; + const struct lacp_tlv_actor_partner_info_t *lacp_tlv_actor_partner_info; + const struct lacp_tlv_collector_info_t *lacp_tlv_collector_info; + const 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; + + 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) && + tlv_header->type != LACP_TLV_TERMINATOR && + tlv_header->type != MARKER_TLV_TERMINATOR) { + printf("\n\t-----trailing data-----"); + print_unknown_data(tptr+sizeof(sizeof(struct tlv_header_t)),"\n\t ",tlen); + 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.lacp_tlv_actor_partner_info = (const struct lacp_tlv_actor_partner_info_t *)tlv_tptr; + + printf("\n\t System %s, System Priority %u, Key %u" \ + ", Port %u, Port Priority %u\n\t State Flags [%s]", + etheraddr_string(tlv_ptr.lacp_tlv_actor_partner_info->sys), + EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri), + EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->key), + EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port), + EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port_pri), + bittok2str(lacp_tlv_actor_partner_info_state_values, + "none", + tlv_ptr.lacp_tlv_actor_partner_info->state)); + + break; + + case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO): + tlv_ptr.lacp_tlv_collector_info = (const struct lacp_tlv_collector_info_t *)tlv_tptr; + + printf("\n\t Max Delay %u", + EXTRACT_16BITS(tlv_ptr.lacp_tlv_collector_info->max_delay)); + + break; + + case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO): + tlv_ptr.marker_tlv_marker_info = (const struct marker_tlv_marker_info_t *)tlv_tptr; + + 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; + + /* those two TLVs have the same structure -> fall through */ + case ((SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR): + case ((SLOW_PROTO_MARKER << 8) + LACP_TLV_TERMINATOR): + tlv_ptr.lacp_marker_tlv_terminator = (const struct lacp_marker_tlv_terminator_t *)tlv_tptr; + if (tlv_len == 0) { + tlv_len = sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad) + + sizeof(struct tlv_header_t); + /* tell the user that we modified the length field */ + if (vflag>1) + printf(" (=%u)",tlv_len); + /* we have messed around with the length field - now we need to check + * again if there are enough bytes on the wire for the hexdump */ + TCHECK2(tlv_ptr.lacp_marker_tlv_terminator->pad[0], + sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad)); + } + + break; + + default: + if (vflag <= 1) + print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen); + break; + } + /* do we want to see an additionally hexdump ? */ + if (vflag > 1) + print_unknown_data(tptr+sizeof(sizeof(struct tlv_header_t)),"\n\t ", + tlv_len-sizeof(struct tlv_header_t)); + + tptr+=tlv_len; + tlen-=tlv_len; + } + return; +trunc: + printf("\n\t\t packet exceeded snapshot"); +}