xref: /illumos-gate/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_mount.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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