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 * rpcb_prot.c 37 * XDR routines for the rpcbinder version 3. 38 * 39 */ 40 41 #include <rpc/rpc.h> 42 #include <rpc/trace.h> 43 #include <rpc/types.h> 44 #include <rpc/xdr.h> 45 #include <rpc/rpcb_prot.h> 46 47 48 bool_t 49 xdr_rpcb(xdrs, objp) 50 XDR *xdrs; 51 RPCB *objp; 52 { 53 trace1(TR_xdr_rpcb, 0); 54 if (!xdr_u_int(xdrs, (u_int *)&objp->r_prog)) { 55 trace1(TR_xdr_rpcb, 1); 56 return (FALSE); 57 } 58 if (!xdr_u_int(xdrs, (u_int *)&objp->r_vers)) { 59 trace1(TR_xdr_rpcb, 1); 60 return (FALSE); 61 } 62 if (!xdr_string(xdrs, &objp->r_netid, ~0)) { 63 return (FALSE); 64 } 65 if (!xdr_string(xdrs, &objp->r_addr, ~0)) { 66 trace1(TR_xdr_rpcb, 1); 67 return (FALSE); 68 } 69 if (!xdr_string(xdrs, &objp->r_owner, ~0)) { 70 trace1(TR_xdr_rpcb, 1); 71 return (FALSE); 72 } 73 trace1(TR_xdr_rpcb, 1); 74 return (TRUE); 75 } 76 77 /* 78 * rpcblist_ptr implements a linked list. The RPCL definition from 79 * rpcb_prot.x is: 80 * 81 * struct rpcblist { 82 * rpcb rpcb_map; 83 * struct rpcblist *rpcb_next; 84 * }; 85 * typedef rpcblist *rpcblist_ptr; 86 * 87 * Recall that "pointers" in XDR are encoded as a boolean, indicating whether 88 * there's any data behind the pointer, followed by the data (if any exists). 89 * The boolean can be interpreted as ``more data follows me''; if FALSE then 90 * nothing follows the boolean; if TRUE then the boolean is followed by an 91 * actual struct rpcb, and another rpcblist_ptr (declared in RPCL as "struct 92 * rpcblist *"). 93 * 94 * This could be implemented via the xdr_pointer type, though this would 95 * result in one recursive call per element in the list. Rather than do that 96 * we can ``unwind'' the recursion into a while loop and use xdr_reference to 97 * serialize the rpcb elements. 98 */ 99 100 bool_t 101 xdr_rpcblist_ptr(xdrs, rp) 102 register XDR *xdrs; 103 register rpcblist_ptr *rp; 104 { 105 /* 106 * more_elements is pre-computed in case the direction is 107 * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 108 * xdr_bool when the direction is XDR_DECODE. 109 */ 110 bool_t more_elements; 111 register int freeing = (xdrs->x_op == XDR_FREE); 112 rpcblist_ptr next; 113 rpcblist_ptr next_copy; 114 115 trace1(TR_xdr_rpcblist_ptr, 0); 116 /*CONSTANTCONDITION*/ 117 while (TRUE) { 118 more_elements = (bool_t)(*rp != NULL); 119 if (! xdr_bool(xdrs, &more_elements)) { 120 trace1(TR_xdr_rpcblist_ptr, 1); 121 return (FALSE); 122 } 123 if (! more_elements) { 124 trace1(TR_xdr_rpcblist_ptr, 1); 125 return (TRUE); /* we are done */ 126 } 127 /* 128 * the unfortunate side effect of non-recursion is that in 129 * the case of freeing we must remember the next object 130 * before we free the current object ... 131 */ 132 if (freeing) 133 next = (*rp)->rpcb_next; 134 if (! xdr_reference(xdrs, (caddr_t *)rp, 135 (u_int) sizeof (rpcblist), (xdrproc_t)xdr_rpcb)) { 136 trace1(TR_xdr_rpcblist_ptr, 1); 137 return (FALSE); 138 } 139 if (freeing) { 140 next_copy = next; 141 rp = &next_copy; 142 /* 143 * Note that in the subsequent iteration, next_copy 144 * gets nulled out by the xdr_reference 145 * but next itself survives. 146 */ 147 } else { 148 rp = &((*rp)->rpcb_next); 149 } 150 } 151 /*NOTREACHED*/ 152 } 153 154 /* 155 * xdr_rpcblist() is specified to take a RPCBLIST **, but is identical in 156 * functionality to xdr_rpcblist_ptr(). 157 */ 158 bool_t 159 xdr_rpcblist(xdrs, rp) 160 register XDR *xdrs; 161 register RPCBLIST **rp; 162 { 163 bool_t dummy; 164 165 dummy = xdr_rpcblist_ptr(xdrs, (rpcblist_ptr *)rp); 166 return (dummy); 167 } 168 169 170 bool_t 171 xdr_rpcb_entry(xdrs, objp) 172 XDR *xdrs; 173 rpcb_entry *objp; 174 { 175 trace1(TR_xdr_rpcb_entry, 0); 176 if (!xdr_string(xdrs, &objp->r_maddr, ~0)) { 177 trace1(TR_xdr_rpcb_entry, 1); 178 return (FALSE); 179 } 180 if (!xdr_string(xdrs, &objp->r_nc_netid, ~0)) { 181 trace1(TR_xdr_rpcb_entry, 1); 182 return (FALSE); 183 } 184 if (!xdr_u_int(xdrs, &objp->r_nc_semantics)) { 185 trace1(TR_xdr_rpcb_entry, 1); 186 return (FALSE); 187 } 188 if (!xdr_string(xdrs, &objp->r_nc_protofmly, ~0)) { 189 trace1(TR_xdr_rpcb_entry, 1); 190 return (FALSE); 191 } 192 if (!xdr_string(xdrs, &objp->r_nc_proto, ~0)) { 193 trace1(TR_xdr_rpcb_entry, 1); 194 return (FALSE); 195 } 196 trace1(TR_xdr_rpcb_entry, 1); 197 return (TRUE); 198 } 199 200 bool_t 201 xdr_rpcb_entry_list_ptr(xdrs, rp) 202 register XDR *xdrs; 203 register rpcb_entry_list_ptr *rp; 204 { 205 /* 206 * more_elements is pre-computed in case the direction is 207 * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 208 * xdr_bool when the direction is XDR_DECODE. 209 */ 210 bool_t more_elements; 211 register int freeing = (xdrs->x_op == XDR_FREE); 212 rpcb_entry_list_ptr next; 213 rpcb_entry_list_ptr next_copy; 214 215 trace1(TR_xdr_rpcb_entry_list_ptr, 0); 216 /*CONSTANTCONDITION*/ 217 while (TRUE) { 218 more_elements = (bool_t)(*rp != NULL); 219 if (! xdr_bool(xdrs, &more_elements)) { 220 trace1(TR_xdr_rpcb_entry_list, 1); 221 return (FALSE); 222 } 223 if (! more_elements) { 224 trace1(TR_xdr_rpcb_entry_list, 1); 225 return (TRUE); /* we are done */ 226 } 227 /* 228 * the unfortunate side effect of non-recursion is that in 229 * the case of freeing we must remember the next object 230 * before we free the current object ... 231 */ 232 if (freeing) 233 next = (*rp)->rpcb_entry_next; 234 if (! xdr_reference(xdrs, (caddr_t *)rp, 235 (u_int) sizeof (rpcb_entry_list), 236 (xdrproc_t)xdr_rpcb_entry)) { 237 trace1(TR_xdr_rpcb_entry_list, 1); 238 return (FALSE); 239 } 240 if (freeing) { 241 next_copy = next; 242 rp = &next_copy; 243 /* 244 * Note that in the subsequent iteration, next_copy 245 * gets nulled out by the xdr_reference 246 * but next itself survives. 247 */ 248 } else { 249 rp = &((*rp)->rpcb_entry_next); 250 } 251 } 252 /*NOTREACHED*/ 253 } 254 255 /* 256 * XDR remote call arguments 257 * written for XDR_ENCODE direction only 258 */ 259 bool_t 260 xdr_rpcb_rmtcallargs(xdrs, objp) 261 XDR *xdrs; 262 struct r_rpcb_rmtcallargs *objp; 263 { 264 u_int lenposition, argposition, position; 265 register rpc_inline_t *buf; 266 267 trace1(TR_xdr_rpcb_rmtcallargs, 0); 268 buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT); 269 if (buf == NULL) { 270 if (!xdr_u_int(xdrs, (u_int *)&objp->prog)) { 271 trace1(TR_xdr_rpcb_rmtcallargs, 1); 272 return (FALSE); 273 } 274 if (!xdr_u_int(xdrs, (u_int *)&objp->vers)) { 275 trace1(TR_xdr_rpcb_rmtcallargs, 1); 276 return (FALSE); 277 } 278 if (!xdr_u_int(xdrs, (u_int *)&objp->proc)) { 279 trace1(TR_xdr_rpcb_rmtcallargs, 1); 280 return (FALSE); 281 } 282 } else { 283 IXDR_PUT_U_INT32(buf, objp->prog); 284 IXDR_PUT_U_INT32(buf, objp->vers); 285 IXDR_PUT_U_INT32(buf, objp->proc); 286 } 287 288 /* 289 * All the jugglery for just getting the size of the arguments 290 */ 291 lenposition = XDR_GETPOS(xdrs); 292 if (! xdr_u_int(xdrs, &(objp->args.args_len))) { 293 trace1(TR_xdr_rpcb_rmtcallargs, 1); 294 return (FALSE); 295 } 296 argposition = XDR_GETPOS(xdrs); 297 if (! (*objp->xdr_args)(xdrs, objp->args.args_val)) { 298 trace1(TR_xdr_rpcb_rmtcallargs, 1); 299 return (FALSE); 300 } 301 position = XDR_GETPOS(xdrs); 302 objp->args.args_len = (u_int)position - (u_int)argposition; 303 XDR_SETPOS(xdrs, lenposition); 304 if (! xdr_u_int(xdrs, &(objp->args.args_len))) { 305 trace1(TR_xdr_rpcb_rmtcallargs, 1); 306 return (FALSE); 307 } 308 XDR_SETPOS(xdrs, position); 309 trace1(TR_xdr_rpcb_rmtcallargs, 1); 310 return (TRUE); 311 } 312 313 /* 314 * XDR remote call results 315 * written for XDR_DECODE direction only 316 */ 317 bool_t 318 xdr_rpcb_rmtcallres(xdrs, objp) 319 XDR *xdrs; 320 struct r_rpcb_rmtcallres *objp; 321 { 322 bool_t dummy; 323 324 trace1(TR_xdr_rpcb_rmtcallres, 0); 325 if (!xdr_string(xdrs, &objp->addr, ~0)) { 326 trace1(TR_xdr_rpcb_rmtcallres, 1); 327 return (FALSE); 328 } 329 if (!xdr_u_int(xdrs, &objp->results.results_len)) { 330 trace1(TR_xdr_rpcb_rmtcallres, 1); 331 return (FALSE); 332 } 333 dummy = (*(objp->xdr_res))(xdrs, objp->results.results_val); 334 trace1(TR_xdr_rpcb_rmtcallres, 1); 335 return (dummy); 336 } 337 338 bool_t 339 xdr_netbuf(xdrs, objp) 340 XDR *xdrs; 341 struct netbuf *objp; 342 { 343 bool_t dummy; 344 345 trace1(TR_xdr_netbuf, 0); 346 if (!xdr_u_int(xdrs, (u_int *) &objp->maxlen)) { 347 trace1(TR_xdr_netbuf, 1); 348 return (FALSE); 349 } 350 dummy = xdr_bytes(xdrs, (char **)&(objp->buf), 351 (u_int *)&(objp->len), objp->maxlen); 352 trace1(TR_xdr_netbuf, 1); 353 return (dummy); 354 } 355