]> The Tcpdump Group git mirrors - tcpdump/commitdiff
From Peter Fales <[email protected]>: add support for
authorguy <guy>
Thu, 23 Jan 2003 09:05:37 +0000 (09:05 +0000)
committerguy <guy>
Thu, 23 Jan 2003 09:05:37 +0000 (09:05 +0000)
DLT_ARCNET_LINUX.

Also handle IPX-over-ARCNET.

CREDITS
arcnet.h
interface.h
print-arcnet.c
tcpdump.c

diff --git a/CREDITS b/CREDITS
index 088f60f5a401c5ae0b65ea50fcf5ec0268ca26d6..8915959600f9ea2fae4f51e6d42bbc399aeaddf8 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -86,6 +86,7 @@ Additional people who have contributed patches:
        Paul S. Traina                  <[email protected]>
        Pavlin Radoslavov               <[email protected]>
        Pekka Savola                    <[email protected]>     
+       Peter Fales                     <[email protected]>
        Peter Jeremy                    <[email protected]>
        Phil Wood                       <[email protected]>
        Rafal Maszkowski                <[email protected]>
index 144e99b66da605392f8ba553800ac49e204aa8be..3b609566ff81bb26f755f04e2f0df9888bb8bc8f 100644 (file)
--- a/arcnet.h
+++ b/arcnet.h
  * 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
index 9d2a41fcefaab619f28a44062521d6c74f8839c5..5a16403284f81a2e1e2fe2e2bce89dbf3ca8274b 100644 (file)
@@ -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 *);
index 50d7bf833389c0602d6b8b61b2be9fd841c5bcad..abec0240e60b296d7e23ff84a55cde43eab8caf8 100644 (file)
@@ -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);
        }
index 216bad49ed25bb7f6793dd6b040e11ad08a0ef44..e8a89fbe0d2a3630ab106c6073e677b87b527a70 100644 (file)
--- 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