1 /* $NetBSD: rpcb_prot.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ 2 3 /* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or 9 * program developed by the user. 10 * 11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14 * 15 * Sun RPC is provided with no support and without any obligation on the 16 * part of Sun Microsystems, Inc. to assist in its use, correction, 17 * modification or enhancement. 18 * 19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21 * OR ANY PART THEREOF. 22 * 23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24 * or profits or other special, indirect and consequential damages, even if 25 * Sun has been advised of the possibility of such damages. 26 * 27 * Sun Microsystems, Inc. 28 * 2550 Garcia Avenue 29 * Mountain View, California 94043 30 */ 31 /* 32 * Copyright (c) 1986-1991 by Sun Microsystems Inc. 33 */ 34 35 /* #ident "@(#)rpcb_prot.c 1.13 94/04/24 SMI" */ 36 37 #if defined(LIBC_SCCS) && !defined(lint) 38 static char sccsid[] = "@(#)rpcb_prot.c 1.9 89/04/21 Copyr 1984 Sun Micro"; 39 #endif 40 #include <sys/cdefs.h> 41 __FBSDID("$FreeBSD$"); 42 43 /* 44 * rpcb_prot.c 45 * XDR routines for the rpcbinder version 3. 46 * 47 * Copyright (C) 1984, 1988, Sun Microsystems, Inc. 48 */ 49 50 #include "namespace.h" 51 #include <rpc/rpc.h> 52 #include <rpc/types.h> 53 #include <rpc/xdr.h> 54 #include <rpc/rpcb_prot.h> 55 #include "un-namespace.h" 56 57 bool_t 58 xdr_rpcb(xdrs, objp) 59 XDR *xdrs; 60 RPCB *objp; 61 { 62 if (!xdr_u_int32_t(xdrs, &objp->r_prog)) { 63 return (FALSE); 64 } 65 if (!xdr_u_int32_t(xdrs, &objp->r_vers)) { 66 return (FALSE); 67 } 68 if (!xdr_string(xdrs, &objp->r_netid, (u_int)~0)) { 69 return (FALSE); 70 } 71 if (!xdr_string(xdrs, &objp->r_addr, (u_int)~0)) { 72 return (FALSE); 73 } 74 if (!xdr_string(xdrs, &objp->r_owner, (u_int)~0)) { 75 return (FALSE); 76 } 77 return (TRUE); 78 } 79 80 /* 81 * rpcblist_ptr implements a linked list. The RPCL definition from 82 * rpcb_prot.x is: 83 * 84 * struct rpcblist { 85 * rpcb rpcb_map; 86 * struct rpcblist *rpcb_next; 87 * }; 88 * typedef rpcblist *rpcblist_ptr; 89 * 90 * Recall that "pointers" in XDR are encoded as a boolean, indicating whether 91 * there's any data behind the pointer, followed by the data (if any exists). 92 * The boolean can be interpreted as ``more data follows me''; if FALSE then 93 * nothing follows the boolean; if TRUE then the boolean is followed by an 94 * actual struct rpcb, and another rpcblist_ptr (declared in RPCL as "struct 95 * rpcblist *"). 96 * 97 * This could be implemented via the xdr_pointer type, though this would 98 * result in one recursive call per element in the list. Rather than do that 99 * we can ``unwind'' the recursion into a while loop and use xdr_reference to 100 * serialize the rpcb elements. 101 */ 102 103 bool_t 104 xdr_rpcblist_ptr(xdrs, rp) 105 XDR *xdrs; 106 rpcblist_ptr *rp; 107 { 108 /* 109 * more_elements is pre-computed in case the direction is 110 * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 111 * xdr_bool when the direction is XDR_DECODE. 112 */ 113 bool_t more_elements; 114 int freeing = (xdrs->x_op == XDR_FREE); 115 rpcblist_ptr next; 116 rpcblist_ptr next_copy; 117 118 next = NULL; 119 for (;;) { 120 more_elements = (bool_t)(*rp != NULL); 121 if (! xdr_bool(xdrs, &more_elements)) { 122 return (FALSE); 123 } 124 if (! more_elements) { 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 && *rp) 133 next = (*rp)->rpcb_next; 134 if (! xdr_reference(xdrs, (caddr_t *)rp, 135 (u_int)sizeof (rpcblist), (xdrproc_t)xdr_rpcb)) { 136 return (FALSE); 137 } 138 if (freeing) { 139 next_copy = next; 140 rp = &next_copy; 141 /* 142 * Note that in the subsequent iteration, next_copy 143 * gets nulled out by the xdr_reference 144 * but next itself survives. 145 */ 146 } else if (*rp) { 147 rp = &((*rp)->rpcb_next); 148 } 149 } 150 /*NOTREACHED*/ 151 } 152 153 /* 154 * xdr_rpcblist() is specified to take a RPCBLIST **, but is identical in 155 * functionality to xdr_rpcblist_ptr(). 156 */ 157 bool_t 158 xdr_rpcblist(xdrs, rp) 159 XDR *xdrs; 160 RPCBLIST **rp; 161 { 162 bool_t dummy; 163 164 dummy = xdr_rpcblist_ptr(xdrs, (rpcblist_ptr *)rp); 165 return (dummy); 166 } 167 168 169 bool_t 170 xdr_rpcb_entry(xdrs, objp) 171 XDR *xdrs; 172 rpcb_entry *objp; 173 { 174 if (!xdr_string(xdrs, &objp->r_maddr, (u_int)~0)) { 175 return (FALSE); 176 } 177 if (!xdr_string(xdrs, &objp->r_nc_netid, (u_int)~0)) { 178 return (FALSE); 179 } 180 if (!xdr_u_int32_t(xdrs, &objp->r_nc_semantics)) { 181 return (FALSE); 182 } 183 if (!xdr_string(xdrs, &objp->r_nc_protofmly, (u_int)~0)) { 184 return (FALSE); 185 } 186 if (!xdr_string(xdrs, &objp->r_nc_proto, (u_int)~0)) { 187 return (FALSE); 188 } 189 return (TRUE); 190 } 191 192 bool_t 193 xdr_rpcb_entry_list_ptr(xdrs, rp) 194 XDR *xdrs; 195 rpcb_entry_list_ptr *rp; 196 { 197 /* 198 * more_elements is pre-computed in case the direction is 199 * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 200 * xdr_bool when the direction is XDR_DECODE. 201 */ 202 bool_t more_elements; 203 int freeing = (xdrs->x_op == XDR_FREE); 204 rpcb_entry_list_ptr next; 205 rpcb_entry_list_ptr next_copy; 206 207 next = NULL; 208 for (;;) { 209 more_elements = (bool_t)(*rp != NULL); 210 if (! xdr_bool(xdrs, &more_elements)) { 211 return (FALSE); 212 } 213 if (! more_elements) { 214 return (TRUE); /* we are done */ 215 } 216 /* 217 * the unfortunate side effect of non-recursion is that in 218 * the case of freeing we must remember the next object 219 * before we free the current object ... 220 */ 221 if (freeing) 222 next = (*rp)->rpcb_entry_next; 223 if (! xdr_reference(xdrs, (caddr_t *)rp, 224 (u_int)sizeof (rpcb_entry_list), 225 (xdrproc_t)xdr_rpcb_entry)) { 226 return (FALSE); 227 } 228 if (freeing && *rp) { 229 next_copy = next; 230 rp = &next_copy; 231 /* 232 * Note that in the subsequent iteration, next_copy 233 * gets nulled out by the xdr_reference 234 * but next itself survives. 235 */ 236 } else if (*rp) { 237 rp = &((*rp)->rpcb_entry_next); 238 } 239 } 240 /*NOTREACHED*/ 241 } 242 243 /* 244 * XDR remote call arguments 245 * written for XDR_ENCODE direction only 246 */ 247 bool_t 248 xdr_rpcb_rmtcallargs(xdrs, p) 249 XDR *xdrs; 250 struct rpcb_rmtcallargs *p; 251 { 252 struct r_rpcb_rmtcallargs *objp = 253 (struct r_rpcb_rmtcallargs *)(void *)p; 254 u_int lenposition, argposition, position; 255 int32_t *buf; 256 257 buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT); 258 if (buf == NULL) { 259 if (!xdr_u_int32_t(xdrs, &objp->prog)) { 260 return (FALSE); 261 } 262 if (!xdr_u_int32_t(xdrs, &objp->vers)) { 263 return (FALSE); 264 } 265 if (!xdr_u_int32_t(xdrs, &objp->proc)) { 266 return (FALSE); 267 } 268 } else { 269 IXDR_PUT_U_INT32(buf, objp->prog); 270 IXDR_PUT_U_INT32(buf, objp->vers); 271 IXDR_PUT_U_INT32(buf, objp->proc); 272 } 273 274 /* 275 * All the jugglery for just getting the size of the arguments 276 */ 277 lenposition = XDR_GETPOS(xdrs); 278 if (! xdr_u_int(xdrs, &(objp->args.args_len))) { 279 return (FALSE); 280 } 281 argposition = XDR_GETPOS(xdrs); 282 if (! (*objp->xdr_args)(xdrs, objp->args.args_val)) { 283 return (FALSE); 284 } 285 position = XDR_GETPOS(xdrs); 286 objp->args.args_len = (u_int)((u_long)position - (u_long)argposition); 287 XDR_SETPOS(xdrs, lenposition); 288 if (! xdr_u_int(xdrs, &(objp->args.args_len))) { 289 return (FALSE); 290 } 291 XDR_SETPOS(xdrs, position); 292 return (TRUE); 293 } 294 295 /* 296 * XDR remote call results 297 * written for XDR_DECODE direction only 298 */ 299 bool_t 300 xdr_rpcb_rmtcallres(xdrs, p) 301 XDR *xdrs; 302 struct rpcb_rmtcallres *p; 303 { 304 bool_t dummy; 305 struct r_rpcb_rmtcallres *objp = (struct r_rpcb_rmtcallres *)(void *)p; 306 307 if (!xdr_string(xdrs, &objp->addr, (u_int)~0)) { 308 return (FALSE); 309 } 310 if (!xdr_u_int(xdrs, &objp->results.results_len)) { 311 return (FALSE); 312 } 313 dummy = (*(objp->xdr_res))(xdrs, objp->results.results_val); 314 return (dummy); 315 } 316 317 bool_t 318 xdr_netbuf(xdrs, objp) 319 XDR *xdrs; 320 struct netbuf *objp; 321 { 322 bool_t dummy; 323 void **pp; 324 325 if (!xdr_u_int32_t(xdrs, (u_int32_t *) &objp->maxlen)) { 326 return (FALSE); 327 } 328 pp = &objp->buf; 329 dummy = xdr_bytes(xdrs, (char **) pp, 330 (u_int *)&(objp->len), objp->maxlen); 331 return (dummy); 332 } 333