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
49 extern char *dlc_header;
50 extern jmp_buf xdr_err;
51
52 static void mountcall(int, int);
53 static void mountreply(int, int);
54
55 static void sum_mountstat(char *);
56 static void sum_mountstat3(char *);
57 static char *sum_mountfh(void);
58 static char *sum_mountfh3(void);
59 static char *sum_exports(void);
60 static char *sum_mounts(void);
61
62 static int detail_mountstat(void);
63 static void detail_mountstat3(void);
64 static void detail_mountfh(void);
65 static void detail_mountfh3(void);
66 static void detail_exports(void);
67 static void detail_mounts(void);
68
69 static char *statusmsg3(ulong_t);
70
71 static 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
82 static 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
95 void
interpret_mount(flags,type,xid,vers,proc,data,len)96 interpret_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
206 static void
mountcall(proc,vers)207 mountcall(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
242 static void
mountreply(proc,vers)243 mountreply(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
283 static void
sum_mountstat(line)284 sum_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
301 static int
detail_mountstat()302 detail_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
318 char *
sum_mountfh()319 sum_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
329 static void
detail_mountfh()330 detail_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
342 static char *
print_auth()343 print_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
378 static void
sum_mountstat3(line)379 sum_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
393 static void
detail_mountstat3()394 detail_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
408 char *
sum_mountfh3()409 sum_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
421 static void
detail_mountfh3()422 detail_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
441 static char *
sum_exports()442 sum_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
464 static void
detail_exports()465 detail_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
489 static char *
sum_mounts()490 sum_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
510 static void
detail_mounts()511 detail_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
534 char *
statusmsg3(status)535 statusmsg3(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