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-2000 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 <setjmp.h> 32#include <sys/tiuser.h> 33 34#include <rpc/types.h> 35#include <rpc/xdr.h> 36#include <rpc/auth.h> 37#include <rpc/clnt.h> 38#include <rpc/rpc_msg.h> 39#include <nfs/nfs.h> 40#include <rpcsvc/mount.h> 41#include <string.h> 42#include "snoop.h" 43#include "snoop_nfs.h" 44 45#ifndef MIN 46#define MIN(a, b) ((a) < (b) ? (a) : (b)) 47#endif 48 49extern char *dlc_header; 50extern jmp_buf xdr_err; 51 52static void mountcall(int, int); 53static void mountreply(int, int); 54 55static void sum_mountstat(char *); 56static void sum_mountstat3(char *); 57static char *sum_mountfh(void); 58static char *sum_mountfh3(void); 59static char *sum_exports(void); 60static char *sum_mounts(void); 61 62static int detail_mountstat(void); 63static void detail_mountstat3(void); 64static void detail_mountfh(void); 65static void detail_mountfh3(void); 66static void detail_exports(void); 67static void detail_mounts(void); 68 69static char *statusmsg3(ulong_t); 70 71static char *procnames_short[] = { 72 "Null", /* 0 */ 73 "Mount", /* 1 */ 74 "Get mount list", /* 2 */ 75 "Unmount", /* 3 */ 76 "Unmountall", /* 4 */ 77 "Get export list", /* 5 */ 78 "Get export list", /* 6 */ 79 "PATHCONF", /* 7 */ 80}; 81 82static char *procnames_long[] = { 83 "Null procedure", /* 0 */ 84 "Add mount entry", /* 1 */ 85 "Return mount entries", /* 2 */ 86 "Remove mount entry", /* 3 */ 87 "Remove all mount entries", /* 4 */ 88 "Return export list", /* 5 */ 89 "Return export list", /* 6 */ 90 "Get POSIX Pathconf info", /* 7 */ 91}; 92 93#define MAXPROC 7 94 95void 96interpret_mount(flags, type, xid, vers, proc, data, len) 97 int flags, type, xid, vers, proc; 98 char *data; 99 int len; 100{ 101 char *line; 102 char buff[MNTPATHLEN + 1]; 103 104 if (proc < 0 || proc > MAXPROC) 105 return; 106 107 if (flags & F_SUM) { 108 if (setjmp(xdr_err)) { 109 return; 110 } 111 112 line = get_sum_line(); 113 114 if (type == CALL) { 115 (void) sprintf(line, "MOUNT%d C %s", 116 vers, procnames_short[proc]); 117 line += strlen(line); 118 switch (proc) { 119 case MOUNTPROC_MNT: 120 case MOUNTPROC_UMNT: 121 (void) sprintf(line, " %s", 122 getxdr_string(buff, MNTPATHLEN)); 123 break; 124 case MOUNTPROC_DUMP: 125 case MOUNTPROC_UMNTALL: 126 case MOUNTPROC_EXPORT: 127 case MOUNTPROC_EXPORTALL: 128#ifdef MOUNTPROC_PATHCONF 129 case MOUNTPROC_PATHCONF: 130 if (vers != 3) 131 (void) sprintf(line, " %s", 132 getxdr_string(buff, 133 MNTPATHLEN)); 134#endif 135 break; 136 default: 137 break; 138 } 139 140 check_retransmit(line, xid); 141 } else { 142 (void) sprintf(line, "MOUNT%d R %s ", 143 vers, procnames_short[proc]); 144 line += strlen(line); 145 switch (proc) { 146 case MOUNTPROC_MNT: 147 if (vers == 3) 148 sum_mountstat3(line); 149 else 150 sum_mountstat(line); 151 break; 152 case MOUNTPROC_DUMP: 153 (void) sprintf(line, sum_mounts()); 154 break; 155 case MOUNTPROC_UMNT: 156 case MOUNTPROC_UMNTALL: 157 (void) sprintf(line, "reply"); 158 break; 159 case MOUNTPROC_EXPORTALL: 160 /* 161 * EXPORTALL is the same as EXPORT in v1 162 * and v2, and it doesn't exist in v3. 163 */ 164 if (vers == 3) 165 break; 166 /*FALLTHROUGH*/ 167 case MOUNTPROC_EXPORT: 168 (void) sprintf(line, sum_exports()); 169 break; 170#ifdef MOUNTPROC_PATHCONF 171 case MOUNTPROC_PATHCONF: 172 if (vers != 2) 173 break; 174#ifdef notyet 175 (void) sprintf(line, sum_ppathcnf()); 176#endif 177 break; 178#endif 179 default: 180 break; 181 } 182 } 183 } 184 185 if (flags & F_DTAIL) { 186 show_header("MOUNT:", "NFS MOUNT", len); 187 show_space(); 188 if (setjmp(xdr_err)) { 189 return; 190 } 191 (void) sprintf(get_line(0, 0), 192 "Proc = %d (%s)", 193 proc, procnames_long[proc]); 194 if (type == CALL) 195 mountcall(proc, vers); 196 else 197 mountreply(proc, vers); 198 show_trailer(); 199 } 200} 201 202/* 203 * Interpret call packets in detail 204 */ 205 206static void 207mountcall(proc, vers) 208 int proc, vers; 209{ 210 211 switch (proc) { 212 case MOUNTPROC_MNT: 213 case MOUNTPROC_UMNT: 214 (void) showxdr_string(MNTPATHLEN, "Directory = %s"); 215 break; 216 case MOUNTPROC_DUMP: 217 break; 218 case MOUNTPROC_UMNTALL: 219 break; 220 case MOUNTPROC_EXPORTALL: 221 if (vers == 3) 222 break; 223 break; 224 case MOUNTPROC_EXPORT: 225 break; 226#ifdef MOUNTPROC_PATHCONF 227 case MOUNTPROC_PATHCONF: 228 if (vers != 2) 229 break; 230 (void) showxdr_string(MNTPATHLEN, "File = %s"); 231#endif 232 break; 233 default: 234 break; 235 } 236} 237 238/* 239 * Interpret reply packets in detail 240 */ 241 242static void 243mountreply(proc, vers) 244 int proc, vers; 245{ 246 247 switch (proc) { 248 case MOUNTPROC_MNT: 249 if (vers == 3) { 250 detail_mountstat3(); 251 } else { 252 if (detail_mountstat() == 0) { 253 detail_mountfh(); 254 } 255 } 256 break; 257 case MOUNTPROC_DUMP: 258 detail_mounts(); 259 break; 260 case MOUNTPROC_UMNT: 261 case MOUNTPROC_UMNTALL: 262 (void) detail_mountstat(); 263 break; 264 case MOUNTPROC_EXPORTALL: 265 if (vers == 3) 266 break; 267 /*FALLTHROUGH*/ 268 case MOUNTPROC_EXPORT: 269 detail_exports(); 270 break; 271#ifdef MOUNTPROC_PATHCONF 272 case MOUNTPROC_PATHCONF: 273#ifdef notyet 274 (void) detail_ppathcnf(); 275#endif 276 break; 277#endif 278 default: 279 break; 280 } 281} 282 283static void 284sum_mountstat(line) 285 char *line; 286{ 287 ulong_t status; 288 char *str; 289 290 status = getxdr_u_long(); 291 if (status == 0) 292 str = "OK"; 293 else if ((str = strerror(status)) == (char *)NULL) 294 str = ""; 295 (void) strcpy(line, str); 296 if (status == 0) { 297 (void) strcat(line, sum_mountfh()); 298 } 299} 300 301static int 302detail_mountstat() 303{ 304 ulong_t status; 305 char *str; 306 307 status = getxdr_u_long(); 308 if (status == 0) 309 str = "OK"; 310 else if ((str = strerror(status)) == (char *)NULL) 311 str = ""; 312 313 (void) sprintf(get_line(0, 0), "Status = %d (%s)", status, str); 314 315 return ((int)status); 316} 317 318char * 319sum_mountfh() 320{ 321 int fh; 322 static char buff[8]; 323 324 fh = sum_filehandle(NFS_FHSIZE); 325 (void) sprintf(buff, " FH=%04X", fh & 0xFFFF); 326 return (buff); 327} 328 329static void 330detail_mountfh() 331{ 332 int pos; 333 int fh; 334 335 pos = getxdr_pos(); 336 fh = sum_filehandle(NFS_FHSIZE); 337 setxdr_pos(pos); 338 (void) sprintf(get_line(0, 0), "File handle = [%04X]", fh & 0xFFFF); 339 (void) showxdr_hex(NFS_FHSIZE, " %s"); 340} 341 342static char * 343print_auth() 344{ 345 int i, auth, flavors; 346 char *p; 347 static char buff[64]; 348 349 buff[0] = '\0'; 350 flavors = getxdr_long(); 351 for (i = 0; i < flavors; i++) { 352 if (i > 0) 353 (void) strlcat(buff, ",", sizeof (buff)); 354 switch (auth = getxdr_u_long()) { 355 case AUTH_NONE: 356 (void) strlcat(buff, "none", sizeof (buff)); 357 break; 358 case AUTH_UNIX: 359 (void) strlcat(buff, "unix", sizeof (buff)); 360 break; 361 case AUTH_SHORT: 362 (void) strlcat(buff, "short", sizeof (buff)); 363 break; 364 case AUTH_DES: 365 (void) strlcat(buff, "des", sizeof (buff)); 366 break; 367 default: 368 p = buff + strlen(buff); 369 if (p < &buff[sizeof (buff)]) 370 (void) snprintf(p, sizeof (buff) - strlen(buff), 371 "%d", auth); 372 break; 373 } 374 } 375 return (buff); 376} 377 378static void 379sum_mountstat3(line) 380 char *line; 381{ 382 ulong_t status; 383 384 status = getxdr_u_long(); 385 (void) strcpy(line, statusmsg3(status)); 386 if (status == 0) { 387 (void) strcat(line, sum_mountfh3()); 388 (void) strcat(line, " Auth="); 389 (void) strcat(line, print_auth()); 390 } 391} 392 393static void 394detail_mountstat3() 395{ 396 ulong_t status; 397 398 status = getxdr_u_long(); 399 (void) sprintf(get_line(0, 0), "Status = %d (%s)", status, 400 statusmsg3(status)); 401 if (status == 0) { 402 detail_mountfh3(); 403 (void) sprintf(get_line(0, 0), "Authentication flavor = %s", 404 print_auth()); 405 } 406} 407 408char * 409sum_mountfh3() 410{ 411 int len; 412 int fh; 413 static char buff[8]; 414 415 len = getxdr_long(); 416 fh = sum_filehandle(len); 417 (void) sprintf(buff, " FH=%04X", fh & 0xFFFF); 418 return (buff); 419} 420 421static void 422detail_mountfh3() 423{ 424 int pos; 425 int i, l, len; 426 int fh; 427 428 len = getxdr_long(); 429 pos = getxdr_pos(); 430 fh = sum_filehandle(len); 431 setxdr_pos(pos); 432 (void) sprintf(get_line(0, 0), "File handle = [%04X]", fh & 0xFFFF); 433 i = 0; 434 while (i < len) { 435 l = MIN(len - i, 32); 436 (void) showxdr_hex(l, " %s"); 437 i += l; 438 } 439} 440 441static char * 442sum_exports() 443{ 444 static char buff[MNTPATHLEN + 1]; 445 int entries = 0; 446 447 if (setjmp(xdr_err)) { 448 (void) sprintf(buff, "%d+ entries", entries); 449 return (buff); 450 } 451 452 while (getxdr_long()) { 453 (void) getxdr_string(buff, MNTPATHLEN); 454 while (getxdr_long()) { 455 (void) getxdr_string(buff, MNTNAMLEN); 456 } 457 entries++; 458 } 459 460 (void) sprintf(buff, "%d entries", entries); 461 return (buff); 462} 463 464static void 465detail_exports() 466{ 467 int entries = 0; 468 char *dirpath, *grpname; 469 char buff[MNTPATHLEN + 1]; 470 471 if (setjmp(xdr_err)) { 472 (void) sprintf(get_line(0, 0), 473 " %d+ entries. (Frame is incomplete)", 474 entries); 475 return; 476 } 477 478 while (getxdr_long()) { 479 dirpath = (char *)getxdr_string(buff, MNTPATHLEN); 480 (void) sprintf(get_line(0, 0), "Directory = %s", dirpath); 481 entries++; 482 while (getxdr_long()) { 483 grpname = (char *)getxdr_string(buff, MNTNAMLEN); 484 (void) sprintf(get_line(0, 0), " Group = %s", grpname); 485 } 486 } 487} 488 489static char * 490sum_mounts() 491{ 492 int entries = 0; 493 static char buff[MNTPATHLEN + 1]; 494 495 if (setjmp(xdr_err)) { 496 (void) sprintf(buff, "%d+ entries", entries); 497 return (buff); 498 } 499 500 while (getxdr_long()) { 501 (void) getxdr_string(buff, MNTNAMLEN); 502 (void) getxdr_string(buff, MNTPATHLEN); 503 entries++; 504 } 505 506 (void) sprintf(buff, "%d entries", entries); 507 return (buff); 508} 509 510static void 511detail_mounts() 512{ 513 int entries = 0; 514 char *hostname, *directory; 515 char buff1[MNTNAMLEN + 1], buff2[MNTPATHLEN + 1]; 516 517 if (setjmp(xdr_err)) { 518 (void) sprintf(get_line(0, 0), 519 " %d+ entries. (Frame is incomplete)", 520 entries); 521 return; 522 } 523 524 (void) sprintf(get_line(0, 0), "Mount list"); 525 526 while (getxdr_long()) { 527 hostname = (char *)getxdr_string(buff1, MNTNAMLEN); 528 directory = (char *)getxdr_string(buff2, MNTPATHLEN); 529 (void) sprintf(get_line(0, 0), " %s:%s", hostname, directory); 530 entries++; 531 } 532} 533 534char * 535statusmsg3(status) 536 ulong_t status; 537{ 538 539 switch (status) { 540 case MNT_OK: 541 return ("OK"); 542 case MNT3ERR_PERM: 543 return ("Not owner"); 544 case MNT3ERR_NOENT: 545 return ("No such file or directory"); 546 case MNT3ERR_IO: 547 return ("I/O error"); 548 case MNT3ERR_ACCES: 549 return ("Permission denied"); 550 case MNT3ERR_NOTDIR: 551 return ("Not a directory"); 552 case MNT3ERR_INVAL: 553 return ("Invalid argument"); 554 case MNT3ERR_NAMETOOLONG: 555 return ("File name too long"); 556 case MNT3ERR_NOTSUPP: 557 return ("Operation not supported"); 558 case MNT3ERR_SERVERFAULT: 559 return ("Server error"); 560 default: 561 return ("(unknown error)"); 562 } 563} 564