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  * Copyright 1991 Sun Microsystems, Inc.  All rights reserved.
23*0Sstevel@tonic-gate  * Use is subject to license terms.
24*0Sstevel@tonic-gate  */
25*0Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26*0Sstevel@tonic-gate /* All Rights Reserved */
27*0Sstevel@tonic-gate /*
28*0Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
29*0Sstevel@tonic-gate  * 4.3 BSD under license from the Regents of the University of
30*0Sstevel@tonic-gate  * California.
31*0Sstevel@tonic-gate  */
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate /*
36*0Sstevel@tonic-gate  * pmap_prot.c
37*0Sstevel@tonic-gate  * Protocol for the local binder service, or pmap.
38*0Sstevel@tonic-gate  * All the pmap xdr routines here.
39*0Sstevel@tonic-gate  *
40*0Sstevel@tonic-gate  */
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #include <rpc/types.h>
43*0Sstevel@tonic-gate #include <rpc/trace.h>
44*0Sstevel@tonic-gate #include <rpc/xdr.h>
45*0Sstevel@tonic-gate #include <rpc/pmap_prot.h>
46*0Sstevel@tonic-gate #include <rpc/pmap_rmt.h>
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate bool_t
49*0Sstevel@tonic-gate xdr_pmap(xdrs, objp)
50*0Sstevel@tonic-gate 	XDR *xdrs;
51*0Sstevel@tonic-gate 	struct pmap *objp;
52*0Sstevel@tonic-gate {
53*0Sstevel@tonic-gate 
54*0Sstevel@tonic-gate 	register rpc_inline_t *buf;
55*0Sstevel@tonic-gate 	bool_t dummy;
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate 	trace1(TR_xdr_pmap, 0);
58*0Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
59*0Sstevel@tonic-gate 		buf = XDR_INLINE(xdrs, 4 * BYTES_PER_XDR_UNIT);
60*0Sstevel@tonic-gate 		if (buf == NULL) {
61*0Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (u_int *)&objp->pm_prog)) {
62*0Sstevel@tonic-gate 				trace1(TR_xdr_pmap, 1);
63*0Sstevel@tonic-gate 				return (FALSE);
64*0Sstevel@tonic-gate 			}
65*0Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (u_int *)&objp->pm_vers)) {
66*0Sstevel@tonic-gate 				trace1(TR_xdr_pmap, 1);
67*0Sstevel@tonic-gate 				return (FALSE);
68*0Sstevel@tonic-gate 			}
69*0Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (u_int *)&objp->pm_prot)) {
70*0Sstevel@tonic-gate 				trace1(TR_xdr_pmap, 1);
71*0Sstevel@tonic-gate 				return (FALSE);
72*0Sstevel@tonic-gate 			}
73*0Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (u_int *)&objp->pm_port)) {
74*0Sstevel@tonic-gate 				trace1(TR_xdr_pmap, 1);
75*0Sstevel@tonic-gate 				return (FALSE);
76*0Sstevel@tonic-gate 			}
77*0Sstevel@tonic-gate 		} else {
78*0Sstevel@tonic-gate 			IXDR_PUT_U_INT32(buf, objp->pm_prog);
79*0Sstevel@tonic-gate 			IXDR_PUT_U_INT32(buf, objp->pm_vers);
80*0Sstevel@tonic-gate 			IXDR_PUT_U_INT32(buf, objp->pm_prot);
81*0Sstevel@tonic-gate 			IXDR_PUT_U_INT32(buf, objp->pm_port);
82*0Sstevel@tonic-gate 		}
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 		trace1(TR_xdr_pmap, 1);
85*0Sstevel@tonic-gate 		return (TRUE);
86*0Sstevel@tonic-gate 	} else if (xdrs->x_op == XDR_DECODE) {
87*0Sstevel@tonic-gate 		buf = XDR_INLINE(xdrs, 4 * BYTES_PER_XDR_UNIT);
88*0Sstevel@tonic-gate 		if (buf == NULL) {
89*0Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (u_int *)&objp->pm_prog)) {
90*0Sstevel@tonic-gate 				trace1(TR_xdr_pmap, 1);
91*0Sstevel@tonic-gate 				return (FALSE);
92*0Sstevel@tonic-gate 			}
93*0Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (u_int *)&objp->pm_vers)) {
94*0Sstevel@tonic-gate 				trace1(TR_xdr_pmap, 1);
95*0Sstevel@tonic-gate 				return (FALSE);
96*0Sstevel@tonic-gate 			}
97*0Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (u_int *)&objp->pm_prot)) {
98*0Sstevel@tonic-gate 				trace1(TR_xdr_pmap, 1);
99*0Sstevel@tonic-gate 				return (FALSE);
100*0Sstevel@tonic-gate 			}
101*0Sstevel@tonic-gate 			if (!xdr_u_int(xdrs, (u_int *)&objp->pm_port)) {
102*0Sstevel@tonic-gate 				trace1(TR_xdr_pmap, 1);
103*0Sstevel@tonic-gate 				return (FALSE);
104*0Sstevel@tonic-gate 			}
105*0Sstevel@tonic-gate 
106*0Sstevel@tonic-gate 		} else {
107*0Sstevel@tonic-gate 			objp->pm_prog = IXDR_GET_U_INT32(buf);
108*0Sstevel@tonic-gate 			objp->pm_vers = IXDR_GET_U_INT32(buf);
109*0Sstevel@tonic-gate 			objp->pm_prot = IXDR_GET_U_INT32(buf);
110*0Sstevel@tonic-gate 			objp->pm_port = IXDR_GET_U_INT32(buf);
111*0Sstevel@tonic-gate 		}
112*0Sstevel@tonic-gate 		trace1(TR_xdr_pmap, 1);
113*0Sstevel@tonic-gate 		return (TRUE);
114*0Sstevel@tonic-gate 	}
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 	if (xdr_u_int(xdrs, (u_int *)&objp->pm_prog) &&
117*0Sstevel@tonic-gate 	    xdr_u_int(xdrs, (u_int *)&objp->pm_vers) &&
118*0Sstevel@tonic-gate 	    xdr_u_int(xdrs, (u_int *)&objp->pm_prot)) {
119*0Sstevel@tonic-gate 		dummy = xdr_u_int(xdrs, (u_int *)&objp->pm_port);
120*0Sstevel@tonic-gate 		trace1(TR_xdr_pmap, 1);
121*0Sstevel@tonic-gate 		return (dummy);
122*0Sstevel@tonic-gate 	}
123*0Sstevel@tonic-gate 	trace1(TR_xdr_pmap, 1);
124*0Sstevel@tonic-gate 	return (FALSE);
125*0Sstevel@tonic-gate }
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate /*
128*0Sstevel@tonic-gate  * pmaplist_ptr implements a linked list.  The RPCL definition from
129*0Sstevel@tonic-gate  * pmap_prot.x is:
130*0Sstevel@tonic-gate  *
131*0Sstevel@tonic-gate  * struct pm__list {
132*0Sstevel@tonic-gate  * 	pmap		pml_map;
133*0Sstevel@tonic-gate  *	struct pm__list *pml_next;
134*0Sstevel@tonic-gate  * };
135*0Sstevel@tonic-gate  * typedef pm__list *pmaplist_ptr;
136*0Sstevel@tonic-gate  *
137*0Sstevel@tonic-gate  * Recall that "pointers" in XDR are encoded as a boolean, indicating whether
138*0Sstevel@tonic-gate  * there's any data behind the pointer, followed by the data (if any exists).
139*0Sstevel@tonic-gate  * The boolean can be interpreted as ``more data follows me''; if FALSE then
140*0Sstevel@tonic-gate  * nothing follows the boolean; if TRUE then the boolean is followed by an
141*0Sstevel@tonic-gate  * actual struct pmap, and another pmaplist_ptr (declared in RPCL as "struct
142*0Sstevel@tonic-gate  * pmaplist *").
143*0Sstevel@tonic-gate  *
144*0Sstevel@tonic-gate  * This could be implemented via the xdr_pointer type, though this would
145*0Sstevel@tonic-gate  * result in one recursive call per element in the list.  Rather than do that
146*0Sstevel@tonic-gate  * we can ``unwind'' the recursion into a while loop and use xdr_reference to
147*0Sstevel@tonic-gate  * serialize the pmap elements.
148*0Sstevel@tonic-gate  */
149*0Sstevel@tonic-gate bool_t
150*0Sstevel@tonic-gate xdr_pmaplist_ptr(xdrs, rp)
151*0Sstevel@tonic-gate 	register XDR *xdrs;
152*0Sstevel@tonic-gate 	register pmaplist_ptr *rp;
153*0Sstevel@tonic-gate {
154*0Sstevel@tonic-gate 	/*
155*0Sstevel@tonic-gate 	 * more_elements is pre-computed in case the direction is
156*0Sstevel@tonic-gate 	 * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
157*0Sstevel@tonic-gate 	 * xdr_bool when the direction is XDR_DECODE.
158*0Sstevel@tonic-gate 	 */
159*0Sstevel@tonic-gate 	bool_t more_elements;
160*0Sstevel@tonic-gate 	register int freeing = (xdrs->x_op == XDR_FREE);
161*0Sstevel@tonic-gate 	pmaplist_ptr next;
162*0Sstevel@tonic-gate 	pmaplist_ptr next_copy;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	trace1(TR_xdr_pmaplist_ptr, 0);
165*0Sstevel@tonic-gate 	/*CONSTANTCONDITION*/
166*0Sstevel@tonic-gate 	while (TRUE) {
167*0Sstevel@tonic-gate 		more_elements = (bool_t)(*rp != NULL);
168*0Sstevel@tonic-gate 		if (! xdr_bool(xdrs, &more_elements)) {
169*0Sstevel@tonic-gate 			trace1(TR_xdr_pmaplist_ptr, 1);
170*0Sstevel@tonic-gate 			return (FALSE);
171*0Sstevel@tonic-gate 		}
172*0Sstevel@tonic-gate 		if (! more_elements) {
173*0Sstevel@tonic-gate 			trace1(TR_xdr_pmaplist_ptr, 1);
174*0Sstevel@tonic-gate 			return (TRUE);  /* we are done */
175*0Sstevel@tonic-gate 		}
176*0Sstevel@tonic-gate 		/*
177*0Sstevel@tonic-gate 		 * the unfortunate side effect of non-recursion is that in
178*0Sstevel@tonic-gate 		 * the case of freeing we must remember the next object
179*0Sstevel@tonic-gate 		 * before we free the current object ...
180*0Sstevel@tonic-gate 		 */
181*0Sstevel@tonic-gate 		if (freeing)
182*0Sstevel@tonic-gate 			next = (*rp)->pml_next;
183*0Sstevel@tonic-gate 		if (! xdr_reference(xdrs, (caddr_t *)rp,
184*0Sstevel@tonic-gate 		    (u_int)sizeof (struct pmaplist), (xdrproc_t) xdr_pmap)) {
185*0Sstevel@tonic-gate 			trace1(TR_xdr_pmaplist_ptr, 1);
186*0Sstevel@tonic-gate 			return (FALSE);
187*0Sstevel@tonic-gate 		}
188*0Sstevel@tonic-gate 		if (freeing) {
189*0Sstevel@tonic-gate 			next_copy = next;
190*0Sstevel@tonic-gate 			rp = &next_copy;
191*0Sstevel@tonic-gate 			/*
192*0Sstevel@tonic-gate 			 * Note that in the subsequent iteration, next_copy
193*0Sstevel@tonic-gate 			 * gets nulled out by the xdr_reference
194*0Sstevel@tonic-gate 			 * but next itself survives.
195*0Sstevel@tonic-gate 			 */
196*0Sstevel@tonic-gate 		} else {
197*0Sstevel@tonic-gate 			rp = &((*rp)->pml_next);
198*0Sstevel@tonic-gate 		}
199*0Sstevel@tonic-gate 	}
200*0Sstevel@tonic-gate 	/*NOTREACHED*/
201*0Sstevel@tonic-gate }
202*0Sstevel@tonic-gate 
203*0Sstevel@tonic-gate /*
204*0Sstevel@tonic-gate  * xdr_pmaplist() is specified to take a PMAPLIST **, but is identical in
205*0Sstevel@tonic-gate  * functionality to xdr_pmaplist_ptr().
206*0Sstevel@tonic-gate  */
207*0Sstevel@tonic-gate bool_t
208*0Sstevel@tonic-gate xdr_pmaplist(xdrs, rp)
209*0Sstevel@tonic-gate 	register XDR *xdrs;
210*0Sstevel@tonic-gate 	register PMAPLIST **rp;
211*0Sstevel@tonic-gate {
212*0Sstevel@tonic-gate 	bool_t	dummy;
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate 	dummy = xdr_pmaplist_ptr(xdrs, (pmaplist_ptr *)rp);
215*0Sstevel@tonic-gate 	return (dummy);
216*0Sstevel@tonic-gate }
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate /*
220*0Sstevel@tonic-gate  * XDR remote call arguments
221*0Sstevel@tonic-gate  * written for XDR_ENCODE direction only
222*0Sstevel@tonic-gate  */
223*0Sstevel@tonic-gate bool_t
224*0Sstevel@tonic-gate xdr_rmtcallargs(xdrs, cap)
225*0Sstevel@tonic-gate 	register XDR *xdrs;
226*0Sstevel@tonic-gate 	register struct p_rmtcallargs *cap;
227*0Sstevel@tonic-gate {
228*0Sstevel@tonic-gate 	u_int lenposition, argposition, position;
229*0Sstevel@tonic-gate 	register    rpc_inline_t *buf;
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	trace1(TR_xdr_rmtcallargs, 0);
233*0Sstevel@tonic-gate 	buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT);
234*0Sstevel@tonic-gate 	if (buf == NULL) {
235*0Sstevel@tonic-gate 		if (!xdr_u_int(xdrs, (u_int *)&(cap->prog)) ||
236*0Sstevel@tonic-gate 		    !xdr_u_int(xdrs, (u_int *)&(cap->vers)) ||
237*0Sstevel@tonic-gate 		    !xdr_u_int(xdrs, (u_int *)&(cap->proc))) {
238*0Sstevel@tonic-gate 			trace1(TR_xdr_rmtcallargs, 1);
239*0Sstevel@tonic-gate 			return (FALSE);
240*0Sstevel@tonic-gate 		}
241*0Sstevel@tonic-gate 	} else {
242*0Sstevel@tonic-gate 		IXDR_PUT_U_INT32(buf, cap->prog);
243*0Sstevel@tonic-gate 		IXDR_PUT_U_INT32(buf, cap->vers);
244*0Sstevel@tonic-gate 		IXDR_PUT_U_INT32(buf, cap->proc);
245*0Sstevel@tonic-gate 	}
246*0Sstevel@tonic-gate 
247*0Sstevel@tonic-gate 	/*
248*0Sstevel@tonic-gate 	 * All the jugglery for just getting the size of the arguments
249*0Sstevel@tonic-gate 	 */
250*0Sstevel@tonic-gate 	lenposition = XDR_GETPOS(xdrs);
251*0Sstevel@tonic-gate 	if (! xdr_u_int(xdrs, &(cap->args.args_len)))  {
252*0Sstevel@tonic-gate 		trace1(TR_xdr_rmtcallargs, 1);
253*0Sstevel@tonic-gate 		return (FALSE);
254*0Sstevel@tonic-gate 	}
255*0Sstevel@tonic-gate 	argposition = XDR_GETPOS(xdrs);
256*0Sstevel@tonic-gate 	if (! (*cap->xdr_args)(xdrs, cap->args.args_val)) {
257*0Sstevel@tonic-gate 		trace1(TR_xdr_rmtcallargs, 1);
258*0Sstevel@tonic-gate 		return (FALSE);
259*0Sstevel@tonic-gate 	}
260*0Sstevel@tonic-gate 	position = XDR_GETPOS(xdrs);
261*0Sstevel@tonic-gate 	cap->args.args_len = position - argposition;
262*0Sstevel@tonic-gate 	XDR_SETPOS(xdrs, lenposition);
263*0Sstevel@tonic-gate 	if (! xdr_u_int(xdrs, &(cap->args.args_len))) {
264*0Sstevel@tonic-gate 		trace1(TR_xdr_rmtcallargs, 1);
265*0Sstevel@tonic-gate 		return (FALSE);
266*0Sstevel@tonic-gate 	}
267*0Sstevel@tonic-gate 	XDR_SETPOS(xdrs, position);
268*0Sstevel@tonic-gate 	trace1(TR_xdr_rmtcallargs, 1);
269*0Sstevel@tonic-gate 	return (TRUE);
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate }
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate /*
275*0Sstevel@tonic-gate  * XDR remote call results
276*0Sstevel@tonic-gate  * written for XDR_DECODE direction only
277*0Sstevel@tonic-gate  */
278*0Sstevel@tonic-gate bool_t
279*0Sstevel@tonic-gate xdr_rmtcallres(xdrs, crp)
280*0Sstevel@tonic-gate 	register XDR *xdrs;
281*0Sstevel@tonic-gate 	register struct p_rmtcallres *crp;
282*0Sstevel@tonic-gate {
283*0Sstevel@tonic-gate 	bool_t	dummy;
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 	trace1(TR_xdr_rmtcallres, 0);
286*0Sstevel@tonic-gate 	if (xdr_u_int(xdrs, (u_int *)&crp->port) &&
287*0Sstevel@tonic-gate 	    xdr_u_int(xdrs, &crp->res.res_len)) {
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate 		dummy = (*(crp->xdr_res))(xdrs, crp->res.res_val);
290*0Sstevel@tonic-gate 		trace1(TR_xdr_rmtcallres, 1);
291*0Sstevel@tonic-gate 		return (dummy);
292*0Sstevel@tonic-gate 	}
293*0Sstevel@tonic-gate 	trace1(TR_xdr_rmtcallres, 1);
294*0Sstevel@tonic-gate 	return (FALSE);
295*0Sstevel@tonic-gate }
296