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