rpcb_prot.c revision 90271
174462Salfred/*	$NetBSD: rpcb_prot.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $	*/
274462Salfred/*	$FreeBSD: head/lib/libc/rpc/rpcb_prot.c 90271 2002-02-05 23:43:43Z alfred $ */
374462Salfred
474462Salfred/*
574462Salfred * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
674462Salfred * unrestricted use provided that this legend is included on all tape
774462Salfred * media and as a part of the software program in whole or part.  Users
874462Salfred * may copy or modify Sun RPC without charge, but are not authorized
974462Salfred * to license or distribute it to anyone else except as part of a product or
1074462Salfred * program developed by the user.
1174462Salfred *
1274462Salfred * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1374462Salfred * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1474462Salfred * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1574462Salfred *
1674462Salfred * Sun RPC is provided with no support and without any obligation on the
1774462Salfred * part of Sun Microsystems, Inc. to assist in its use, correction,
1874462Salfred * modification or enhancement.
1974462Salfred *
2074462Salfred * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
2174462Salfred * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
2274462Salfred * OR ANY PART THEREOF.
2374462Salfred *
2474462Salfred * In no event will Sun Microsystems, Inc. be liable for any lost revenue
2574462Salfred * or profits or other special, indirect and consequential damages, even if
2674462Salfred * Sun has been advised of the possibility of such damages.
2774462Salfred *
2874462Salfred * Sun Microsystems, Inc.
2974462Salfred * 2550 Garcia Avenue
3074462Salfred * Mountain View, California  94043
3174462Salfred */
3274462Salfred/*
3374462Salfred * Copyright (c) 1986-1991 by Sun Microsystems Inc.
3474462Salfred */
3574462Salfred
3674462Salfred/* #ident	"@(#)rpcb_prot.c	1.13	94/04/24 SMI" */
3774462Salfred
3874462Salfred#if 0
3974462Salfred#if !defined(lint) && defined(SCCSIDS)
4074462Salfredstatic char sccsid[] = "@(#)rpcb_prot.c 1.9 89/04/21 Copyr 1984 Sun Micro";
4174462Salfred#endif
4274462Salfred#endif
4374462Salfred
4474462Salfred/*
4574462Salfred * rpcb_prot.c
4674462Salfred * XDR routines for the rpcbinder version 3.
4774462Salfred *
4874462Salfred * Copyright (C) 1984, 1988, Sun Microsystems, Inc.
4974462Salfred */
5074462Salfred
5174462Salfred#include "namespace.h"
5274462Salfred#include <rpc/rpc.h>
5374462Salfred#include <rpc/types.h>
5474462Salfred#include <rpc/xdr.h>
5574462Salfred#include <rpc/rpcb_prot.h>
5674462Salfred#include "un-namespace.h"
5774462Salfred
5874462Salfredbool_t
5974462Salfredxdr_rpcb(xdrs, objp)
6074462Salfred	XDR *xdrs;
6174462Salfred	RPCB *objp;
6274462Salfred{
6374462Salfred	if (!xdr_u_int32_t(xdrs, &objp->r_prog)) {
6474462Salfred		return (FALSE);
6574462Salfred	}
6674462Salfred	if (!xdr_u_int32_t(xdrs, &objp->r_vers)) {
6774462Salfred		return (FALSE);
6874462Salfred	}
6974462Salfred	if (!xdr_string(xdrs, &objp->r_netid, (u_int)~0)) {
7074462Salfred		return (FALSE);
7174462Salfred	}
7274462Salfred	if (!xdr_string(xdrs, &objp->r_addr, (u_int)~0)) {
7374462Salfred		return (FALSE);
7474462Salfred	}
7574462Salfred	if (!xdr_string(xdrs, &objp->r_owner, (u_int)~0)) {
7674462Salfred		return (FALSE);
7774462Salfred	}
7874462Salfred	return (TRUE);
7974462Salfred}
8074462Salfred
8174462Salfred/*
8274462Salfred * rpcblist_ptr implements a linked list.  The RPCL definition from
8374462Salfred * rpcb_prot.x is:
8474462Salfred *
8574462Salfred * struct rpcblist {
8674462Salfred * 	rpcb		rpcb_map;
8774462Salfred *	struct rpcblist *rpcb_next;
8874462Salfred * };
8974462Salfred * typedef rpcblist *rpcblist_ptr;
9074462Salfred *
9174462Salfred * Recall that "pointers" in XDR are encoded as a boolean, indicating whether
9274462Salfred * there's any data behind the pointer, followed by the data (if any exists).
9374462Salfred * The boolean can be interpreted as ``more data follows me''; if FALSE then
9474462Salfred * nothing follows the boolean; if TRUE then the boolean is followed by an
9574462Salfred * actual struct rpcb, and another rpcblist_ptr (declared in RPCL as "struct
9674462Salfred * rpcblist *").
9774462Salfred *
9874462Salfred * This could be implemented via the xdr_pointer type, though this would
9974462Salfred * result in one recursive call per element in the list.  Rather than do that
10074462Salfred * we can ``unwind'' the recursion into a while loop and use xdr_reference to
10174462Salfred * serialize the rpcb elements.
10274462Salfred */
10374462Salfred
10474462Salfredbool_t
10574462Salfredxdr_rpcblist_ptr(xdrs, rp)
10674462Salfred	XDR *xdrs;
10774462Salfred	rpcblist_ptr *rp;
10874462Salfred{
10974462Salfred	/*
11074462Salfred	 * more_elements is pre-computed in case the direction is
11174462Salfred	 * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
11274462Salfred	 * xdr_bool when the direction is XDR_DECODE.
11374462Salfred	 */
11474462Salfred	bool_t more_elements;
11574462Salfred	int freeing = (xdrs->x_op == XDR_FREE);
11674462Salfred	rpcblist_ptr next;
11774462Salfred	rpcblist_ptr next_copy;
11874462Salfred
11990271Salfred	next = NULL;
12074462Salfred	for (;;) {
12174462Salfred		more_elements = (bool_t)(*rp != NULL);
12274462Salfred		if (! xdr_bool(xdrs, &more_elements)) {
12374462Salfred			return (FALSE);
12474462Salfred		}
12574462Salfred		if (! more_elements) {
12674462Salfred			return (TRUE);  /* we are done */
12774462Salfred		}
12874462Salfred		/*
12974462Salfred		 * the unfortunate side effect of non-recursion is that in
13074462Salfred		 * the case of freeing we must remember the next object
13174462Salfred		 * before we free the current object ...
13274462Salfred		 */
13374462Salfred		if (freeing)
13474462Salfred			next = (*rp)->rpcb_next;
13574462Salfred		if (! xdr_reference(xdrs, (caddr_t *)rp,
13674462Salfred		    (u_int)sizeof (rpcblist), (xdrproc_t)xdr_rpcb)) {
13774462Salfred			return (FALSE);
13874462Salfred		}
13974462Salfred		if (freeing) {
14074462Salfred			next_copy = next;
14174462Salfred			rp = &next_copy;
14274462Salfred			/*
14374462Salfred			 * Note that in the subsequent iteration, next_copy
14474462Salfred			 * gets nulled out by the xdr_reference
14574462Salfred			 * but next itself survives.
14674462Salfred			 */
14774462Salfred		} else {
14874462Salfred			rp = &((*rp)->rpcb_next);
14974462Salfred		}
15074462Salfred	}
15174462Salfred	/*NOTREACHED*/
15274462Salfred}
15374462Salfred
15474462Salfred/*
15574462Salfred * xdr_rpcblist() is specified to take a RPCBLIST **, but is identical in
15674462Salfred * functionality to xdr_rpcblist_ptr().
15774462Salfred */
15874462Salfredbool_t
15974462Salfredxdr_rpcblist(xdrs, rp)
16074462Salfred	XDR *xdrs;
16174462Salfred	RPCBLIST **rp;
16274462Salfred{
16374462Salfred	bool_t	dummy;
16474462Salfred
16574462Salfred	dummy = xdr_rpcblist_ptr(xdrs, (rpcblist_ptr *)rp);
16674462Salfred	return (dummy);
16774462Salfred}
16874462Salfred
16974462Salfred
17074462Salfredbool_t
17174462Salfredxdr_rpcb_entry(xdrs, objp)
17274462Salfred	XDR *xdrs;
17374462Salfred	rpcb_entry *objp;
17474462Salfred{
17574462Salfred	if (!xdr_string(xdrs, &objp->r_maddr, (u_int)~0)) {
17674462Salfred		return (FALSE);
17774462Salfred	}
17874462Salfred	if (!xdr_string(xdrs, &objp->r_nc_netid, (u_int)~0)) {
17974462Salfred		return (FALSE);
18074462Salfred	}
18174462Salfred	if (!xdr_u_int32_t(xdrs, &objp->r_nc_semantics)) {
18274462Salfred		return (FALSE);
18374462Salfred	}
18474462Salfred	if (!xdr_string(xdrs, &objp->r_nc_protofmly, (u_int)~0)) {
18574462Salfred		return (FALSE);
18674462Salfred	}
18774462Salfred	if (!xdr_string(xdrs, &objp->r_nc_proto, (u_int)~0)) {
18874462Salfred		return (FALSE);
18974462Salfred	}
19074462Salfred	return (TRUE);
19174462Salfred}
19274462Salfred
19374462Salfredbool_t
19474462Salfredxdr_rpcb_entry_list_ptr(xdrs, rp)
19574462Salfred	XDR *xdrs;
19674462Salfred	rpcb_entry_list_ptr *rp;
19774462Salfred{
19874462Salfred	/*
19974462Salfred	 * more_elements is pre-computed in case the direction is
20074462Salfred	 * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
20174462Salfred	 * xdr_bool when the direction is XDR_DECODE.
20274462Salfred	 */
20374462Salfred	bool_t more_elements;
20474462Salfred	int freeing = (xdrs->x_op == XDR_FREE);
20574462Salfred	rpcb_entry_list_ptr next;
20674462Salfred	rpcb_entry_list_ptr next_copy;
20774462Salfred
20890271Salfred	next = NULL;
20974462Salfred	for (;;) {
21074462Salfred		more_elements = (bool_t)(*rp != NULL);
21174462Salfred		if (! xdr_bool(xdrs, &more_elements)) {
21274462Salfred			return (FALSE);
21374462Salfred		}
21474462Salfred		if (! more_elements) {
21574462Salfred			return (TRUE);  /* we are done */
21674462Salfred		}
21774462Salfred		/*
21874462Salfred		 * the unfortunate side effect of non-recursion is that in
21974462Salfred		 * the case of freeing we must remember the next object
22074462Salfred		 * before we free the current object ...
22174462Salfred		 */
22274462Salfred		if (freeing)
22374462Salfred			next = (*rp)->rpcb_entry_next;
22474462Salfred		if (! xdr_reference(xdrs, (caddr_t *)rp,
22574462Salfred		    (u_int)sizeof (rpcb_entry_list),
22674462Salfred				    (xdrproc_t)xdr_rpcb_entry)) {
22774462Salfred			return (FALSE);
22874462Salfred		}
22974462Salfred		if (freeing) {
23074462Salfred			next_copy = next;
23174462Salfred			rp = &next_copy;
23274462Salfred			/*
23374462Salfred			 * Note that in the subsequent iteration, next_copy
23474462Salfred			 * gets nulled out by the xdr_reference
23574462Salfred			 * but next itself survives.
23674462Salfred			 */
23774462Salfred		} else {
23874462Salfred			rp = &((*rp)->rpcb_entry_next);
23974462Salfred		}
24074462Salfred	}
24174462Salfred	/*NOTREACHED*/
24274462Salfred}
24374462Salfred
24474462Salfred/*
24574462Salfred * XDR remote call arguments
24674462Salfred * written for XDR_ENCODE direction only
24774462Salfred */
24874462Salfredbool_t
24974462Salfredxdr_rpcb_rmtcallargs(xdrs, p)
25074462Salfred	XDR *xdrs;
25174462Salfred	struct rpcb_rmtcallargs *p;
25274462Salfred{
25374462Salfred	struct r_rpcb_rmtcallargs *objp =
25474462Salfred	    (struct r_rpcb_rmtcallargs *)(void *)p;
25574462Salfred	u_int lenposition, argposition, position;
25674462Salfred	int32_t *buf;
25774462Salfred
25874462Salfred	buf = XDR_INLINE(xdrs, 3 * BYTES_PER_XDR_UNIT);
25974462Salfred	if (buf == NULL) {
26074462Salfred		if (!xdr_u_int32_t(xdrs, &objp->prog)) {
26174462Salfred			return (FALSE);
26274462Salfred		}
26374462Salfred		if (!xdr_u_int32_t(xdrs, &objp->vers)) {
26474462Salfred			return (FALSE);
26574462Salfred		}
26674462Salfred		if (!xdr_u_int32_t(xdrs, &objp->proc)) {
26774462Salfred			return (FALSE);
26874462Salfred		}
26974462Salfred	} else {
27074462Salfred		IXDR_PUT_U_INT32(buf, objp->prog);
27174462Salfred		IXDR_PUT_U_INT32(buf, objp->vers);
27274462Salfred		IXDR_PUT_U_INT32(buf, objp->proc);
27374462Salfred	}
27474462Salfred
27574462Salfred	/*
27674462Salfred	 * All the jugglery for just getting the size of the arguments
27774462Salfred	 */
27874462Salfred	lenposition = XDR_GETPOS(xdrs);
27974462Salfred	if (! xdr_u_int(xdrs, &(objp->args.args_len))) {
28074462Salfred		return (FALSE);
28174462Salfred	}
28274462Salfred	argposition = XDR_GETPOS(xdrs);
28374462Salfred	if (! (*objp->xdr_args)(xdrs, objp->args.args_val)) {
28474462Salfred		return (FALSE);
28574462Salfred	}
28674462Salfred	position = XDR_GETPOS(xdrs);
28774462Salfred	objp->args.args_len = (u_int)((u_long)position - (u_long)argposition);
28874462Salfred	XDR_SETPOS(xdrs, lenposition);
28974462Salfred	if (! xdr_u_int(xdrs, &(objp->args.args_len))) {
29074462Salfred		return (FALSE);
29174462Salfred	}
29274462Salfred	XDR_SETPOS(xdrs, position);
29374462Salfred	return (TRUE);
29474462Salfred}
29574462Salfred
29674462Salfred/*
29774462Salfred * XDR remote call results
29874462Salfred * written for XDR_DECODE direction only
29974462Salfred */
30074462Salfredbool_t
30174462Salfredxdr_rpcb_rmtcallres(xdrs, p)
30274462Salfred	XDR *xdrs;
30374462Salfred	struct rpcb_rmtcallres *p;
30474462Salfred{
30574462Salfred	bool_t dummy;
30674462Salfred	struct r_rpcb_rmtcallres *objp = (struct r_rpcb_rmtcallres *)(void *)p;
30774462Salfred
30874462Salfred	if (!xdr_string(xdrs, &objp->addr, (u_int)~0)) {
30974462Salfred		return (FALSE);
31074462Salfred	}
31174462Salfred	if (!xdr_u_int(xdrs, &objp->results.results_len)) {
31274462Salfred		return (FALSE);
31374462Salfred	}
31474462Salfred	dummy = (*(objp->xdr_res))(xdrs, objp->results.results_val);
31574462Salfred	return (dummy);
31674462Salfred}
31774462Salfred
31874462Salfredbool_t
31974462Salfredxdr_netbuf(xdrs, objp)
32074462Salfred	XDR *xdrs;
32174462Salfred	struct netbuf *objp;
32274462Salfred{
32374462Salfred	bool_t dummy;
32474462Salfred
32574462Salfred	if (!xdr_u_int32_t(xdrs, (u_int32_t *) &objp->maxlen)) {
32674462Salfred		return (FALSE);
32774462Salfred	}
32874462Salfred	dummy = xdr_bytes(xdrs, (char **)&(objp->buf),
32974462Salfred			(u_int *)&(objp->len), objp->maxlen);
33074462Salfred	return (dummy);
33174462Salfred}
332