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 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 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 * 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 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 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 * 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 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 * 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 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 * 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 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