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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
27 #include <sys/errno.h>
30 #include <netinet/in.h>
33 #include <sys/tiuser.h>
34 #include <rpc/types.h>
37 #include <rpc/auth_unix.h>
38 #include <rpc/auth_des.h>
40 #include <rpc/rpc_msg.h>
41 #include <rpc/pmap_clnt.h>
43 #include <rpcsvc/yp_prot.h>
44 #include <rpc/pmap_prot.h>
48 #define MIN(a, b) ((a) < (b) ? (a) : (b))
52 struct cache_struct
*find_xid();
53 extern jmp_buf xdr_err
;
55 void print_rpcsec_gss_cred(int xid
, int authlen
);
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);
65 #define LAST_FRAG ((ulong_t)1 << 31)
68 interpret_rpc(int flags
, char *rpc
, int fraglen
, int type
)
72 struct cache_struct
*x
;
73 int rpcvers
, prog
, vers
, proc
;
74 int status
, astat
, rstat
, why
;
81 xdr_init(rpc
, fraglen
);
83 if (setjmp(xdr_err
)) {
85 (void) sprintf(get_line(0, 0),
86 "---- short frame ---");
90 if (type
== IPPROTO_TCP
) { /* record mark */
91 markpos
= getxdr_pos();
92 recmark
= getxdr_long();
95 xid
= getxdr_u_long();
96 direction
= getxdr_long();
98 if (direction
== CALL
) {
99 rpcvers
= getxdr_long();
101 prog
= getxdr_long();
102 vers
= getxdr_long();
103 proc
= getxdr_long();
104 stash_xid(xid
, pi_frame
, prog
, vers
, proc
);
105 if (!(flags
& (F_SUM
| F_DTAIL
))) {
106 protoprint(flags
, CALL
, xid
, prog
, vers
, proc
,
116 (void) sprintf(get_sum_line(),
117 "RPC C XID=%lu PROG=%d (%s) VERS=%d PROC=%d",
119 prog
, nameof_prog(prog
),
121 if (getxdr_long() == RPCSEC_GSS
) { /* Cred auth type */
122 extract_rpcsec_gss_cred_info(xid
);
123 /* RPCSEC_GSS cred auth data */
125 xdr_skip(getxdr_long());
126 /* non RPCSEC_GSS cred auth data */
128 xdr_skip(4); /* Verf auth type */
129 xdr_skip(RNDUP(getxdr_long())); /* Verf auth data */
131 protoprint(flags
, CALL
, xid
, prog
, vers
, proc
,
138 (void) sprintf(lp
, "RPC R XID=%lu", xid
);
140 (void) sprintf(lp
, "RPC R (#%d) XID=%lu",
144 status
= getxdr_long();
147 /* eat flavor and verifier */
148 (void) getxdr_long();
149 xdr_skip(RNDUP(getxdr_long()));
150 astat
= getxdr_long();
151 (void) sprintf(lp
, " %s",
152 nameof_astat(astat
));
158 protoprint(flags
, REPLY
,
173 " (low=%d, high=%d)",
185 rstat
= getxdr_long();
192 " Vers mismatch (low=%d, high=%d)",
197 why
= getxdr_u_long();
199 " Can't authenticate (%s)",
208 if (flags
& F_DTAIL
) {
209 show_header("RPC: ", "SUN RPC Header", fraglen
);
211 if (type
== IPPROTO_TCP
) { /* record mark */
212 (void) sprintf(get_line(markpos
, markpos
+4),
213 "Record Mark: %s fragment, length = %d",
214 recmark
& LAST_FRAG
? "last" : "",
215 recmark
& ~LAST_FRAG
);
218 (void) sprintf(get_line(0, 0),
219 "Transaction id = %lu",
221 (void) sprintf(get_line(0, 0),
224 direction
== CALL
? "Call":"Reply");
228 rpc_detail_call(flags
, xid
, rpcvers
,
229 prog
, vers
, proc
, rpc
, fraglen
);
232 rpc_detail_reply(flags
, xid
, x
, rpc
, fraglen
);
241 rpc_detail_call(int flags
, int xid
, int rpcvers
, int prog
, int vers
, int proc
,
244 char *nameof_flavor();
247 (void) sprintf(get_line(pos
, getxdr_pos()),
250 (void) sprintf(get_line(pos
, getxdr_pos()),
251 "Program = %d (%s), version = %d, procedure = %d",
252 prog
, nameof_prog(prog
), vers
, proc
);
256 protoprint(flags
, CALL
, xid
, prog
, vers
, proc
, data
, len
);
260 nameof_flavor(flavor
)
264 case AUTH_NONE
: return ("None");
265 case AUTH_UNIX
: return ("Unix");
266 case AUTH_SHORT
: return ("Unix short");
267 case AUTH_DES
: return ("DES");
268 case RPCSEC_GSS
: return ("RPCSEC_GSS");
269 default: return ("unknown");
274 tohex(char *p
, int len
)
277 static char hbuff
[1024];
278 static char *hexstr
= "0123456789ABCDEF";
281 if (len
* 2 > sizeof (hbuff
)) {
283 len
= sizeof (hbuff
) / 2;
287 for (i
= 0; i
< len
; i
++) {
288 hbuff
[j
++] = hexstr
[p
[i
] >> 4 & 0x0f];
289 hbuff
[j
++] = hexstr
[p
[i
] & 0x0f];
293 hbuff
[len
* 2 - strlen("<Too Long>")] = '\0';
294 strcat(hbuff
, "<Too Long>");
304 int pos
, flavor
, authlen
;
311 flavor
= getxdr_long();
312 authlen
= getxdr_long();
313 (void) sprintf(get_line(pos
, getxdr_pos()),
314 "Credentials: Flavor = %d (%s), len = %d bytes",
315 flavor
, nameof_flavor(flavor
), authlen
);
321 (void) showxdr_time(" Time = %s");
322 (void) showxdr_string(MAX_MACHINE_NAME
, " Hostname = %s");
324 uid
= getxdr_u_long();
325 gid
= getxdr_u_long();
326 (void) sprintf(get_line(pos
, getxdr_pos()),
327 " Uid = %d, Gid = %d",
329 len
= getxdr_u_long();
330 line
= get_line(pos
, len
* 4);
332 (void) sprintf(line
, " Groups = (none)");
334 (void) sprintf(line
, " Groups = ");
335 line
+= strlen(line
);
337 gid
= getxdr_u_long();
338 (void) sprintf(line
, "%d ", gid
);
339 line
+= strlen(line
);
345 namekind
= getxdr_u_long();
346 (void) sprintf(get_line(pos
, getxdr_pos()),
347 " Name kind = %d (%s)",
349 namekind
== ADN_FULLNAME
?
350 "fullname" : "nickname");
353 (void) showxdr_string(64,
354 " Network name = %s");
355 (void) showxdr_hex(8,
356 " Conversation key = 0x%s (DES encrypted)");
357 (void) showxdr_hex(4,
358 " Window = 0x%s (DES encrypted)");
362 (void) showxdr_hex(4, " Nickname = 0x%s");
368 print_rpcsec_gss_cred(xid
, authlen
);
372 (void) showxdr_hex(authlen
, "[%s]");
378 print_verif(int direction
)
380 int pos
, flavor
, verlen
;
383 flavor
= getxdr_long();
384 verlen
= getxdr_long();
385 (void) sprintf(get_line(pos
, getxdr_pos()),
386 "Verifier : Flavor = %d (%s), len = %d bytes",
387 flavor
, nameof_flavor(flavor
), verlen
);
393 (void) showxdr_hex(8, " Timestamp = 0x%s (DES encrypted)");
394 if (direction
== CALL
)
395 (void) showxdr_hex(4,
396 " Window = 0x%s (DES encrypted)");
398 (void) showxdr_hex(4, " Nickname = 0x%s");
401 /* For other flavors like AUTH_NONE, AUTH_UNIX, RPCSEC_GSS etc. */
403 (void) showxdr_hex(verlen
, "[%s]");
412 100000, "PMAP", /* Portmapper */
413 100001, "RSTAT", /* Remote stats */
414 100002, "RUSERS", /* Remote users */
415 100003, "NFS", /* Nfs */
416 100004, "NIS", /* Network Information Service */
417 100005, "MOUNT", /* Mount demon */
418 100006, "DBX", /* Remote dbx */
419 100007, "NISBIND", /* NIS binder */
420 100008, "WALL", /* Shutdown msg */
421 100009, "NISPASSWD", /* Yppasswd server */
422 100010, "ETHERSTAT", /* Ether stats */
423 100011, "RQUOTA", /* Disk quotas */
424 100012, "SPRAY", /* Spray packets */
425 100013, "IBM3270", /* 3270 mapper */
426 100014, "IBMRJE", /* RJE mapper */
427 100015, "SELNSVC", /* Selection service */
428 100016, "RDATABASE", /* Remote database access */
429 100017, "REX", /* Remote execution */
430 100018, "ALICE", /* Alice Office Automation */
431 100019, "SCHED", /* Scheduling service */
432 100020, "LLM", /* Local lock manager */
433 100021, "NLM", /* Network lock manager */
434 100022, "X25INR", /* X.25 inr protocol */
435 100023, "STATMON1", /* Status monitor 1 */
436 100024, "STATMON2", /* Status monitor 2 */
437 100025, "SELNLIB", /* Selection library */
438 100026, "BOOTPARAM", /* Boot parameters service */
439 100027, "MAZEPROG", /* Mazewars game */
440 100028, "NISUPDATE", /* NIS update */
441 100029, "KEYSERVE", /* Key server */
442 100030, "SECURECMD", /* Secure login */
443 100031, "NETFWDI", /* NFS net forwarder init */
444 100032, "NETFWDT", /* NFS net forwarder trans */
445 100033, "SUNLINKMAP", /* Sunlink MAP */
446 100034, "NETMON", /* Network monitor */
447 100035, "DBASE", /* Lightweight database */
448 100036, "PWDAUTH", /* Password authorization */
449 100037, "TFS", /* Translucent file svc */
450 100038, "NSE", /* NSE server */
451 100039, "NSE_ACTIVATE", /* NSE activate daemon */
452 100040, "SUNVIEW_HELP", /* Sunview help */
453 100041, "PNP", /* PNP install */
454 100042, "IPADDR_ALLOC", /* IP addr allocator */
455 100043, "FILEHANDLE", /* Show filehandle */
456 100044, "MVSNFS", /* MVS NFS mount */
457 100045, "REM_FILEOP_USER", /* Remote user file operations */
458 100046, "BATCH_NISUPDATE", /* Batched ypupdate */
459 100047, "NEM", /* Network execution mgr */
460 100048, "RAYTRACE_RD", /* Raytrace/mandelbrot remote daemon */
461 100049, "RAYTRACE_LD", /* Raytrace/mandelbrot local daemon */
462 100050, "REM_FILEOP_GROUP", /* Remote group file operations */
463 100051, "REM_FILEOP_SYSTEM", /* Remote system file operations */
464 100052, "REM_SYSTEM_ROLE", /* Remote system role operations */
465 100055, "IOADMD", /* Ioadmd */
466 100056, "FILEMERGE", /* Filemerge */
467 100057, "NAMEBIND", /* Name Binding Program */
468 100058, "NJE", /* Sunlink NJE */
469 100059, "MVSATTR", /* MVSNFS get attribute service */
470 100060, "RMGR", /* SunAccess/SunLink resource manager */
471 100061, "UIDALLOC", /* UID allocation service */
472 100062, "LBSERVER", /* License broker */
473 100063, "LBBINDER", /* NETlicense client binder */
474 100064, "GIDALLOC", /* GID allocation service */
475 100065, "SUNISAM", /* SunIsam */
476 100066, "RDBSRV", /* Remote Debug Server */
477 100067, "NETDIR", /* Network directory daemon */
478 100068, "CMSD", /* Network calendar program */
479 100069, "NISXFR", /* NIS transfer */
480 100070, "TIMED", /* RPC.timed */
481 100071, "BUGTRAQ", /* Bugtraqd */
482 100072, "NeFS", /* Internal use only */
483 100073, "BILLBOARD", /* Connectathon Billboard - NFS */
484 100074, "BILLBOARD", /* Connectathon Billboard - X */
485 100075, "SCHEDROOM", /* Sun meeting room scheduler */
486 100076, "AUTHNEGOTIATE", /* Authentication negotiation */
487 100077, "ATTRPROG", /* Database manipulation */
488 100080, "AUTODUMP", /* Sun consulting special */
489 100081, "EVENT_SVC", /* Event protocol */
490 100085, "ARM_PSD", /* ARM policy */
491 100086, "ARMTOD", /* ARM TOD */
492 100087, "NA.ADMIN", /* Sun (SNAG) administration agent */
493 100099, "PLD", /* Genesil 8.1 hot plot */
494 100101, "NA.EVENT", /* SNM (SunNet Manager) event dispatcher */
495 100102, "NA.LOGGER", /* SNM report logger */
496 100103, "NA.DISCOVER", /* SNM network discovery agent */
497 100104, "NA.SYNC", /* SNM sync interface agent */
498 100105, "NA.DISKINFO", /* SNM disk info agent */
499 100106, "NA.IOSTAT", /* SNM iostat agent */
500 100107, "NA.HOSTPERF", /* SNM rstat proxy agent */
501 100108, "NA.CONFIG", /* SNM host configuration agent */
502 100109, "NA.ACTIVITY", /* SNM activity daemon */
503 100111, "NA.LPSTAT", /* SNM printer agent */
504 100112, "NA.HOSTMEM", /* SNM host network memory agent */
505 100113, "NA.SAMPLE", /* SNM sample agent */
506 100114, "NA.X25", /* SNM X.25 agent */
507 100115, "NA.PING", /* SNM ping proxy agent */
508 100116, "NA.RPCNFS", /* SNM rpc and nfs agent */
509 100117, "NA.HOSTIF", /* SNM host interface agent */
510 100118, "NA.ETHERIF", /* SNM ethernet interface agent */
511 100119, "NA.IPPATH", /* SNM traceroute proxy agent */
512 100120, "NA.IPROUTES", /* SNM routing table agent */
513 100121, "NA.LAYERS", /* SNM protocol layers gent */
514 100122, "NA.SNMP", /* SNM SNMP proxy agent */
515 100123, "NA.TRAFFIC", /* SNM network traffic agent */
516 100124, "NA.DNI", /* DNI (DECnet) proxy agent */
517 100125, "NA.CHAT", /* IBM Channel attach proxy agent */
518 100126, "NA.FDDI", /* FDDI agent */
519 100127, "NA.FDDISMT", /* FDDI SMT proxy agent */
520 100128, "NA.MHS", /* MHS agent */
521 100130, "SNM_GRAPHER", /* SNM 3D grapher */
522 100132, "NA.TR", /* Token Ring agent */
523 100134, "NA.TOKENRING", /* Token Ring agent */
524 100136, "NA.FRAMERELAY", /* Frame Relay agent */
525 100175, "NA.SNMPTRAP", /* SNM SNMP trap daemon */
526 100180, "NA.MIPROUTES", /* SNM multicast routing table agent */
527 100201, "MVSNFSSTAT", /* MVS/NFS Memory usage statistic server */
528 100227, "NFS_ACL", /* NFS ACL support */
529 101002, "NSELINKTOOL", /* NSE link daemon */
530 101003, "NSELINKAPP", /* NSE link application */
531 110001, "GOLABEL", /* SunOS MLS */
532 110002, "PUC", /* SunOS MLS */
533 150001, "PCNFSD", /* PC passwd authorization */
534 150002, "TOPS", /* TOPS name mapping */
535 150003, "TOPS", /* TOPS external attribute storage */
536 150004, "TOPS", /* TOPS hierarchical file system */
537 150005, "TOPS", /* TOPS NFS transparency extensions */
538 150006, "SOLARNET_FW", /* SolarNet Framework protocol */
539 160001, "CM", /* Nihon Sun - Japanese Input system */
540 300004, "FRAME 1", /* Frame program 1 */
541 300009, "FRAME 2", /* Frame program 2 */
542 390101, "RAP", /* Legato RAP protocol */
543 390102, "RAPRD", /* Legato RAP resource dir protocol */
544 500021, "ZNS", /* Zeus Network Service */
549 register struct rpcnames
*a
, *b
;
551 return (a
->rp_prog
- b
->rp_prog
);
559 struct rpcnames
*bsearch();
560 int elems
= sizeof (rpcnames
) / sizeof (*r
);
562 r
= bsearch(&prog
, rpcnames
, elems
, sizeof (*r
), compare
);
566 if (prog
>= 0x40000000 && prog
<= 0x5fffffff)
567 return ("transient");
577 case SUCCESS
: return ("Success");
578 case PROG_UNAVAIL
: return ("Program unavailable");
579 case PROG_MISMATCH
: return ("Program number mismatch");
580 case PROC_UNAVAIL
: return ("Procedure unavailable");
581 case GARBAGE_ARGS
: return ("Garbage arguments");
582 case SYSTEM_ERR
: return ("System error");
583 default: return ("unknown");
592 case AUTH_BADCRED
: return ("bogus credentials (seal broken)");
593 case AUTH_REJECTEDCRED
: return ("client should begin new session");
594 case AUTH_BADVERF
: return ("bogus verifier (seal broken)");
595 case AUTH_REJECTEDVERF
: return ("verifier expired or was replayed");
596 case AUTH_TOOWEAK
: return ("too weak");
597 case AUTH_INVALIDRESP
: return ("bogus response verifier");
598 case AUTH_TIMEEXPIRE
: return ("time of credential expired");
599 case AUTH_TKT_FILE
: return ("something wrong with ticket file");
600 case AUTH_DECODE
: return ("can't decode authenticator");
601 case AUTH_NET_ADDR
: return ("net address in ticket wrong");
602 case RPCSEC_GSS_NOCRED
: return ("no credentials for user");
603 case RPCSEC_GSS_FAILED
: return ("GSS failure, credentials deleted");
606 return ("unknown reason");
611 rpc_detail_reply(int flags
, int xid
, struct cache_struct
*x
, char *data
,
615 int astat
, rstat
, why
;
619 (void) sprintf(get_line(0, 0),
620 "This is a reply to frame %d",
624 status
= getxdr_long();
625 (void) sprintf(get_line(pos
, getxdr_pos()),
627 status
, status
? "Denied" : "Accepted");
633 astat
= getxdr_long();
634 (void) sprintf(get_line(pos
, getxdr_pos()),
635 "Accept status = %d (%s)",
636 astat
, nameof_astat(astat
));
642 protoprint(flags
, REPLY
, xid
,
643 x
->xid_prog
, x
->xid_vers
, x
->xid_proc
,
651 showxdr_long(" Low = %d");
652 showxdr_long(" High = %d");
664 rstat
= getxdr_long();
665 (void) sprintf(get_line(pos
, getxdr_pos()),
666 "Reject status = %d (%s)",
668 rstat
? "can't authenticate"
669 : "version mismatch");
673 showxdr_long(" Low = %d");
674 showxdr_long(" High = %d");
677 why
= getxdr_u_long();
678 (void) sprintf(get_line(pos
, getxdr_pos()),
680 why
, nameof_why(why
));
688 * Return true if this is a valid RPC packet
691 valid_rpc(char *rpc
, int rpclen
)
699 xdrmem_create(&xdrm
, rpc
, rpclen
, XDR_DECODE
);
700 if (xdr_u_int(&xdrm
, &msg
.rm_xid
) &&
701 xdr_u_int(&xdrm
, (uint_t
*)&msg
.rm_direction
)) {
702 switch (msg
.rm_direction
) {
704 if (xdr_rpcvers(&xdrm
, &msg
.rm_call
.cb_rpcvers
) &&
705 msg
.rm_call
.cb_rpcvers
== 2)
710 (uint_t
*)&msg
.rm_reply
.rp_stat
) &&
711 (msg
.rm_reply
.rp_stat
== MSG_ACCEPTED
||
712 msg
.rm_reply
.rp_stat
== MSG_DENIED
))
721 struct cache_struct
*xcpfirst
= &xid_cache
[0];
722 struct cache_struct
*xcp
= &xid_cache
[0];
723 struct cache_struct
*xcplast
= &xid_cache
[XID_CACHE_SIZE
- 1];
725 struct cache_struct
*
729 struct cache_struct
*x
;
731 for (x
= xcp
; x
>= xcpfirst
; x
--)
732 if (x
->xid_num
== xid
)
734 for (x
= xcplast
; x
> xcp
; x
--)
735 if (x
->xid_num
== xid
)
741 stash_xid(ulong_t xid
, int frame
, int prog
, int vers
, int proc
)
743 struct cache_struct
*x
;
751 x
->xid_frame
= frame
;
756 x
->xid_gss_proc
= RPCSEC_GSS_DATA
;
757 x
->xid_gss_service
= rpc_gss_svc_default
;
761 check_retransmit(line
, xid
)
765 struct cache_struct
*x
;
769 if (x
&& x
->xid_frame
!= pi_frame
)
770 (void) strcat(line
, " (retransmit)");