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 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/errno.h> 31 #include <setjmp.h> 32 33 #include <netinet/in.h> 34 #include <netdb.h> 35 36 #include <sys/tiuser.h> 37 #include <rpc/types.h> 38 #include <rpc/xdr.h> 39 #include <rpc/auth.h> 40 #include <rpc/auth_unix.h> 41 #include <rpc/auth_des.h> 42 #include <rpc/clnt.h> 43 #include <rpc/rpc_msg.h> 44 #include <rpc/pmap_clnt.h> 45 #include <rpc/svc.h> 46 #include <rpcsvc/yp_prot.h> 47 #include <rpc/pmap_prot.h> 48 #include "snoop.h" 49 50 #ifndef MIN 51 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 52 #endif 53 54 int pos; 55 struct cache_struct *find_xid(); 56 extern jmp_buf xdr_err; 57 void protoprint(); 58 void print_rpcsec_gss_cred(int xid, int authlen); 59 char *nameof_prog(); 60 char *nameof_astat(); 61 char *nameof_why(); 62 static void rpc_detail_call(int, int, int, int, int, int, char *, int); 63 static void rpc_detail_reply(int, int, struct cache_struct *, char *, int len); 64 static void print_creds(int); 65 static void print_verif(int); 66 static void stash_xid(ulong_t, int, int, int, int); 67 int valid_rpc(char *, int); 68 69 #define LAST_FRAG ((ulong_t)1 << 31) 70 71 int 72 interpret_rpc(int flags, char *rpc, int fraglen, int type) 73 { 74 ulong_t xid; 75 int direction; 76 struct cache_struct *x; 77 int rpcvers, prog, vers, proc; 78 int status, astat, rstat, why; 79 char *lp; 80 unsigned recmark; 81 int markpos; 82 extern int pi_frame; 83 int lo, hi; 84 85 xdr_init(rpc, fraglen); 86 87 if (setjmp(xdr_err)) { 88 if (flags & F_DTAIL) 89 (void) sprintf(get_line(0, 0), 90 "---- short frame ---"); 91 return (fraglen); 92 } 93 94 if (type == IPPROTO_TCP) { /* record mark */ 95 markpos = getxdr_pos(); 96 recmark = getxdr_long(); 97 } 98 99 xid = getxdr_u_long(); 100 direction = getxdr_long(); 101 102 if (direction == CALL) { 103 rpcvers = getxdr_long(); 104 pos = getxdr_pos(); 105 prog = getxdr_long(); 106 vers = getxdr_long(); 107 proc = getxdr_long(); 108 stash_xid(xid, pi_frame, prog, vers, proc); 109 if (!(flags & (F_SUM | F_DTAIL))) 110 protoprint(flags, CALL, xid, prog, vers, proc, 111 rpc, fraglen); 112 } else { 113 x = find_xid(xid); 114 } 115 116 if (flags & F_SUM) { 117 switch (direction) { 118 case CALL: 119 (void) sprintf(get_sum_line(), 120 "RPC C XID=%lu PROG=%d (%s) VERS=%d PROC=%d", 121 xid, 122 prog, nameof_prog(prog), 123 vers, proc); 124 if (getxdr_long() == RPCSEC_GSS) { /* Cred auth type */ 125 extract_rpcsec_gss_cred_info(xid); 126 /* RPCSEC_GSS cred auth data */ 127 } else { 128 xdr_skip(getxdr_long()); 129 /* non RPCSEC_GSS cred auth data */ 130 } 131 xdr_skip(4); /* Verf auth type */ 132 xdr_skip(RNDUP(getxdr_long())); /* Verf auth data */ 133 134 protoprint(flags, CALL, xid, prog, vers, proc, 135 rpc, fraglen); 136 break; 137 138 case REPLY: 139 lp = get_sum_line(); 140 if (x == NULL) 141 (void) sprintf(lp, "RPC R XID=%lu", xid); 142 else 143 (void) sprintf(lp, "RPC R (#%d) XID=%lu", 144 x->xid_frame, xid); 145 146 lp += strlen(lp); 147 status = getxdr_long(); 148 switch (status) { 149 case MSG_ACCEPTED: 150 /* eat flavor and verifier */ 151 (void) getxdr_long(); 152 xdr_skip(RNDUP(getxdr_long())); 153 astat = getxdr_long(); 154 (void) sprintf(lp, " %s", 155 nameof_astat(astat)); 156 lp += strlen(lp); 157 158 switch (astat) { 159 case SUCCESS: 160 if (x) { 161 protoprint(flags, REPLY, 162 xid, 163 x->xid_prog, 164 x->xid_vers, 165 x->xid_proc, 166 rpc, fraglen); 167 } 168 break; 169 170 case PROG_UNAVAIL : 171 case PROG_MISMATCH: 172 case PROC_UNAVAIL : 173 lo = getxdr_long(); 174 hi = getxdr_long(); 175 (void) sprintf(lp, 176 " (low=%d, high=%d)", 177 lo, hi); 178 break; 179 180 case GARBAGE_ARGS: 181 case SYSTEM_ERR: 182 default: 183 ; 184 } 185 break; 186 187 case MSG_DENIED: 188 rstat = getxdr_long(); 189 190 switch (rstat) { 191 case RPC_MISMATCH: 192 lo = getxdr_long(); 193 hi = getxdr_long(); 194 (void) sprintf(lp, 195 " Vers mismatch (low=%d, high=%d)", 196 lo, hi); 197 break; 198 199 case AUTH_ERROR: 200 why = getxdr_u_long(); 201 (void) sprintf(lp, 202 " Can't authenticate (%s)", 203 nameof_why(why)); 204 break; 205 } 206 } 207 break; 208 } 209 } 210 211 if (flags & F_DTAIL) { 212 show_header("RPC: ", "SUN RPC Header", fraglen); 213 show_space(); 214 if (type == IPPROTO_TCP) { /* record mark */ 215 (void) sprintf(get_line(markpos, markpos+4), 216 "Record Mark: %s fragment, length = %d", 217 recmark & LAST_FRAG ? "last" : "", 218 recmark & ~LAST_FRAG); 219 } 220 221 (void) sprintf(get_line(0, 0), 222 "Transaction id = %lu", 223 xid); 224 (void) sprintf(get_line(0, 0), 225 "Type = %d (%s)", 226 direction, 227 direction == CALL ? "Call":"Reply"); 228 229 switch (direction) { 230 case CALL: 231 rpc_detail_call(flags, xid, rpcvers, 232 prog, vers, proc, rpc, fraglen); 233 break; 234 case REPLY: 235 rpc_detail_reply(flags, xid, x, rpc, fraglen); 236 break; 237 } 238 } 239 240 return (fraglen); 241 } 242 243 static void 244 rpc_detail_call(int flags, int xid, int rpcvers, int prog, int vers, int proc, 245 char *data, int len) 246 { 247 char *nameof_flavor(); 248 char *nameof_prog(); 249 250 (void) sprintf(get_line(pos, getxdr_pos()), 251 "RPC version = %d", 252 rpcvers); 253 (void) sprintf(get_line(pos, getxdr_pos()), 254 "Program = %d (%s), version = %d, procedure = %d", 255 prog, nameof_prog(prog), vers, proc); 256 print_creds(xid); 257 print_verif(CALL); 258 show_trailer(); 259 protoprint(flags, CALL, xid, prog, vers, proc, data, len); 260 } 261 262 char * 263 nameof_flavor(flavor) 264 int flavor; 265 { 266 switch (flavor) { 267 case AUTH_NONE : return ("None"); 268 case AUTH_UNIX : return ("Unix"); 269 case AUTH_SHORT: return ("Unix short"); 270 case AUTH_DES : return ("DES"); 271 case RPCSEC_GSS: return ("RPCSEC_GSS"); 272 default: return ("unknown"); 273 } 274 } 275 276 char * 277 tohex(char *p, int len) 278 { 279 int i, j; 280 static char hbuff[1024]; 281 static char *hexstr = "0123456789ABCDEF"; 282 char toobig = 0; 283 284 if (len * 2 > sizeof (hbuff)) { 285 toobig++; 286 len = sizeof (hbuff) / 2; 287 } 288 289 j = 0; 290 for (i = 0; i < len; i++) { 291 hbuff[j++] = hexstr[p[i] >> 4 & 0x0f]; 292 hbuff[j++] = hexstr[p[i] & 0x0f]; 293 } 294 295 if (toobig) { 296 hbuff[len * 2 - strlen("<Too Long>")] = '\0'; 297 strcat(hbuff, "<Too Long>"); 298 } else 299 hbuff[j] = '\0'; 300 301 return (hbuff); 302 } 303 304 static void 305 print_creds(int xid) 306 { 307 int pos, flavor, authlen; 308 int uid, gid, len; 309 int tlen, idlen; 310 int i, namekind; 311 char *p, *line; 312 313 pos = getxdr_pos(); 314 flavor = getxdr_long(); 315 authlen = getxdr_long(); 316 (void) sprintf(get_line(pos, getxdr_pos()), 317 "Credentials: Flavor = %d (%s), len = %d bytes", 318 flavor, nameof_flavor(flavor), authlen); 319 if (authlen <= 0) 320 return; 321 322 switch (flavor) { 323 case AUTH_UNIX: 324 (void) showxdr_time(" Time = %s"); 325 (void) showxdr_string(MAX_MACHINE_NAME, " Hostname = %s"); 326 pos = getxdr_pos(); 327 uid = getxdr_u_long(); 328 gid = getxdr_u_long(); 329 (void) sprintf(get_line(pos, getxdr_pos()), 330 " Uid = %d, Gid = %d", 331 uid, gid); 332 len = getxdr_u_long(); 333 line = get_line(pos, len * 4); 334 if (len == 0) 335 (void) sprintf(line, " Groups = (none)"); 336 else { 337 (void) sprintf(line, " Groups = "); 338 line += strlen(line); 339 while (len--) { 340 gid = getxdr_u_long(); 341 (void) sprintf(line, "%d ", gid); 342 line += strlen(line); 343 } 344 } 345 break; 346 347 case AUTH_DES: 348 namekind = getxdr_u_long(); 349 (void) sprintf(get_line(pos, getxdr_pos()), 350 " Name kind = %d (%s)", 351 namekind, 352 namekind == ADN_FULLNAME ? 353 "fullname" : "nickname"); 354 switch (namekind) { 355 case ADN_FULLNAME: 356 (void) showxdr_string(64, 357 " Network name = %s"); 358 (void) showxdr_hex(8, 359 " Conversation key = 0x%s (DES encrypted)"); 360 (void) showxdr_hex(4, 361 " Window = 0x%s (DES encrypted)"); 362 break; 363 364 case ADN_NICKNAME: 365 (void) showxdr_hex(4, " Nickname = 0x%s"); 366 break; 367 }; 368 break; 369 370 case RPCSEC_GSS: 371 print_rpcsec_gss_cred(xid, authlen); 372 break; 373 374 default: 375 (void) showxdr_hex(authlen, "[%s]"); 376 break; 377 } 378 } 379 380 static void 381 print_verif(int direction) 382 { 383 int pos, flavor, verlen; 384 385 pos = getxdr_pos(); 386 flavor = getxdr_long(); 387 verlen = getxdr_long(); 388 (void) sprintf(get_line(pos, getxdr_pos()), 389 "Verifier : Flavor = %d (%s), len = %d bytes", 390 flavor, nameof_flavor(flavor), verlen); 391 if (verlen == 0) 392 return; 393 394 switch (flavor) { 395 case AUTH_DES: 396 (void) showxdr_hex(8, " Timestamp = 0x%s (DES encrypted)"); 397 if (direction == CALL) 398 (void) showxdr_hex(4, 399 " Window = 0x%s (DES encrypted)"); 400 else 401 (void) showxdr_hex(4, " Nickname = 0x%s"); 402 break; 403 404 /* For other flavors like AUTH_NONE, AUTH_UNIX, RPCSEC_GSS etc. */ 405 default: 406 (void) showxdr_hex(verlen, "[%s]"); 407 break; 408 } 409 } 410 411 struct rpcnames { 412 int rp_prog; 413 char *rp_name; 414 } rpcnames[] = { 415 100000, "PMAP", /* Portmapper */ 416 100001, "RSTAT", /* Remote stats */ 417 100002, "RUSERS", /* Remote users */ 418 100003, "NFS", /* Nfs */ 419 100004, "NIS", /* Network Information Service */ 420 100005, "MOUNT", /* Mount demon */ 421 100006, "DBX", /* Remote dbx */ 422 100007, "NISBIND", /* NIS binder */ 423 100008, "WALL", /* Shutdown msg */ 424 100009, "NISPASSWD", /* Yppasswd server */ 425 100010, "ETHERSTAT", /* Ether stats */ 426 100011, "RQUOTA", /* Disk quotas */ 427 100012, "SPRAY", /* Spray packets */ 428 100013, "IBM3270", /* 3270 mapper */ 429 100014, "IBMRJE", /* RJE mapper */ 430 100015, "SELNSVC", /* Selection service */ 431 100016, "RDATABASE", /* Remote database access */ 432 100017, "REX", /* Remote execution */ 433 100018, "ALICE", /* Alice Office Automation */ 434 100019, "SCHED", /* Scheduling service */ 435 100020, "LLM", /* Local lock manager */ 436 100021, "NLM", /* Network lock manager */ 437 100022, "X25INR", /* X.25 inr protocol */ 438 100023, "STATMON1", /* Status monitor 1 */ 439 100024, "STATMON2", /* Status monitor 2 */ 440 100025, "SELNLIB", /* Selection library */ 441 100026, "BOOTPARAM", /* Boot parameters service */ 442 100027, "MAZEPROG", /* Mazewars game */ 443 100028, "NISUPDATE", /* NIS update */ 444 100029, "KEYSERVE", /* Key server */ 445 100030, "SECURECMD", /* Secure login */ 446 100031, "NETFWDI", /* NFS net forwarder init */ 447 100032, "NETFWDT", /* NFS net forwarder trans */ 448 100033, "SUNLINKMAP", /* Sunlink MAP */ 449 100034, "NETMON", /* Network monitor */ 450 100035, "DBASE", /* Lightweight database */ 451 100036, "PWDAUTH", /* Password authorization */ 452 100037, "TFS", /* Translucent file svc */ 453 100038, "NSE", /* NSE server */ 454 100039, "NSE_ACTIVATE", /* NSE activate daemon */ 455 100040, "SUNVIEW_HELP", /* Sunview help */ 456 100041, "PNP", /* PNP install */ 457 100042, "IPADDR_ALLOC", /* IP addr allocator */ 458 100043, "FILEHANDLE", /* Show filehandle */ 459 100044, "MVSNFS", /* MVS NFS mount */ 460 100045, "REM_FILEOP_USER", /* Remote user file operations */ 461 100046, "BATCH_NISUPDATE", /* Batched ypupdate */ 462 100047, "NEM", /* Network execution mgr */ 463 100048, "RAYTRACE_RD", /* Raytrace/mandelbrot remote daemon */ 464 100049, "RAYTRACE_LD", /* Raytrace/mandelbrot local daemon */ 465 100050, "REM_FILEOP_GROUP", /* Remote group file operations */ 466 100051, "REM_FILEOP_SYSTEM", /* Remote system file operations */ 467 100052, "REM_SYSTEM_ROLE", /* Remote system role operations */ 468 100055, "IOADMD", /* Ioadmd */ 469 100056, "FILEMERGE", /* Filemerge */ 470 100057, "NAMEBIND", /* Name Binding Program */ 471 100058, "NJE", /* Sunlink NJE */ 472 100059, "MVSATTR", /* MVSNFS get attribute service */ 473 100060, "RMGR", /* SunAccess/SunLink resource manager */ 474 100061, "UIDALLOC", /* UID allocation service */ 475 100062, "LBSERVER", /* License broker */ 476 100063, "LBBINDER", /* NETlicense client binder */ 477 100064, "GIDALLOC", /* GID allocation service */ 478 100065, "SUNISAM", /* SunIsam */ 479 100066, "RDBSRV", /* Remote Debug Server */ 480 100067, "NETDIR", /* Network directory daemon */ 481 100068, "CMSD", /* Network calendar program */ 482 100069, "NISXFR", /* NIS transfer */ 483 100070, "TIMED", /* RPC.timed */ 484 100071, "BUGTRAQ", /* Bugtraqd */ 485 100072, "NeFS", /* Internal use only */ 486 100073, "BILLBOARD", /* Connectathon Billboard - NFS */ 487 100074, "BILLBOARD", /* Connectathon Billboard - X */ 488 100075, "SCHEDROOM", /* Sun meeting room scheduler */ 489 100076, "AUTHNEGOTIATE", /* Authentication negotiation */ 490 100077, "ATTRPROG", /* Database manipulation */ 491 100080, "AUTODUMP", /* Sun consulting special */ 492 100081, "EVENT_SVC", /* Event protocol */ 493 100085, "ARM_PSD", /* ARM policy */ 494 100086, "ARMTOD", /* ARM TOD */ 495 100087, "NA.ADMIN", /* Sun (SNAG) administration agent */ 496 100099, "PLD", /* Genesil 8.1 hot plot */ 497 100101, "NA.EVENT", /* SNM (SunNet Manager) event dispatcher */ 498 100102, "NA.LOGGER", /* SNM report logger */ 499 100103, "NA.DISCOVER", /* SNM network discovery agent */ 500 100104, "NA.SYNC", /* SNM sync interface agent */ 501 100105, "NA.DISKINFO", /* SNM disk info agent */ 502 100106, "NA.IOSTAT", /* SNM iostat agent */ 503 100107, "NA.HOSTPERF", /* SNM rstat proxy agent */ 504 100108, "NA.CONFIG", /* SNM host configuration agent */ 505 100109, "NA.ACTIVITY", /* SNM activity daemon */ 506 100111, "NA.LPSTAT", /* SNM printer agent */ 507 100112, "NA.HOSTMEM", /* SNM host network memory agent */ 508 100113, "NA.SAMPLE", /* SNM sample agent */ 509 100114, "NA.X25", /* SNM X.25 agent */ 510 100115, "NA.PING", /* SNM ping proxy agent */ 511 100116, "NA.RPCNFS", /* SNM rpc and nfs agent */ 512 100117, "NA.HOSTIF", /* SNM host interface agent */ 513 100118, "NA.ETHERIF", /* SNM ethernet interface agent */ 514 100119, "NA.IPPATH", /* SNM traceroute proxy agent */ 515 100120, "NA.IPROUTES", /* SNM routing table agent */ 516 100121, "NA.LAYERS", /* SNM protocol layers gent */ 517 100122, "NA.SNMP", /* SNM SNMP proxy agent */ 518 100123, "NA.TRAFFIC", /* SNM network traffic agent */ 519 100124, "NA.DNI", /* DNI (DECnet) proxy agent */ 520 100125, "NA.CHAT", /* IBM Channel attach proxy agent */ 521 100126, "NA.FDDI", /* FDDI agent */ 522 100127, "NA.FDDISMT", /* FDDI SMT proxy agent */ 523 100128, "NA.MHS", /* MHS agent */ 524 100130, "SNM_GRAPHER", /* SNM 3D grapher */ 525 100132, "NA.TR", /* Token Ring agent */ 526 100134, "NA.TOKENRING", /* Token Ring agent */ 527 100136, "NA.FRAMERELAY", /* Frame Relay agent */ 528 100175, "NA.SNMPTRAP", /* SNM SNMP trap daemon */ 529 100180, "NA.MIPROUTES", /* SNM multicast routing table agent */ 530 100201, "MVSNFSSTAT", /* MVS/NFS Memory usage statistic server */ 531 100227, "NFS_ACL", /* NFS ACL support */ 532 100300, "NIS+", /* NIS+ name service */ 533 100302, "NIS+ CB", /* NIS+ callbacks */ 534 101002, "NSELINKTOOL", /* NSE link daemon */ 535 101003, "NSELINKAPP", /* NSE link application */ 536 110001, "GOLABEL", /* SunOS MLS */ 537 110002, "PUC", /* SunOS MLS */ 538 150001, "PCNFSD", /* PC passwd authorization */ 539 150002, "TOPS", /* TOPS name mapping */ 540 150003, "TOPS", /* TOPS external attribute storage */ 541 150004, "TOPS", /* TOPS hierarchical file system */ 542 150005, "TOPS", /* TOPS NFS transparency extensions */ 543 150006, "SOLARNET_FW", /* SolarNet Framework protocol */ 544 160001, "CM", /* Nihon Sun - Japanese Input system */ 545 300004, "FRAME 1", /* Frame program 1 */ 546 300009, "FRAME 2", /* Frame program 2 */ 547 390101, "RAP", /* Legato RAP protocol */ 548 390102, "RAPRD", /* Legato RAP resource dir protocol */ 549 500021, "ZNS", /* Zeus Network Service */ 550 }; 551 552 int 553 compare(a, b) 554 register struct rpcnames *a, *b; 555 { 556 return (a->rp_prog - b->rp_prog); 557 } 558 559 char * 560 nameof_prog(prog) 561 int prog; 562 { 563 struct rpcnames *r; 564 struct rpcnames *bsearch(); 565 int elems = sizeof (rpcnames) / sizeof (*r); 566 567 r = bsearch(&prog, rpcnames, elems, sizeof (*r), compare); 568 if (r) 569 return (r->rp_name); 570 571 if (prog >= 0x40000000 && prog <= 0x5fffffff) 572 return ("transient"); 573 574 return ("?"); 575 } 576 577 char * 578 nameof_astat(status) 579 int status; 580 { 581 switch (status) { 582 case SUCCESS : return ("Success"); 583 case PROG_UNAVAIL : return ("Program unavailable"); 584 case PROG_MISMATCH: return ("Program number mismatch"); 585 case PROC_UNAVAIL : return ("Procedure unavailable"); 586 case GARBAGE_ARGS : return ("Garbage arguments"); 587 case SYSTEM_ERR : return ("System error"); 588 default: return ("unknown"); 589 } 590 } 591 592 char * 593 nameof_why(why) 594 int why; 595 { 596 switch (why) { 597 case AUTH_BADCRED: return ("bogus credentials (seal broken)"); 598 case AUTH_REJECTEDCRED: return ("client should begin new session"); 599 case AUTH_BADVERF: return ("bogus verifier (seal broken)"); 600 case AUTH_REJECTEDVERF: return ("verifier expired or was replayed"); 601 case AUTH_TOOWEAK: return ("too weak"); 602 case AUTH_INVALIDRESP: return ("bogus response verifier"); 603 case AUTH_TIMEEXPIRE: return ("time of credential expired"); 604 case AUTH_TKT_FILE: return ("something wrong with ticket file"); 605 case AUTH_DECODE: return ("can't decode authenticator"); 606 case AUTH_NET_ADDR: return ("net address in ticket wrong"); 607 case RPCSEC_GSS_NOCRED: return ("no credentials for user"); 608 case RPCSEC_GSS_FAILED: return ("GSS failure, credentials deleted"); 609 case AUTH_FAILED: 610 default: 611 return ("unknown reason"); 612 } 613 } 614 615 static void 616 rpc_detail_reply(int flags, int xid, struct cache_struct *x, char *data, 617 int len) 618 { 619 int status; 620 int astat, rstat, why; 621 int pos; 622 623 if (x) { 624 (void) sprintf(get_line(0, 0), 625 "This is a reply to frame %d", 626 x->xid_frame); 627 } 628 pos = getxdr_pos(); 629 status = getxdr_long(); 630 (void) sprintf(get_line(pos, getxdr_pos()), 631 "Status = %d (%s)", 632 status, status ? "Denied" : "Accepted"); 633 634 switch (status) { 635 case MSG_ACCEPTED: 636 print_verif(REPLY); 637 pos = getxdr_pos(); 638 astat = getxdr_long(); 639 (void) sprintf(get_line(pos, getxdr_pos()), 640 "Accept status = %d (%s)", 641 astat, nameof_astat(astat)); 642 643 switch (astat) { 644 case SUCCESS: 645 if (x) { 646 show_trailer(); 647 protoprint(flags, REPLY, xid, 648 x->xid_prog, x->xid_vers, x->xid_proc, 649 data, len); 650 } 651 break; 652 case PROG_UNAVAIL : 653 break; 654 case PROG_MISMATCH: 655 case PROC_UNAVAIL : 656 showxdr_long(" Low = %d"); 657 showxdr_long(" High = %d"); 658 break; 659 case GARBAGE_ARGS: 660 case SYSTEM_ERR: 661 default: 662 ; 663 } 664 665 break; 666 667 case MSG_DENIED: 668 pos = getxdr_pos(); 669 rstat = getxdr_long(); 670 (void) sprintf(get_line(pos, getxdr_pos()), 671 "Reject status = %d (%s)", 672 rstat, 673 rstat ? "can't authenticate" 674 : "version mismatch"); 675 676 switch (rstat) { 677 case RPC_MISMATCH: 678 showxdr_long(" Low = %d"); 679 showxdr_long(" High = %d"); 680 break; 681 case AUTH_ERROR: 682 why = getxdr_u_long(); 683 (void) sprintf(get_line(pos, getxdr_pos()), 684 " Why = %d (%s)", 685 why, nameof_why(why)); 686 break; 687 } 688 break; 689 } 690 } 691 692 /* 693 * Return true if this is a valid RPC packet 694 */ 695 int 696 valid_rpc(char *rpc, int rpclen) 697 { 698 XDR xdrm; 699 struct rpc_msg msg; 700 701 if (rpclen < 12) 702 return (0); 703 704 xdrmem_create(&xdrm, rpc, rpclen, XDR_DECODE); 705 if (xdr_u_int(&xdrm, &msg.rm_xid) && 706 xdr_u_int(&xdrm, (uint_t *)&msg.rm_direction)) { 707 switch (msg.rm_direction) { 708 case CALL: 709 if (xdr_rpcvers(&xdrm, &msg.rm_call.cb_rpcvers) && 710 msg.rm_call.cb_rpcvers == 2) 711 return (1); 712 break; 713 case REPLY: 714 if (xdr_u_int(&xdrm, 715 (uint_t *)&msg.rm_reply.rp_stat) && 716 (msg.rm_reply.rp_stat == MSG_ACCEPTED || 717 msg.rm_reply.rp_stat == MSG_DENIED)) 718 return (1); 719 break; 720 } 721 } 722 723 return (0); 724 } 725 726 struct cache_struct *xcpfirst = &xid_cache[0]; 727 struct cache_struct *xcp = &xid_cache[0]; 728 struct cache_struct *xcplast = &xid_cache[XID_CACHE_SIZE - 1]; 729 730 struct cache_struct * 731 find_xid(xid) 732 ulong_t xid; 733 { 734 struct cache_struct *x; 735 736 for (x = xcp; x >= xcpfirst; x--) 737 if (x->xid_num == xid) 738 return (x); 739 for (x = xcplast; x > xcp; x--) 740 if (x->xid_num == xid) 741 return (x); 742 return (NULL); 743 } 744 745 static void 746 stash_xid(ulong_t xid, int frame, int prog, int vers, int proc) 747 { 748 struct cache_struct *x; 749 750 x = find_xid(xid); 751 if (x == NULL) { 752 x = xcp++; 753 if (xcp > xcplast) 754 xcp = xcpfirst; 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 x->xid_gss_proc = RPCSEC_GSS_DATA; 762 x->xid_gss_service = rpc_gss_svc_default; 763 } 764 765 void 766 check_retransmit(line, xid) 767 char *line; 768 ulong_t xid; 769 { 770 struct cache_struct *x; 771 extern int pi_frame; 772 773 x = find_xid(xid); 774 if (x && x->xid_frame != pi_frame) 775 (void) strcat(line, " (retransmit)"); 776 } 777