X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/4bec97f457e593be925e92fa28d73af6a57d81cf..a2eaf8ffa75adaf3f4e8e45fd6b5b28f4505e184:/print-arcnet.c diff --git a/print-arcnet.c b/print-arcnet.c index 50d7bf83..08da74f0 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.15 2003-01-23 09:15:14 guy Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -151,11 +151,11 @@ arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p) return (caplen); } flag = ap->arc_flag2; - seqid = ap->arc_seqid2; + seqid = ntohs(ap->arc_seqid2); archdrlen = ARC_HDRNEWLEN_EXC; } else { flag = ap->arc_flag; - seqid = ap->arc_seqid; + seqid = ntohs(ap->arc_seqid); archdrlen = ARC_HDRNEWLEN; } } @@ -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, it always supplies + * reassembled packets rather than raw 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 archdrlen = 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, 0, 0); + + /* + * 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); }