]> The Tcpdump Group git mirrors - tcpdump/blob - print-arcnet.c
whitespace cleanup
[tcpdump] / print-arcnet.c
1 /*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * From: NetBSD: print-arcnet.c,v 1.2 2000/04/24 13:02:28 itojun Exp
22 */
23 #ifndef lint
24 static const char rcsid[] =
25 "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.8 2002-06-11 17:08:41 itojun Exp $ (LBL)";
26 #endif
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <sys/param.h>
33 #include <sys/time.h>
34 #include <sys/socket.h>
35
36 #include <netinet/in.h>
37
38 #include <stdio.h>
39 #include <pcap.h>
40
41 #include "interface.h"
42 #include "arcnet.h"
43
44 int arcnet_encap_print(u_char arctype, const u_char *p,
45 u_int length, u_int caplen);
46
47 struct tok arctypemap[] = {
48 { ARCTYPE_IP_OLD, "oldip" },
49 { ARCTYPE_ARP_OLD, "oldarp" },
50 { ARCTYPE_IP, "ip" },
51 { ARCTYPE_ARP, "arp" },
52 { ARCTYPE_REVARP, "rarp" },
53 { ARCTYPE_ATALK, "atalk" },
54 { ARCTYPE_BANIAN, "banyan" },
55 { ARCTYPE_IPX, "ipx" },
56 { ARCTYPE_INET6, "ipv6" },
57 { ARCTYPE_DIAGNOSE, "diag" },
58 { 0, 0 }
59 };
60
61 static inline void
62 arcnet_print(const u_char *bp, u_int length, int phds, int flag, u_int seqid)
63 {
64 const struct arc_header *ap;
65 const char *arctypename;
66
67
68 ap = (const struct arc_header *)bp;
69
70
71 if (qflag) {
72 (void)printf("%02x %02x %d: ",
73 ap->arc_shost,
74 ap->arc_dhost,
75 length);
76 return;
77 }
78
79 arctypename = tok2str(arctypemap, "%02x", ap->arc_type);
80
81 if (!phds) {
82 (void)printf("%02x %02x %s %d: ",
83 ap->arc_shost, ap->arc_dhost, arctypename,
84 length);
85 return;
86 }
87
88 if (flag == 0) {
89 (void)printf("%02x %02x %s seqid %04x %d: ",
90 ap->arc_shost, ap->arc_dhost, arctypename, seqid,
91 length);
92 return;
93 }
94
95 if (flag & 1)
96 (void)printf("%02x %02x %s seqid %04x "
97 "(first of %d fragments) %d: ",
98 ap->arc_shost, ap->arc_dhost, arctypename, seqid,
99 (flag + 3) / 2, length);
100 else
101 (void)printf("%02x %02x %s seqid %04x "
102 "(fragment %d) %d: ",
103 ap->arc_shost, ap->arc_dhost, arctypename, seqid,
104 flag/2 + 1, length);
105 }
106
107 /*
108 * This is the top level routine of the printer. 'p' is the points
109 * to the ether header of the packet, 'tvp' is the timestamp,
110 * 'length' is the length of the packet off the wire, and 'caplen'
111 * is the number of bytes actually captured.
112 */
113 void
114 arcnet_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
115 {
116 u_int caplen = h->caplen;
117 u_int length = h->len;
118 const struct arc_header *ap;
119
120 int phds, flag = 0, archdrlen = 0;
121 u_int seqid = 0;
122 u_char arc_type;
123
124 ++infodelay;
125 ts_print(&h->ts);
126
127 if (caplen < ARC_HDRLEN) {
128 printf("[|arcnet]");
129 goto out;
130 }
131
132 ap = (const struct arc_header *)p;
133 arc_type = ap->arc_type;
134
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;
145 }
146
147 if (phds) {
148 if (caplen < ARC_HDRNEWLEN) {
149 arcnet_print(p, length, 0, 0, 0);
150 printf("[|phds]");
151 goto out;
152 }
153
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 goto out;
159 }
160 flag = ap->arc_flag2;
161 seqid = ap->arc_seqid2;
162 archdrlen = ARC_HDRNEWLEN_EXC;
163 } else {
164 flag = ap->arc_flag;
165 seqid = ap->arc_seqid;
166 archdrlen = ARC_HDRNEWLEN;
167 }
168 }
169
170
171 if (eflag)
172 arcnet_print(p, length, phds, flag, seqid);
173
174 /*
175 * Some printers want to get back at the ethernet addresses,
176 * and/or check that they're not walking off the end of the packet.
177 * Rather than pass them all the way down, we set these globals.
178 */
179 packetp = p;
180 snapend = p + caplen;
181
182 length -= archdrlen;
183 caplen -= archdrlen;
184 p += archdrlen;
185
186 if (phds && flag && (flag & 1) == 0)
187 goto out2;
188
189 if (!arcnet_encap_print(arc_type, p, length, caplen)) {
190 default_print(p, caplen);
191 goto out;
192 }
193
194 out2:
195 if (xflag)
196 default_print(p, caplen);
197
198 out:
199 putchar('\n');
200 --infodelay;
201 if (infoprint)
202 info(0);
203 }
204
205 /*
206 * Prints the packet encapsulated in an ARCnet data field,
207 * given the ARCnet system code.
208 *
209 * Returns non-zero if it can do so, zero if the system code is unknown.
210 */
211
212
213 int
214 arcnet_encap_print(u_char arctype, const u_char *p,
215 u_int length, u_int caplen)
216 {
217 switch (arctype) {
218
219 case ARCTYPE_IP_OLD:
220 case ARCTYPE_IP:
221 ip_print(p, length);
222 return (1);
223
224 #ifdef INET6
225 case ARCTYPE_INET6:
226 ip6_print(p, length);
227 return (1);
228 #endif /*INET6*/
229
230 case ARCTYPE_ARP_OLD:
231 case ARCTYPE_ARP:
232 case ARCTYPE_REVARP:
233 arp_print(p, length, caplen);
234 return (1);
235
236 case ARCTYPE_ATALK: /* XXX was this ever used? */
237 if (vflag)
238 fputs("et1 ", stdout);
239 atalk_print(p, length);
240 return (1);
241
242 default:
243 return (0);
244 }
245 }