1dfdcada3SDoug Rabson /* $NetBSD: rpcb_prot.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ 2dfdcada3SDoug Rabson 3*2e322d37SHiroki Sato /*- 4*2e322d37SHiroki Sato * Copyright (c) 2009, Sun Microsystems, Inc. 5*2e322d37SHiroki Sato * All rights reserved. 6dfdcada3SDoug Rabson * 7*2e322d37SHiroki Sato * Redistribution and use in source and binary forms, with or without 8*2e322d37SHiroki Sato * modification, are permitted provided that the following conditions are met: 9*2e322d37SHiroki Sato * - Redistributions of source code must retain the above copyright notice, 10*2e322d37SHiroki Sato * this list of conditions and the following disclaimer. 11*2e322d37SHiroki Sato * - Redistributions in binary form must reproduce the above copyright notice, 12*2e322d37SHiroki Sato * this list of conditions and the following disclaimer in the documentation 13*2e322d37SHiroki Sato * and/or other materials provided with the distribution. 14*2e322d37SHiroki Sato * - Neither the name of Sun Microsystems, Inc. nor the names of its 15*2e322d37SHiroki Sato * contributors may be used to endorse or promote products derived 16*2e322d37SHiroki Sato * from this software without specific prior written permission. 17dfdcada3SDoug Rabson * 18*2e322d37SHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19*2e322d37SHiroki Sato * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20*2e322d37SHiroki Sato * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21*2e322d37SHiroki Sato * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22*2e322d37SHiroki Sato * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23*2e322d37SHiroki Sato * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24*2e322d37SHiroki Sato * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25*2e322d37SHiroki Sato * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26*2e322d37SHiroki Sato * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27*2e322d37SHiroki Sato * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28*2e322d37SHiroki Sato * POSSIBILITY OF SUCH DAMAGE. 29dfdcada3SDoug Rabson */ 30dfdcada3SDoug Rabson /* 31dfdcada3SDoug Rabson * Copyright (c) 1986-1991 by Sun Microsystems Inc. 32dfdcada3SDoug Rabson */ 33dfdcada3SDoug Rabson 34dfdcada3SDoug Rabson /* #ident "@(#)rpcb_prot.c 1.13 94/04/24 SMI" */ 35dfdcada3SDoug Rabson 36dfdcada3SDoug Rabson #if defined(LIBC_SCCS) && !defined(lint) 37dfdcada3SDoug Rabson static char sccsid[] = "@(#)rpcb_prot.c 1.9 89/04/21 Copyr 1984 Sun Micro"; 38dfdcada3SDoug Rabson #endif 39dfdcada3SDoug Rabson #include <sys/cdefs.h> 40dfdcada3SDoug Rabson __FBSDID("$FreeBSD$"); 41dfdcada3SDoug Rabson 42dfdcada3SDoug Rabson /* 43dfdcada3SDoug Rabson * rpcb_prot.c 44dfdcada3SDoug Rabson * XDR routines for the rpcbinder version 3. 45dfdcada3SDoug Rabson * 46dfdcada3SDoug Rabson * Copyright (C) 1984, 1988, Sun Microsystems, Inc. 47dfdcada3SDoug Rabson */ 48dfdcada3SDoug Rabson 49dfdcada3SDoug Rabson #include <sys/param.h> 50dfdcada3SDoug Rabson #include <sys/systm.h> 51dfdcada3SDoug Rabson #include <sys/kernel.h> 52dfdcada3SDoug Rabson #include <sys/malloc.h> 53dfdcada3SDoug Rabson 54dfdcada3SDoug Rabson #include <rpc/rpc.h> 55dfdcada3SDoug Rabson #include <rpc/rpcb_prot.h> 56dfdcada3SDoug Rabson 57dfdcada3SDoug Rabson bool_t 5871066861SDoug Rabson xdr_portmap(XDR *xdrs, struct portmap *regs) 59dfdcada3SDoug Rabson { 60dfdcada3SDoug Rabson 61dfdcada3SDoug Rabson if (xdr_u_long(xdrs, ®s->pm_prog) && 62dfdcada3SDoug Rabson xdr_u_long(xdrs, ®s->pm_vers) && 63dfdcada3SDoug Rabson xdr_u_long(xdrs, ®s->pm_prot)) 64dfdcada3SDoug Rabson return (xdr_u_long(xdrs, ®s->pm_port)); 65dfdcada3SDoug Rabson return (FALSE); 66dfdcada3SDoug Rabson } 67dfdcada3SDoug Rabson 68dfdcada3SDoug Rabson bool_t 69dfdcada3SDoug Rabson xdr_rpcb(XDR *xdrs, RPCB *objp) 70dfdcada3SDoug Rabson { 71dfdcada3SDoug Rabson if (!xdr_uint32_t(xdrs, &objp->r_prog)) { 72dfdcada3SDoug Rabson return (FALSE); 73dfdcada3SDoug Rabson } 74dfdcada3SDoug Rabson if (!xdr_uint32_t(xdrs, &objp->r_vers)) { 75dfdcada3SDoug Rabson return (FALSE); 76dfdcada3SDoug Rabson } 77dfdcada3SDoug Rabson if (!xdr_string(xdrs, &objp->r_netid, (u_int)~0)) { 78dfdcada3SDoug Rabson return (FALSE); 79dfdcada3SDoug Rabson } 80dfdcada3SDoug Rabson if (!xdr_string(xdrs, &objp->r_addr, (u_int)~0)) { 81dfdcada3SDoug Rabson return (FALSE); 82dfdcada3SDoug Rabson } 83dfdcada3SDoug Rabson if (!xdr_string(xdrs, &objp->r_owner, (u_int)~0)) { 84dfdcada3SDoug Rabson return (FALSE); 85dfdcada3SDoug Rabson } 86dfdcada3SDoug Rabson return (TRUE); 87dfdcada3SDoug Rabson } 88dfdcada3SDoug Rabson 89dfdcada3SDoug Rabson /* 90dfdcada3SDoug Rabson * rpcblist_ptr implements a linked list. The RPCL definition from 91dfdcada3SDoug Rabson * rpcb_prot.x is: 92dfdcada3SDoug Rabson * 93dfdcada3SDoug Rabson * struct rpcblist { 94dfdcada3SDoug Rabson * rpcb rpcb_map; 95dfdcada3SDoug Rabson * struct rpcblist *rpcb_next; 96dfdcada3SDoug Rabson * }; 97dfdcada3SDoug Rabson * typedef rpcblist *rpcblist_ptr; 98dfdcada3SDoug Rabson * 99dfdcada3SDoug Rabson * Recall that "pointers" in XDR are encoded as a boolean, indicating whether 100dfdcada3SDoug Rabson * there's any data behind the pointer, followed by the data (if any exists). 101dfdcada3SDoug Rabson * The boolean can be interpreted as ``more data follows me''; if FALSE then 102dfdcada3SDoug Rabson * nothing follows the boolean; if TRUE then the boolean is followed by an 103dfdcada3SDoug Rabson * actual struct rpcb, and another rpcblist_ptr (declared in RPCL as "struct 104dfdcada3SDoug Rabson * rpcblist *"). 105dfdcada3SDoug Rabson * 106dfdcada3SDoug Rabson * This could be implemented via the xdr_pointer type, though this would 107dfdcada3SDoug Rabson * result in one recursive call per element in the list. Rather than do that 108dfdcada3SDoug Rabson * we can ``unwind'' the recursion into a while loop and use xdr_reference to 109dfdcada3SDoug Rabson * serialize the rpcb elements. 110dfdcada3SDoug Rabson */ 111dfdcada3SDoug Rabson 112dfdcada3SDoug Rabson bool_t 113dfdcada3SDoug Rabson xdr_rpcblist_ptr(XDR *xdrs, rpcblist_ptr *rp) 114dfdcada3SDoug Rabson { 115dfdcada3SDoug Rabson /* 116dfdcada3SDoug Rabson * more_elements is pre-computed in case the direction is 117dfdcada3SDoug Rabson * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 118dfdcada3SDoug Rabson * xdr_bool when the direction is XDR_DECODE. 119dfdcada3SDoug Rabson */ 120dfdcada3SDoug Rabson bool_t more_elements; 121dfdcada3SDoug Rabson int freeing = (xdrs->x_op == XDR_FREE); 122dfdcada3SDoug Rabson rpcblist_ptr next; 123dfdcada3SDoug Rabson rpcblist_ptr next_copy; 124dfdcada3SDoug Rabson 125dfdcada3SDoug Rabson next = NULL; 126dfdcada3SDoug Rabson for (;;) { 127dfdcada3SDoug Rabson more_elements = (bool_t)(*rp != NULL); 128dfdcada3SDoug Rabson if (! xdr_bool(xdrs, &more_elements)) { 129dfdcada3SDoug Rabson return (FALSE); 130dfdcada3SDoug Rabson } 131dfdcada3SDoug Rabson if (! more_elements) { 132dfdcada3SDoug Rabson return (TRUE); /* we are done */ 133dfdcada3SDoug Rabson } 134dfdcada3SDoug Rabson /* 135dfdcada3SDoug Rabson * the unfortunate side effect of non-recursion is that in 136dfdcada3SDoug Rabson * the case of freeing we must remember the next object 137dfdcada3SDoug Rabson * before we free the current object ... 138dfdcada3SDoug Rabson */ 139dfdcada3SDoug Rabson if (freeing && *rp) 140dfdcada3SDoug Rabson next = (*rp)->rpcb_next; 141dfdcada3SDoug Rabson if (! xdr_reference(xdrs, (caddr_t *)rp, 142dfdcada3SDoug Rabson (u_int)sizeof (RPCBLIST), (xdrproc_t)xdr_rpcb)) { 143dfdcada3SDoug Rabson return (FALSE); 144dfdcada3SDoug Rabson } 145dfdcada3SDoug Rabson if (freeing) { 146dfdcada3SDoug Rabson next_copy = next; 147dfdcada3SDoug Rabson rp = &next_copy; 148dfdcada3SDoug Rabson /* 149dfdcada3SDoug Rabson * Note that in the subsequent iteration, next_copy 150dfdcada3SDoug Rabson * gets nulled out by the xdr_reference 151dfdcada3SDoug Rabson * but next itself survives. 152dfdcada3SDoug Rabson */ 153dfdcada3SDoug Rabson } else if (*rp) { 154dfdcada3SDoug Rabson rp = &((*rp)->rpcb_next); 155dfdcada3SDoug Rabson } 156dfdcada3SDoug Rabson } 157dfdcada3SDoug Rabson /*NOTREACHED*/ 158dfdcada3SDoug Rabson } 159dfdcada3SDoug Rabson 160dfdcada3SDoug Rabson #if 0 161dfdcada3SDoug Rabson /* 162dfdcada3SDoug Rabson * xdr_rpcblist() is specified to take a RPCBLIST **, but is identical in 163dfdcada3SDoug Rabson * functionality to xdr_rpcblist_ptr(). 164dfdcada3SDoug Rabson */ 165dfdcada3SDoug Rabson bool_t 166dfdcada3SDoug Rabson xdr_rpcblist(XDR *xdrs, RPCBLIST **rp) 167dfdcada3SDoug Rabson { 168dfdcada3SDoug Rabson bool_t dummy; 169dfdcada3SDoug Rabson 170dfdcada3SDoug Rabson dummy = xdr_rpcblist_ptr(xdrs, (rpcblist_ptr *)rp); 171dfdcada3SDoug Rabson return (dummy); 172dfdcada3SDoug Rabson } 173dfdcada3SDoug Rabson #endif 174dfdcada3SDoug Rabson 175dfdcada3SDoug Rabson bool_t 176dfdcada3SDoug Rabson xdr_rpcb_entry(XDR *xdrs, rpcb_entry *objp) 177dfdcada3SDoug Rabson { 178dfdcada3SDoug Rabson if (!xdr_string(xdrs, &objp->r_maddr, (u_int)~0)) { 179dfdcada3SDoug Rabson return (FALSE); 180dfdcada3SDoug Rabson } 181dfdcada3SDoug Rabson if (!xdr_string(xdrs, &objp->r_nc_netid, (u_int)~0)) { 182dfdcada3SDoug Rabson return (FALSE); 183dfdcada3SDoug Rabson } 184dfdcada3SDoug Rabson if (!xdr_uint32_t(xdrs, &objp->r_nc_semantics)) { 185dfdcada3SDoug Rabson return (FALSE); 186dfdcada3SDoug Rabson } 187dfdcada3SDoug Rabson if (!xdr_string(xdrs, &objp->r_nc_protofmly, (u_int)~0)) { 188dfdcada3SDoug Rabson return (FALSE); 189dfdcada3SDoug Rabson } 190dfdcada3SDoug Rabson if (!xdr_string(xdrs, &objp->r_nc_proto, (u_int)~0)) { 191dfdcada3SDoug Rabson return (FALSE); 192dfdcada3SDoug Rabson } 193dfdcada3SDoug Rabson return (TRUE); 194dfdcada3SDoug Rabson } 195dfdcada3SDoug Rabson 196dfdcada3SDoug Rabson bool_t 197dfdcada3SDoug Rabson xdr_rpcb_entry_list_ptr(XDR *xdrs, rpcb_entry_list_ptr *rp) 198dfdcada3SDoug Rabson { 199dfdcada3SDoug Rabson /* 200dfdcada3SDoug Rabson * more_elements is pre-computed in case the direction is 201dfdcada3SDoug Rabson * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 202dfdcada3SDoug Rabson * xdr_bool when the direction is XDR_DECODE. 203dfdcada3SDoug Rabson */ 204dfdcada3SDoug Rabson bool_t more_elements; 205dfdcada3SDoug Rabson int freeing = (xdrs->x_op == XDR_FREE); 206dfdcada3SDoug Rabson rpcb_entry_list_ptr next; 207dfdcada3SDoug Rabson rpcb_entry_list_ptr next_copy; 208dfdcada3SDoug Rabson 209dfdcada3SDoug Rabson next = NULL; 210dfdcada3SDoug Rabson for (;;) { 211dfdcada3SDoug Rabson more_elements = (bool_t)(*rp != NULL); 212dfdcada3SDoug Rabson if (! xdr_bool(xdrs, &more_elements)) { 213dfdcada3SDoug Rabson return (FALSE); 214dfdcada3SDoug Rabson } 215dfdcada3SDoug Rabson if (! more_elements) { 216dfdcada3SDoug Rabson return (TRUE); /* we are done */ 217dfdcada3SDoug Rabson } 218dfdcada3SDoug Rabson /* 219dfdcada3SDoug Rabson * the unfortunate side effect of non-recursion is that in 220dfdcada3SDoug Rabson * the case of freeing we must remember the next object 221dfdcada3SDoug Rabson * before we free the current object ... 222dfdcada3SDoug Rabson */ 223dfdcada3SDoug Rabson if (freeing) 224dfdcada3SDoug Rabson next = (*rp)->rpcb_entry_next; 225dfdcada3SDoug Rabson if (! xdr_reference(xdrs, (caddr_t *)rp, 226dfdcada3SDoug Rabson (u_int)sizeof (rpcb_entry_list), 227dfdcada3SDoug Rabson (xdrproc_t)xdr_rpcb_entry)) { 228dfdcada3SDoug Rabson return (FALSE); 229dfdcada3SDoug Rabson } 230dfdcada3SDoug Rabson if (freeing && *rp) { 231dfdcada3SDoug Rabson next_copy = next; 232dfdcada3SDoug Rabson rp = &next_copy; 233dfdcada3SDoug Rabson /* 234dfdcada3SDoug Rabson * Note that in the subsequent iteration, next_copy 235dfdcada3SDoug Rabson * gets nulled out by the xdr_reference 236dfdcada3SDoug Rabson * but next itself survives. 237dfdcada3SDoug Rabson */ 238dfdcada3SDoug Rabson } else if (*rp) { 239dfdcada3SDoug Rabson rp = &((*rp)->rpcb_entry_next); 240dfdcada3SDoug Rabson } 241dfdcada3SDoug Rabson } 242dfdcada3SDoug Rabson /*NOTREACHED*/ 243dfdcada3SDoug Rabson } 244