From: guy Date: Thu, 23 Jan 2003 09:05:37 +0000 (+0000) Subject: From Peter Fales : add support for X-Git-Tag: tcpdump-3.8-bp~226 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/ad06a893cfd3acca3fba38d8b39b6b15dd3053ea From Peter Fales : add support for DLT_ARCNET_LINUX. Also handle IPX-over-ARCNET. --- diff --git a/CREDITS b/CREDITS index 088f60f5..89159596 100644 --- a/CREDITS +++ b/CREDITS @@ -86,6 +86,7 @@ Additional people who have contributed patches: Paul S. Traina Pavlin Radoslavov Pekka Savola + Peter Fales Peter Jeremy Phil Wood Rafal Maszkowski diff --git a/arcnet.h b/arcnet.h index 144e99b6..3b609566 100644 --- a/arcnet.h +++ b/arcnet.h @@ -30,13 +30,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#) $Id: arcnet.h,v 1.2 2002-12-11 07:13:50 guy Exp $ (LBL) + * @(#) $Id: arcnet.h,v 1.3 2003-01-23 09:05:37 guy Exp $ (LBL) * * from: NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp */ /* - * Structure of a 2.5MB/s Arcnet header. + * Structure of a 2.5MB/s Arcnet header on the BSDs, * as given to interface code. */ struct arc_header { @@ -77,3 +77,25 @@ struct arc_header { #define ARCTYPE_INET6 0xc4 /* IPng */ #define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */ + +/* + * Structure of a 2.5MB/s Arcnet header on Linux. Linux has + * an extra "offset" field when given to interface code, and + * never presents packets that look like exception frames. + */ +struct arc_linux_header { + u_int8_t arc_shost; + u_int8_t arc_dhost; + u_int16_t arc_offset; + u_int8_t arc_type; + /* + * only present for newstyle encoding with LL fragmentation. + * Don't use sizeof(anything), use ARC_LINUX_HDR{,NEW}LEN + * instead. + */ + u_int8_t arc_flag; + u_int16_t arc_seqid; +}; + +#define ARC_LINUX_HDRLEN 5 +#define ARC_LINUX_HDRNEWLEN 8 diff --git a/interface.h b/interface.h index 9d2a41fc..5a164032 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.204 2002-12-22 01:26:48 hannes Exp $ (LBL) + * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.205 2003-01-23 09:05:38 guy Exp $ (LBL) */ #ifndef tcpdump_interface_h @@ -214,6 +214,7 @@ extern void dvmrp_print(const u_char *, u_int); extern void egp_print(const u_char *); extern u_int pflog_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int arcnet_if_print(const struct pcap_pkthdr *, const u_char *); +extern u_int arcnet_linux_if_print(const struct pcap_pkthdr *, const u_char *); extern void ether_print(const u_char *, u_int, u_int); extern u_int ether_if_print(const struct pcap_pkthdr *, const u_char *); diff --git a/print-arcnet.c b/print-arcnet.c index 50d7bf83..abec0240 100644 --- a/print-arcnet.c +++ b/print-arcnet.c @@ -22,7 +22,7 @@ */ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.13 2002-12-19 09:39:10 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.14 2003-01-23 09:05:38 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -171,8 +171,71 @@ arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p) caplen -= archdrlen; p += archdrlen; - if (phds && flag && (flag & 1) == 0) + if (phds && flag && (flag & 1) == 0) { + /* + * This is a middle fragment. + */ return (archdrlen); + } + + if (!arcnet_encap_print(arc_type, p, length, caplen)) + default_print(p, caplen); + + return (archdrlen); +} + +/* + * This is the top level routine of the printer. 'p' points + * to the ARCNET header of the packet, 'h->ts' is the timestamp, + * 'h->length' is the length of the packet off the wire, and 'h->caplen' + * is the number of bytes actually captured. It is quite similar + * to the non-Linux style printer except that Linux doesn't ever + * supply packets that look like exception frames, and headers have an + * extra "offset" field between the src/dest and packet type. + */ +u_int +arcnet_linux_if_print(const struct pcap_pkthdr *h, const u_char *p) +{ + u_int caplen = h->caplen; + u_int length = h->len; + const struct arc_linux_header *ap; + + int flag = 0, archdrlen = 0; + u_int seqid = 0; + u_char arc_type; + + if (caplen < ARC_LINUX_HDRLEN) { + printf("[|arcnet]"); + return (caplen); + } + + ap = (const struct arc_linux_header *)p; + arc_type = ap->arc_type; + + switch (arc_type) { + default: + archdrlen = ARC_LINUX_HDRNEWLEN; + if (caplen < ARC_LINUX_HDRNEWLEN) { + printf("[|arcnet]"); + return (caplen); + } + break; + case ARCTYPE_IP_OLD: + case ARCTYPE_ARP_OLD: + case ARCTYPE_DIAGNOSE: + archdrlen = ARC_LINUX_HDRLEN; + break; + } + + if (eflag) + arcnet_print(p, length, 0, flag, seqid); + + /* + * Go past the ARCNET header. + */ + length -= archdrlen; + caplen -= archdrlen; + p += archdrlen; if (!arcnet_encap_print(arc_type, p, length, caplen)) default_print(p, caplen); @@ -217,6 +280,10 @@ arcnet_encap_print(u_char arctype, const u_char *p, atalk_print(p, length); return (1); + case ARCTYPE_IPX: + ipx_print(p, length); + return (1); + default: return (0); } diff --git a/tcpdump.c b/tcpdump.c index 216bad49..e8a89fbe 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -30,7 +30,7 @@ static const char copyright[] = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ The Regents of the University of California. All rights reserved.\n"; static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.200 2003-01-16 07:55:06 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.201 2003-01-23 09:05:38 guy Exp $ (LBL)"; #endif /* @@ -132,6 +132,9 @@ struct printer { static struct printer printers[] = { { arcnet_if_print, DLT_ARCNET }, +#ifdef DLT_ARCNET_LINUX + { arcnet_linux_if_print, DLT_ARCNET_LINUX }, +#endif { ether_if_print, DLT_EN10MB }, { token_if_print, DLT_IEEE802 }, #ifdef DLT_LANE8023