1 /*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * 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
22 #ifndef lint
23 static char rcsid[] =
24 "@(#) $Header: print-nfs.c,v 1.17 91/05/06 00:54:21 mccanne Exp $ (LBL)";
25 #endif
26
27 #include <sys/param.h>
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <net/if.h>
31 #include <netinet/in.h>
32 #include <netinet/if_ether.h>
33 #include <netinet/in_systm.h>
34 #include <netinet/ip.h>
35 #include <netinet/ip_var.h>
36
37 #include <sys/time.h>
38 #include <errno.h>
39 #include <rpc/types.h>
40 #include <rpc/auth.h>
41 #include <rpc/auth_unix.h>
42 #include <rpc/svc.h>
43 #include <rpc/xdr.h>
44 #include <rpc/rpc_msg.h>
45
46 #include <ctype.h>
47
48 #include "interface.h"
49 /* These must come after interface.h for BSD. */
50 #if BSD >= 199006
51 #include <nfs/nfsv2.h>
52 #endif
53 #include <nfs/nfs.h>
54
55 #include "addrtoname.h"
56 #include "extract.h"
57
58 static void printfh(), nfs_printfn();
59
60 void
nfsreply_print(rp,length,ip)61 nfsreply_print(rp, length, ip)
62 register struct rpc_msg *rp;
63 int length;
64 register struct ip *ip;
65 {
66 #if BYTE_ORDER == LITTLE_ENDIAN
67 bswap(rp, sizeof(*rp));
68 #endif
69 if (!nflag)
70 (void)printf("%s.nfs > %s.%x: reply %s %d",
71 ipaddr_string(&ip->ip_src),
72 ipaddr_string(&ip->ip_dst),
73 rp->rm_xid,
74 rp->rm_reply.rp_stat == MSG_ACCEPTED? "ok":"ERR",
75 length);
76 else
77 (void)printf("%s.%x > %s.%x: reply %s %d",
78 ipaddr_string(&ip->ip_src),
79 NFS_PORT,
80 ipaddr_string(&ip->ip_dst),
81 rp->rm_xid,
82 rp->rm_reply.rp_stat == MSG_ACCEPTED? "ok":"ERR",
83 length);
84 }
85
86 void
nfsreq_print(rp,length,ip)87 nfsreq_print(rp, length, ip)
88 register struct rpc_msg *rp;
89 int length;
90 register struct ip *ip;
91 {
92 register u_long *dp;
93 register u_long *ep = (u_long *)snapend;
94
95 #if BYTE_ORDER == LITTLE_ENDIAN
96 bswap(rp, sizeof(*rp));
97 #endif
98
99 if (!nflag)
100 (void)printf("%s.%x > %s.nfs: %d",
101 ipaddr_string(&ip->ip_src),
102 rp->rm_xid,
103 ipaddr_string(&ip->ip_dst),
104 length);
105 else
106 (void)printf("%s.%x > %s.%x: %d",
107 ipaddr_string(&ip->ip_src),
108 rp->rm_xid,
109 ipaddr_string(&ip->ip_dst),
110 NFS_PORT,
111 length);
112
113
114 /* find the start of the req data(if we captured it) */
115 dp = (u_long *)(&rp->rm_call.cb_cred);
116 if (dp < ep && dp[1] < length) {
117 dp += (dp[1] + (2*sizeof(u_long) + 3)) / sizeof(u_long);
118 if ((dp < ep) && (dp[1] < length)) {
119 dp += (dp[1] + (2*sizeof(u_long) + 3)) /
120 sizeof(u_long);
121 if (dp >= ep)
122 dp = 0;
123 } else
124 dp = 0;
125 } else
126 dp = 0;
127
128 switch (rp->rm_call.cb_proc) {
129 case RFS_NULL:
130 printf(" null");
131 break;
132 case RFS_GETATTR:
133 printf(" getattr");
134 if (dp)
135 printfh(dp);
136 break;
137 case RFS_SETATTR:
138 printf(" setattr");
139 if (dp)
140 printfh(dp);
141 break;
142 case RFS_ROOT:
143 printf(" root");
144 break;
145 case RFS_LOOKUP:
146 printf(" lookup");
147 if (dp) {
148 printfh(dp);
149 putchar(' ');
150 nfs_printfn(&dp[8]);
151 }
152 break;
153 case RFS_READLINK:
154 printf(" readlink");
155 if (dp)
156 printfh(dp);
157 break;
158 case RFS_READ:
159 printf(" read");
160 if (dp) {
161 printfh(dp);
162 printf(" %d (%d) bytes @ %d",
163 ntohl(dp[9]), ntohl(dp[10]), ntohl(dp[8]));
164 }
165 break;
166 case RFS_WRITECACHE:
167 printf(" writecache");
168 if (dp) {
169 printfh(dp);
170 printf(" %d (%d) bytes @ %d (%d)",
171 ntohl(dp[11]), ntohl(dp[10]),
172 ntohl(dp[9]), ntohl(dp[8]));
173 }
174 break;
175 case RFS_WRITE:
176 printf(" write");
177 if (dp) {
178 printfh(dp);
179 printf(" %d (%d) bytes @ %d (%d)",
180 ntohl(dp[11]), ntohl(dp[10]),
181 ntohl(dp[9]), ntohl(dp[8]));
182 }
183 break;
184 case RFS_CREATE:
185 printf(" create");
186 if (dp) {
187 printfh(dp);
188 putchar(' ');
189 nfs_printfn(&dp[8]);
190 }
191 break;
192 case RFS_REMOVE:
193 printf(" remove");
194 if (dp) {
195 printfh(dp);
196 putchar(' ');
197 nfs_printfn(&dp[8]);
198 }
199 break;
200 case RFS_RENAME:
201 printf(" rename");
202 if (dp) {
203 printfh(dp);
204 putchar(' ');
205 nfs_printfn(&dp[8]);
206 }
207 break;
208 case RFS_LINK:
209 printf(" link");
210 if (dp)
211 printfh(dp);
212 break;
213 case RFS_SYMLINK:
214 printf(" symlink");
215 if (dp) {
216 printfh(dp);
217 putchar(' ');
218 nfs_printfn(&dp[8]);
219 }
220 break;
221 case RFS_MKDIR:
222 printf(" mkdir");
223 if (dp) {
224 printfh(dp);
225 putchar(' ');
226 nfs_printfn(&dp[8]);
227 }
228 break;
229 case RFS_RMDIR:
230 printf(" rmdir");
231 if (dp) {
232 printfh(dp);
233 putchar(' ');
234 nfs_printfn(&dp[8]);
235 }
236 break;
237 case RFS_READDIR:
238 printf(" readdir");
239 if (dp) {
240 printfh(dp);
241 printf(" %d bytes @ %d", ntohl(dp[9]), ntohl(dp[8]));
242 }
243 break;
244 case RFS_STATFS:
245 printf(" statfs");
246 if (dp)
247 printfh(dp);
248 break;
249 default:
250 printf(" proc-%d", rp->rm_call.cb_proc);
251 break;
252 }
253 }
254
255 static void
printfh(dp)256 printfh(dp)
257 register u_long *dp;
258 {
259 /*
260 * take a wild guess at the structure of file handles.
261 * On sun 3s, there are 2 longs of fsid, a short
262 * len == 8, a long of inode & a long of generation number.
263 * On sun 4s, the len == 10 & there are 2 bytes of
264 * padding immediately following it.
265 */
266 if (dp[2] == 0xa0000) {
267 if (dp[1])
268 (void) printf(" fh %d.%d.%d", dp[0], dp[1], dp[3]);
269 else
270 (void) printf(" fh %d.%d", dp[0], dp[3]);
271 } else if ((dp[2] >> 16) == 8)
272 /*
273 * 'dp' is longword aligned, so we must use the extract
274 * macros below for dp+10 which cannot possibly be aligned.
275 */
276 if (dp[1])
277 (void) printf(" fh %d.%d.%d", dp[0], dp[1],
278 EXTRACT_LONG((u_char *)dp + 10));
279 else
280 (void) printf(" fh %d.%d", dp[0],
281 EXTRACT_LONG((u_char *)dp + 10));
282 /* On Ultrix pre-4.0, three longs: fsid, fno, fgen and then zeros */
283 else if (dp[3] == 0) {
284 (void)printf(" fh %d,%d/%d.%d", major(dp[0]), minor(dp[0]),
285 dp[1], dp[2]);
286 }
287 /*
288 * On Ultrix 4.0,
289 * five longs: fsid, fno, fgen, eno, egen and then zeros
290 */
291 else if (dp[5] == 0) {
292 (void)printf(" fh %d,%d/%d.%d", major(dp[0]), minor(dp[0]),
293 dp[1], dp[2]);
294 if (vflag) {
295 /* print additional info */
296 (void)printf("[%d.%d]", dp[3], dp[4]);
297 }
298 }
299 else
300 (void) printf(" fh %x.%x.%x.%x", dp[0], dp[1], dp[2], dp[3]);
301 }
302
303 static void
nfs_printfn(dp)304 nfs_printfn(dp)
305 u_long *dp;
306 {
307 register u_int i = *dp++;
308 register u_char *cp = (u_char *)dp;
309 register char c;
310
311 i = ntohl(i);
312 if (i == 0) { /* otherwise we decrement to MAXINT before testing i */
313 putchar('"');
314 putchar('"');
315 return;
316 }
317 if (i < 64) { /* sanity */
318 putchar('"');
319 do {
320 c = toascii(*cp++);
321 if (!isascii(c)) {
322 c = toascii(c);
323 putchar('M');
324 putchar('-');
325 }
326 if (!isprint(c)) {
327 c ^= 0x40; /* DEL to ?, others to alpha */
328 putchar('^');
329 }
330 putchar(c);
331 } while (--i);
332 putchar('"');
333 }
334 }
335
336 #if BYTE_ORDER == LITTLE_ENDIAN
337 /* assumes input is long-aligned and N*sizeof(long) bytes */
bswap(bp,len)338 static bswap(bp, len)
339 long *bp;
340 int len;
341 {
342 int i;
343 len = len/sizeof(long);
344
345 for (i = 0; i < len; i++)
346 bp[i] = ntohl(bp[i]);
347 }
348 #endif
349