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