174462Salfred/* $NetBSD: rpcb_prot.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ 274462Salfred 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. 1774462Salfred * 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. 2974462Salfred */ 3074462Salfred/* 3174462Salfred * Copyright (c) 1986-1991 by Sun Microsystems Inc. 3274462Salfred */ 3374462Salfred 3474462Salfred/* #ident "@(#)rpcb_prot.c 1.13 94/04/24 SMI" */ 3574462Salfred 36136581Sobrien#if defined(LIBC_SCCS) && !defined(lint) 3774462Salfredstatic char sccsid[] = "@(#)rpcb_prot.c 1.9 89/04/21 Copyr 1984 Sun Micro"; 3874462Salfred#endif 3992990Sobrien#include <sys/cdefs.h> 4092990Sobrien__FBSDID("$FreeBSD$"); 4174462Salfred 4274462Salfred/* 4374462Salfred * rpcb_prot.c 4474462Salfred * XDR routines for the rpcbinder version 3. 4574462Salfred * 4674462Salfred * Copyright (C) 1984, 1988, Sun Microsystems, Inc. 4774462Salfred */ 4874462Salfred 4974462Salfred#include "namespace.h" 5074462Salfred#include <rpc/rpc.h> 5174462Salfred#include <rpc/types.h> 5274462Salfred#include <rpc/xdr.h> 5374462Salfred#include <rpc/rpcb_prot.h> 5474462Salfred#include "un-namespace.h" 5574462Salfred 5674462Salfredbool_t 5774462Salfredxdr_rpcb(xdrs, objp) 5874462Salfred XDR *xdrs; 5974462Salfred RPCB *objp; 6074462Salfred{ 6174462Salfred if (!xdr_u_int32_t(xdrs, &objp->r_prog)) { 6274462Salfred return (FALSE); 6374462Salfred } 6474462Salfred if (!xdr_u_int32_t(xdrs, &objp->r_vers)) { 6574462Salfred return (FALSE); 6674462Salfred } 6774462Salfred if (!xdr_string(xdrs, &objp->r_netid, (u_int)~0)) { 6874462Salfred return (FALSE); 6974462Salfred } 7074462Salfred if (!xdr_string(xdrs, &objp->r_addr, (u_int)~0)) { 7174462Salfred return (FALSE); 7274462Salfred } 7374462Salfred if (!xdr_string(xdrs, &objp->r_owner, (u_int)~0)) { 7474462Salfred return (FALSE); 7574462Salfred } 7674462Salfred return (TRUE); 7774462Salfred} 7874462Salfred 7974462Salfred/* 8074462Salfred * rpcblist_ptr implements a linked list. The RPCL definition from 8174462Salfred * rpcb_prot.x is: 8274462Salfred * 8374462Salfred * struct rpcblist { 8474462Salfred * rpcb rpcb_map; 8574462Salfred * struct rpcblist *rpcb_next; 8674462Salfred * }; 8774462Salfred * typedef rpcblist *rpcblist_ptr; 8874462Salfred * 8974462Salfred * Recall that "pointers" in XDR are encoded as a boolean, indicating whether 9074462Salfred * there's any data behind the pointer, followed by the data (if any exists). 9174462Salfred * The boolean can be interpreted as ``more data follows me''; if FALSE then 9274462Salfred * nothing follows the boolean; if TRUE then the boolean is followed by an 9374462Salfred * actual struct rpcb, and another rpcblist_ptr (declared in RPCL as "struct 9474462Salfred * rpcblist *"). 9574462Salfred * 9674462Salfred * This could be implemented via the xdr_pointer type, though this would 9774462Salfred * result in one recursive call per element in the list. Rather than do that 9874462Salfred * we can ``unwind'' the recursion into a while loop and use xdr_reference to 9974462Salfred * serialize the rpcb elements. 10074462Salfred */ 10174462Salfred 10274462Salfredbool_t 10374462Salfredxdr_rpcblist_ptr(xdrs, rp) 10474462Salfred XDR *xdrs; 10574462Salfred rpcblist_ptr *rp; 10674462Salfred{ 10774462Salfred /* 10874462Salfred * more_elements is pre-computed in case the direction is 10974462Salfred * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 11074462Salfred * xdr_bool when the direction is XDR_DECODE. 11174462Salfred */ 11274462Salfred bool_t more_elements; 11374462Salfred int freeing = (xdrs->x_op == XDR_FREE); 11474462Salfred rpcblist_ptr next; 11574462Salfred rpcblist_ptr next_copy; 11674462Salfred 11790271Salfred next = NULL; 11874462Salfred for (;;) { 11974462Salfred more_elements = (bool_t)(*rp != NULL); 12074462Salfred if (! xdr_bool(xdrs, &more_elements)) { 12174462Salfred return (FALSE); 12274462Salfred } 12374462Salfred if (! more_elements) { 12474462Salfred return (TRUE); /* we are done */ 12574462Salfred } 12674462Salfred /* 12774462Salfred * the unfortunate side effect of non-recursion is that in 12874462Salfred * the case of freeing we must remember the next object 12974462Salfred * before we free the current object ... 13074462Salfred */ 131162194Smbr if (freeing && *rp) 13274462Salfred next = (*rp)->rpcb_next; 13374462Salfred if (! xdr_reference(xdrs, (caddr_t *)rp, 13474462Salfred (u_int)sizeof (rpcblist), (xdrproc_t)xdr_rpcb)) { 13574462Salfred return (FALSE); 13674462Salfred } 13774462Salfred if (freeing) { 13874462Salfred next_copy = next; 13974462Salfred rp = &next_copy; 14074462Salfred /* 14174462Salfred * Note that in the subsequent iteration, next_copy 14274462Salfred * gets nulled out by the xdr_reference 14374462Salfred * but next itself survives. 14474462Salfred */ 145162194Smbr } else if (*rp) { 14674462Salfred rp = &((*rp)->rpcb_next); 14774462Salfred } 14874462Salfred } 14974462Salfred /*NOTREACHED*/ 15074462Salfred} 15174462Salfred 15274462Salfred/* 15374462Salfred * xdr_rpcblist() is specified to take a RPCBLIST **, but is identical in 15474462Salfred * functionality to xdr_rpcblist_ptr(). 15574462Salfred */ 15674462Salfredbool_t 15774462Salfredxdr_rpcblist(xdrs, rp) 15874462Salfred XDR *xdrs; 15974462Salfred RPCBLIST **rp; 16074462Salfred{ 16174462Salfred bool_t dummy; 16274462Salfred 16374462Salfred dummy = xdr_rpcblist_ptr(xdrs, (rpcblist_ptr *)rp); 16474462Salfred return (dummy); 16574462Salfred} 16674462Salfred 16774462Salfred 16874462Salfredbool_t 16974462Salfredxdr_rpcb_entry(xdrs, objp) 17074462Salfred XDR *xdrs; 17174462Salfred rpcb_entry *objp; 17274462Salfred{ 17374462Salfred if (!xdr_string(xdrs, &objp->r_maddr, (u_int)~0)) { 17474462Salfred return (FALSE); 17574462Salfred } 17674462Salfred if (!xdr_string(xdrs, &objp->r_nc_netid, (u_int)~0)) { 17774462Salfred return (FALSE); 17874462Salfred } 17974462Salfred if (!xdr_u_int32_t(xdrs, &objp->r_nc_semantics)) { 18074462Salfred return (FALSE); 18174462Salfred } 18274462Salfred if (!xdr_string(xdrs, &objp->r_nc_protofmly, (u_int)~0)) { 18374462Salfred return (FALSE); 18474462Salfred } 18574462Salfred if (!xdr_string(xdrs, &objp->r_nc_proto, (u_int)~0)) { 18674462Salfred return (FALSE); 18774462Salfred } 18874462Salfred return (TRUE); 18974462Salfred} 19074462Salfred 19174462Salfredbool_t 19274462Salfredxdr_rpcb_entry_list_ptr(xdrs, rp) 19374462Salfred XDR *xdrs; 19474462Salfred rpcb_entry_list_ptr *rp; 19574462Salfred{ 19674462Salfred /* 19774462Salfred * more_elements is pre-computed in case the direction is 19874462Salfred * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 19974462Salfred * xdr_bool when the direction is XDR_DECODE. 20074462Salfred */ 20174462Salfred bool_t more_elements; 20274462Salfred int freeing = (xdrs->x_op == XDR_FREE); 20374462Salfred rpcb_entry_list_ptr next; 20474462Salfred rpcb_entry_list_ptr next_copy; 20574462Salfred 20690271Salfred next = NULL; 20774462Salfred for (;;) { 20874462Salfred more_elements = (bool_t)(*rp != NULL); 20974462Salfred if (! xdr_bool(xdrs, &more_elements)) { 21074462Salfred return (FALSE); 21174462Salfred } 21274462Salfred if (! more_elements) { 21374462Salfred return (TRUE); /* we are done */ 21474462Salfred } 21574462Salfred /* 21674462Salfred * the unfortunate side effect of non-recursion is that in 21774462Salfred * the case of freeing we must remember the next object 21874462Salfred * before we free the current object ... 21974462Salfred */ 22074462Salfred if (freeing) 22174462Salfred next = (*rp)->rpcb_entry_next; 22274462Salfred if (! xdr_reference(xdrs, (caddr_t *)rp, 22374462Salfred (u_int)sizeof (rpcb_entry_list), 22474462Salfred (xdrproc_t)xdr_rpcb_entry)) { 22574462Salfred return (FALSE); 22674462Salfred } 227162194Smbr if (freeing && *rp) { 22874462Salfred next_copy = next; 22974462Salfred rp = &next_copy; 23074462Salfred /* 23174462Salfred * Note that in the subsequent iteration, next_copy 23274462Salfred * gets nulled out by the xdr_reference 23374462Salfred * but next itself survives. 23474462Salfred */ 235162194Smbr } else if (*rp) { 23674462Salfred rp = &((*rp)->rpcb_entry_next); 23774462Salfred } 23874462Salfred } 23974462Salfred /*NOTREACHED*/ 24074462Salfred} 24174462Salfred 24274462Salfred/* 24374462Salfred * XDR remote call arguments 24474462Salfred * written for XDR_ENCODE direction only 24574462Salfred */ 24674462Salfredbool_t 24774462Salfredxdr_rpcb_rmtcallargs(xdrs, p) 24874462Salfred XDR *xdrs; 24974462Salfred struct rpcb_rmtcallargs *p; 25074462Salfred{ 25174462Salfred struct r_rpcb_rmtcallargs *objp = 25274462Salfred (struct r_rpcb_rmtcallargs *)(void *)p; 25374462Salfred u_int lenposition, argposition, position; 25474462Salfred int32_t *buf; 25574462Salfred 25674462Salfred buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT); 25774462Salfred if (buf == NULL) { 25874462Salfred if (!xdr_u_int32_t(xdrs, &objp->prog)) { 25974462Salfred return (FALSE); 26074462Salfred } 26174462Salfred if (!xdr_u_int32_t(xdrs, &objp->vers)) { 26274462Salfred return (FALSE); 26374462Salfred } 26474462Salfred if (!xdr_u_int32_t(xdrs, &objp->proc)) { 26574462Salfred return (FALSE); 26674462Salfred } 26774462Salfred } else { 26874462Salfred IXDR_PUT_U_INT32(buf, objp->prog); 26974462Salfred IXDR_PUT_U_INT32(buf, objp->vers); 27074462Salfred IXDR_PUT_U_INT32(buf, objp->proc); 27174462Salfred } 27274462Salfred 27374462Salfred /* 27474462Salfred * All the jugglery for just getting the size of the arguments 27574462Salfred */ 27674462Salfred lenposition = XDR_GETPOS(xdrs); 27774462Salfred if (! xdr_u_int(xdrs, &(objp->args.args_len))) { 27874462Salfred return (FALSE); 27974462Salfred } 28074462Salfred argposition = XDR_GETPOS(xdrs); 28174462Salfred if (! (*objp->xdr_args)(xdrs, objp->args.args_val)) { 28274462Salfred return (FALSE); 28374462Salfred } 28474462Salfred position = XDR_GETPOS(xdrs); 28574462Salfred objp->args.args_len = (u_int)((u_long)position - (u_long)argposition); 28674462Salfred XDR_SETPOS(xdrs, lenposition); 28774462Salfred if (! xdr_u_int(xdrs, &(objp->args.args_len))) { 28874462Salfred return (FALSE); 28974462Salfred } 29074462Salfred XDR_SETPOS(xdrs, position); 29174462Salfred return (TRUE); 29274462Salfred} 29374462Salfred 29474462Salfred/* 29574462Salfred * XDR remote call results 29674462Salfred * written for XDR_DECODE direction only 29774462Salfred */ 29874462Salfredbool_t 29974462Salfredxdr_rpcb_rmtcallres(xdrs, p) 30074462Salfred XDR *xdrs; 30174462Salfred struct rpcb_rmtcallres *p; 30274462Salfred{ 30374462Salfred bool_t dummy; 30474462Salfred struct r_rpcb_rmtcallres *objp = (struct r_rpcb_rmtcallres *)(void *)p; 30574462Salfred 30674462Salfred if (!xdr_string(xdrs, &objp->addr, (u_int)~0)) { 30774462Salfred return (FALSE); 30874462Salfred } 30974462Salfred if (!xdr_u_int(xdrs, &objp->results.results_len)) { 31074462Salfred return (FALSE); 31174462Salfred } 31274462Salfred dummy = (*(objp->xdr_res))(xdrs, objp->results.results_val); 31374462Salfred return (dummy); 31474462Salfred} 31574462Salfred 31674462Salfredbool_t 31774462Salfredxdr_netbuf(xdrs, objp) 31874462Salfred XDR *xdrs; 31974462Salfred struct netbuf *objp; 32074462Salfred{ 32174462Salfred bool_t dummy; 322173763Sjb void **pp; 32374462Salfred 32474462Salfred if (!xdr_u_int32_t(xdrs, (u_int32_t *) &objp->maxlen)) { 32574462Salfred return (FALSE); 32674462Salfred } 327173763Sjb pp = &objp->buf; 328173763Sjb dummy = xdr_bytes(xdrs, (char **) pp, 32974462Salfred (u_int *)&(objp->len), objp->maxlen); 33074462Salfred return (dummy); 33174462Salfred} 332