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 <sys/tiuser.h>
33 #include <string.h>
34
35 #include <rpc/types.h>
36 #include <rpc/xdr.h>
37 #include <rpc/auth.h>
38 #include <rpc/clnt.h>
39 #include <rpc/rpc_msg.h>
40 #include <rpc/pmap_prot.h>
41 #include "snoop.h"
42
43 /*
44 * Number of bytes to display from a string (address, netid, etc.).
45 */
46 #define MAXSTRINGLEN 64
47
48 extern char *dlc_header;
49 extern jmp_buf xdr_err;
50
51 static void interpret_pmap_2(int, int, int, int, int, char *, int);
52 static void interpret_pmap_4(int, int, int, int, int, char *, int);
53 static void stash_callit(ulong_t, int, int, int, int);
54
55 void
interpret_pmap(flags,type,xid,vers,proc,data,len)56 interpret_pmap(flags, type, xid, vers, proc, data, len)
57 int flags, type, xid, vers, proc;
58 char *data;
59 int len;
60 {
61 switch (vers) {
62 case 2: interpret_pmap_2(flags, type, xid, vers, proc, data, len);
63 break;
64
65 /* Version 3 is a subset of version 4 */
66 case 3:
67 case 4: interpret_pmap_4(flags, type, xid, vers, proc, data, len);
68 break;
69 }
70 }
71
72 void show_pmap();
73 char *sum_pmaplist();
74 void show_pmaplist();
75
76 static char *procnames_short_2[] = {
77 "Null", /* 0 */
78 "SET", /* 1 */
79 "UNSET", /* 2 */
80 "GETPORT", /* 3 */
81 "DUMP", /* 4 */
82 "CALLIT", /* 5 */
83 };
84
85 static char *procnames_long_2[] = {
86 "Null procedure", /* 0 */
87 "Set port", /* 1 */
88 "Unset port", /* 2 */
89 "Get port number", /* 3 */
90 "Dump the mappings", /* 4 */
91 "Indirect call", /* 5 */
92 };
93
94 #define MAXPROC_2 5
95
96 void
interpret_pmap_2(flags,type,xid,vers,proc,data,len)97 interpret_pmap_2(flags, type, xid, vers, proc, data, len)
98 int flags, type, xid, vers, proc;
99 char *data;
100 int len;
101 {
102 char *line;
103 unsigned port, proto;
104 unsigned iprog, ivers, iproc, ilen;
105 extern int pi_frame;
106 struct cache_struct *x, *find_callit();
107 int trailer_done = 0;
108
109 if (proc < 0 || proc > MAXPROC_2)
110 return;
111
112 if (proc == PMAPPROC_CALLIT) {
113 if (type == CALL) {
114 iprog = getxdr_u_long();
115 ivers = getxdr_u_long();
116 iproc = getxdr_u_long();
117 stash_callit(xid, pi_frame,
118 iprog, ivers, iproc);
119 } else {
120 x = find_callit(xid);
121 }
122 }
123
124 if (flags & F_SUM) {
125 if (setjmp(xdr_err)) {
126 return;
127 }
128
129 line = get_sum_line();
130
131 if (type == CALL) {
132 (void) sprintf(line,
133 "PORTMAP C %s",
134 procnames_short_2[proc]);
135 line += strlen(line);
136 switch (proc) {
137 case PMAPPROC_GETPORT:
138 iprog = getxdr_u_long();
139 ivers = getxdr_u_long();
140 proto = getxdr_u_long();
141 (void) sprintf(line,
142 " prog=%d (%s) vers=%d proto=%s",
143 iprog, nameof_prog(iprog),
144 ivers,
145 getproto(proto));
146 break;
147 case PMAPPROC_CALLIT:
148 (void) getxdr_u_long(); /* length */
149 (void) sprintf(line,
150 " prog=%s vers=%d proc=%d",
151 nameof_prog(iprog),
152 ivers, iproc);
153 data += 16; /* prog+ver+proc+len */
154 len -= 16;
155 protoprint(flags, type, xid,
156 iprog, ivers, iproc,
157 data, len);
158 break;
159 default:
160 break;
161 }
162 check_retransmit(line, xid);
163 } else {
164 (void) sprintf(line, "PORTMAP R %s ",
165 procnames_short_2[proc]);
166 line += strlen(line);
167 switch (proc) {
168 case PMAPPROC_GETPORT:
169 port = getxdr_u_long();
170 (void) sprintf(line, "port=%d",
171 port);
172 break;
173 case PMAPPROC_DUMP:
174 (void) sprintf(line, "%s",
175 sum_pmaplist());
176 break;
177 case PMAPPROC_CALLIT:
178 port = getxdr_u_long();
179 ilen = getxdr_u_long();
180 (void) sprintf(line, "port=%d len=%d",
181 port, ilen);
182 if (x != NULL) {
183 protoprint(flags, type, xid,
184 x->xid_prog,
185 x->xid_vers,
186 x->xid_proc,
187 data, len);
188 }
189 break;
190 default:
191 break;
192 }
193 }
194 }
195
196 if (flags & F_DTAIL) {
197 show_header("PMAP: ", "Portmapper", len);
198 show_space();
199 if (setjmp(xdr_err)) {
200 return;
201 }
202 (void) sprintf(get_line(0, 0),
203 "Proc = %d (%s)",
204 proc, procnames_long_2[proc]);
205 if (type == CALL) {
206 switch (proc) {
207 case PMAPPROC_NULL:
208 case PMAPPROC_SET:
209 case PMAPPROC_UNSET:
210 break;
211 case PMAPPROC_GETPORT:
212 iprog = getxdr_u_long();
213 (void) sprintf(get_line(0, 0),
214 "Program = %d (%s)",
215 iprog, nameof_prog(iprog));
216 (void) showxdr_u_long("Version = %d");
217 proto = getxdr_u_long();
218 (void) sprintf(get_line(0, 0),
219 "Protocol = %d (%s)",
220 proto, getproto(proto));
221 break;
222 case PMAPPROC_DUMP:
223 break;
224 case PMAPPROC_CALLIT:
225 (void) sprintf(get_line(0, 0),
226 "Program = %d (%s)",
227 iprog, nameof_prog(iprog));
228 (void) sprintf(get_line(0, 0),
229 "Version = %d", ivers);
230 (void) sprintf(get_line(0, 0),
231 "Proc = %d", iproc);
232 (void) showxdr_u_long(
233 "Callit data = %d bytes");
234 show_trailer();
235 trailer_done = 1;
236 data += 16; /* prog+ver+proc+len */
237 len -= 16;
238 protoprint(flags, type, xid,
239 iprog, ivers, iproc,
240 data, len);
241 break;
242 }
243 } else {
244 switch (proc) {
245 case PMAPPROC_NULL:
246 case PMAPPROC_SET:
247 case PMAPPROC_UNSET:
248 break;
249 case PMAPPROC_GETPORT:
250 (void) showxdr_u_long("Port = %d");
251 break;
252 case PMAPPROC_DUMP:
253 show_pmaplist();
254 break;
255 case PMAPPROC_CALLIT:
256 (void) showxdr_u_long("Port = %d");
257 (void) showxdr_u_long("Length = %d bytes");
258 show_trailer();
259 trailer_done = 1;
260 if (x != NULL) {
261 protoprint(flags, type, xid,
262 x->xid_prog,
263 x->xid_vers,
264 x->xid_proc,
265 data, len);
266 }
267 break;
268 }
269 }
270 if (!trailer_done)
271 show_trailer();
272 }
273 }
274
275 char *
sum_pmaplist()276 sum_pmaplist()
277 {
278 int maps = 0;
279 static char buff[16];
280
281 if (setjmp(xdr_err)) {
282 (void) sprintf(buff, "%d+ map(s) found", maps);
283 return (buff);
284 }
285
286 while (getxdr_u_long()) {
287 (void) getxdr_u_long(); /* program */
288 (void) getxdr_u_long(); /* version */
289 (void) getxdr_u_long(); /* protocol */
290 (void) getxdr_u_long(); /* port */
291 maps++;
292 }
293
294 (void) sprintf(buff, "%d map(s) found", maps);
295 return (buff);
296 }
297
298 void
show_pmaplist()299 show_pmaplist()
300 {
301 unsigned prog, vers, proto, port;
302 int maps = 0;
303
304 if (setjmp(xdr_err)) {
305 (void) sprintf(get_line(0, 0),
306 " %d+ maps. (Frame is incomplete)",
307 maps);
308 return;
309 }
310
311 (void) sprintf(get_line(0, 0),
312 " Program Version Protocol Port");
313
314 while (getxdr_u_long()) {
315 prog = getxdr_u_long();
316 vers = getxdr_u_long();
317 proto = getxdr_u_long();
318 port = getxdr_u_long();
319 (void) sprintf(get_line(0, 0),
320 "%8d%8d%9d%7d %s",
321 prog, vers, proto, port, nameof_prog(prog));
322 maps++;
323 }
324
325 (void) sprintf(get_line(0, 0), " %d maps", maps);
326 }
327
328 /*
329 * ******************************************
330 */
331 char *sum_rpcblist();
332 void show_rpcblist();
333 char *sum_rpcb_entry_list();
334 void show_rpcb_entry_list();
335
336 static char *procnames_short_4[] = {
337 /*
338 * version 3 and 4 procs
339 */
340 "Null", /* 0 */
341 "SET", /* 1 */
342 "UNSET", /* 2 */
343 "GETADDR", /* 3 */
344 "DUMP", /* 4 */
345 "BCAST", /* 5 */
346 "GETTIME", /* 6 */
347 "UADDR2TADDR", /* 7 */
348 "TADDR2UADDR", /* 8 */
349 /*
350 * version 4 procs only
351 */
352 "GETVERSADDR", /* 9 */
353 "INDIRECT", /* 10 */
354 "GETADDRLIST", /* 11 */
355 "GETSTAT", /* 12 */
356 };
357
358 static char *procnames_long_4[] = {
359 /*
360 * version 3 and 4 procs
361 */
362 "Null procedure", /* 0 */
363 "Set address", /* 1 */
364 "Unset address", /* 2 */
365 "Get address", /* 3 */
366 "Dump the mappings", /* 4 */
367 "Broadcast call (no error)", /* 5 */
368 "Get the time", /* 6 */
369 "Universal to transport address", /* 7 */
370 "Transport to universal address", /* 8 */
371 /*
372 * version 4 procs only
373 */
374 "Get address of specific version", /* 9 */
375 "Indirect call (return error)", /* 10 */
376 "Return addresses of prog/vers", /* 11 */
377 "Get statistics", /* 12 */
378 };
379
380 #define MAXPROC_4 12
381 #define RPCBPROC_NULL 0
382
383 void
interpret_pmap_4(flags,type,xid,vers,proc,data,len)384 interpret_pmap_4(flags, type, xid, vers, proc, data, len)
385 int flags, type, xid, vers, proc;
386 char *data;
387 int len;
388 {
389 char *line;
390 unsigned prog, ver;
391 char buff1[MAXSTRINGLEN + 1];
392 int iprog, ivers, iproc, ilen;
393 extern int pi_frame;
394 struct cache_struct *x, *find_callit();
395 int trailer_done = 0;
396
397 if (proc < 0 || proc > MAXPROC_4)
398 return;
399
400 if (proc == RPCBPROC_BCAST) {
401 if (type == CALL) {
402 iprog = getxdr_u_long();
403 ivers = getxdr_u_long();
404 iproc = getxdr_u_long();
405 stash_callit(xid, pi_frame,
406 iprog, ivers, iproc);
407 } else {
408 x = find_callit(xid);
409 }
410 }
411
412 if (flags & F_SUM) {
413 if (setjmp(xdr_err)) {
414 return;
415 }
416
417 line = get_sum_line();
418
419 if (type == CALL) {
420 (void) sprintf(line,
421 "RPCBIND C %s",
422 procnames_short_4[proc]);
423 line += strlen(line);
424 switch (proc) {
425 case RPCBPROC_SET:
426 case RPCBPROC_UNSET:
427 case RPCBPROC_GETADDR:
428 case RPCBPROC_GETVERSADDR:
429 case RPCBPROC_GETADDRLIST:
430 prog = getxdr_u_long();
431 ver = getxdr_u_long();
432 (void) sprintf(line,
433 " prog=%d (%s) vers=%d",
434 prog, nameof_prog(prog),
435 ver);
436 break;
437 case RPCBPROC_BCAST:
438 case RPCBPROC_INDIRECT:
439 (void) getxdr_u_long(); /* length */
440 (void) sprintf(line,
441 " prog=%s vers=%d proc=%d",
442 nameof_prog(iprog),
443 ivers, iproc);
444 data += 16; /* prog+ver+proc+len */
445 len -= 16;
446 protoprint(flags, type, xid,
447 iprog, ivers, iproc,
448 data, len);
449 break;
450 default:
451 break;
452 }
453
454 check_retransmit(line, xid);
455 } else {
456 (void) sprintf(line, "RPCBIND R %s ",
457 procnames_short_4[proc]);
458 line += strlen(line);
459 switch (proc) {
460 case RPCBPROC_GETADDR:
461 case RPCBPROC_TADDR2UADDR:
462 case RPCBPROC_GETVERSADDR:
463 (void) getxdr_string(buff1, MAXSTRINGLEN);
464 (void) sprintf(line,
465 " Uaddr=%s",
466 buff1);
467 break;
468 case RPCBPROC_BCAST:
469 case RPCBPROC_INDIRECT:
470 (void) getxdr_string(buff1, MAXSTRINGLEN);
471 ilen = getxdr_u_long();
472 (void) sprintf(line, "Uaddr=%s len=%d",
473 buff1, ilen);
474 data += 16; /* prog+ver+proc+len */
475 len -= 16;
476 if (x != NULL) {
477 protoprint(flags, type, xid,
478 x->xid_prog,
479 x->xid_vers,
480 x->xid_proc,
481 data, len);
482 }
483 break;
484 case RPCBPROC_DUMP:
485 (void) sprintf(line, "%s",
486 sum_rpcblist());
487 break;
488 case RPCBPROC_GETTIME:
489 (void) sprintf(line, "%s",
490 getxdr_date());
491 break;
492 case RPCBPROC_GETADDRLIST:
493 (void) sprintf(line, "%s",
494 sum_rpcb_entry_list());
495 break;
496 default:
497 break;
498 }
499 }
500 }
501
502 if (flags & F_DTAIL) {
503 show_header("RPCB: ", "RPC Bind", len);
504 show_space();
505 if (setjmp(xdr_err)) {
506 return;
507 }
508 (void) sprintf(get_line(0, 0),
509 "Proc = %d (%s)",
510 proc, procnames_long_4[proc]);
511 if (type == CALL) {
512 switch (proc) {
513 case RPCBPROC_NULL:
514 break;
515 case RPCBPROC_SET:
516 case RPCBPROC_UNSET:
517 case RPCBPROC_GETADDR:
518 case RPCBPROC_GETVERSADDR:
519 case RPCBPROC_GETADDRLIST:
520 (void) showxdr_u_long("Program = %d");
521 (void) showxdr_u_long("Version = %d");
522 (void) showxdr_string(64, "Netid = %s");
523 break;
524 case RPCBPROC_DUMP:
525 break;
526 case RPCBPROC_BCAST:
527 case RPCBPROC_INDIRECT:
528 (void) sprintf(get_line(0, 0),
529 "Program = %d (%s)",
530 iprog, nameof_prog(iprog));
531 (void) sprintf(get_line(0, 0),
532 "Version = %d", ivers);
533 (void) sprintf(get_line(0, 0),
534 "Proc = %d", iproc);
535 (void) showxdr_u_long(
536 "Callit data = %d bytes");
537 show_trailer();
538 trailer_done = 1;
539 data += 16; /* prog+ver+proc+len */
540 len -= 16;
541 protoprint(flags, type, xid,
542 iprog, ivers, iproc,
543 data, len);
544 break;
545 case RPCBPROC_GETTIME:
546 break;
547 case RPCBPROC_UADDR2TADDR:
548 case RPCBPROC_TADDR2UADDR:
549 break;
550 }
551 } else {
552 switch (proc) {
553 case RPCBPROC_NULL:
554 case RPCBPROC_SET:
555 case RPCBPROC_UNSET:
556 break;
557 case RPCBPROC_GETADDR:
558 case RPCBPROC_TADDR2UADDR:
559 case RPCBPROC_GETVERSADDR:
560 (void) showxdr_string(64, "Uaddr = %s");
561 break;
562 case RPCBPROC_DUMP:
563 show_rpcblist();
564 break;
565 case RPCBPROC_BCAST:
566 case RPCBPROC_INDIRECT:
567 (void) showxdr_string(64, "Uaddr = %s");
568 (void) showxdr_u_long("Length = %d bytes");
569 show_trailer();
570 trailer_done = 1;
571 if (x != NULL) {
572 protoprint(flags, type, xid,
573 x->xid_prog,
574 x->xid_vers,
575 x->xid_proc,
576 data, len);
577 }
578 break;
579 case RPCBPROC_GETTIME:
580 (void) showxdr_date("Time = %s");
581 break;
582 case RPCBPROC_UADDR2TADDR:
583 break;
584 case RPCBPROC_GETADDRLIST:
585 show_rpcb_entry_list();
586 break;
587 }
588 }
589 if (!trailer_done)
590 show_trailer();
591 }
592 }
593
594 char *
sum_rpcblist()595 sum_rpcblist()
596 {
597 int maps = 0;
598 static char buff[MAXSTRINGLEN + 1];
599
600 if (setjmp(xdr_err)) {
601 (void) sprintf(buff, "%d+ map(s) found", maps);
602 return (buff);
603 }
604
605 while (getxdr_u_long()) {
606 (void) getxdr_u_long(); /* program */
607 (void) getxdr_u_long(); /* version */
608 (void) getxdr_string(buff, MAXSTRINGLEN); /* netid */
609 (void) getxdr_string(buff, MAXSTRINGLEN); /* uaddr */
610 (void) getxdr_string(buff, MAXSTRINGLEN); /* owner */
611 maps++;
612 }
613
614 (void) sprintf(buff, "%d map(s) found", maps);
615 return (buff);
616 }
617
618 void
show_rpcblist()619 show_rpcblist()
620 {
621 unsigned prog, vers;
622 char netid[MAXSTRINGLEN + 1], uaddr[MAXSTRINGLEN + 1];
623 char owner[MAXSTRINGLEN + 1];
624 int maps = 0;
625
626 if (setjmp(xdr_err)) {
627 (void) sprintf(get_line(0, 0),
628 " %d+ maps. (Frame is incomplete)",
629 maps);
630 return;
631 }
632
633 show_space();
634 (void) sprintf(get_line(0, 0),
635 " Program Vers Netid Uaddr Owner");
636
637 while (getxdr_u_long()) {
638 prog = getxdr_u_long();
639 vers = getxdr_u_long();
640 (void) getxdr_string(netid, MAXSTRINGLEN);
641 (void) getxdr_string(uaddr, MAXSTRINGLEN);
642 (void) getxdr_string(owner, MAXSTRINGLEN);
643 (void) sprintf(get_line(0, 0),
644 "%8d%5d %-12s %-18s %-10s (%s)",
645 prog, vers,
646 netid, uaddr, owner,
647 nameof_prog(prog));
648 maps++;
649 }
650
651 (void) sprintf(get_line(0, 0), " (%d maps)", maps);
652 }
653
654 char *
sum_rpcb_entry_list()655 sum_rpcb_entry_list()
656 {
657 int maps = 0;
658 static char buff[MAXSTRINGLEN + 1];
659
660 if (setjmp(xdr_err)) {
661 (void) sprintf(buff, "%d+ map(s) found", maps);
662 return (buff);
663 }
664
665 while (getxdr_u_long()) {
666 (void) getxdr_string(buff, MAXSTRINGLEN); /* maddr */
667 (void) getxdr_string(buff, MAXSTRINGLEN); /* nc_netid */
668 (void) getxdr_u_long(); /* nc_semantics */
669 (void) getxdr_string(buff, MAXSTRINGLEN); /* nc_protofmly */
670 (void) getxdr_string(buff, MAXSTRINGLEN); /* nc_proto */
671 maps++;
672 }
673
674 (void) sprintf(buff, "%d map(s) found", maps);
675 return (buff);
676 }
677
678 char *semantics_strs[] = {"", "CLTS", "COTS", "COTS-ORD", "RAW"};
679
680 void
show_rpcb_entry_list()681 show_rpcb_entry_list()
682 {
683 char maddr[MAXSTRINGLEN + 1], netid[MAXSTRINGLEN + 1];
684 char protofmly[MAXSTRINGLEN + 1], proto[MAXSTRINGLEN + 1];
685 unsigned sem;
686 int maps = 0;
687
688 if (setjmp(xdr_err)) {
689 (void) sprintf(get_line(0, 0),
690 " %d+ maps. (Frame is incomplete)",
691 maps);
692 return;
693 }
694
695 show_space();
696 (void) sprintf(get_line(0, 0),
697 " Maddr Netid Semantics Protofmly Proto");
698
699 while (getxdr_u_long()) {
700 (void) getxdr_string(maddr, MAXSTRINGLEN);
701 (void) getxdr_string(netid, MAXSTRINGLEN);
702 sem = getxdr_u_long();
703 (void) getxdr_string(protofmly, MAXSTRINGLEN);
704 (void) getxdr_string(proto, MAXSTRINGLEN);
705 (void) sprintf(get_line(0, 0),
706 "%-12s %-12s %-8s %-8s %-8s",
707 maddr, netid,
708 semantics_strs[sem],
709 protofmly, proto);
710 maps++;
711 }
712
713 (void) sprintf(get_line(0, 0), " (%d maps)", maps);
714 }
715
716 #define CXID_CACHE_SIZE 16
717 struct cache_struct cxid_cache[CXID_CACHE_SIZE];
718 struct cache_struct *cxcpfirst = &cxid_cache[0];
719 struct cache_struct *cxcp = &cxid_cache[0];
720 struct cache_struct *cxcplast = &cxid_cache[CXID_CACHE_SIZE - 1];
721
722 struct cache_struct *
find_callit(xid)723 find_callit(xid)
724 ulong_t xid;
725 {
726 struct cache_struct *x;
727
728 for (x = cxcp; x >= cxcpfirst; x--)
729 if (x->xid_num == xid)
730 return (x);
731 for (x = cxcplast; x > cxcp; x--)
732 if (x->xid_num == xid)
733 return (x);
734 return (NULL);
735 }
736
737 static void
stash_callit(xid,frame,prog,vers,proc)738 stash_callit(xid, frame, prog, vers, proc)
739 ulong_t xid;
740 int frame, prog, vers, proc;
741 {
742 struct cache_struct *x;
743
744 x = find_callit(xid);
745 if (x == NULL) {
746 x = cxcp++;
747 if (cxcp > cxcplast)
748 cxcp = cxcpfirst;
749 x->xid_num = xid;
750 x->xid_frame = frame;
751 }
752 x->xid_prog = prog;
753 x->xid_vers = vers;
754 x->xid_proc = proc;
755 }
756