Drop ".i0", it is an undefined macro.
[netbsd-mini2440.git] / dist / tcpdump / print-arcnet.c
blob88fe7c6b2ee6d117fceccf2ae697d1677f294789
1 /* $NetBSD$ */
3 /*
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
18 * written permission.
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>
26 #ifndef lint
27 #if 0
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)";
30 #else
31 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
32 #endif
33 #endif
35 #ifdef HAVE_CONFIG_H
36 #include "config.h"
37 #endif
39 #include <tcpdump-stdinc.h>
41 #include <stdio.h>
42 #include <pcap.h>
44 #include "interface.h"
45 #include "arcnet.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" },
53 { ARCTYPE_IP, "ip" },
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" },
61 { 0, 0 }
64 static inline void
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;
74 if (qflag) {
75 (void)printf("%02x %02x %d: ",
76 ap->arc_shost,
77 ap->arc_dhost,
78 length);
79 return;
82 arctypename = tok2str(arctypemap, "%02x", ap->arc_type);
84 if (!phds) {
85 (void)printf("%02x %02x %s %d: ",
86 ap->arc_shost, ap->arc_dhost, arctypename,
87 length);
88 return;
91 if (flag == 0) {
92 (void)printf("%02x %02x %s seqid %04x %d: ",
93 ap->arc_shost, ap->arc_dhost, arctypename, seqid,
94 length);
95 return;
98 if (flag & 1)
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);
103 else
104 (void)printf("%02x %02x %s seqid %04x "
105 "(fragment %d) %d: ",
106 ap->arc_shost, ap->arc_dhost, arctypename, seqid,
107 flag/2 + 1, length);
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.
116 u_int
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;
124 u_int seqid = 0;
125 u_char arc_type;
127 if (caplen < ARC_HDRLEN) {
128 printf("[|arcnet]");
129 return (caplen);
132 ap = (const struct arc_header *)p;
133 arc_type = ap->arc_type;
135 switch (arc_type) {
136 default:
137 phds = 1;
138 break;
139 case ARCTYPE_IP_OLD:
140 case ARCTYPE_ARP_OLD:
141 case ARCTYPE_DIAGNOSE:
142 phds = 0;
143 archdrlen = ARC_HDRLEN;
144 break;
147 if (phds) {
148 if (caplen < ARC_HDRNEWLEN) {
149 arcnet_print(p, length, 0, 0, 0);
150 printf("[|phds]");
151 return (caplen);
154 if (ap->arc_flag == 0xff) {
155 if (caplen < ARC_HDRNEWLEN_EXC) {
156 arcnet_print(p, length, 0, 0, 0);
157 printf("[|phds extended]");
158 return (caplen);
160 flag = ap->arc_flag2;
161 seqid = ntohs(ap->arc_seqid2);
162 archdrlen = ARC_HDRNEWLEN_EXC;
163 } else {
164 flag = ap->arc_flag;
165 seqid = ntohs(ap->arc_seqid);
166 archdrlen = ARC_HDRNEWLEN;
171 if (eflag)
172 arcnet_print(p, length, phds, flag, seqid);
175 * Go past the ARCNET header.
177 length -= archdrlen;
178 caplen -= archdrlen;
179 p += archdrlen;
181 if (phds && flag && (flag & 1) == 0) {
183 * This is a middle fragment.
185 return (archdrlen);
188 if (!arcnet_encap_print(arc_type, p, length, caplen))
189 default_print(p, caplen);
191 return (archdrlen);
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.
204 u_int
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;
211 int archdrlen = 0;
212 u_char arc_type;
214 if (caplen < ARC_LINUX_HDRLEN) {
215 printf("[|arcnet]");
216 return (caplen);
219 ap = (const struct arc_linux_header *)p;
220 arc_type = ap->arc_type;
222 switch (arc_type) {
223 default:
224 archdrlen = ARC_LINUX_HDRNEWLEN;
225 if (caplen < ARC_LINUX_HDRNEWLEN) {
226 printf("[|arcnet]");
227 return (caplen);
229 break;
230 case ARCTYPE_IP_OLD:
231 case ARCTYPE_ARP_OLD:
232 case ARCTYPE_DIAGNOSE:
233 archdrlen = ARC_LINUX_HDRLEN;
234 break;
237 if (eflag)
238 arcnet_print(p, length, 0, 0, 0);
241 * Go past the ARCNET header.
243 length -= archdrlen;
244 caplen -= archdrlen;
245 p += archdrlen;
247 if (!arcnet_encap_print(arc_type, p, length, caplen))
248 default_print(p, caplen);
250 return (archdrlen);
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.
261 static int
262 arcnet_encap_print(u_char arctype, const u_char *p,
263 u_int length, u_int caplen)
265 switch (arctype) {
267 case ARCTYPE_IP_OLD:
268 case ARCTYPE_IP:
269 ip_print(gndo, p, length);
270 return (1);
272 #ifdef INET6
273 case ARCTYPE_INET6:
274 ip6_print(p, length);
275 return (1);
276 #endif /*INET6*/
278 case ARCTYPE_ARP_OLD:
279 case ARCTYPE_ARP:
280 case ARCTYPE_REVARP:
281 arp_print(gndo, p, length, caplen);
282 return (1);
284 case ARCTYPE_ATALK: /* XXX was this ever used? */
285 if (vflag)
286 fputs("et1 ", stdout);
287 atalk_print(p, length);
288 return (1);
290 case ARCTYPE_IPX:
291 ipx_print(p, length);
292 return (1);
294 default:
295 return (0);
300 * Local Variables:
301 * c-style: bsd
302 * End: