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