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