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