1177633Sdfr/*	$NetBSD: rpc_callmsg.c,v 1.16 2000/07/14 08:40:42 fvdl Exp $	*/
2177633Sdfr
3261046Smav/*-
4261046Smav * Copyright (c) 2009, Sun Microsystems, Inc.
5261046Smav * All rights reserved.
6177633Sdfr *
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.
17261046Smav *
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#if defined(LIBC_SCCS) && !defined(lint)
32177633Sdfrstatic char *sccsid2 = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
33177633Sdfrstatic char *sccsid = "@(#)rpc_callmsg.c	2.1 88/07/29 4.0 RPCSRC";
34177633Sdfr#endif
35177633Sdfr#include <sys/cdefs.h>
36177633Sdfr__FBSDID("$FreeBSD$");
37177633Sdfr
38177633Sdfr/*
39177633Sdfr * rpc_callmsg.c
40177633Sdfr *
41177633Sdfr * Copyright (C) 1984, Sun Microsystems, Inc.
42177633Sdfr *
43177633Sdfr */
44177633Sdfr
45177633Sdfr#include <sys/param.h>
46177633Sdfr#include <sys/systm.h>
47177633Sdfr#include <sys/malloc.h>
48177633Sdfr
49177633Sdfr#include <rpc/rpc.h>
50177633Sdfr
51177633Sdfr/*
52177633Sdfr * XDR a call message
53177633Sdfr */
54177633Sdfrbool_t
55177633Sdfrxdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg)
56177633Sdfr{
57177633Sdfr	enum msg_type *prm_direction;
58177633Sdfr	int32_t *buf;
59177633Sdfr	struct opaque_auth *oa;
60177633Sdfr
61177633Sdfr	if (xdrs->x_op == XDR_ENCODE) {
62177633Sdfr		if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
63177633Sdfr			return (FALSE);
64177633Sdfr		}
65177633Sdfr		if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
66177633Sdfr			return (FALSE);
67177633Sdfr		}
68177633Sdfr		buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
69177633Sdfr			+ RNDUP(cmsg->rm_call.cb_cred.oa_length)
70177633Sdfr			+ 2 * BYTES_PER_XDR_UNIT
71177633Sdfr			+ RNDUP(cmsg->rm_call.cb_verf.oa_length));
72177633Sdfr		if (buf != NULL) {
73177633Sdfr			IXDR_PUT_INT32(buf, cmsg->rm_xid);
74177633Sdfr			IXDR_PUT_ENUM(buf, cmsg->rm_direction);
75177633Sdfr			if (cmsg->rm_direction != CALL) {
76177633Sdfr				return (FALSE);
77177633Sdfr			}
78177633Sdfr			IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers);
79177633Sdfr			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
80177633Sdfr				return (FALSE);
81177633Sdfr			}
82177633Sdfr			IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog);
83177633Sdfr			IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers);
84177633Sdfr			IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc);
85177633Sdfr			oa = &cmsg->rm_call.cb_cred;
86177633Sdfr			IXDR_PUT_ENUM(buf, oa->oa_flavor);
87177633Sdfr			IXDR_PUT_INT32(buf, oa->oa_length);
88177633Sdfr			if (oa->oa_length) {
89177633Sdfr				memcpy(buf, oa->oa_base, oa->oa_length);
90177633Sdfr				buf += RNDUP(oa->oa_length) / sizeof (int32_t);
91177633Sdfr			}
92177633Sdfr			oa = &cmsg->rm_call.cb_verf;
93177633Sdfr			IXDR_PUT_ENUM(buf, oa->oa_flavor);
94177633Sdfr			IXDR_PUT_INT32(buf, oa->oa_length);
95177633Sdfr			if (oa->oa_length) {
96177633Sdfr				memcpy(buf, oa->oa_base, oa->oa_length);
97177633Sdfr				/* no real need....
98177633Sdfr				buf += RNDUP(oa->oa_length) / sizeof (int32_t);
99177633Sdfr				*/
100177633Sdfr			}
101177633Sdfr			return (TRUE);
102177633Sdfr		}
103177633Sdfr	}
104177633Sdfr	if (xdrs->x_op == XDR_DECODE) {
105177633Sdfr		buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
106177633Sdfr		if (buf != NULL) {
107177633Sdfr			cmsg->rm_xid = IXDR_GET_UINT32(buf);
108177633Sdfr			cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
109177633Sdfr			if (cmsg->rm_direction != CALL) {
110177633Sdfr				return (FALSE);
111177633Sdfr			}
112177633Sdfr			cmsg->rm_call.cb_rpcvers = IXDR_GET_UINT32(buf);
113177633Sdfr			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
114177633Sdfr				return (FALSE);
115177633Sdfr			}
116177633Sdfr			cmsg->rm_call.cb_prog = IXDR_GET_UINT32(buf);
117177633Sdfr			cmsg->rm_call.cb_vers = IXDR_GET_UINT32(buf);
118177633Sdfr			cmsg->rm_call.cb_proc = IXDR_GET_UINT32(buf);
119177633Sdfr			oa = &cmsg->rm_call.cb_cred;
120177633Sdfr			oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
121177633Sdfr			oa->oa_length = (u_int)IXDR_GET_UINT32(buf);
122177633Sdfr			if (oa->oa_length) {
123177633Sdfr				if (oa->oa_length > MAX_AUTH_BYTES) {
124177633Sdfr					return (FALSE);
125177633Sdfr				}
126177633Sdfr				if (oa->oa_base == NULL) {
127177633Sdfr					oa->oa_base = (caddr_t)
128177633Sdfr					    mem_alloc(oa->oa_length);
129177633Sdfr					if (oa->oa_base == NULL)
130177633Sdfr						return (FALSE);
131177633Sdfr				}
132177633Sdfr				buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
133177633Sdfr				if (buf == NULL) {
134177633Sdfr					if (xdr_opaque(xdrs, oa->oa_base,
135177633Sdfr					    oa->oa_length) == FALSE) {
136177633Sdfr						return (FALSE);
137177633Sdfr					}
138177633Sdfr				} else {
139177633Sdfr					memcpy(oa->oa_base, buf,
140177633Sdfr					    oa->oa_length);
141177633Sdfr					/* no real need....
142177633Sdfr					buf += RNDUP(oa->oa_length) /
143177633Sdfr						sizeof (int32_t);
144177633Sdfr					*/
145177633Sdfr				}
146177633Sdfr			}
147177633Sdfr			oa = &cmsg->rm_call.cb_verf;
148177633Sdfr			buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
149177633Sdfr			if (buf == NULL) {
150177633Sdfr				if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
151177633Sdfr				    xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
152177633Sdfr					return (FALSE);
153177633Sdfr				}
154177633Sdfr			} else {
155177633Sdfr				oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
156177633Sdfr				oa->oa_length = (u_int)IXDR_GET_UINT32(buf);
157177633Sdfr			}
158177633Sdfr			if (oa->oa_length) {
159177633Sdfr				if (oa->oa_length > MAX_AUTH_BYTES) {
160177633Sdfr					return (FALSE);
161177633Sdfr				}
162177633Sdfr				if (oa->oa_base == NULL) {
163177633Sdfr					oa->oa_base = (caddr_t)
164177633Sdfr					    mem_alloc(oa->oa_length);
165177633Sdfr					if (oa->oa_base == NULL)
166177633Sdfr						return (FALSE);
167177633Sdfr				}
168177633Sdfr				buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
169177633Sdfr				if (buf == NULL) {
170177633Sdfr					if (xdr_opaque(xdrs, oa->oa_base,
171177633Sdfr					    oa->oa_length) == FALSE) {
172177633Sdfr						return (FALSE);
173177633Sdfr					}
174177633Sdfr				} else {
175177633Sdfr					memcpy(oa->oa_base, buf,
176177633Sdfr					    oa->oa_length);
177177633Sdfr					/* no real need...
178177633Sdfr					buf += RNDUP(oa->oa_length) /
179177633Sdfr						sizeof (int32_t);
180177633Sdfr					*/
181177633Sdfr				}
182177633Sdfr			}
183177633Sdfr			return (TRUE);
184177633Sdfr		}
185177633Sdfr	}
186177633Sdfr	prm_direction = &cmsg->rm_direction;
187177633Sdfr	if (
188177633Sdfr	    xdr_uint32_t(xdrs, &(cmsg->rm_xid)) &&
189177633Sdfr	    xdr_enum(xdrs, (enum_t *) prm_direction) &&
190177633Sdfr	    (cmsg->rm_direction == CALL) &&
191177633Sdfr	    xdr_uint32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
192177633Sdfr	    (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
193177633Sdfr	    xdr_uint32_t(xdrs, &(cmsg->rm_call.cb_prog)) &&
194177633Sdfr	    xdr_uint32_t(xdrs, &(cmsg->rm_call.cb_vers)) &&
195177633Sdfr	    xdr_uint32_t(xdrs, &(cmsg->rm_call.cb_proc)) &&
196177633Sdfr	    xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
197177633Sdfr		return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
198177633Sdfr	return (FALSE);
199177633Sdfr}
200