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