1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1991, 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 #ident "%Z%%M% %I% %E% SMI" /* SunOS */
28
29 #include <sys/types.h>
30 #include <sys/errno.h>
31 #include <sys/tiuser.h>
32 #include <setjmp.h>
33 #include <string.h>
34
35 #include <rpc/types.h>
36 #include <rpc/xdr.h>
37 #include <rpc/auth.h>
38 #include <rpc/clnt.h>
39 #include <rpc/rpc_msg.h>
40 #include "snoop.h"
41 #include "snoop_nfs.h"
42
43 #include <sys/stat.h>
44 #include <sys/param.h>
45 #include <rpcsvc/nfs_prot.h>
46
47 #ifndef MIN
48 #define MIN(a, b) ((a) < (b) ? (a) : (b))
49 #endif
50
51 extern jmp_buf xdr_err;
52
53 static void nfscall3(int);
54 static void nfsreply3(int);
55 static char *perms(int);
56 static char *filetype(int);
57 static char *sum_access(void);
58 static char *sum_readdirres(void);
59 static char *sum_readdirplusres(void);
60 static char *sum_createhow(void);
61 static char *sum_stablehow(void);
62 static void detail_sattr3(void);
63 static void detail_diropargs3(void);
64 static void detail_readdirres(void);
65 static void detail_readdirplusres(void);
66 static void detail_fattr3(void);
67 static void detail_access(void);
68 static void detail_mode(int);
69 static void detail_wcc_attr(void);
70 static void detail_pre_op_attr(char *);
71 static void detail_wcc_data(char *);
72 static void skip_postop(void);
73 static void skip_wcc_data(void);
74 static void skip_sattr3(void);
75
76 #define DONT_CHANGE 0
77 #define SET_TO_SERVER_TIME 1
78 #define SET_TO_CLIENT_TIME 2
79
80 #define UNCHECKED 0
81 #define GUARDED 1
82 #define EXCLUSIVE 2
83
84 #define ACCESS3_READ 0x0001
85 #define ACCESS3_LOOKUP 0x0002
86 #define ACCESS3_MODIFY 0x0004
87 #define ACCESS3_EXTEND 0x0008
88 #define ACCESS3_DELETE 0x0010
89 #define ACCESS3_EXECUTE 0x0020
90
91 #define UNSTABLE 0
92 #define DATA_SYNC 1
93 #define FILE_SYNC 2
94
95 #define NF3REG 1 /* regular file */
96 #define NF3DIR 2 /* directory */
97 #define NF3BLK 3 /* block special */
98 #define NF3CHR 4 /* character special */
99 #define NF3LNK 5 /* symbolic link */
100 #define NF3SOCK 6 /* unix domain socket */
101 #define NF3FIFO 7 /* named pipe */
102
103 #define NFS3_FHSIZE 64
104
105 static char *procnames_short[] = {
106 "NULL3", /* 0 */
107 "GETATTR3", /* 1 */
108 "SETATTR3", /* 2 */
109 "LOOKUP3", /* 3 */
110 "ACCESS3", /* 4 */
111 "READLINK3", /* 5 */
112 "READ3", /* 6 */
113 "WRITE3", /* 7 */
114 "CREATE3", /* 8 */
115 "MKDIR3", /* 9 */
116 "SYMLINK3", /* 10 */
117 "MKNOD3", /* 11 */
118 "REMOVE3", /* 12 */
119 "RMDIR3", /* 13 */
120 "RENAME3", /* 14 */
121 "LINK3", /* 15 */
122 "READDIR3", /* 16 */
123 "READDIRPLUS3", /* 17 */
124 "FSSTAT3", /* 18 */
125 "FSINFO3", /* 19 */
126 "PATHCONF3", /* 20 */
127 "COMMIT3", /* 21 */
128 };
129
130 static char *procnames_long[] = {
131 "Null procedure", /* 0 */
132 "Get file attributes", /* 1 */
133 "Set file attributes", /* 2 */
134 "Look up file name", /* 3 */
135 "Check access permission", /* 4 */
136 "Read from symbolic link", /* 5 */
137 "Read from file", /* 6 */
138 "Write to file", /* 7 */
139 "Create file", /* 8 */
140 "Make directory", /* 9 */
141 "Make symbolic link", /* 10 */
142 "Make special file", /* 11 */
143 "Remove file", /* 12 */
144 "Remove directory", /* 13 */
145 "Rename", /* 14 */
146 "Link", /* 15 */
147 "Read from directory", /* 16 */
148 "Read from directory - plus", /* 17 */
149 "Get filesystem statistics", /* 18 */
150 "Get filesystem information", /* 19 */
151 "Get POSIX information", /* 20 */
152 "Commit to stable storage", /* 21 */
153 };
154
155 #define MAXPROC 21
156
157 void
interpret_nfs3(flags,type,xid,vers,proc,data,len)158 interpret_nfs3(flags, type, xid, vers, proc, data, len)
159 int flags, type, xid, vers, proc;
160 char *data;
161 int len;
162 {
163 char *line;
164 char buff[NFS_MAXPATHLEN + 1]; /* protocol allows longer */
165 u_longlong_t off;
166 int sz, how;
167 char *fh, *name;
168
169 if (proc < 0 || proc > MAXPROC)
170 return;
171
172 if (flags & F_SUM) {
173 line = get_sum_line();
174
175 if (type == CALL) {
176 (void) sprintf(line, "NFS C %s",
177 procnames_short[proc]);
178 line += strlen(line);
179 switch (proc) {
180 case NFSPROC3_GETATTR:
181 case NFSPROC3_READLINK:
182 case NFSPROC3_FSSTAT:
183 case NFSPROC3_FSINFO:
184 case NFSPROC3_PATHCONF:
185 (void) sprintf(line, sum_nfsfh3());
186 break;
187 case NFSPROC3_SETATTR:
188 (void) sprintf(line, sum_nfsfh3());
189 break;
190 case NFSPROC3_READDIR:
191 fh = sum_nfsfh3();
192 off = getxdr_u_longlong();
193 (void) getxdr_u_longlong();
194 sz = getxdr_u_long();
195 (void) sprintf(line, "%s Cookie=%llu for %lu",
196 fh, off, sz);
197 break;
198 case NFSPROC3_READDIRPLUS:
199 fh = sum_nfsfh3();
200 off = getxdr_u_longlong();
201 (void) getxdr_u_longlong();
202 sz = getxdr_u_long();
203 (void) sprintf(line,
204 "%s Cookie=%llu for %lu/%lu",
205 fh, off, sz, getxdr_u_long());
206 break;
207 case NFSPROC3_ACCESS:
208 fh = sum_nfsfh3();
209 (void) sprintf(line, "%s (%s)",
210 fh, sum_access());
211 break;
212 case NFSPROC3_LOOKUP:
213 case NFSPROC3_REMOVE:
214 case NFSPROC3_RMDIR:
215 case NFSPROC3_MKDIR:
216 fh = sum_nfsfh3();
217 (void) sprintf(line, "%s %s",
218 fh, getxdr_string(buff,
219 NFS_MAXPATHLEN));
220 break;
221 case NFSPROC3_CREATE:
222 fh = sum_nfsfh3();
223 name = getxdr_string(buff, NFS_MAXPATHLEN);
224 (void) sprintf(line, "%s (%s) %s",
225 fh, sum_createhow(), name);
226 break;
227 case NFSPROC3_MKNOD:
228 fh = sum_nfsfh3();
229 name = getxdr_string(buff, NFS_MAXPATHLEN);
230 how = getxdr_long();
231 (void) sprintf(line, "%s (%s) %s",
232 fh, filetype(how), name);
233 break;
234 case NFSPROC3_READ:
235 fh = sum_nfsfh3();
236 off = getxdr_u_longlong();
237 sz = getxdr_u_long();
238 (void) sprintf(line, "%s at %llu for %lu",
239 fh, off, sz);
240 break;
241 case NFSPROC3_WRITE:
242 fh = sum_nfsfh3();
243 off = getxdr_u_longlong();
244 sz = getxdr_u_long();
245 (void) sprintf(line, "%s at %llu for %lu (%s)",
246 fh, off, sz, sum_stablehow());
247 break;
248 case NFSPROC3_SYMLINK:
249 fh = sum_nfsfh3();
250 (void) sprintf(line, "%s %s",
251 fh, getxdr_string(buff,
252 NFS_MAXPATHLEN));
253 skip_sattr3();
254 line += strlen(line);
255 (void) sprintf(line, " to %s",
256 getxdr_string(buff, NFS_MAXPATHLEN));
257 break;
258 case NFSPROC3_RENAME:
259 fh = sum_nfsfh3();
260 (void) sprintf(line, "%s %s",
261 fh, getxdr_string(buff,
262 NFS_MAXPATHLEN));
263 line += strlen(line);
264 fh = sum_nfsfh3();
265 (void) sprintf(line, " to%s %s",
266 fh, getxdr_string(buff,
267 NFS_MAXPATHLEN));
268 break;
269 case NFSPROC3_LINK:
270 fh = sum_nfsfh3();
271 (void) sprintf(line, "%s", fh);
272 line += strlen(line);
273 fh = sum_nfsfh3();
274 (void) sprintf(line, " to%s %s",
275 fh, getxdr_string(buff,
276 NFS_MAXPATHLEN));
277 break;
278 case NFSPROC3_COMMIT:
279 fh = sum_nfsfh3();
280 off = getxdr_u_longlong();
281 sz = getxdr_u_long();
282 (void) sprintf(line, "%s at %llu for %lu",
283 fh, off, sz);
284 break;
285 default:
286 break;
287 }
288
289 check_retransmit(line, xid);
290 } else {
291 (void) sprintf(line, "NFS R %s ",
292 procnames_short[proc]);
293 line += strlen(line);
294 switch (proc) {
295 case NFSPROC3_LOOKUP:
296 if (sum_nfsstat3(line) == NFS3_OK)
297 (void) strcat(line, sum_nfsfh3());
298 break;
299 case NFSPROC3_CREATE:
300 case NFSPROC3_MKDIR:
301 case NFSPROC3_SYMLINK:
302 case NFSPROC3_MKNOD:
303 if (sum_nfsstat3(line) == NFS3_OK) {
304 if (getxdr_bool())
305 (void) strcat(line,
306 sum_nfsfh3());
307 }
308 break;
309 case NFSPROC3_READLINK:
310 if (sum_nfsstat3(line) == NFS3_OK) {
311 line += strlen(line);
312 skip_postop();
313 (void) sprintf(line, " (Path=%s)",
314 getxdr_string(buff,
315 NFS_MAXPATHLEN));
316 }
317 break;
318 case NFSPROC3_GETATTR:
319 case NFSPROC3_SETATTR:
320 case NFSPROC3_REMOVE:
321 case NFSPROC3_RMDIR:
322 case NFSPROC3_RENAME:
323 case NFSPROC3_LINK:
324 case NFSPROC3_FSSTAT:
325 case NFSPROC3_FSINFO:
326 case NFSPROC3_PATHCONF:
327 (void) sum_nfsstat3(line);
328 break;
329 case NFSPROC3_ACCESS:
330 if (sum_nfsstat3(line) == NFS3_OK) {
331 line += strlen(line);
332 skip_postop();
333 (void) sprintf(line, " (%s)",
334 sum_access());
335 }
336 break;
337 case NFSPROC3_WRITE:
338 if (sum_nfsstat3(line) == NFS3_OK) {
339 line += strlen(line);
340 skip_wcc_data();
341 sz = getxdr_u_long();
342 (void) sprintf(line, " %d (%s)",
343 sz, sum_stablehow());
344 }
345 break;
346 case NFSPROC3_READDIR:
347 if (sum_nfsstat3(line) == NFS3_OK)
348 (void) strcat(line, sum_readdirres());
349 break;
350 case NFSPROC3_READ:
351 if (sum_nfsstat3(line) == NFS3_OK) {
352 line += strlen(line);
353 skip_postop();
354 (void) sprintf(line, " (%lu bytes)",
355 getxdr_u_long());
356 if (getxdr_bool())
357 (void) strcat(line, " EOF");
358 }
359 break;
360 case NFSPROC3_READDIRPLUS:
361 if (sum_nfsstat3(line) == NFS3_OK)
362 (void) strcat(line,
363 sum_readdirplusres());
364 break;
365 case NFSPROC3_COMMIT:
366 (void) sum_nfsstat3(line);
367 break;
368 default:
369 break;
370 }
371 }
372 }
373
374 if (flags & F_DTAIL) {
375 show_header("NFS: ", "Sun NFS", len);
376 show_space();
377 (void) sprintf(get_line(0, 0), "Proc = %d (%s)",
378 proc, procnames_long[proc]);
379 if (type == CALL)
380 nfscall3(proc);
381 else
382 nfsreply3(proc);
383 show_trailer();
384 }
385 }
386
387 /*
388 * Print out version 3 NFS call packets
389 */
390 static void
nfscall3(proc)391 nfscall3(proc)
392 int proc;
393 {
394 int h;
395
396 switch (proc) {
397 case NFSPROC3_GETATTR:
398 case NFSPROC3_READLINK:
399 case NFSPROC3_FSINFO:
400 case NFSPROC3_FSSTAT:
401 case NFSPROC3_PATHCONF:
402 detail_nfsfh3();
403 break;
404 case NFSPROC3_SETATTR:
405 detail_nfsfh3();
406 detail_sattr3();
407 if (getxdr_bool())
408 (void) showxdr_date_ns("Guard = %s");
409 break;
410 case NFSPROC3_LOOKUP:
411 case NFSPROC3_REMOVE:
412 case NFSPROC3_RMDIR:
413 detail_diropargs3();
414 break;
415 case NFSPROC3_ACCESS:
416 detail_nfsfh3();
417 detail_access();
418 break;
419 case NFSPROC3_MKDIR:
420 detail_diropargs3();
421 detail_sattr3();
422 break;
423 case NFSPROC3_CREATE:
424 detail_diropargs3();
425 h = getxdr_u_long();
426 if (h == EXCLUSIVE)
427 showxdr_hex(8, "Guard = %s");
428 else {
429 (void) sprintf(get_line(0, 0), "Method = %s",
430 h == UNCHECKED ? "Unchecked" : "Guarded");
431 detail_sattr3();
432 }
433 break;
434 case NFSPROC3_MKNOD:
435 detail_diropargs3();
436 h = getxdr_u_long();
437 (void) sprintf(get_line(0, 0), "File type = %s",
438 filetype(h));
439 switch (h) {
440 case NF3CHR:
441 case NF3BLK:
442 detail_sattr3();
443 showxdr_u_long("Major = %lu");
444 showxdr_u_long("Minor = %lu");
445 break;
446 case NF3SOCK:
447 case NF3FIFO:
448 detail_sattr3();
449 break;
450 }
451 break;
452 case NFSPROC3_WRITE:
453 detail_nfsfh3();
454 (void) showxdr_u_longlong("Offset = %llu");
455 (void) showxdr_u_long("Size = %lu");
456 (void) sprintf(get_line(0, 0), "Stable = %s",
457 sum_stablehow());
458 break;
459 case NFSPROC3_RENAME:
460 detail_diropargs3();
461 detail_diropargs3();
462 break;
463 case NFSPROC3_LINK:
464 detail_nfsfh3();
465 detail_diropargs3();
466 break;
467 case NFSPROC3_SYMLINK:
468 detail_diropargs3();
469 detail_sattr3();
470 (void) showxdr_string(MAXPATHLEN, "Path = %s");
471 break;
472 case NFSPROC3_READDIR:
473 detail_nfsfh3();
474 (void) showxdr_u_longlong("Cookie = %llu");
475 (void) showxdr_hex(8, "Verifier = %s");
476 (void) showxdr_u_long("Count = %lu");
477 break;
478 case NFSPROC3_READDIRPLUS:
479 detail_nfsfh3();
480 (void) showxdr_u_longlong("Cookie = %llu");
481 (void) showxdr_hex(8, "Verifier = %s");
482 (void) showxdr_u_long("Dircount = %lu");
483 (void) showxdr_u_long("Maxcount = %lu");
484 break;
485 case NFSPROC3_READ:
486 case NFSPROC3_COMMIT:
487 detail_nfsfh3();
488 (void) showxdr_u_longlong("Offset = %llu");
489 (void) showxdr_long("Count = %lu");
490 break;
491 default:
492 break;
493 }
494 }
495
496 /*
497 * Print out version 3 NFS reply packets
498 */
499 static void
nfsreply3(proc)500 nfsreply3(proc)
501 int proc;
502 {
503 int bits;
504
505 switch (proc) {
506 case NFSPROC3_GETATTR:
507 if (detail_nfsstat3() == NFS3_OK) {
508 detail_fattr3();
509 }
510 break;
511 case NFSPROC3_SETATTR:
512 (void) detail_nfsstat3();
513 detail_wcc_data("");
514 break;
515 case NFSPROC3_WRITE:
516 if (detail_nfsstat3() == NFS3_OK) {
517 detail_wcc_data("");
518 (void) showxdr_u_long("Count = %lu bytes written");
519 (void) sprintf(get_line(0, 0), "Stable = %s",
520 sum_stablehow());
521 (void) showxdr_hex(8, "Verifier = %s");
522 } else
523 detail_wcc_data("");
524 break;
525 case NFSPROC3_LOOKUP:
526 if (detail_nfsstat3() == NFS3_OK) {
527 detail_nfsfh3();
528 detail_post_op_attr("(object)");
529 }
530 detail_post_op_attr("(directory)");
531 break;
532 case NFSPROC3_CREATE:
533 case NFSPROC3_MKDIR:
534 case NFSPROC3_SYMLINK:
535 case NFSPROC3_MKNOD:
536 if (detail_nfsstat3() == NFS3_OK) {
537 if (getxdr_bool())
538 detail_nfsfh3();
539 else
540 (void) sprintf(get_line(0, 0),
541 "(No file handle available)");
542 detail_post_op_attr("");
543 }
544 detail_wcc_data("");
545 break;
546 case NFSPROC3_READLINK:
547 if (detail_nfsstat3() == NFS3_OK) {
548 detail_post_op_attr("");
549 (void) showxdr_string(MAXPATHLEN, "Path = %s");
550 } else
551 detail_post_op_attr("");
552 break;
553 case NFSPROC3_READ:
554 if (detail_nfsstat3() == NFS3_OK) {
555 detail_post_op_attr("");
556 (void) showxdr_u_long("Count = %lu bytes read");
557 (void) showxdr_bool("End of file = %s");
558 } else
559 detail_post_op_attr("");
560 break;
561 case NFSPROC3_ACCESS:
562 if (detail_nfsstat3() == NFS3_OK) {
563 detail_post_op_attr("");
564 (void) sprintf(get_line(0, 0), "Access = %s",
565 sum_access());
566 } else
567 detail_post_op_attr("");
568 break;
569 case NFSPROC3_REMOVE:
570 case NFSPROC3_RMDIR:
571 (void) detail_nfsstat3();
572 detail_wcc_data("");
573 break;
574 case NFSPROC3_RENAME:
575 (void) detail_nfsstat3();
576 detail_wcc_data("(from directory)");
577 detail_wcc_data("(to directory)");
578 break;
579 case NFSPROC3_LINK:
580 (void) detail_nfsstat3();
581 detail_post_op_attr("");
582 detail_wcc_data("");
583 break;
584 case NFSPROC3_READDIR:
585 if (detail_nfsstat3() == NFS3_OK) {
586 detail_readdirres();
587 } else
588 detail_post_op_attr("");
589 break;
590 case NFSPROC3_READDIRPLUS:
591 if (detail_nfsstat3() == NFS3_OK) {
592 detail_readdirplusres();
593 } else
594 detail_post_op_attr("");
595 break;
596 case NFSPROC3_FSSTAT:
597 if (detail_nfsstat3() == NFS3_OK) {
598 detail_post_op_attr("");
599 (void) showxdr_u_longlong(
600 "Total space = %llu bytes");
601 (void) showxdr_u_longlong(
602 "Available space = %llu bytes");
603 (void) showxdr_u_longlong(
604 "Available space - this user = %llu bytes");
605 (void) showxdr_u_longlong(
606 "Total file slots = %llu");
607 (void) showxdr_u_longlong(
608 "Available file slots = %llu");
609 (void) showxdr_u_longlong(
610 "Available file slots - this user = %llu");
611 (void) showxdr_u_long("Invariant time = %lu sec");
612 } else
613 detail_post_op_attr("");
614 break;
615 case NFSPROC3_FSINFO:
616 if (detail_nfsstat3() == NFS3_OK) {
617 detail_post_op_attr("");
618 (void) show_line("Read transfer sizes:");
619 (void) showxdr_u_long(" Maximum = %lu bytes");
620 (void) showxdr_u_long(" Preferred = %lu bytes");
621 (void) showxdr_u_long(
622 " Suggested multiple = %lu bytes");
623 (void) show_line("Write transfer sizes:");
624 (void) showxdr_u_long(" Maximum = %lu bytes");
625 (void) showxdr_u_long(" Preferred = %lu bytes");
626 (void) showxdr_u_long(
627 " Suggested multiple = %lu bytes");
628 (void) show_line("Directory read size:");
629 (void) showxdr_u_long(" Preferred = %lu bytes");
630 (void) show_line("File system limits:");
631 (void) showxdr_u_longlong(
632 " Max file size = %llu bytes");
633 (void) showxdr_date_ns(
634 " Server minimum time discrimination = %s sec");
635 bits = showxdr_u_long("Properties = 0x%02x");
636 (void) sprintf(get_line(0, 0), " %s",
637 getflag(bits, FSF3_LINK,
638 "Hard links supported",
639 "(hard links not supported)"));
640 (void) sprintf(get_line(0, 0), " %s",
641 getflag(bits, FSF3_SYMLINK,
642 "Symbolic links supported",
643 "(symbolic links not supported)"));
644 (void) sprintf(get_line(0, 0), " %s",
645 getflag(bits, FSF3_HOMOGENEOUS,
646 "Pathconf cannot vary per file",
647 "(pathconf can vary per file)"));
648 (void) sprintf(get_line(0, 0), " %s",
649 getflag(bits, FSF3_CANSETTIME,
650 "Server can always set file times",
651 "(server cannot always set file times)"));
652 } else
653 detail_post_op_attr("");
654 break;
655 case NFSPROC3_PATHCONF:
656 if (detail_nfsstat3() == NFS3_OK) {
657 detail_post_op_attr("");
658 (void) showxdr_u_long("Link max = %lu");
659 (void) showxdr_u_long("Name max = %lu");
660 (void) showxdr_bool("No trunc = %s");
661 (void) showxdr_bool("Chown restricted = %s");
662 (void) showxdr_bool("Case insensitive = %s");
663 (void) showxdr_bool("Case preserving = %s");
664 } else
665 detail_post_op_attr("");
666 break;
667 case NFSPROC3_COMMIT:
668 if (detail_nfsstat3() == NFS3_OK) {
669 detail_wcc_data("");
670 (void) showxdr_hex(8, "Verifier = %s");
671 } else
672 detail_wcc_data("");
673 break;
674 default:
675 break;
676 }
677 }
678
679 static void
detail_diropargs3()680 detail_diropargs3()
681 {
682
683 detail_nfsfh3();
684 (void) showxdr_string(MAXPATHLEN, "File name = %s");
685 }
686
687 int
sum_nfsstat3(line)688 sum_nfsstat3(line)
689 char *line;
690 {
691 ulong_t status;
692 char *p;
693
694 status = getxdr_long();
695 switch (status) {
696 case NFS3_OK: p = "OK"; break;
697 case NFS3ERR_PERM: p = "Not owner"; break;
698 case NFS3ERR_NOENT: p = "No such file or directory"; break;
699 case NFS3ERR_IO: p = "I/O error"; break;
700 case NFS3ERR_NXIO: p = "No such device or address"; break;
701 case NFS3ERR_ACCES: p = "Permission denied"; break;
702 case NFS3ERR_EXIST: p = "File exists"; break;
703 case NFS3ERR_XDEV: p = "Attempted cross-device link"; break;
704 case NFS3ERR_NODEV: p = "No such device"; break;
705 case NFS3ERR_NOTDIR: p = "Not a directory"; break;
706 case NFS3ERR_ISDIR: p = "Is a directory"; break;
707 case NFS3ERR_INVAL: p = "Invalid argument"; break;
708 case NFS3ERR_FBIG: p = "File too large"; break;
709 case NFS3ERR_NOSPC: p = "No space left on device"; break;
710 case NFS3ERR_ROFS: p = "Read-only file system"; break;
711 case NFS3ERR_MLINK: p = "Too many links"; break;
712 case NFS3ERR_NAMETOOLONG:p = "File name too long"; break;
713 case NFS3ERR_NOTEMPTY: p = "Directory not empty"; break;
714 case NFS3ERR_DQUOT: p = "Disc quota exceeded"; break;
715 case NFS3ERR_STALE: p = "Stale NFS file handle"; break;
716 case NFS3ERR_REMOTE: p = "Too many levels of remote in path"; break;
717 case NFS3ERR_BADHANDLE: p = "Illegal NFS file handle"; break;
718 case NFS3ERR_NOT_SYNC: p = "Update synch mismatch"; break;
719 case NFS3ERR_BAD_COOKIE:p = "Readdir cookie is stale"; break;
720 case NFS3ERR_NOTSUPP: p = "Operation not supported"; break;
721 case NFS3ERR_TOOSMALL: p = "Buffer/request too small"; break;
722 case NFS3ERR_SERVERFAULT:p = "Server fault"; break;
723 case NFS3ERR_BADTYPE: p = "Bad type"; break;
724 case NFS3ERR_JUKEBOX: p = "File is temporarily unavailable"; break;
725 default: p = "(unknown error)"; break;
726 }
727
728 (void) strcpy(line, p);
729 return (status);
730 }
731
732 int
detail_nfsstat3()733 detail_nfsstat3()
734 {
735 ulong_t status;
736 char buff[64];
737 int pos;
738
739 pos = getxdr_pos();
740 status = sum_nfsstat3(buff);
741
742 (void) sprintf(get_line(pos, getxdr_pos()), "Status = %d (%s)",
743 status, buff);
744
745 return ((int)status);
746 }
747
748 static void
skip_postop()749 skip_postop()
750 {
751
752 if (getxdr_bool())
753 xdr_skip(21 * 4); /* XDR size of fattr3 */
754 }
755
756 static void
skip_wcc_data()757 skip_wcc_data()
758 {
759
760 if (getxdr_bool() > 0)
761 xdr_skip(3 * 8);
762 skip_postop();
763 }
764
765 static void
skip_sattr3()766 skip_sattr3()
767 {
768
769 if (getxdr_bool() > 0)
770 xdr_skip(4); /* mode */
771 if (getxdr_bool() > 0)
772 xdr_skip(4); /* uid */
773 if (getxdr_bool() > 0)
774 xdr_skip(4); /* gid */
775 if (getxdr_bool() > 0)
776 xdr_skip(8); /* size */
777 if (getxdr_bool() > 0)
778 xdr_skip(8); /* atime */
779 if (getxdr_bool() > 0)
780 xdr_skip(8); /* mtime */
781 }
782
783 char *
sum_nfsfh3()784 sum_nfsfh3()
785 {
786 int len;
787 int fh;
788 static char buff[16];
789
790 len = getxdr_long();
791 fh = sum_filehandle(len);
792 (void) sprintf(buff, " FH=%04X", fh & 0xFFFF);
793 return (buff);
794 }
795
796 void
detail_nfsfh3()797 detail_nfsfh3()
798 {
799 int pos;
800 int i, l, len;
801 int fh;
802
803 len = getxdr_long();
804 pos = getxdr_pos();
805 fh = sum_filehandle(len);
806 setxdr_pos(pos);
807 (void) sprintf(get_line(0, 0), "File handle = [%04X]", fh & 0xFFFF);
808 i = 0;
809 while (i < len) {
810 l = MIN(len - i, 32);
811 (void) showxdr_hex(l, " %s");
812 i += l;
813 }
814 }
815
816 static char *
sum_access()817 sum_access()
818 {
819 int bits;
820 static char buff[64];
821
822 bits = getxdr_u_long();
823 buff[0] = '\0';
824
825 if (bits & ACCESS3_READ)
826 (void) strcat(buff, "read,");
827 if (bits & ACCESS3_LOOKUP)
828 (void) strcat(buff, "lookup,");
829 if (bits & ACCESS3_MODIFY)
830 (void) strcat(buff, "modify,");
831 if (bits & ACCESS3_EXTEND)
832 (void) strcat(buff, "extend,");
833 if (bits & ACCESS3_DELETE)
834 (void) strcat(buff, "delete,");
835 if (bits & ACCESS3_EXECUTE)
836 (void) strcat(buff, "execute,");
837 if (buff[0] != '\0')
838 buff[strlen(buff) - 1] = '\0';
839
840 return (buff);
841 }
842
843 static void
detail_access()844 detail_access()
845 {
846 uint_t bits;
847
848 bits = showxdr_u_long("Access bits = 0x%08x");
849 (void) sprintf(get_line(0, 0), " %s",
850 getflag(bits, ACCESS3_READ, "Read", "(no read)"));
851 (void) sprintf(get_line(0, 0), " %s",
852 getflag(bits, ACCESS3_LOOKUP, "Lookup", "(no lookup)"));
853 (void) sprintf(get_line(0, 0), " %s",
854 getflag(bits, ACCESS3_MODIFY, "Modify", "(no modify)"));
855 (void) sprintf(get_line(0, 0), " %s",
856 getflag(bits, ACCESS3_EXTEND, "Extend", "(no extend)"));
857 (void) sprintf(get_line(0, 0), " %s",
858 getflag(bits, ACCESS3_DELETE, "Delete", "(no delete)"));
859 (void) sprintf(get_line(0, 0), " %s",
860 getflag(bits, ACCESS3_EXECUTE, "Execute", "(no execute)"));
861 }
862
863 static void
detail_mode(mode)864 detail_mode(mode)
865 int mode;
866 {
867
868 (void) sprintf(get_line(0, 0), " Mode = 0%o", mode);
869 (void) sprintf(get_line(0, 0),
870 " Setuid = %d, Setgid = %d, Sticky = %d",
871 (mode & S_ISUID) != 0,
872 (mode & S_ISGID) != 0,
873 (mode & S_ISVTX) != 0);
874 (void) sprintf(get_line(0, 0), " Owner's permissions = %s",
875 perms(mode >> 6 & 0x7));
876 (void) sprintf(get_line(0, 0), " Group's permissions = %s",
877 perms(mode >> 3 & 0x7));
878 (void) sprintf(get_line(0, 0), " Other's permissions = %s",
879 perms(mode & 0x7));
880 }
881
882 static void
detail_fattr3()883 detail_fattr3()
884 {
885 uint_t fltype, mode, nlinks, uid, gid;
886 uint_t major, minor;
887 u_longlong_t size, used, fsid, fileid;
888
889 fltype = getxdr_u_long();
890 mode = getxdr_u_long();
891 nlinks = getxdr_u_long();
892 uid = getxdr_u_long();
893 gid = getxdr_u_long();
894 size = getxdr_u_longlong();
895 used = getxdr_u_longlong();
896 major = getxdr_u_long();
897 minor = getxdr_u_long();
898 fsid = getxdr_u_longlong();
899 fileid = getxdr_u_longlong();
900
901 (void) sprintf(get_line(0, 0),
902 " File type = %d (%s)",
903 fltype, filetype(fltype));
904 detail_mode(mode);
905 (void) sprintf(get_line(0, 0),
906 " Link count = %u, User ID = %u, Group ID = %u",
907 nlinks, uid, gid);
908 (void) sprintf(get_line(0, 0),
909 " File size = %llu, Used = %llu",
910 size, used);
911 (void) sprintf(get_line(0, 0),
912 " Special: Major = %u, Minor = %u",
913 major, minor);
914 (void) sprintf(get_line(0, 0),
915 " File system id = %llu, File id = %llu",
916 fsid, fileid);
917 (void) showxdr_date_ns(" Last access time = %s");
918 (void) showxdr_date_ns(" Modification time = %s");
919 (void) showxdr_date_ns(" Attribute change time = %s");
920 (void) show_line("");
921 }
922
923 static void
detail_sattr3()924 detail_sattr3()
925 {
926 int t;
927
928 if (getxdr_bool())
929 detail_mode(getxdr_u_long());
930 else
931 (void) sprintf(get_line(0, 0), "Mode = (not set)");
932 if (getxdr_bool())
933 (void) showxdr_long("User ID = %d");
934 else
935 (void) sprintf(get_line(0, 0), "User ID = (not set)");
936 if (getxdr_bool())
937 (void) showxdr_long("Group ID = %d");
938 else
939 (void) sprintf(get_line(0, 0), "Group ID = (not set)");
940 if (getxdr_bool())
941 (void) showxdr_u_longlong("Size = %llu");
942 else
943 (void) sprintf(get_line(0, 0), "Size = (not set)");
944
945 if ((t = getxdr_u_long()) == SET_TO_CLIENT_TIME)
946 (void) showxdr_date("Access time = %s (set to client time)");
947 else if (t == SET_TO_SERVER_TIME)
948 (void) sprintf(get_line(0, 0),
949 "Access time = (set to server time)");
950 else
951 (void) sprintf(get_line(0, 0), "Access time = (do not set)");
952
953 if ((t = getxdr_u_long()) == SET_TO_CLIENT_TIME) {
954 (void) showxdr_date(
955 "Modification time = %s (set to client time)");
956 } else if (t == SET_TO_SERVER_TIME)
957 (void) sprintf(get_line(0, 0),
958 "Modification time = (set to server time)");
959 else
960 (void) sprintf(get_line(0, 0),
961 "Modification time = (do not set)");
962 (void) show_line("");
963 }
964
965 static char *
filetype(n)966 filetype(n)
967 int n;
968 {
969
970 switch (n) {
971 case NF3REG:
972 return ("Regular File");
973 case NF3DIR:
974 return ("Directory");
975 case NF3BLK:
976 return ("Block special");
977 case NF3CHR:
978 return ("Character special");
979 case NF3LNK:
980 return ("Symbolic Link");
981 case NF3SOCK:
982 return ("Unix domain socket");
983 case NF3FIFO:
984 return ("Named pipe");
985 default:
986 return ("?");
987 }
988 /* NOTREACHED */
989 }
990
991 static char *
perms(n)992 perms(n)
993 int n;
994 {
995 static char buff[4];
996
997 buff[0] = n & 4 ? 'r' : '-';
998 buff[1] = n & 2 ? 'w' : '-';
999 buff[2] = n & 1 ? 'x' : '-';
1000 buff[3] = '\0';
1001 return (buff);
1002 }
1003
1004 static void
detail_wcc_attr()1005 detail_wcc_attr()
1006 {
1007
1008 (void) showxdr_u_longlong(" Size = %llu bytes");
1009 (void) showxdr_date_ns(" Modification time = %s");
1010 (void) showxdr_date_ns(" Attribute change time = %s");
1011 (void) show_line("");
1012 }
1013
1014 static void
detail_pre_op_attr(str)1015 detail_pre_op_attr(str)
1016 char *str;
1017 {
1018
1019 if (getxdr_bool()) {
1020 (void) sprintf(get_line(0, 0),
1021 "Pre-operation attributes: %s", str);
1022 detail_wcc_attr();
1023 } else
1024 (void) sprintf(get_line(0, 0),
1025 "Pre-operation attributes: %s (not available)", str);
1026 }
1027
1028 void
detail_post_op_attr(str)1029 detail_post_op_attr(str)
1030 char *str;
1031 {
1032
1033 if (getxdr_bool()) {
1034 (void) sprintf(get_line(0, 0),
1035 "Post-operation attributes: %s", str);
1036 detail_fattr3();
1037 } else
1038 (void) sprintf(get_line(0, 0),
1039 "Post-operation attributes: %s (not available)", str);
1040 }
1041
1042 static void
detail_wcc_data(str)1043 detail_wcc_data(str)
1044 char *str;
1045 {
1046
1047 detail_pre_op_attr(str);
1048 detail_post_op_attr(str);
1049 }
1050
1051 static char *
sum_readdirres()1052 sum_readdirres()
1053 {
1054 static char buff[NFS_MAXNAMLEN + 1]; /* protocol allows longer names */
1055 static int entries;
1056
1057 entries = 0;
1058 if (setjmp(xdr_err)) {
1059 (void) sprintf(buff, " %d+ entries (incomplete)", entries);
1060 return (buff);
1061 }
1062 skip_postop();
1063 xdr_skip(8); /* cookieverf */
1064 while (getxdr_bool()) {
1065 entries++;
1066 xdr_skip(8); /* fileid */
1067 (void) getxdr_string(buff, NFS_MAXNAMLEN); /* name */
1068 xdr_skip(8); /* cookie */
1069 }
1070
1071 (void) sprintf(buff, " %d entries (%s)",
1072 entries, getxdr_bool() ? "No more" : "More");
1073 return (buff);
1074 }
1075
1076 static char *
sum_readdirplusres()1077 sum_readdirplusres()
1078 {
1079 static char buff[NFS_MAXNAMLEN + 1]; /* protocol allows longer */
1080 static int entries;
1081 int skip;
1082
1083 entries = 0;
1084 if (setjmp(xdr_err)) {
1085 (void) sprintf(buff, " %d+ entries (incomplete)", entries);
1086 return (buff);
1087 }
1088 skip_postop();
1089 xdr_skip(8); /* cookieverf */
1090 while (getxdr_bool()) {
1091 entries++;
1092 xdr_skip(8); /* fileid */
1093 (void) getxdr_string(buff, NFS_MAXNAMLEN); /* name */
1094 xdr_skip(8); /* cookie */
1095 skip_postop(); /* post-op */
1096 if (getxdr_bool()) {
1097 skip = getxdr_long();
1098 xdr_skip(RNDUP(skip)); /* fhandle */
1099 }
1100 }
1101
1102 (void) sprintf(buff, " %d entries (%s)",
1103 entries, getxdr_bool() ? "No more" : "More");
1104 return (buff);
1105 }
1106
1107 static void
detail_readdirres()1108 detail_readdirres()
1109 {
1110 static int entries;
1111 u_longlong_t fileid, cookie;
1112 char *name;
1113 char buff[NFS_MAXNAMLEN + 1]; /* protocol allows longer names */
1114
1115 entries = 0;
1116 detail_post_op_attr("");
1117 (void) showxdr_hex(8, "Cookie verifier = %s");
1118 (void) show_line("");
1119 (void) sprintf(get_line(0, 0), " File id Cookie Name");
1120
1121 if (setjmp(xdr_err)) {
1122 (void) sprintf(get_line(0, 0),
1123 " %d+ entries. (Frame is incomplete)",
1124 entries);
1125 return;
1126 }
1127 while (getxdr_bool()) {
1128 entries++;
1129 fileid = getxdr_u_longlong();
1130 name = (char *)getxdr_string(buff, NFS_MAXNAMLEN);
1131 cookie = getxdr_u_longlong();
1132 (void) sprintf(get_line(0, 0),
1133 " %10llu %10llu %s",
1134 fileid, cookie, name);
1135 }
1136
1137 (void) sprintf(get_line(0, 0), " %d entries", entries);
1138 (void) showxdr_bool("EOF = %s");
1139 }
1140
1141 static void
detail_readdirplusres()1142 detail_readdirplusres()
1143 {
1144 static int entries;
1145
1146 entries = 0;
1147 detail_post_op_attr("");
1148 (void) showxdr_hex(8, "Cookie verifier = %s");
1149 (void) show_line("");
1150
1151 if (setjmp(xdr_err)) {
1152 (void) sprintf(get_line(0, 0),
1153 " %d+ entries. (Frame is incomplete)",
1154 entries);
1155 return;
1156 }
1157 while (getxdr_bool()) {
1158 entries++;
1159 (void) sprintf(get_line(0, 0),
1160 "------------------ entry #%d",
1161 entries);
1162 (void) showxdr_u_longlong("File ID = %llu");
1163 (void) showxdr_string(NFS_MAXNAMLEN, "Name = %s");
1164 (void) showxdr_u_longlong("Cookie = %llu");
1165 detail_post_op_attr("");
1166 if (getxdr_bool())
1167 detail_nfsfh3();
1168 else
1169 (void) sprintf(get_line(0, 0),
1170 "(No file handle available)");
1171 }
1172
1173 (void) show_line("");
1174 (void) sprintf(get_line(0, 0), " %d entries", entries);
1175 (void) showxdr_bool("EOF = %s");
1176 }
1177
1178 static char *
sum_createhow()1179 sum_createhow()
1180 {
1181 long how;
1182
1183 how = getxdr_long();
1184 switch (how) {
1185 case UNCHECKED:
1186 return ("UNCHECKED");
1187 case GUARDED:
1188 return ("GUARDED");
1189 case EXCLUSIVE:
1190 return ("EXCLUSIVE");
1191 default:
1192 return ("?");
1193 }
1194 /* NOTREACHED */
1195 }
1196
1197 static char *
sum_stablehow()1198 sum_stablehow()
1199 {
1200 long stable;
1201
1202 stable = getxdr_long();
1203 switch (stable) {
1204 case UNSTABLE:
1205 return ("ASYNC");
1206 case DATA_SYNC:
1207 return ("DSYNC");
1208 case FILE_SYNC:
1209 return ("FSYNC");
1210 default:
1211 return ("?");
1212 }
1213 /* NOTREACHED */
1214 }
1215