4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * From: NetBSD: print-arcnet.c,v 1.2 2000/04/24 13:02:28 itojun Exp
25 #include <sys/cdefs.h>
28 static const char rcsid
[] _U_
=
29 "@(#) Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.20 2005/04/06 21:32:38 mcr Exp (LBL)";
31 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
39 #include <tcpdump-stdinc.h>
44 #include "interface.h"
47 static int arcnet_encap_print(u_char arctype
, const u_char
*p
,
48 u_int length
, u_int caplen
);
50 struct tok arctypemap
[] = {
51 { ARCTYPE_IP_OLD
, "oldip" },
52 { ARCTYPE_ARP_OLD
, "oldarp" },
54 { ARCTYPE_ARP
, "arp" },
55 { ARCTYPE_REVARP
, "rarp" },
56 { ARCTYPE_ATALK
, "atalk" },
57 { ARCTYPE_BANIAN
, "banyan" },
58 { ARCTYPE_IPX
, "ipx" },
59 { ARCTYPE_INET6
, "ipv6" },
60 { ARCTYPE_DIAGNOSE
, "diag" },
65 arcnet_print(const u_char
*bp
, u_int length
, int phds
, int flag
, u_int seqid
)
67 const struct arc_header
*ap
;
68 const char *arctypename
;
71 ap
= (const struct arc_header
*)bp
;
75 (void)printf("%02x %02x %d: ",
82 arctypename
= tok2str(arctypemap
, "%02x", ap
->arc_type
);
85 (void)printf("%02x %02x %s %d: ",
86 ap
->arc_shost
, ap
->arc_dhost
, arctypename
,
92 (void)printf("%02x %02x %s seqid %04x %d: ",
93 ap
->arc_shost
, ap
->arc_dhost
, arctypename
, seqid
,
99 (void)printf("%02x %02x %s seqid %04x "
100 "(first of %d fragments) %d: ",
101 ap
->arc_shost
, ap
->arc_dhost
, arctypename
, seqid
,
102 (flag
+ 3) / 2, length
);
104 (void)printf("%02x %02x %s seqid %04x "
105 "(fragment %d) %d: ",
106 ap
->arc_shost
, ap
->arc_dhost
, arctypename
, seqid
,
111 * This is the top level routine of the printer. 'p' points
112 * to the ARCNET header of the packet, 'h->ts' is the timestamp,
113 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
114 * is the number of bytes actually captured.
117 arcnet_if_print(const struct pcap_pkthdr
*h
, const u_char
*p
)
119 u_int caplen
= h
->caplen
;
120 u_int length
= h
->len
;
121 const struct arc_header
*ap
;
123 int phds
, flag
= 0, archdrlen
= 0;
127 if (caplen
< ARC_HDRLEN
) {
132 ap
= (const struct arc_header
*)p
;
133 arc_type
= ap
->arc_type
;
140 case ARCTYPE_ARP_OLD
:
141 case ARCTYPE_DIAGNOSE
:
143 archdrlen
= ARC_HDRLEN
;
148 if (caplen
< ARC_HDRNEWLEN
) {
149 arcnet_print(p
, length
, 0, 0, 0);
154 if (ap
->arc_flag
== 0xff) {
155 if (caplen
< ARC_HDRNEWLEN_EXC
) {
156 arcnet_print(p
, length
, 0, 0, 0);
157 printf("[|phds extended]");
160 flag
= ap
->arc_flag2
;
161 seqid
= ntohs(ap
->arc_seqid2
);
162 archdrlen
= ARC_HDRNEWLEN_EXC
;
165 seqid
= ntohs(ap
->arc_seqid
);
166 archdrlen
= ARC_HDRNEWLEN
;
172 arcnet_print(p
, length
, phds
, flag
, seqid
);
175 * Go past the ARCNET header.
181 if (phds
&& flag
&& (flag
& 1) == 0) {
183 * This is a middle fragment.
188 if (!arcnet_encap_print(arc_type
, p
, length
, caplen
))
189 default_print(p
, caplen
);
195 * This is the top level routine of the printer. 'p' points
196 * to the ARCNET header of the packet, 'h->ts' is the timestamp,
197 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
198 * is the number of bytes actually captured. It is quite similar
199 * to the non-Linux style printer except that Linux doesn't ever
200 * supply packets that look like exception frames, it always supplies
201 * reassembled packets rather than raw frames, and headers have an
202 * extra "offset" field between the src/dest and packet type.
205 arcnet_linux_if_print(const struct pcap_pkthdr
*h
, const u_char
*p
)
207 u_int caplen
= h
->caplen
;
208 u_int length
= h
->len
;
209 const struct arc_linux_header
*ap
;
214 if (caplen
< ARC_LINUX_HDRLEN
) {
219 ap
= (const struct arc_linux_header
*)p
;
220 arc_type
= ap
->arc_type
;
224 archdrlen
= ARC_LINUX_HDRNEWLEN
;
225 if (caplen
< ARC_LINUX_HDRNEWLEN
) {
231 case ARCTYPE_ARP_OLD
:
232 case ARCTYPE_DIAGNOSE
:
233 archdrlen
= ARC_LINUX_HDRLEN
;
238 arcnet_print(p
, length
, 0, 0, 0);
241 * Go past the ARCNET header.
247 if (!arcnet_encap_print(arc_type
, p
, length
, caplen
))
248 default_print(p
, caplen
);
254 * Prints the packet encapsulated in an ARCnet data field,
255 * given the ARCnet system code.
257 * Returns non-zero if it can do so, zero if the system code is unknown.
262 arcnet_encap_print(u_char arctype
, const u_char
*p
,
263 u_int length
, u_int caplen
)
269 ip_print(gndo
, p
, length
);
274 ip6_print(p
, length
);
278 case ARCTYPE_ARP_OLD
:
281 arp_print(gndo
, p
, length
, caplen
);
284 case ARCTYPE_ATALK
: /* XXX was this ever used? */
286 fputs("et1 ", stdout
);
287 atalk_print(p
, length
);
291 ipx_print(p
, length
);