xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_pmap.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 1991, 1999 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #ident	"%Z%%M%	%I%	%E% SMI"	/* SunOS	*/
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <sys/types.h>
30*0Sstevel@tonic-gate #include <sys/errno.h>
31*0Sstevel@tonic-gate #include <setjmp.h>
32*0Sstevel@tonic-gate #include <sys/tiuser.h>
33*0Sstevel@tonic-gate #include <string.h>
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <rpc/types.h>
36*0Sstevel@tonic-gate #include <rpc/xdr.h>
37*0Sstevel@tonic-gate #include <rpc/auth.h>
38*0Sstevel@tonic-gate #include <rpc/clnt.h>
39*0Sstevel@tonic-gate #include <rpc/rpc_msg.h>
40*0Sstevel@tonic-gate #include <rpc/pmap_prot.h>
41*0Sstevel@tonic-gate #include "snoop.h"
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate /*
44*0Sstevel@tonic-gate  * Number of bytes to display from a string (address, netid, etc.).
45*0Sstevel@tonic-gate  */
46*0Sstevel@tonic-gate #define	MAXSTRINGLEN	64
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate extern char *dlc_header;
49*0Sstevel@tonic-gate extern jmp_buf xdr_err;
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate static void interpret_pmap_2(int, int, int, int, int, char *, int);
52*0Sstevel@tonic-gate static void interpret_pmap_4(int, int, int, int, int, char *, int);
53*0Sstevel@tonic-gate static void stash_callit(ulong_t, int, int, int, int);
54*0Sstevel@tonic-gate 
55*0Sstevel@tonic-gate void
interpret_pmap(flags,type,xid,vers,proc,data,len)56*0Sstevel@tonic-gate interpret_pmap(flags, type, xid, vers, proc, data, len)
57*0Sstevel@tonic-gate 	int flags, type, xid, vers, proc;
58*0Sstevel@tonic-gate 	char *data;
59*0Sstevel@tonic-gate 	int len;
60*0Sstevel@tonic-gate {
61*0Sstevel@tonic-gate 	switch (vers) {
62*0Sstevel@tonic-gate 	case 2:	interpret_pmap_2(flags, type, xid, vers, proc, data, len);
63*0Sstevel@tonic-gate 		break;
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	/* Version 3 is a subset of version 4 */
66*0Sstevel@tonic-gate 	case 3:
67*0Sstevel@tonic-gate 	case 4:	interpret_pmap_4(flags, type, xid, vers, proc, data, len);
68*0Sstevel@tonic-gate 		break;
69*0Sstevel@tonic-gate 	}
70*0Sstevel@tonic-gate }
71*0Sstevel@tonic-gate 
72*0Sstevel@tonic-gate void show_pmap();
73*0Sstevel@tonic-gate char *sum_pmaplist();
74*0Sstevel@tonic-gate void show_pmaplist();
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate static char *procnames_short_2[] = {
77*0Sstevel@tonic-gate 	"Null",		/* 0 */
78*0Sstevel@tonic-gate 	"SET",		/* 1 */
79*0Sstevel@tonic-gate 	"UNSET",	/* 2 */
80*0Sstevel@tonic-gate 	"GETPORT",	/* 3 */
81*0Sstevel@tonic-gate 	"DUMP",		/* 4 */
82*0Sstevel@tonic-gate 	"CALLIT",	/* 5 */
83*0Sstevel@tonic-gate };
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate static char *procnames_long_2[] = {
86*0Sstevel@tonic-gate 	"Null procedure",	/* 0 */
87*0Sstevel@tonic-gate 	"Set port",		/* 1 */
88*0Sstevel@tonic-gate 	"Unset port",		/* 2 */
89*0Sstevel@tonic-gate 	"Get port number",	/* 3 */
90*0Sstevel@tonic-gate 	"Dump the mappings",	/* 4 */
91*0Sstevel@tonic-gate 	"Indirect call",	/* 5 */
92*0Sstevel@tonic-gate };
93*0Sstevel@tonic-gate 
94*0Sstevel@tonic-gate #define	MAXPROC_2	5
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate void
interpret_pmap_2(flags,type,xid,vers,proc,data,len)97*0Sstevel@tonic-gate interpret_pmap_2(flags, type, xid, vers, proc, data, len)
98*0Sstevel@tonic-gate 	int flags, type, xid, vers, proc;
99*0Sstevel@tonic-gate 	char *data;
100*0Sstevel@tonic-gate 	int len;
101*0Sstevel@tonic-gate {
102*0Sstevel@tonic-gate 	char *line;
103*0Sstevel@tonic-gate 	unsigned port, proto;
104*0Sstevel@tonic-gate 	unsigned iprog, ivers, iproc, ilen;
105*0Sstevel@tonic-gate 	extern int pi_frame;
106*0Sstevel@tonic-gate 	struct cache_struct *x, *find_callit();
107*0Sstevel@tonic-gate 	int trailer_done = 0;
108*0Sstevel@tonic-gate 
109*0Sstevel@tonic-gate 	if (proc < 0 || proc > MAXPROC_2)
110*0Sstevel@tonic-gate 		return;
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate 	if (proc == PMAPPROC_CALLIT) {
113*0Sstevel@tonic-gate 		if (type == CALL) {
114*0Sstevel@tonic-gate 			iprog = getxdr_u_long();
115*0Sstevel@tonic-gate 			ivers = getxdr_u_long();
116*0Sstevel@tonic-gate 			iproc = getxdr_u_long();
117*0Sstevel@tonic-gate 			stash_callit(xid, pi_frame,
118*0Sstevel@tonic-gate 				iprog, ivers, iproc);
119*0Sstevel@tonic-gate 		} else {
120*0Sstevel@tonic-gate 			x = find_callit(xid);
121*0Sstevel@tonic-gate 		}
122*0Sstevel@tonic-gate 	}
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate 	if (flags & F_SUM) {
125*0Sstevel@tonic-gate 		if (setjmp(xdr_err)) {
126*0Sstevel@tonic-gate 			return;
127*0Sstevel@tonic-gate 		}
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate 		line = get_sum_line();
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate 		if (type == CALL) {
132*0Sstevel@tonic-gate 			(void) sprintf(line,
133*0Sstevel@tonic-gate 				"PORTMAP C %s",
134*0Sstevel@tonic-gate 				procnames_short_2[proc]);
135*0Sstevel@tonic-gate 			line += strlen(line);
136*0Sstevel@tonic-gate 			switch (proc) {
137*0Sstevel@tonic-gate 			case PMAPPROC_GETPORT:
138*0Sstevel@tonic-gate 				iprog = getxdr_u_long();
139*0Sstevel@tonic-gate 				ivers = getxdr_u_long();
140*0Sstevel@tonic-gate 				proto = getxdr_u_long();
141*0Sstevel@tonic-gate 				(void) sprintf(line,
142*0Sstevel@tonic-gate 					" prog=%d (%s) vers=%d proto=%s",
143*0Sstevel@tonic-gate 					iprog, nameof_prog(iprog),
144*0Sstevel@tonic-gate 					ivers,
145*0Sstevel@tonic-gate 					getproto(proto));
146*0Sstevel@tonic-gate 				break;
147*0Sstevel@tonic-gate 			case PMAPPROC_CALLIT:
148*0Sstevel@tonic-gate 				(void) getxdr_u_long(); /* length */
149*0Sstevel@tonic-gate 				(void) sprintf(line,
150*0Sstevel@tonic-gate 					" prog=%s vers=%d proc=%d",
151*0Sstevel@tonic-gate 					nameof_prog(iprog),
152*0Sstevel@tonic-gate 					ivers, iproc);
153*0Sstevel@tonic-gate 				data += 16; /* prog+ver+proc+len */
154*0Sstevel@tonic-gate 				len -= 16;
155*0Sstevel@tonic-gate 				protoprint(flags, type, xid,
156*0Sstevel@tonic-gate 					iprog, ivers, iproc,
157*0Sstevel@tonic-gate 					data, len);
158*0Sstevel@tonic-gate 				break;
159*0Sstevel@tonic-gate 			default:
160*0Sstevel@tonic-gate 				break;
161*0Sstevel@tonic-gate 			}
162*0Sstevel@tonic-gate 			check_retransmit(line, xid);
163*0Sstevel@tonic-gate 		} else {
164*0Sstevel@tonic-gate 			(void) sprintf(line, "PORTMAP R %s ",
165*0Sstevel@tonic-gate 				procnames_short_2[proc]);
166*0Sstevel@tonic-gate 			line += strlen(line);
167*0Sstevel@tonic-gate 			switch (proc) {
168*0Sstevel@tonic-gate 			case PMAPPROC_GETPORT:
169*0Sstevel@tonic-gate 				port = getxdr_u_long();
170*0Sstevel@tonic-gate 				(void) sprintf(line, "port=%d",
171*0Sstevel@tonic-gate 					port);
172*0Sstevel@tonic-gate 				break;
173*0Sstevel@tonic-gate 			case PMAPPROC_DUMP:
174*0Sstevel@tonic-gate 				(void) sprintf(line, "%s",
175*0Sstevel@tonic-gate 					sum_pmaplist());
176*0Sstevel@tonic-gate 				break;
177*0Sstevel@tonic-gate 			case PMAPPROC_CALLIT:
178*0Sstevel@tonic-gate 				port = getxdr_u_long();
179*0Sstevel@tonic-gate 				ilen = getxdr_u_long();
180*0Sstevel@tonic-gate 				(void) sprintf(line, "port=%d len=%d",
181*0Sstevel@tonic-gate 					port, ilen);
182*0Sstevel@tonic-gate 				if (x != NULL) {
183*0Sstevel@tonic-gate 					protoprint(flags, type, xid,
184*0Sstevel@tonic-gate 						x->xid_prog,
185*0Sstevel@tonic-gate 						x->xid_vers,
186*0Sstevel@tonic-gate 						x->xid_proc,
187*0Sstevel@tonic-gate 						data, len);
188*0Sstevel@tonic-gate 				}
189*0Sstevel@tonic-gate 				break;
190*0Sstevel@tonic-gate 			default:
191*0Sstevel@tonic-gate 				break;
192*0Sstevel@tonic-gate 			}
193*0Sstevel@tonic-gate 		}
194*0Sstevel@tonic-gate 	}
195*0Sstevel@tonic-gate 
196*0Sstevel@tonic-gate 	if (flags & F_DTAIL) {
197*0Sstevel@tonic-gate 		show_header("PMAP:  ", "Portmapper", len);
198*0Sstevel@tonic-gate 		show_space();
199*0Sstevel@tonic-gate 		if (setjmp(xdr_err)) {
200*0Sstevel@tonic-gate 			return;
201*0Sstevel@tonic-gate 		}
202*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
203*0Sstevel@tonic-gate 			"Proc = %d (%s)",
204*0Sstevel@tonic-gate 			proc, procnames_long_2[proc]);
205*0Sstevel@tonic-gate 		if (type == CALL) {
206*0Sstevel@tonic-gate 			switch (proc) {
207*0Sstevel@tonic-gate 			case PMAPPROC_NULL:
208*0Sstevel@tonic-gate 			case PMAPPROC_SET:
209*0Sstevel@tonic-gate 			case PMAPPROC_UNSET:
210*0Sstevel@tonic-gate 				break;
211*0Sstevel@tonic-gate 			case PMAPPROC_GETPORT:
212*0Sstevel@tonic-gate 				iprog = getxdr_u_long();
213*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
214*0Sstevel@tonic-gate 					"Program = %d (%s)",
215*0Sstevel@tonic-gate 					iprog, nameof_prog(iprog));
216*0Sstevel@tonic-gate 				(void) showxdr_u_long("Version = %d");
217*0Sstevel@tonic-gate 				proto = getxdr_u_long();
218*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
219*0Sstevel@tonic-gate 					"Protocol = %d (%s)",
220*0Sstevel@tonic-gate 					proto, getproto(proto));
221*0Sstevel@tonic-gate 				break;
222*0Sstevel@tonic-gate 			case PMAPPROC_DUMP:
223*0Sstevel@tonic-gate 				break;
224*0Sstevel@tonic-gate 			case PMAPPROC_CALLIT:
225*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
226*0Sstevel@tonic-gate 					"Program = %d (%s)",
227*0Sstevel@tonic-gate 					iprog, nameof_prog(iprog));
228*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
229*0Sstevel@tonic-gate 					"Version = %d", ivers);
230*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
231*0Sstevel@tonic-gate 					"Proc    = %d", iproc);
232*0Sstevel@tonic-gate 				(void) showxdr_u_long(
233*0Sstevel@tonic-gate 					"Callit data = %d bytes");
234*0Sstevel@tonic-gate 				show_trailer();
235*0Sstevel@tonic-gate 				trailer_done = 1;
236*0Sstevel@tonic-gate 				data += 16; /* prog+ver+proc+len */
237*0Sstevel@tonic-gate 				len -= 16;
238*0Sstevel@tonic-gate 				protoprint(flags, type, xid,
239*0Sstevel@tonic-gate 					iprog, ivers, iproc,
240*0Sstevel@tonic-gate 					data, len);
241*0Sstevel@tonic-gate 				break;
242*0Sstevel@tonic-gate 			}
243*0Sstevel@tonic-gate 		} else {
244*0Sstevel@tonic-gate 			switch (proc) {
245*0Sstevel@tonic-gate 			case PMAPPROC_NULL:
246*0Sstevel@tonic-gate 			case PMAPPROC_SET:
247*0Sstevel@tonic-gate 			case PMAPPROC_UNSET:
248*0Sstevel@tonic-gate 				break;
249*0Sstevel@tonic-gate 			case PMAPPROC_GETPORT:
250*0Sstevel@tonic-gate 				(void) showxdr_u_long("Port = %d");
251*0Sstevel@tonic-gate 				break;
252*0Sstevel@tonic-gate 			case PMAPPROC_DUMP:
253*0Sstevel@tonic-gate 				show_pmaplist();
254*0Sstevel@tonic-gate 				break;
255*0Sstevel@tonic-gate 			case PMAPPROC_CALLIT:
256*0Sstevel@tonic-gate 				(void) showxdr_u_long("Port = %d");
257*0Sstevel@tonic-gate 				(void) showxdr_u_long("Length = %d bytes");
258*0Sstevel@tonic-gate 				show_trailer();
259*0Sstevel@tonic-gate 				trailer_done = 1;
260*0Sstevel@tonic-gate 				if (x != NULL) {
261*0Sstevel@tonic-gate 					protoprint(flags, type, xid,
262*0Sstevel@tonic-gate 						x->xid_prog,
263*0Sstevel@tonic-gate 						x->xid_vers,
264*0Sstevel@tonic-gate 						x->xid_proc,
265*0Sstevel@tonic-gate 						data, len);
266*0Sstevel@tonic-gate 				}
267*0Sstevel@tonic-gate 				break;
268*0Sstevel@tonic-gate 			}
269*0Sstevel@tonic-gate 		}
270*0Sstevel@tonic-gate 		if (!trailer_done)
271*0Sstevel@tonic-gate 			show_trailer();
272*0Sstevel@tonic-gate 	}
273*0Sstevel@tonic-gate }
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate char *
sum_pmaplist()276*0Sstevel@tonic-gate sum_pmaplist()
277*0Sstevel@tonic-gate {
278*0Sstevel@tonic-gate 	int maps = 0;
279*0Sstevel@tonic-gate 	static char buff[16];
280*0Sstevel@tonic-gate 
281*0Sstevel@tonic-gate 	if (setjmp(xdr_err)) {
282*0Sstevel@tonic-gate 		(void) sprintf(buff, "%d+ map(s) found", maps);
283*0Sstevel@tonic-gate 		return (buff);
284*0Sstevel@tonic-gate 	}
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate 	while (getxdr_u_long()) {
287*0Sstevel@tonic-gate 		(void) getxdr_u_long();	/* program */
288*0Sstevel@tonic-gate 		(void) getxdr_u_long();	/* version */
289*0Sstevel@tonic-gate 		(void) getxdr_u_long();	/* protocol */
290*0Sstevel@tonic-gate 		(void) getxdr_u_long();	/* port */
291*0Sstevel@tonic-gate 		maps++;
292*0Sstevel@tonic-gate 	}
293*0Sstevel@tonic-gate 
294*0Sstevel@tonic-gate 	(void) sprintf(buff, "%d map(s) found", maps);
295*0Sstevel@tonic-gate 	return (buff);
296*0Sstevel@tonic-gate }
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate void
show_pmaplist()299*0Sstevel@tonic-gate show_pmaplist()
300*0Sstevel@tonic-gate {
301*0Sstevel@tonic-gate 	unsigned prog, vers, proto, port;
302*0Sstevel@tonic-gate 	int maps = 0;
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate 	if (setjmp(xdr_err)) {
305*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
306*0Sstevel@tonic-gate 			" %d+ maps. (Frame is incomplete)",
307*0Sstevel@tonic-gate 			maps);
308*0Sstevel@tonic-gate 		return;
309*0Sstevel@tonic-gate 	}
310*0Sstevel@tonic-gate 
311*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0),
312*0Sstevel@tonic-gate 		" Program Version Protocol   Port");
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate 	while (getxdr_u_long()) {
315*0Sstevel@tonic-gate 		prog  = getxdr_u_long();
316*0Sstevel@tonic-gate 		vers  = getxdr_u_long();
317*0Sstevel@tonic-gate 		proto = getxdr_u_long();
318*0Sstevel@tonic-gate 		port  = getxdr_u_long();
319*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
320*0Sstevel@tonic-gate 			"%8d%8d%9d%7d  %s",
321*0Sstevel@tonic-gate 			prog, vers, proto, port, nameof_prog(prog));
322*0Sstevel@tonic-gate 		maps++;
323*0Sstevel@tonic-gate 	}
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), " %d maps", maps);
326*0Sstevel@tonic-gate }
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate /*
329*0Sstevel@tonic-gate  * ******************************************
330*0Sstevel@tonic-gate  */
331*0Sstevel@tonic-gate char *sum_rpcblist();
332*0Sstevel@tonic-gate void show_rpcblist();
333*0Sstevel@tonic-gate char *sum_rpcb_entry_list();
334*0Sstevel@tonic-gate void show_rpcb_entry_list();
335*0Sstevel@tonic-gate 
336*0Sstevel@tonic-gate static char *procnames_short_4[] = {
337*0Sstevel@tonic-gate 	/*
338*0Sstevel@tonic-gate 	 * version 3 and 4 procs
339*0Sstevel@tonic-gate 	 */
340*0Sstevel@tonic-gate 	"Null",		/* 0 */
341*0Sstevel@tonic-gate 	"SET",		/* 1 */
342*0Sstevel@tonic-gate 	"UNSET",	/* 2 */
343*0Sstevel@tonic-gate 	"GETADDR",	/* 3 */
344*0Sstevel@tonic-gate 	"DUMP",		/* 4 */
345*0Sstevel@tonic-gate 	"BCAST",	/* 5 */
346*0Sstevel@tonic-gate 	"GETTIME",	/* 6 */
347*0Sstevel@tonic-gate 	"UADDR2TADDR",	/* 7 */
348*0Sstevel@tonic-gate 	"TADDR2UADDR",	/* 8 */
349*0Sstevel@tonic-gate 	/*
350*0Sstevel@tonic-gate 	 * version 4 procs only
351*0Sstevel@tonic-gate 	 */
352*0Sstevel@tonic-gate 	"GETVERSADDR",	/* 9 */
353*0Sstevel@tonic-gate 	"INDIRECT",	/* 10 */
354*0Sstevel@tonic-gate 	"GETADDRLIST",	/* 11 */
355*0Sstevel@tonic-gate 	"GETSTAT",	/* 12 */
356*0Sstevel@tonic-gate };
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate static char *procnames_long_4[] = {
359*0Sstevel@tonic-gate 	/*
360*0Sstevel@tonic-gate 	 * version 3 and 4 procs
361*0Sstevel@tonic-gate 	 */
362*0Sstevel@tonic-gate 	"Null procedure",			/* 0 */
363*0Sstevel@tonic-gate 	"Set address",				/* 1 */
364*0Sstevel@tonic-gate 	"Unset address",			/* 2 */
365*0Sstevel@tonic-gate 	"Get address",				/* 3 */
366*0Sstevel@tonic-gate 	"Dump the mappings",			/* 4 */
367*0Sstevel@tonic-gate 	"Broadcast call (no error)",		/* 5 */
368*0Sstevel@tonic-gate 	"Get the time",				/* 6 */
369*0Sstevel@tonic-gate 	"Universal to transport address",	/* 7 */
370*0Sstevel@tonic-gate 	"Transport to universal address",	/* 8 */
371*0Sstevel@tonic-gate 	/*
372*0Sstevel@tonic-gate 	 * version 4 procs only
373*0Sstevel@tonic-gate 	 */
374*0Sstevel@tonic-gate 	"Get address of specific version",	/* 9 */
375*0Sstevel@tonic-gate 	"Indirect call (return error)",		/* 10 */
376*0Sstevel@tonic-gate 	"Return addresses of prog/vers",	/* 11 */
377*0Sstevel@tonic-gate 	"Get statistics",			/* 12 */
378*0Sstevel@tonic-gate };
379*0Sstevel@tonic-gate 
380*0Sstevel@tonic-gate #define	MAXPROC_4		12
381*0Sstevel@tonic-gate #define	RPCBPROC_NULL		0
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate void
interpret_pmap_4(flags,type,xid,vers,proc,data,len)384*0Sstevel@tonic-gate interpret_pmap_4(flags, type, xid, vers, proc, data, len)
385*0Sstevel@tonic-gate 	int flags, type, xid, vers, proc;
386*0Sstevel@tonic-gate 	char *data;
387*0Sstevel@tonic-gate 	int len;
388*0Sstevel@tonic-gate {
389*0Sstevel@tonic-gate 	char *line;
390*0Sstevel@tonic-gate 	unsigned prog, ver;
391*0Sstevel@tonic-gate 	char buff1[MAXSTRINGLEN + 1];
392*0Sstevel@tonic-gate 	int iprog, ivers, iproc, ilen;
393*0Sstevel@tonic-gate 	extern int pi_frame;
394*0Sstevel@tonic-gate 	struct cache_struct *x, *find_callit();
395*0Sstevel@tonic-gate 	int trailer_done = 0;
396*0Sstevel@tonic-gate 
397*0Sstevel@tonic-gate 	if (proc < 0 || proc > MAXPROC_4)
398*0Sstevel@tonic-gate 		return;
399*0Sstevel@tonic-gate 
400*0Sstevel@tonic-gate 	if (proc == RPCBPROC_BCAST) {
401*0Sstevel@tonic-gate 		if (type == CALL) {
402*0Sstevel@tonic-gate 			iprog = getxdr_u_long();
403*0Sstevel@tonic-gate 			ivers = getxdr_u_long();
404*0Sstevel@tonic-gate 			iproc = getxdr_u_long();
405*0Sstevel@tonic-gate 			stash_callit(xid, pi_frame,
406*0Sstevel@tonic-gate 				iprog, ivers, iproc);
407*0Sstevel@tonic-gate 		} else {
408*0Sstevel@tonic-gate 			x = find_callit(xid);
409*0Sstevel@tonic-gate 		}
410*0Sstevel@tonic-gate 	}
411*0Sstevel@tonic-gate 
412*0Sstevel@tonic-gate 	if (flags & F_SUM) {
413*0Sstevel@tonic-gate 		if (setjmp(xdr_err)) {
414*0Sstevel@tonic-gate 			return;
415*0Sstevel@tonic-gate 		}
416*0Sstevel@tonic-gate 
417*0Sstevel@tonic-gate 		line = get_sum_line();
418*0Sstevel@tonic-gate 
419*0Sstevel@tonic-gate 		if (type == CALL) {
420*0Sstevel@tonic-gate 			(void) sprintf(line,
421*0Sstevel@tonic-gate 				"RPCBIND C %s",
422*0Sstevel@tonic-gate 				procnames_short_4[proc]);
423*0Sstevel@tonic-gate 			line += strlen(line);
424*0Sstevel@tonic-gate 			switch (proc) {
425*0Sstevel@tonic-gate 			case RPCBPROC_SET:
426*0Sstevel@tonic-gate 			case RPCBPROC_UNSET:
427*0Sstevel@tonic-gate 			case RPCBPROC_GETADDR:
428*0Sstevel@tonic-gate 			case RPCBPROC_GETVERSADDR:
429*0Sstevel@tonic-gate 			case RPCBPROC_GETADDRLIST:
430*0Sstevel@tonic-gate 				prog = getxdr_u_long();
431*0Sstevel@tonic-gate 				ver  = getxdr_u_long();
432*0Sstevel@tonic-gate 				(void) sprintf(line,
433*0Sstevel@tonic-gate 					" prog=%d (%s) vers=%d",
434*0Sstevel@tonic-gate 					prog, nameof_prog(prog),
435*0Sstevel@tonic-gate 					ver);
436*0Sstevel@tonic-gate 				break;
437*0Sstevel@tonic-gate 			case RPCBPROC_BCAST:
438*0Sstevel@tonic-gate 			case RPCBPROC_INDIRECT:
439*0Sstevel@tonic-gate 				(void) getxdr_u_long(); /* length */
440*0Sstevel@tonic-gate 				(void) sprintf(line,
441*0Sstevel@tonic-gate 					" prog=%s vers=%d proc=%d",
442*0Sstevel@tonic-gate 					nameof_prog(iprog),
443*0Sstevel@tonic-gate 					ivers, iproc);
444*0Sstevel@tonic-gate 				data += 16; /* prog+ver+proc+len */
445*0Sstevel@tonic-gate 				len -= 16;
446*0Sstevel@tonic-gate 				protoprint(flags, type, xid,
447*0Sstevel@tonic-gate 					iprog, ivers, iproc,
448*0Sstevel@tonic-gate 					data, len);
449*0Sstevel@tonic-gate 				break;
450*0Sstevel@tonic-gate 			default:
451*0Sstevel@tonic-gate 				break;
452*0Sstevel@tonic-gate 			}
453*0Sstevel@tonic-gate 
454*0Sstevel@tonic-gate 			check_retransmit(line, xid);
455*0Sstevel@tonic-gate 		} else {
456*0Sstevel@tonic-gate 			(void) sprintf(line, "RPCBIND R %s ",
457*0Sstevel@tonic-gate 				procnames_short_4[proc]);
458*0Sstevel@tonic-gate 			line += strlen(line);
459*0Sstevel@tonic-gate 			switch (proc) {
460*0Sstevel@tonic-gate 			case RPCBPROC_GETADDR:
461*0Sstevel@tonic-gate 			case RPCBPROC_TADDR2UADDR:
462*0Sstevel@tonic-gate 			case RPCBPROC_GETVERSADDR:
463*0Sstevel@tonic-gate 				(void) getxdr_string(buff1, MAXSTRINGLEN);
464*0Sstevel@tonic-gate 				(void) sprintf(line,
465*0Sstevel@tonic-gate 					" Uaddr=%s",
466*0Sstevel@tonic-gate 					buff1);
467*0Sstevel@tonic-gate 				break;
468*0Sstevel@tonic-gate 			case RPCBPROC_BCAST:
469*0Sstevel@tonic-gate 			case RPCBPROC_INDIRECT:
470*0Sstevel@tonic-gate 				(void) getxdr_string(buff1, MAXSTRINGLEN);
471*0Sstevel@tonic-gate 				ilen = getxdr_u_long();
472*0Sstevel@tonic-gate 				(void) sprintf(line, "Uaddr=%s len=%d",
473*0Sstevel@tonic-gate 					buff1, ilen);
474*0Sstevel@tonic-gate 				data += 16; /* prog+ver+proc+len */
475*0Sstevel@tonic-gate 				len -= 16;
476*0Sstevel@tonic-gate 				if (x != NULL) {
477*0Sstevel@tonic-gate 					protoprint(flags, type, xid,
478*0Sstevel@tonic-gate 						x->xid_prog,
479*0Sstevel@tonic-gate 						x->xid_vers,
480*0Sstevel@tonic-gate 						x->xid_proc,
481*0Sstevel@tonic-gate 						data, len);
482*0Sstevel@tonic-gate 				}
483*0Sstevel@tonic-gate 				break;
484*0Sstevel@tonic-gate 			case RPCBPROC_DUMP:
485*0Sstevel@tonic-gate 				(void) sprintf(line, "%s",
486*0Sstevel@tonic-gate 					sum_rpcblist());
487*0Sstevel@tonic-gate 				break;
488*0Sstevel@tonic-gate 			case RPCBPROC_GETTIME:
489*0Sstevel@tonic-gate 				(void) sprintf(line, "%s",
490*0Sstevel@tonic-gate 					getxdr_date());
491*0Sstevel@tonic-gate 				break;
492*0Sstevel@tonic-gate 			case RPCBPROC_GETADDRLIST:
493*0Sstevel@tonic-gate 				(void) sprintf(line, "%s",
494*0Sstevel@tonic-gate 					sum_rpcb_entry_list());
495*0Sstevel@tonic-gate 				break;
496*0Sstevel@tonic-gate 			default:
497*0Sstevel@tonic-gate 				break;
498*0Sstevel@tonic-gate 			}
499*0Sstevel@tonic-gate 		}
500*0Sstevel@tonic-gate 	}
501*0Sstevel@tonic-gate 
502*0Sstevel@tonic-gate 	if (flags & F_DTAIL) {
503*0Sstevel@tonic-gate 		show_header("RPCB:  ", "RPC Bind", len);
504*0Sstevel@tonic-gate 		show_space();
505*0Sstevel@tonic-gate 		if (setjmp(xdr_err)) {
506*0Sstevel@tonic-gate 			return;
507*0Sstevel@tonic-gate 		}
508*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
509*0Sstevel@tonic-gate 			"Proc = %d (%s)",
510*0Sstevel@tonic-gate 			proc, procnames_long_4[proc]);
511*0Sstevel@tonic-gate 		if (type == CALL) {
512*0Sstevel@tonic-gate 			switch (proc) {
513*0Sstevel@tonic-gate 			case RPCBPROC_NULL:
514*0Sstevel@tonic-gate 				break;
515*0Sstevel@tonic-gate 			case RPCBPROC_SET:
516*0Sstevel@tonic-gate 			case RPCBPROC_UNSET:
517*0Sstevel@tonic-gate 			case RPCBPROC_GETADDR:
518*0Sstevel@tonic-gate 			case RPCBPROC_GETVERSADDR:
519*0Sstevel@tonic-gate 			case RPCBPROC_GETADDRLIST:
520*0Sstevel@tonic-gate 				(void) showxdr_u_long("Program = %d");
521*0Sstevel@tonic-gate 				(void) showxdr_u_long("Version = %d");
522*0Sstevel@tonic-gate 				(void) showxdr_string(64, "Netid   = %s");
523*0Sstevel@tonic-gate 				break;
524*0Sstevel@tonic-gate 			case RPCBPROC_DUMP:
525*0Sstevel@tonic-gate 				break;
526*0Sstevel@tonic-gate 			case RPCBPROC_BCAST:
527*0Sstevel@tonic-gate 			case RPCBPROC_INDIRECT:
528*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
529*0Sstevel@tonic-gate 					"Program = %d (%s)",
530*0Sstevel@tonic-gate 					iprog, nameof_prog(iprog));
531*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
532*0Sstevel@tonic-gate 					"Version = %d", ivers);
533*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
534*0Sstevel@tonic-gate 					"Proc    = %d", iproc);
535*0Sstevel@tonic-gate 				(void) showxdr_u_long(
536*0Sstevel@tonic-gate 					"Callit data = %d bytes");
537*0Sstevel@tonic-gate 				show_trailer();
538*0Sstevel@tonic-gate 				trailer_done = 1;
539*0Sstevel@tonic-gate 				data += 16; /* prog+ver+proc+len */
540*0Sstevel@tonic-gate 				len -= 16;
541*0Sstevel@tonic-gate 				protoprint(flags, type, xid,
542*0Sstevel@tonic-gate 					iprog, ivers, iproc,
543*0Sstevel@tonic-gate 					data, len);
544*0Sstevel@tonic-gate 				break;
545*0Sstevel@tonic-gate 			case RPCBPROC_GETTIME:
546*0Sstevel@tonic-gate 				break;
547*0Sstevel@tonic-gate 			case RPCBPROC_UADDR2TADDR:
548*0Sstevel@tonic-gate 			case RPCBPROC_TADDR2UADDR:
549*0Sstevel@tonic-gate 				break;
550*0Sstevel@tonic-gate 			}
551*0Sstevel@tonic-gate 		} else {
552*0Sstevel@tonic-gate 			switch (proc) {
553*0Sstevel@tonic-gate 			case RPCBPROC_NULL:
554*0Sstevel@tonic-gate 			case RPCBPROC_SET:
555*0Sstevel@tonic-gate 			case RPCBPROC_UNSET:
556*0Sstevel@tonic-gate 				break;
557*0Sstevel@tonic-gate 			case RPCBPROC_GETADDR:
558*0Sstevel@tonic-gate 			case RPCBPROC_TADDR2UADDR:
559*0Sstevel@tonic-gate 			case RPCBPROC_GETVERSADDR:
560*0Sstevel@tonic-gate 				(void) showxdr_string(64, "Uaddr = %s");
561*0Sstevel@tonic-gate 				break;
562*0Sstevel@tonic-gate 			case RPCBPROC_DUMP:
563*0Sstevel@tonic-gate 				show_rpcblist();
564*0Sstevel@tonic-gate 				break;
565*0Sstevel@tonic-gate 			case RPCBPROC_BCAST:
566*0Sstevel@tonic-gate 			case RPCBPROC_INDIRECT:
567*0Sstevel@tonic-gate 				(void) showxdr_string(64, "Uaddr = %s");
568*0Sstevel@tonic-gate 				(void) showxdr_u_long("Length = %d bytes");
569*0Sstevel@tonic-gate 				show_trailer();
570*0Sstevel@tonic-gate 				trailer_done = 1;
571*0Sstevel@tonic-gate 				if (x != NULL) {
572*0Sstevel@tonic-gate 					protoprint(flags, type, xid,
573*0Sstevel@tonic-gate 						x->xid_prog,
574*0Sstevel@tonic-gate 						x->xid_vers,
575*0Sstevel@tonic-gate 						x->xid_proc,
576*0Sstevel@tonic-gate 						data, len);
577*0Sstevel@tonic-gate 				}
578*0Sstevel@tonic-gate 				break;
579*0Sstevel@tonic-gate 			case RPCBPROC_GETTIME:
580*0Sstevel@tonic-gate 				(void) showxdr_date("Time = %s");
581*0Sstevel@tonic-gate 				break;
582*0Sstevel@tonic-gate 			case RPCBPROC_UADDR2TADDR:
583*0Sstevel@tonic-gate 				break;
584*0Sstevel@tonic-gate 			case RPCBPROC_GETADDRLIST:
585*0Sstevel@tonic-gate 				show_rpcb_entry_list();
586*0Sstevel@tonic-gate 				break;
587*0Sstevel@tonic-gate 			}
588*0Sstevel@tonic-gate 		}
589*0Sstevel@tonic-gate 		if (!trailer_done)
590*0Sstevel@tonic-gate 			show_trailer();
591*0Sstevel@tonic-gate 	}
592*0Sstevel@tonic-gate }
593*0Sstevel@tonic-gate 
594*0Sstevel@tonic-gate char *
sum_rpcblist()595*0Sstevel@tonic-gate sum_rpcblist()
596*0Sstevel@tonic-gate {
597*0Sstevel@tonic-gate 	int maps = 0;
598*0Sstevel@tonic-gate 	static char buff[MAXSTRINGLEN + 1];
599*0Sstevel@tonic-gate 
600*0Sstevel@tonic-gate 	if (setjmp(xdr_err)) {
601*0Sstevel@tonic-gate 		(void) sprintf(buff, "%d+ map(s) found", maps);
602*0Sstevel@tonic-gate 		return (buff);
603*0Sstevel@tonic-gate 	}
604*0Sstevel@tonic-gate 
605*0Sstevel@tonic-gate 	while (getxdr_u_long()) {
606*0Sstevel@tonic-gate 		(void) getxdr_u_long();		/* program */
607*0Sstevel@tonic-gate 		(void) getxdr_u_long();		/* version */
608*0Sstevel@tonic-gate 		(void) getxdr_string(buff, MAXSTRINGLEN); /* netid */
609*0Sstevel@tonic-gate 		(void) getxdr_string(buff, MAXSTRINGLEN); /* uaddr */
610*0Sstevel@tonic-gate 		(void) getxdr_string(buff, MAXSTRINGLEN); /* owner */
611*0Sstevel@tonic-gate 		maps++;
612*0Sstevel@tonic-gate 	}
613*0Sstevel@tonic-gate 
614*0Sstevel@tonic-gate 	(void) sprintf(buff, "%d map(s) found", maps);
615*0Sstevel@tonic-gate 	return (buff);
616*0Sstevel@tonic-gate }
617*0Sstevel@tonic-gate 
618*0Sstevel@tonic-gate void
show_rpcblist()619*0Sstevel@tonic-gate show_rpcblist()
620*0Sstevel@tonic-gate {
621*0Sstevel@tonic-gate 	unsigned prog, vers;
622*0Sstevel@tonic-gate 	char netid[MAXSTRINGLEN + 1], uaddr[MAXSTRINGLEN + 1];
623*0Sstevel@tonic-gate 	char owner[MAXSTRINGLEN + 1];
624*0Sstevel@tonic-gate 	int maps = 0;
625*0Sstevel@tonic-gate 
626*0Sstevel@tonic-gate 	if (setjmp(xdr_err)) {
627*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
628*0Sstevel@tonic-gate 			" %d+ maps. (Frame is incomplete)",
629*0Sstevel@tonic-gate 			maps);
630*0Sstevel@tonic-gate 		return;
631*0Sstevel@tonic-gate 	}
632*0Sstevel@tonic-gate 
633*0Sstevel@tonic-gate 	show_space();
634*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0),
635*0Sstevel@tonic-gate 		" Program Vers Netid        Uaddr              Owner");
636*0Sstevel@tonic-gate 
637*0Sstevel@tonic-gate 	while (getxdr_u_long()) {
638*0Sstevel@tonic-gate 		prog  = getxdr_u_long();
639*0Sstevel@tonic-gate 		vers  = getxdr_u_long();
640*0Sstevel@tonic-gate 		(void) getxdr_string(netid, MAXSTRINGLEN);
641*0Sstevel@tonic-gate 		(void) getxdr_string(uaddr, MAXSTRINGLEN);
642*0Sstevel@tonic-gate 		(void) getxdr_string(owner, MAXSTRINGLEN);
643*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
644*0Sstevel@tonic-gate 			"%8d%5d %-12s %-18s %-10s (%s)",
645*0Sstevel@tonic-gate 			prog, vers,
646*0Sstevel@tonic-gate 			netid, uaddr, owner,
647*0Sstevel@tonic-gate 			nameof_prog(prog));
648*0Sstevel@tonic-gate 		maps++;
649*0Sstevel@tonic-gate 	}
650*0Sstevel@tonic-gate 
651*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), " (%d maps)", maps);
652*0Sstevel@tonic-gate }
653*0Sstevel@tonic-gate 
654*0Sstevel@tonic-gate char *
sum_rpcb_entry_list()655*0Sstevel@tonic-gate sum_rpcb_entry_list()
656*0Sstevel@tonic-gate {
657*0Sstevel@tonic-gate 	int maps = 0;
658*0Sstevel@tonic-gate 	static char buff[MAXSTRINGLEN + 1];
659*0Sstevel@tonic-gate 
660*0Sstevel@tonic-gate 	if (setjmp(xdr_err)) {
661*0Sstevel@tonic-gate 		(void) sprintf(buff, "%d+ map(s) found", maps);
662*0Sstevel@tonic-gate 		return (buff);
663*0Sstevel@tonic-gate 	}
664*0Sstevel@tonic-gate 
665*0Sstevel@tonic-gate 	while (getxdr_u_long()) {
666*0Sstevel@tonic-gate 		(void) getxdr_string(buff, MAXSTRINGLEN); /* maddr	*/
667*0Sstevel@tonic-gate 		(void) getxdr_string(buff, MAXSTRINGLEN); /* nc_netid	*/
668*0Sstevel@tonic-gate 		(void) getxdr_u_long();			  /* nc_semantics */
669*0Sstevel@tonic-gate 		(void) getxdr_string(buff, MAXSTRINGLEN); /* nc_protofmly */
670*0Sstevel@tonic-gate 		(void) getxdr_string(buff, MAXSTRINGLEN); /* nc_proto	*/
671*0Sstevel@tonic-gate 		maps++;
672*0Sstevel@tonic-gate 	}
673*0Sstevel@tonic-gate 
674*0Sstevel@tonic-gate 	(void) sprintf(buff, "%d map(s) found", maps);
675*0Sstevel@tonic-gate 	return (buff);
676*0Sstevel@tonic-gate }
677*0Sstevel@tonic-gate 
678*0Sstevel@tonic-gate char *semantics_strs[] = {"", "CLTS", "COTS", "COTS-ORD", "RAW"};
679*0Sstevel@tonic-gate 
680*0Sstevel@tonic-gate void
show_rpcb_entry_list()681*0Sstevel@tonic-gate show_rpcb_entry_list()
682*0Sstevel@tonic-gate {
683*0Sstevel@tonic-gate 	char maddr[MAXSTRINGLEN + 1], netid[MAXSTRINGLEN + 1];
684*0Sstevel@tonic-gate 	char protofmly[MAXSTRINGLEN + 1], proto[MAXSTRINGLEN + 1];
685*0Sstevel@tonic-gate 	unsigned sem;
686*0Sstevel@tonic-gate 	int maps = 0;
687*0Sstevel@tonic-gate 
688*0Sstevel@tonic-gate 	if (setjmp(xdr_err)) {
689*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
690*0Sstevel@tonic-gate 			" %d+ maps. (Frame is incomplete)",
691*0Sstevel@tonic-gate 			maps);
692*0Sstevel@tonic-gate 		return;
693*0Sstevel@tonic-gate 	}
694*0Sstevel@tonic-gate 
695*0Sstevel@tonic-gate 	show_space();
696*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0),
697*0Sstevel@tonic-gate 		" Maddr      Netid        Semantics Protofmly Proto");
698*0Sstevel@tonic-gate 
699*0Sstevel@tonic-gate 	while (getxdr_u_long()) {
700*0Sstevel@tonic-gate 		(void) getxdr_string(maddr, MAXSTRINGLEN);
701*0Sstevel@tonic-gate 		(void) getxdr_string(netid, MAXSTRINGLEN);
702*0Sstevel@tonic-gate 		sem  = getxdr_u_long();
703*0Sstevel@tonic-gate 		(void) getxdr_string(protofmly, MAXSTRINGLEN);
704*0Sstevel@tonic-gate 		(void) getxdr_string(proto, MAXSTRINGLEN);
705*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
706*0Sstevel@tonic-gate 			"%-12s %-12s %-8s %-8s %-8s",
707*0Sstevel@tonic-gate 			maddr, netid,
708*0Sstevel@tonic-gate 			semantics_strs[sem],
709*0Sstevel@tonic-gate 			protofmly, proto);
710*0Sstevel@tonic-gate 		maps++;
711*0Sstevel@tonic-gate 	}
712*0Sstevel@tonic-gate 
713*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), " (%d maps)", maps);
714*0Sstevel@tonic-gate }
715*0Sstevel@tonic-gate 
716*0Sstevel@tonic-gate #define	CXID_CACHE_SIZE	16
717*0Sstevel@tonic-gate struct cache_struct cxid_cache[CXID_CACHE_SIZE];
718*0Sstevel@tonic-gate struct cache_struct *cxcpfirst	= &cxid_cache[0];
719*0Sstevel@tonic-gate struct cache_struct *cxcp	= &cxid_cache[0];
720*0Sstevel@tonic-gate struct cache_struct *cxcplast   = &cxid_cache[CXID_CACHE_SIZE - 1];
721*0Sstevel@tonic-gate 
722*0Sstevel@tonic-gate struct cache_struct *
find_callit(xid)723*0Sstevel@tonic-gate find_callit(xid)
724*0Sstevel@tonic-gate 	ulong_t xid;
725*0Sstevel@tonic-gate {
726*0Sstevel@tonic-gate 	struct cache_struct *x;
727*0Sstevel@tonic-gate 
728*0Sstevel@tonic-gate 	for (x = cxcp; x >= cxcpfirst; x--)
729*0Sstevel@tonic-gate 		if (x->xid_num == xid)
730*0Sstevel@tonic-gate 			return (x);
731*0Sstevel@tonic-gate 	for (x = cxcplast; x > cxcp; x--)
732*0Sstevel@tonic-gate 		if (x->xid_num == xid)
733*0Sstevel@tonic-gate 			return (x);
734*0Sstevel@tonic-gate 	return (NULL);
735*0Sstevel@tonic-gate }
736*0Sstevel@tonic-gate 
737*0Sstevel@tonic-gate static void
stash_callit(xid,frame,prog,vers,proc)738*0Sstevel@tonic-gate stash_callit(xid, frame, prog, vers, proc)
739*0Sstevel@tonic-gate 	ulong_t xid;
740*0Sstevel@tonic-gate 	int frame, prog, vers, proc;
741*0Sstevel@tonic-gate {
742*0Sstevel@tonic-gate 	struct cache_struct *x;
743*0Sstevel@tonic-gate 
744*0Sstevel@tonic-gate 	x = find_callit(xid);
745*0Sstevel@tonic-gate 	if (x == NULL) {
746*0Sstevel@tonic-gate 		x = cxcp++;
747*0Sstevel@tonic-gate 		if (cxcp > cxcplast)
748*0Sstevel@tonic-gate 			cxcp = cxcpfirst;
749*0Sstevel@tonic-gate 		x->xid_num = xid;
750*0Sstevel@tonic-gate 		x->xid_frame = frame;
751*0Sstevel@tonic-gate 	}
752*0Sstevel@tonic-gate 	x->xid_prog = prog;
753*0Sstevel@tonic-gate 	x->xid_vers = vers;
754*0Sstevel@tonic-gate 	x->xid_proc = proc;
755*0Sstevel@tonic-gate }
756