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 0 39 #if !defined(lint) && defined(SCCSIDS) 40 static char sccsid[] = "@(#)rpcb_prot.c 1.9 89/04/21 Copyr 1984 Sun Micro"; 41 #endif 42 #endif 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 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) 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 { 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 for (;;) { 208 more_elements = (bool_t)(*rp != NULL); 209 if (! xdr_bool(xdrs, &more_elements)) { 210 return (FALSE); 211 } 212 if (! more_elements) { 213 return (TRUE); /* we are done */ 214 } 215 /* 216 * the unfortunate side effect of non-recursion is that in 217 * the case of freeing we must remember the next object 218 * before we free the current object ... 219 */ 220 if (freeing) 221 next = (*rp)->rpcb_entry_next; 222 if (! xdr_reference(xdrs, (caddr_t *)rp, 223 (u_int)sizeof (rpcb_entry_list), 224 (xdrproc_t)xdr_rpcb_entry)) { 225 return (FALSE); 226 } 227 if (freeing) { 228 next_copy = next; 229 rp = &next_copy; 230 /* 231 * Note that in the subsequent iteration, next_copy 232 * gets nulled out by the xdr_reference 233 * but next itself survives. 234 */ 235 } else { 236 rp = &((*rp)->rpcb_entry_next); 237 } 238 } 239 /*NOTREACHED*/ 240 } 241 242 /* 243 * XDR remote call arguments 244 * written for XDR_ENCODE direction only 245 */ 246 bool_t 247 xdr_rpcb_rmtcallargs(xdrs, p) 248 XDR *xdrs; 249 struct rpcb_rmtcallargs *p; 250 { 251 struct r_rpcb_rmtcallargs *objp = 252 (struct r_rpcb_rmtcallargs *)(void *)p; 253 u_int lenposition, argposition, position; 254 int32_t *buf; 255 256 buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT); 257 if (buf == NULL) { 258 if (!xdr_u_int32_t(xdrs, &objp->prog)) { 259 return (FALSE); 260 } 261 if (!xdr_u_int32_t(xdrs, &objp->vers)) { 262 return (FALSE); 263 } 264 if (!xdr_u_int32_t(xdrs, &objp->proc)) { 265 return (FALSE); 266 } 267 } else { 268 IXDR_PUT_U_INT32(buf, objp->prog); 269 IXDR_PUT_U_INT32(buf, objp->vers); 270 IXDR_PUT_U_INT32(buf, objp->proc); 271 } 272 273 /* 274 * All the jugglery for just getting the size of the arguments 275 */ 276 lenposition = XDR_GETPOS(xdrs); 277 if (! xdr_u_int(xdrs, &(objp->args.args_len))) { 278 return (FALSE); 279 } 280 argposition = XDR_GETPOS(xdrs); 281 if (! (*objp->xdr_args)(xdrs, objp->args.args_val)) { 282 return (FALSE); 283 } 284 position = XDR_GETPOS(xdrs); 285 objp->args.args_len = (u_int)((u_long)position - (u_long)argposition); 286 XDR_SETPOS(xdrs, lenposition); 287 if (! xdr_u_int(xdrs, &(objp->args.args_len))) { 288 return (FALSE); 289 } 290 XDR_SETPOS(xdrs, position); 291 return (TRUE); 292 } 293 294 /* 295 * XDR remote call results 296 * written for XDR_DECODE direction only 297 */ 298 bool_t 299 xdr_rpcb_rmtcallres(xdrs, p) 300 XDR *xdrs; 301 struct rpcb_rmtcallres *p; 302 { 303 bool_t dummy; 304 struct r_rpcb_rmtcallres *objp = (struct r_rpcb_rmtcallres *)(void *)p; 305 306 if (!xdr_string(xdrs, &objp->addr, (u_int)~0)) { 307 return (FALSE); 308 } 309 if (!xdr_u_int(xdrs, &objp->results.results_len)) { 310 return (FALSE); 311 } 312 dummy = (*(objp->xdr_res))(xdrs, objp->results.results_val); 313 return (dummy); 314 } 315 316 bool_t 317 xdr_netbuf(xdrs, objp) 318 XDR *xdrs; 319 struct netbuf *objp; 320 { 321 bool_t dummy; 322 323 if (!xdr_u_int32_t(xdrs, (u_int32_t *) &objp->maxlen)) { 324 return (FALSE); 325 } 326 dummy = xdr_bytes(xdrs, (char **)&(objp->buf), 327 (u_int *)&(objp->len), objp->maxlen); 328 return (dummy); 329 } 330