xref: /illumos-gate/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_nis.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 <setjmp.h>
32 #include <string.h>
33 
34 #include <sys/socket.h>
35 #include <sys/sockio.h>
36 #include <sys/tiuser.h>
37 #include <net/if.h>
38 #include <netinet/in_systm.h>
39 #include <netinet/in.h>
40 #include <rpc/types.h>
41 #include <rpc/xdr.h>
42 #include <rpc/auth.h>
43 #include <rpc/clnt.h>
44 #include <rpc/rpc_msg.h>
45 #include <rpcsvc/yp_prot.h>
46 #include "snoop.h"
47 
48 extern char *dlc_header;
49 extern jmp_buf xdr_err;
50 char *ypbind_error();
51 char *sum_ypxfrstat();
52 char *sum_ypmaplist();
53 void detail_ypmaplist();
54 
55 static void niscall(int);
56 static void nisreply(int);
57 static int detail_ypstat(void);
58 static int sum_ypstat(char *);
59 
60 /*
61  * Defines missing from 5.0 yp_prot.h
62  */
63 #define	YPBINDPROG		((ulong_t)100007)
64 #define	YPBINDVERS		((ulong_t)2)
65 #define	YPBINDVERS_ORIG		((ulong_t)1)
66 
67 /* Procedure symbols */
68 
69 #define	YPBINDPROC_NULL		((ulong_t)0)
70 #define	YPBINDPROC_DOMAIN	((ulong_t)1)
71 #define	YPBINDPROC_SETDOM	((ulong_t)2)
72 
73 #define	YPBIND_ERR_ERR 1		/* Internal error */
74 #define	YPBIND_ERR_NOSERV 2		/* No bound server for passed domain */
75 #define	YPBIND_ERR_RESC 3		/* System resource allocation failure */
76 
77 
78 static char *procnames_bind_short[] = {
79 	"NULL",			/*  0 */
80 	"DOMAIN",		/*  1 */
81 	"SETDOMAIN",		/*  2 */
82 };
83 
84 static char *procnames_bind_long[] = {
85 	"Null procedure",		/*  0 */
86 	"Get domain name",		/*  1 */
87 	"Set domain name",		/*  2 */
88 };
89 
90 static char *procnames_short[] = {
91 	"NULL",			/*  0 */
92 	"DOMAIN",		/*  1 */
93 	"DOMAIN_NONACK",	/*  2 */
94 	"MATCH",		/*  3 */
95 	"FIRST",		/*  4 */
96 	"NEXT",			/*  5 */
97 	"XFR",			/*  6 */
98 	"CLEAR",		/*  7 */
99 	"ALL",			/*  8 */
100 	"MASTER",		/*  9 */
101 	"ORDER",		/* 10 */
102 	"MAPLIST",		/* 11 */
103 	"NEWXFR",		/* 12 */
104 };
105 
106 #define	MAXPROC_BIND	2
107 #define	MAXPROC		12
108 
109 static char *procnames_long[] = {
110 	"Null procedure",			/*  0 */
111 	"Verify domain support",		/*  1 */
112 	"Verify domain support (broadcast)",	/*  2 */
113 	"Return value of a key",		/*  3 */
114 	"Return first key-value pair in map",	/*  4 */
115 	"Return next key-value pair in map",	/*  5 */
116 	"Request map update (old)",		/*  6 */
117 	"Close current map on server",		/*  7 */
118 	"Get all key-value pairs in map",	/*  8 */
119 	"Get master server",			/*  9 */
120 	"Get order",				/* 10 */
121 	"Return list of supported maps",	/* 11 */
122 	"Request map update",			/* 12 */
123 };
124 
125 void
126 interpret_nisbind(flags, type, xid, vers, proc, data, len)
127 	int flags, type, xid, vers, proc;
128 	char *data;
129 	int len;
130 {
131 	char *line;
132 	char buff[YPMAXDOMAIN + 1];
133 	unsigned int status;
134 
135 	if (proc < 0 || proc > MAXPROC_BIND)
136 		return;
137 
138 	if (flags & F_SUM) {
139 		if (setjmp(xdr_err)) {
140 			return;
141 		}
142 
143 		line = get_sum_line();
144 
145 		if (type == CALL) {
146 			(void) sprintf(line,
147 				"NISBIND C %s",
148 				procnames_bind_short[proc]);
149 			line += strlen(line);
150 			switch (proc) {
151 			case YPBINDPROC_NULL:
152 				break;
153 			case YPBINDPROC_DOMAIN:
154 				(void) sprintf(line, " %s",
155 					getxdr_string(buff, YPMAXDOMAIN));
156 				break;
157 			case YPBINDPROC_SETDOM:
158 				(void) sprintf(line, " %s",
159 					getxdr_string(buff, YPMAXDOMAIN));
160 				break;
161 			default:
162 				break;
163 			}
164 			check_retransmit(line, xid);
165 		} else {
166 			(void) sprintf(line, "NISBIND R %s ",
167 				procnames_bind_short[proc]);
168 			line += strlen(line);
169 			switch (proc) {
170 			case YPBINDPROC_NULL:
171 				break;
172 			case YPBINDPROC_DOMAIN:
173 				status = getxdr_long();
174 				if (status == 1) {	/* success */
175 					(void) strcat(line, "OK");
176 				} else {		/* failure */
177 					status = getxdr_long();
178 					(void) sprintf(line, "ERROR=%s",
179 						ypbind_error(status));
180 				}
181 				break;
182 			case YPBINDPROC_SETDOM:
183 				break;
184 			default:
185 				break;
186 			}
187 		}
188 	}
189 
190 	if (flags & F_DTAIL) {
191 		show_header("NISBIND:",
192 			"Network Information Service Bind", len);
193 		show_space();
194 		if (setjmp(xdr_err)) {
195 			return;
196 		}
197 		(void) sprintf(get_line(0, 0),
198 			"Proc = %d (%s)",
199 			proc, procnames_bind_long[proc]);
200 		if (type == CALL) {
201 			switch (proc) {
202 			case YPBINDPROC_NULL:
203 				break;
204 			case YPBINDPROC_DOMAIN:
205 				(void) showxdr_string(YPMAXDOMAIN,
206 					"Domain = %s");
207 				break;
208 			case YPBINDPROC_SETDOM:
209 				(void) showxdr_string(YPMAXDOMAIN,
210 					"Domain = %s");
211 				(void) showxdr_hex(4, "Address=%s");
212 				(void) showxdr_hex(2, "Port=%s");
213 				(void) showxdr_u_long("Version=%lu");
214 				break;
215 			default:
216 				break;
217 			}
218 		} else {
219 			switch (proc) {
220 			case YPBINDPROC_NULL:
221 				break;
222 			case YPBINDPROC_DOMAIN:
223 				status = getxdr_u_long();
224 				(void) sprintf(get_line(0, 0),
225 					"Status = %lu (%s)",
226 					status,
227 					status == 1 ? "OK":"Fail");
228 				if (status == 1) {
229 					(void) showxdr_hex(4,
230 						"Address=%s");
231 					(void) showxdr_hex(2,
232 						"Port=%s");
233 				} else {
234 					status = getxdr_u_long();
235 					(void) sprintf(get_line(0, 0),
236 						"Error = %lu (%s)",
237 						status,
238 						ypbind_error(status));
239 				}
240 				break;
241 			case YPBINDPROC_SETDOM:
242 				break;
243 			default:
244 				break;
245 			}
246 		}
247 		show_trailer();
248 	}
249 }
250 
251 void
252 interpret_nis(flags, type, xid, vers, proc, data, len)
253 	int flags, type, xid, vers, proc;
254 	char *data;
255 	int len;
256 {
257 	char *line;
258 	char *dom, *map, *key;
259 	int transid, status;
260 	/* buffers are all the same size so we don't have to keep track */
261 	char buff1[YPMAXRECORD + 1], buff2[YPMAXRECORD + 1];
262 	char buff3[YPMAXRECORD + 1];
263 
264 	if (flags & F_SUM) {
265 		if (setjmp(xdr_err)) {
266 			return;
267 		}
268 
269 		line = get_sum_line();
270 
271 		if (type == CALL) {
272 			if (proc > MAXPROC)
273 				(void) sprintf(line, "NIS C %d", proc);
274 			else
275 				(void) sprintf(line,
276 					"NIS C %s",
277 					procnames_short[proc]);
278 			line += strlen(line);
279 			switch (proc) {
280 			case YPPROC_NULL:
281 				break;
282 			case YPPROC_DOMAIN:
283 			case YPPROC_DOMAIN_NONACK:
284 			case YPPROC_MAPLIST:
285 				/* YPMAXDOMAIN > YPMAXMAP */
286 				(void) sprintf(line, " %s",
287 					getxdr_string(buff1, YPMAXDOMAIN));
288 				break;
289 			case YPPROC_FIRST:
290 				dom = getxdr_string(buff1, YPMAXDOMAIN);
291 				map = getxdr_string(buff2, YPMAXMAP);
292 				(void) sprintf(line, " %s", map);
293 				break;
294 			case YPPROC_MATCH:
295 			case YPPROC_NEXT:
296 				dom = getxdr_string(buff1, YPMAXDOMAIN);
297 				map = getxdr_string(buff2, YPMAXMAP);
298 				key = getxdr_string(buff3, YPMAXRECORD);
299 				(void) sprintf(line,
300 					" %s in %s",
301 					key, map);
302 				break;
303 			case YPPROC_NEWXFR:
304 			case YPPROC_XFR:
305 				dom = getxdr_string(buff1, YPMAXDOMAIN);
306 				map = getxdr_string(buff2, YPMAXMAP);
307 				(void) sprintf(line,
308 					" map %s in %s",
309 					map, dom);
310 				break;
311 			case YPPROC_CLEAR:
312 				break;
313 			case YPPROC_ALL:
314 			case YPPROC_MASTER:
315 			case YPPROC_ORDER:
316 				dom = getxdr_string(buff1, YPMAXDOMAIN);
317 				map = getxdr_string(buff2, YPMAXMAP);
318 				(void) sprintf(line,
319 					" map %s in %s",
320 					map, dom);
321 				break;
322 			default:
323 				break;
324 			}
325 			check_retransmit(line, xid);
326 		} else {
327 			if (proc > MAXPROC)
328 				(void) sprintf(line, "NIS R %d ", proc);
329 			else
330 				(void) sprintf(line, "NIS R %s ",
331 					procnames_short[proc]);
332 			line += strlen(line);
333 			switch (proc) {
334 			case YPPROC_NULL:
335 				break;
336 			case YPPROC_DOMAIN:
337 			case YPPROC_DOMAIN_NONACK:
338 				(void) sprintf(line, "%s",
339 					getxdr_long() ? "OK":"Fail");
340 				break;
341 			case YPPROC_MATCH:
342 				(void) sum_ypstat(line);
343 				break;
344 			case YPPROC_FIRST:
345 			case YPPROC_NEXT:
346 				if (sum_ypstat(line) == YP_TRUE) {
347 					line += strlen(line);
348 					(void) getxdr_string(buff1,
349 							YPMAXRECORD);
350 					(void) sprintf(line, " key=%s",
351 						getxdr_string(buff1,
352 							YPMAXRECORD));
353 				}
354 				break;
355 			case YPPROC_NEWXFR:
356 			case YPPROC_XFR:
357 				transid = getxdr_u_long();
358 				status  = getxdr_long();
359 				(void) sprintf(line, "transid=%lu %s",
360 					transid,
361 					sum_ypxfrstat(status));
362 				break;
363 			case YPPROC_CLEAR:
364 				break;
365 			case YPPROC_ALL:
366 				if (getxdr_u_long()) {
367 					(void) sum_ypstat(line);
368 					line += strlen(line);
369 					(void) sprintf(line, " key=%s",
370 					    getxdr_string(buff1, YPMAXRECORD));
371 				} else {
372 					(void) sprintf(line,
373 						"No more");
374 				}
375 				break;
376 			case YPPROC_MASTER:
377 				if (sum_ypstat(line) == YP_TRUE) {
378 					line += strlen(line);
379 					(void) sprintf(line, " peer=%s",
380 						getxdr_string(buff1,
381 							YPMAXPEER));
382 				}
383 				break;
384 			case YPPROC_ORDER:
385 				if (sum_ypstat(line) == YP_TRUE) {
386 					line += strlen(line);
387 					(void) sprintf(line, " order=%lu",
388 						getxdr_u_long());
389 				}
390 				break;
391 			case YPPROC_MAPLIST:
392 				if (sum_ypstat(line) == YP_TRUE) {
393 					line += strlen(line);
394 					(void) sprintf(line, " %s",
395 						sum_ypmaplist());
396 				}
397 				break;
398 			default:
399 				break;
400 			}
401 		}
402 	}
403 
404 	if (flags & F_DTAIL) {
405 		show_header("NIS:  ", "Network Information Service", len);
406 		show_space();
407 		if (setjmp(xdr_err)) {
408 			return;
409 		}
410 		(void) sprintf(get_line(0, 0),
411 			"Proc = %d (%s)",
412 			proc,
413 			proc > MAXPROC ? "unknown" : procnames_long[proc]);
414 		if (type == CALL)
415 			niscall(proc);
416 		else
417 			nisreply(proc);
418 		show_trailer();
419 	}
420 }
421 
422 /*
423  *  Print out version 2 NIS call packets
424  */
425 
426 static void
427 niscall(proc)
428 	int proc;
429 {
430 	switch (proc) {
431 	case YPPROC_NULL:
432 		break;
433 	case YPPROC_DOMAIN:
434 	case YPPROC_DOMAIN_NONACK:
435 	case YPPROC_MAPLIST:
436 		(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
437 		break;
438 	case YPPROC_FIRST:
439 		(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
440 		(void) showxdr_string(YPMAXMAP, "Map = %s");
441 		break;
442 	case YPPROC_MATCH:
443 	case YPPROC_NEXT:
444 		(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
445 		(void) showxdr_string(YPMAXMAP, "Map = %s");
446 		(void) showxdr_string(YPMAXRECORD, "Key = %s");
447 		break;
448 	case YPPROC_NEWXFR:
449 		(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
450 		(void) showxdr_string(YPMAXMAP, "Map = %s");
451 		(void) showxdr_u_long("Order = %lu");
452 		(void) showxdr_string(YPMAXPEER, "Peer = %s");
453 		(void) showxdr_u_long("Transid = %lu");
454 		(void) showxdr_u_long("Prog = %lu");
455 		(void) showxdr_string(YPMAXPEER, "Name = %s");
456 		break;
457 	case YPPROC_XFR:
458 		(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
459 		(void) showxdr_string(YPMAXMAP, "Map = %s");
460 		(void) showxdr_u_long("Order = %lu");
461 		(void) showxdr_string(YPMAXPEER, "Peer = %s");
462 		(void) showxdr_u_long("Transid = %lu");
463 		(void) showxdr_u_long("Prog = %lu");
464 		(void) showxdr_u_long("Port = %lu");
465 		break;
466 	case YPPROC_CLEAR:
467 		break;
468 	case YPPROC_ALL:
469 	case YPPROC_MASTER:
470 	case YPPROC_ORDER:
471 		(void) showxdr_string(YPMAXDOMAIN, "Domain = %s");
472 		(void) showxdr_string(YPMAXMAP, "Map = %s");
473 		break;
474 	default:
475 		break;
476 	}
477 }
478 
479 /*
480  *  Print out version 2 NIS reply packets
481  */
482 
483 void
484 nisreply(proc)
485 	int proc;
486 {
487 	unsigned int xfrstat, more;
488 
489 	switch (proc) {
490 	case YPPROC_NULL:
491 		break;
492 	case YPPROC_DOMAIN:
493 	case YPPROC_DOMAIN_NONACK:
494 		(void) sprintf(get_line(0, 0),
495 			"Result=%s",
496 			getxdr_u_long() ? "OK":"Fail");
497 		break;
498 	case YPPROC_MATCH:
499 		(void) detail_ypstat();
500 		(void) showxdr_string(YPMAXRECORD, "Value = %s");
501 		break;
502 	case YPPROC_FIRST:
503 	case YPPROC_NEXT:
504 		(void) detail_ypstat();
505 		(void) showxdr_string(YPMAXRECORD, "Value = %s");
506 		(void) showxdr_string(YPMAXRECORD, "Key = %s");
507 		break;
508 	case YPPROC_NEWXFR:
509 	case YPPROC_XFR:
510 		(void) showxdr_u_long("Transid = %lu");
511 		xfrstat = getxdr_u_long();
512 		(void) sprintf(get_line(0, 0),
513 			"Transfer status = %lu (%s)",
514 			xfrstat, sum_ypxfrstat(xfrstat));
515 		break;
516 	case YPPROC_CLEAR:
517 		break;
518 	case YPPROC_ALL:
519 		more = getxdr_u_long();
520 		(void) sprintf(get_line(0, 0),
521 			"More = %s",
522 			more ? "true" : "false");
523 		if (more) {
524 			(void) detail_ypstat();
525 			(void) showxdr_string(YPMAXRECORD, "Value = %s");
526 			(void) showxdr_string(YPMAXRECORD, "Key = %s");
527 		}
528 		break;
529 	case YPPROC_MASTER:
530 		(void) detail_ypstat();
531 		(void) showxdr_string(YPMAXPEER, "Peer = %s");
532 	case YPPROC_ORDER:
533 		(void) detail_ypstat();
534 		(void) showxdr_u_long("Order=%lu");
535 		break;
536 	case YPPROC_MAPLIST:
537 		(void) detail_ypstat();
538 		detail_ypmaplist();
539 		break;
540 	default:
541 		break;
542 	}
543 }
544 
545 char *
546 sum_ypxfrstat(status)
547 	int status;
548 {
549 	static char buff [16];
550 
551 	switch (status) {
552 	case   1:	return ("Success");
553 	case   2:	return ("Master's version not newer");
554 	case  -1:	return ("Can't find server for map");
555 	case  -2:	return ("No such domain");
556 	case  -3:	return ("Resource allocation failure");
557 	case  -4:	return ("RPC failure talking to server");
558 	case  -5:	return ("Can't get master address");
559 	case  -6:	return ("NIS server/map db error");
560 	case  -7:	return ("Bad arguments");
561 	case  -8:	return ("Local dbm operation failed");
562 	case  -9:	return ("Local file I/O operation failed");
563 	case -10:	return ("Map version skew during transfer");
564 	case -11:	return ("Can't send clear req to local ypserv");
565 	case -12:	return ("No local order number in map");
566 	case -13:	return ("Transfer error");
567 	case -14:	return ("Transfer request refused");
568 	default:
569 		(void) sprintf(buff, "(%d)", status);
570 		return (buff);
571 	}
572 	/* NOTREACHED */
573 }
574 
575 static int
576 sum_ypstat(line)
577 	char *line;
578 {
579 	ulong_t status;
580 	char *str;
581 	char buff[16];
582 
583 	status = getxdr_u_long();
584 	switch (status) {
585 	case YP_TRUE:	str = "OK";			break;
586 	case YP_NOMORE:	str = "No more entries";	break;
587 	case YP_FALSE:	str = "Fail";			break;
588 	case YP_NOMAP:	str = "No such map";		break;
589 	case YP_NODOM:	str = "No such domain";		break;
590 	case YP_NOKEY:	str = "No such key";		break;
591 	case YP_BADOP:	str = "Invalid operation";	break;
592 	case YP_BADDB:	str = "Bad database";		break;
593 	case YP_YPERR:	str = "Server error";		break;
594 	case YP_BADARGS:str = "Bad args";		break;
595 	case YP_VERS:	str = "Version mismatch";	break;
596 	default:	(void) sprintf(buff, "(%lu)", status);
597 			str = buff;
598 			break;
599 	}
600 	(void) strcpy(line, str);
601 	return ((int)status);
602 }
603 
604 static int
605 detail_ypstat()
606 {
607 	ulong_t status;
608 	char buff[32];
609 
610 
611 	status = sum_ypstat(buff);
612 	(void) sprintf(get_line(0, 0),
613 		"Status = %d (%s)",
614 		status, buff);
615 
616 	return ((int)status);
617 }
618 
619 char *
620 sum_ypmaplist()
621 {
622 	static char buff[YPMAXMAP + 1];
623 	int maps = 0;
624 
625 	if (setjmp(xdr_err)) {
626 		(void) sprintf(buff, "%d+ maps", maps);
627 		return (buff);
628 	}
629 
630 	while (getxdr_long()) {
631 		(void) getxdr_string(buff, YPMAXMAP);
632 		maps++;
633 	}
634 
635 	(void) sprintf(buff, "%d maps", maps);
636 	return (buff);
637 }
638 
639 void
640 detail_ypmaplist()
641 {
642 	int maps = 0;
643 
644 	if (setjmp(xdr_err)) {
645 		(void) sprintf(get_line(0, 0),
646 			" %d+ maps. (Frame is incomplete)",
647 			maps);
648 		return;
649 	}
650 
651 	(void) sprintf(get_line(0, 0), "Map list");
652 
653 	while (getxdr_long()) {
654 		(void) showxdr_string(YPMAXMAP, "  %s");
655 		maps++;
656 	}
657 
658 	(void) sprintf(get_line(0, 0), "%d maps", maps);
659 }
660 
661 char *
662 ypbind_error(err)
663 	int err;
664 {
665 	static char buff[16];
666 
667 	switch (err) {
668 	case YPBIND_ERR_ERR:	return ("Internal error");
669 	case YPBIND_ERR_NOSERV:	return ("Internal error");
670 	case YPBIND_ERR_RESC:	return ("Resource allocation fail");
671 	default:
672 		(void) sprintf(buff, "(%d)", err);
673 		return (buff);
674 	}
675 	/* NOTREACHED */
676 }
677