1177633Sdfr/* $NetBSD: rpcb_prot.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ 2177633Sdfr 3261046Smav/*- 4261046Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261046Smav * All rights reserved. 6261046Smav * 7261046Smav * Redistribution and use in source and binary forms, with or without 8261046Smav * modification, are permitted provided that the following conditions are met: 9261046Smav * - Redistributions of source code must retain the above copyright notice, 10261046Smav * this list of conditions and the following disclaimer. 11261046Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261046Smav * this list of conditions and the following disclaimer in the documentation 13261046Smav * and/or other materials provided with the distribution. 14261046Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261046Smav * contributors may be used to endorse or promote products derived 16261046Smav * from this software without specific prior written permission. 17177633Sdfr * 18261046Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261046Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261046Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261046Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261046Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261046Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261046Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261046Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261046Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261046Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261046Smav * POSSIBILITY OF SUCH DAMAGE. 29177633Sdfr */ 30177633Sdfr/* 31177633Sdfr * Copyright (c) 1986-1991 by Sun Microsystems Inc. 32177633Sdfr */ 33177633Sdfr 34177633Sdfr/* #ident "@(#)rpcb_prot.c 1.13 94/04/24 SMI" */ 35177633Sdfr 36177633Sdfr#if defined(LIBC_SCCS) && !defined(lint) 37177633Sdfrstatic char sccsid[] = "@(#)rpcb_prot.c 1.9 89/04/21 Copyr 1984 Sun Micro"; 38177633Sdfr#endif 39177633Sdfr#include <sys/cdefs.h> 40177633Sdfr__FBSDID("$FreeBSD: stable/10/sys/rpc/rpcb_prot.c 319615 2017-06-06 07:22:26Z delphij $"); 41177633Sdfr 42177633Sdfr/* 43177633Sdfr * rpcb_prot.c 44177633Sdfr * XDR routines for the rpcbinder version 3. 45177633Sdfr * 46177633Sdfr * Copyright (C) 1984, 1988, Sun Microsystems, Inc. 47177633Sdfr */ 48177633Sdfr 49177633Sdfr#include <sys/param.h> 50177633Sdfr#include <sys/systm.h> 51177633Sdfr#include <sys/kernel.h> 52177633Sdfr#include <sys/malloc.h> 53177633Sdfr 54177633Sdfr#include <rpc/rpc.h> 55319615Sdelphij#include <rpc/rpc_com.h> 56177633Sdfr#include <rpc/rpcb_prot.h> 57177633Sdfr 58177633Sdfrbool_t 59182154Sdfrxdr_portmap(XDR *xdrs, struct portmap *regs) 60177633Sdfr{ 61177633Sdfr 62177633Sdfr if (xdr_u_long(xdrs, ®s->pm_prog) && 63177633Sdfr xdr_u_long(xdrs, ®s->pm_vers) && 64177633Sdfr xdr_u_long(xdrs, ®s->pm_prot)) 65177633Sdfr return (xdr_u_long(xdrs, ®s->pm_port)); 66177633Sdfr return (FALSE); 67177633Sdfr} 68177633Sdfr 69177633Sdfrbool_t 70177633Sdfrxdr_rpcb(XDR *xdrs, RPCB *objp) 71177633Sdfr{ 72177633Sdfr if (!xdr_uint32_t(xdrs, &objp->r_prog)) { 73177633Sdfr return (FALSE); 74177633Sdfr } 75177633Sdfr if (!xdr_uint32_t(xdrs, &objp->r_vers)) { 76177633Sdfr return (FALSE); 77177633Sdfr } 78319615Sdelphij if (!xdr_string(xdrs, &objp->r_netid, RPC_MAXDATASIZE)) { 79177633Sdfr return (FALSE); 80177633Sdfr } 81319615Sdelphij if (!xdr_string(xdrs, &objp->r_addr, RPC_MAXDATASIZE)) { 82177633Sdfr return (FALSE); 83177633Sdfr } 84319615Sdelphij if (!xdr_string(xdrs, &objp->r_owner, RPC_MAXDATASIZE)) { 85177633Sdfr return (FALSE); 86177633Sdfr } 87177633Sdfr return (TRUE); 88177633Sdfr} 89177633Sdfr 90177633Sdfr/* 91177633Sdfr * rpcblist_ptr implements a linked list. The RPCL definition from 92177633Sdfr * rpcb_prot.x is: 93177633Sdfr * 94177633Sdfr * struct rpcblist { 95177633Sdfr * rpcb rpcb_map; 96177633Sdfr * struct rpcblist *rpcb_next; 97177633Sdfr * }; 98177633Sdfr * typedef rpcblist *rpcblist_ptr; 99177633Sdfr * 100177633Sdfr * Recall that "pointers" in XDR are encoded as a boolean, indicating whether 101177633Sdfr * there's any data behind the pointer, followed by the data (if any exists). 102177633Sdfr * The boolean can be interpreted as ``more data follows me''; if FALSE then 103177633Sdfr * nothing follows the boolean; if TRUE then the boolean is followed by an 104177633Sdfr * actual struct rpcb, and another rpcblist_ptr (declared in RPCL as "struct 105177633Sdfr * rpcblist *"). 106177633Sdfr * 107177633Sdfr * This could be implemented via the xdr_pointer type, though this would 108177633Sdfr * result in one recursive call per element in the list. Rather than do that 109177633Sdfr * we can ``unwind'' the recursion into a while loop and use xdr_reference to 110177633Sdfr * serialize the rpcb elements. 111177633Sdfr */ 112177633Sdfr 113177633Sdfrbool_t 114177633Sdfrxdr_rpcblist_ptr(XDR *xdrs, rpcblist_ptr *rp) 115177633Sdfr{ 116177633Sdfr /* 117177633Sdfr * more_elements is pre-computed in case the direction is 118177633Sdfr * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 119177633Sdfr * xdr_bool when the direction is XDR_DECODE. 120177633Sdfr */ 121177633Sdfr bool_t more_elements; 122177633Sdfr int freeing = (xdrs->x_op == XDR_FREE); 123177633Sdfr rpcblist_ptr next; 124177633Sdfr rpcblist_ptr next_copy; 125177633Sdfr 126177633Sdfr next = NULL; 127177633Sdfr for (;;) { 128177633Sdfr more_elements = (bool_t)(*rp != NULL); 129177633Sdfr if (! xdr_bool(xdrs, &more_elements)) { 130177633Sdfr return (FALSE); 131177633Sdfr } 132177633Sdfr if (! more_elements) { 133177633Sdfr return (TRUE); /* we are done */ 134177633Sdfr } 135177633Sdfr /* 136177633Sdfr * the unfortunate side effect of non-recursion is that in 137177633Sdfr * the case of freeing we must remember the next object 138177633Sdfr * before we free the current object ... 139177633Sdfr */ 140177633Sdfr if (freeing && *rp) 141177633Sdfr next = (*rp)->rpcb_next; 142177633Sdfr if (! xdr_reference(xdrs, (caddr_t *)rp, 143177633Sdfr (u_int)sizeof (RPCBLIST), (xdrproc_t)xdr_rpcb)) { 144177633Sdfr return (FALSE); 145177633Sdfr } 146177633Sdfr if (freeing) { 147177633Sdfr next_copy = next; 148177633Sdfr rp = &next_copy; 149177633Sdfr /* 150177633Sdfr * Note that in the subsequent iteration, next_copy 151177633Sdfr * gets nulled out by the xdr_reference 152177633Sdfr * but next itself survives. 153177633Sdfr */ 154177633Sdfr } else if (*rp) { 155177633Sdfr rp = &((*rp)->rpcb_next); 156177633Sdfr } 157177633Sdfr } 158177633Sdfr /*NOTREACHED*/ 159177633Sdfr} 160177633Sdfr 161177633Sdfr#if 0 162177633Sdfr/* 163177633Sdfr * xdr_rpcblist() is specified to take a RPCBLIST **, but is identical in 164177633Sdfr * functionality to xdr_rpcblist_ptr(). 165177633Sdfr */ 166177633Sdfrbool_t 167177633Sdfrxdr_rpcblist(XDR *xdrs, RPCBLIST **rp) 168177633Sdfr{ 169177633Sdfr bool_t dummy; 170177633Sdfr 171177633Sdfr dummy = xdr_rpcblist_ptr(xdrs, (rpcblist_ptr *)rp); 172177633Sdfr return (dummy); 173177633Sdfr} 174177633Sdfr#endif 175177633Sdfr 176177633Sdfrbool_t 177177633Sdfrxdr_rpcb_entry(XDR *xdrs, rpcb_entry *objp) 178177633Sdfr{ 179319615Sdelphij if (!xdr_string(xdrs, &objp->r_maddr, RPC_MAXDATASIZE)) { 180177633Sdfr return (FALSE); 181177633Sdfr } 182319615Sdelphij if (!xdr_string(xdrs, &objp->r_nc_netid, RPC_MAXDATASIZE)) { 183177633Sdfr return (FALSE); 184177633Sdfr } 185177633Sdfr if (!xdr_uint32_t(xdrs, &objp->r_nc_semantics)) { 186177633Sdfr return (FALSE); 187177633Sdfr } 188319615Sdelphij if (!xdr_string(xdrs, &objp->r_nc_protofmly, RPC_MAXDATASIZE)) { 189177633Sdfr return (FALSE); 190177633Sdfr } 191319615Sdelphij if (!xdr_string(xdrs, &objp->r_nc_proto, RPC_MAXDATASIZE)) { 192177633Sdfr return (FALSE); 193177633Sdfr } 194177633Sdfr return (TRUE); 195177633Sdfr} 196177633Sdfr 197177633Sdfrbool_t 198177633Sdfrxdr_rpcb_entry_list_ptr(XDR *xdrs, rpcb_entry_list_ptr *rp) 199177633Sdfr{ 200177633Sdfr /* 201177633Sdfr * more_elements is pre-computed in case the direction is 202177633Sdfr * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 203177633Sdfr * xdr_bool when the direction is XDR_DECODE. 204177633Sdfr */ 205177633Sdfr bool_t more_elements; 206177633Sdfr int freeing = (xdrs->x_op == XDR_FREE); 207177633Sdfr rpcb_entry_list_ptr next; 208177633Sdfr rpcb_entry_list_ptr next_copy; 209177633Sdfr 210177633Sdfr next = NULL; 211177633Sdfr for (;;) { 212177633Sdfr more_elements = (bool_t)(*rp != NULL); 213177633Sdfr if (! xdr_bool(xdrs, &more_elements)) { 214177633Sdfr return (FALSE); 215177633Sdfr } 216177633Sdfr if (! more_elements) { 217177633Sdfr return (TRUE); /* we are done */ 218177633Sdfr } 219177633Sdfr /* 220177633Sdfr * the unfortunate side effect of non-recursion is that in 221177633Sdfr * the case of freeing we must remember the next object 222177633Sdfr * before we free the current object ... 223177633Sdfr */ 224177633Sdfr if (freeing) 225177633Sdfr next = (*rp)->rpcb_entry_next; 226177633Sdfr if (! xdr_reference(xdrs, (caddr_t *)rp, 227177633Sdfr (u_int)sizeof (rpcb_entry_list), 228177633Sdfr (xdrproc_t)xdr_rpcb_entry)) { 229177633Sdfr return (FALSE); 230177633Sdfr } 231177633Sdfr if (freeing && *rp) { 232177633Sdfr next_copy = next; 233177633Sdfr rp = &next_copy; 234177633Sdfr /* 235177633Sdfr * Note that in the subsequent iteration, next_copy 236177633Sdfr * gets nulled out by the xdr_reference 237177633Sdfr * but next itself survives. 238177633Sdfr */ 239177633Sdfr } else if (*rp) { 240177633Sdfr rp = &((*rp)->rpcb_entry_next); 241177633Sdfr } 242177633Sdfr } 243177633Sdfr /*NOTREACHED*/ 244177633Sdfr} 245