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