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 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 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 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 680 detail_diropargs3() 681 { 682 683 detail_nfsfh3(); 684 (void) showxdr_string(MAXPATHLEN, "File name = %s"); 685 } 686 687 int 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 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 749 skip_postop() 750 { 751 752 if (getxdr_bool()) 753 xdr_skip(21 * 4); /* XDR size of fattr3 */ 754 } 755 756 static void 757 skip_wcc_data() 758 { 759 760 if (getxdr_bool() > 0) 761 xdr_skip(3 * 8); 762 skip_postop(); 763 } 764 765 static void 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 * 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 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 * 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 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 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 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 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 * 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 * 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 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 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 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 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 * 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 * 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 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 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 * 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 * 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