xref: /freebsd/crypto/krb5/src/lib/rpc/xdr.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /* @(#)xdr.c	2.1 88/07/29 4.0 RPCSRC */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert  * Copyright (c) 2010, Oracle America, Inc.
4*7f2fe78bSCy Schubert  *
5*7f2fe78bSCy Schubert  * All rights reserved.
6*7f2fe78bSCy Schubert  *
7*7f2fe78bSCy Schubert  * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert  * modification, are permitted provided that the following conditions are met:
9*7f2fe78bSCy Schubert  *
10*7f2fe78bSCy Schubert  *     * Redistributions of source code must retain the above copyright
11*7f2fe78bSCy Schubert  *       notice, this list of conditions and the following disclaimer.
12*7f2fe78bSCy Schubert  *
13*7f2fe78bSCy Schubert  *     * Redistributions in binary form must reproduce the above copyright
14*7f2fe78bSCy Schubert  *       notice, this list of conditions and the following disclaimer in
15*7f2fe78bSCy Schubert  *       the documentation and/or other materials provided with the
16*7f2fe78bSCy Schubert  *       distribution.
17*7f2fe78bSCy Schubert  *
18*7f2fe78bSCy Schubert  *     * Neither the name of the "Oracle America, Inc." nor the names of
19*7f2fe78bSCy Schubert  *       its contributors may be used to endorse or promote products
20*7f2fe78bSCy Schubert  *       derived from this software without specific prior written permission.
21*7f2fe78bSCy Schubert  *
22*7f2fe78bSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23*7f2fe78bSCy Schubert  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*7f2fe78bSCy Schubert  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25*7f2fe78bSCy Schubert  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26*7f2fe78bSCy Schubert  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27*7f2fe78bSCy Schubert  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28*7f2fe78bSCy Schubert  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29*7f2fe78bSCy Schubert  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*7f2fe78bSCy Schubert  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*7f2fe78bSCy Schubert  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*7f2fe78bSCy Schubert  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*7f2fe78bSCy Schubert  */
34*7f2fe78bSCy Schubert #if !defined(lint) && defined(SCCSIDS)
35*7f2fe78bSCy Schubert static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
36*7f2fe78bSCy Schubert #endif
37*7f2fe78bSCy Schubert 
38*7f2fe78bSCy Schubert /*
39*7f2fe78bSCy Schubert  * xdr.c, Generic XDR routines implementation.
40*7f2fe78bSCy Schubert  *
41*7f2fe78bSCy Schubert  * These are the "generic" xdr routines used to serialize and de-serialize
42*7f2fe78bSCy Schubert  * most common data items.  See xdr.h for more info on the interface to
43*7f2fe78bSCy Schubert  * xdr.
44*7f2fe78bSCy Schubert  */
45*7f2fe78bSCy Schubert 
46*7f2fe78bSCy Schubert #include <stdio.h>
47*7f2fe78bSCy Schubert #include <string.h>
48*7f2fe78bSCy Schubert 
49*7f2fe78bSCy Schubert #include <gssrpc/types.h>
50*7f2fe78bSCy Schubert #include <gssrpc/xdr.h>
51*7f2fe78bSCy Schubert 
52*7f2fe78bSCy Schubert /*
53*7f2fe78bSCy Schubert  * constants specific to the xdr "protocol"
54*7f2fe78bSCy Schubert  */
55*7f2fe78bSCy Schubert #define XDR_FALSE	((long) 0)
56*7f2fe78bSCy Schubert #define XDR_TRUE	((long) 1)
57*7f2fe78bSCy Schubert #define LASTUNSIGNED	((u_int) 0-1)
58*7f2fe78bSCy Schubert 
59*7f2fe78bSCy Schubert #ifdef USE_VALGRIND
60*7f2fe78bSCy Schubert #include <valgrind/memcheck.h>
61*7f2fe78bSCy Schubert #else
62*7f2fe78bSCy Schubert #define VALGRIND_CHECK_DEFINED(LVALUE)		((void)0)
63*7f2fe78bSCy Schubert #define VALGRIND_CHECK_READABLE(PTR,SIZE)	((void)0)
64*7f2fe78bSCy Schubert #endif
65*7f2fe78bSCy Schubert 
66*7f2fe78bSCy Schubert /*
67*7f2fe78bSCy Schubert  * for unit alignment
68*7f2fe78bSCy Schubert  */
69*7f2fe78bSCy Schubert static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
70*7f2fe78bSCy Schubert 
71*7f2fe78bSCy Schubert /*
72*7f2fe78bSCy Schubert  * Free a data structure using XDR
73*7f2fe78bSCy Schubert  * Not a filter, but a convenient utility nonetheless
74*7f2fe78bSCy Schubert  */
75*7f2fe78bSCy Schubert void
xdr_free(xdrproc_t proc,void * objp)76*7f2fe78bSCy Schubert xdr_free(xdrproc_t proc, void *objp)
77*7f2fe78bSCy Schubert {
78*7f2fe78bSCy Schubert 	XDR x;
79*7f2fe78bSCy Schubert 
80*7f2fe78bSCy Schubert 	x.x_op = XDR_FREE;
81*7f2fe78bSCy Schubert 	(*proc)(&x, objp);
82*7f2fe78bSCy Schubert }
83*7f2fe78bSCy Schubert 
84*7f2fe78bSCy Schubert /*
85*7f2fe78bSCy Schubert  * XDR nothing
86*7f2fe78bSCy Schubert  */
87*7f2fe78bSCy Schubert bool_t
xdr_void(XDR * xdrs,void * addr)88*7f2fe78bSCy Schubert xdr_void(XDR *xdrs, void *addr)
89*7f2fe78bSCy Schubert {
90*7f2fe78bSCy Schubert 
91*7f2fe78bSCy Schubert 	return (TRUE);
92*7f2fe78bSCy Schubert }
93*7f2fe78bSCy Schubert 
94*7f2fe78bSCy Schubert /*
95*7f2fe78bSCy Schubert  * XDR integers
96*7f2fe78bSCy Schubert  */
97*7f2fe78bSCy Schubert bool_t
xdr_int(XDR * xdrs,int * ip)98*7f2fe78bSCy Schubert xdr_int(XDR *xdrs, int *ip)
99*7f2fe78bSCy Schubert {
100*7f2fe78bSCy Schubert 	long l;
101*7f2fe78bSCy Schubert 
102*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
103*7f2fe78bSCy Schubert 
104*7f2fe78bSCy Schubert 	case XDR_ENCODE:
105*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*ip);
106*7f2fe78bSCy Schubert 		if (*ip > 0x7fffffffL || *ip < -0x7fffffffL - 1L)
107*7f2fe78bSCy Schubert 			return (FALSE);
108*7f2fe78bSCy Schubert 
109*7f2fe78bSCy Schubert 		l = (long) *ip;
110*7f2fe78bSCy Schubert 		return (XDR_PUTLONG(xdrs, &l));
111*7f2fe78bSCy Schubert 
112*7f2fe78bSCy Schubert 	case XDR_DECODE:
113*7f2fe78bSCy Schubert 		if (!XDR_GETLONG(xdrs, &l))
114*7f2fe78bSCy Schubert 			return (FALSE);
115*7f2fe78bSCy Schubert 
116*7f2fe78bSCy Schubert 		if (l > INT_MAX || l < INT_MIN)
117*7f2fe78bSCy Schubert 			return (FALSE);
118*7f2fe78bSCy Schubert 
119*7f2fe78bSCy Schubert 		*ip = (int) l;
120*7f2fe78bSCy Schubert 
121*7f2fe78bSCy Schubert 	case XDR_FREE:
122*7f2fe78bSCy Schubert 		return (TRUE);
123*7f2fe78bSCy Schubert 	}
124*7f2fe78bSCy Schubert 	/*NOTREACHED*/
125*7f2fe78bSCy Schubert 	return(FALSE);
126*7f2fe78bSCy Schubert }
127*7f2fe78bSCy Schubert 
128*7f2fe78bSCy Schubert /*
129*7f2fe78bSCy Schubert  * XDR unsigned integers
130*7f2fe78bSCy Schubert  */
131*7f2fe78bSCy Schubert bool_t
xdr_u_int(XDR * xdrs,u_int * up)132*7f2fe78bSCy Schubert xdr_u_int(XDR *xdrs, u_int *up)
133*7f2fe78bSCy Schubert {
134*7f2fe78bSCy Schubert 	u_long l;
135*7f2fe78bSCy Schubert 
136*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
137*7f2fe78bSCy Schubert 
138*7f2fe78bSCy Schubert 	case XDR_ENCODE:
139*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*up);
140*7f2fe78bSCy Schubert 		if (*up > 0xffffffffUL)
141*7f2fe78bSCy Schubert 			return (FALSE);
142*7f2fe78bSCy Schubert 
143*7f2fe78bSCy Schubert 		l = (u_long)*up;
144*7f2fe78bSCy Schubert 		return (XDR_PUTLONG(xdrs, (long *) &l));
145*7f2fe78bSCy Schubert 
146*7f2fe78bSCy Schubert 	case XDR_DECODE:
147*7f2fe78bSCy Schubert 		if (!XDR_GETLONG(xdrs, (long *) &l))
148*7f2fe78bSCy Schubert 			return (FALSE);
149*7f2fe78bSCy Schubert 
150*7f2fe78bSCy Schubert 		if ((uint32_t)l > UINT_MAX)
151*7f2fe78bSCy Schubert 			return (FALSE);
152*7f2fe78bSCy Schubert 
153*7f2fe78bSCy Schubert 		*up = (u_int) l;
154*7f2fe78bSCy Schubert 		return (TRUE);
155*7f2fe78bSCy Schubert 
156*7f2fe78bSCy Schubert 	case XDR_FREE:
157*7f2fe78bSCy Schubert 		return (TRUE);
158*7f2fe78bSCy Schubert 	}
159*7f2fe78bSCy Schubert 	/*NOTREACHED*/
160*7f2fe78bSCy Schubert 	return(FALSE);
161*7f2fe78bSCy Schubert }
162*7f2fe78bSCy Schubert 
163*7f2fe78bSCy Schubert /*
164*7f2fe78bSCy Schubert  * XDR long integers
165*7f2fe78bSCy Schubert  */
166*7f2fe78bSCy Schubert bool_t
xdr_long(XDR * xdrs,long * lp)167*7f2fe78bSCy Schubert xdr_long(XDR *xdrs, long *lp)
168*7f2fe78bSCy Schubert {
169*7f2fe78bSCy Schubert 
170*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
171*7f2fe78bSCy Schubert 	case XDR_ENCODE:
172*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*lp);
173*7f2fe78bSCy Schubert 		if (*lp > 0x7fffffffL || *lp < -0x7fffffffL - 1L)
174*7f2fe78bSCy Schubert 			return (FALSE);
175*7f2fe78bSCy Schubert 
176*7f2fe78bSCy Schubert 		return (XDR_PUTLONG(xdrs, lp));
177*7f2fe78bSCy Schubert 
178*7f2fe78bSCy Schubert 	case XDR_DECODE:
179*7f2fe78bSCy Schubert 		return (XDR_GETLONG(xdrs, lp));
180*7f2fe78bSCy Schubert 
181*7f2fe78bSCy Schubert 	case XDR_FREE:
182*7f2fe78bSCy Schubert 		return (TRUE);
183*7f2fe78bSCy Schubert 	}
184*7f2fe78bSCy Schubert 	return (FALSE);
185*7f2fe78bSCy Schubert }
186*7f2fe78bSCy Schubert 
187*7f2fe78bSCy Schubert /*
188*7f2fe78bSCy Schubert  * XDR unsigned long integers
189*7f2fe78bSCy Schubert  */
190*7f2fe78bSCy Schubert bool_t
xdr_u_long(XDR * xdrs,u_long * ulp)191*7f2fe78bSCy Schubert xdr_u_long(XDR *xdrs, u_long *ulp)
192*7f2fe78bSCy Schubert {
193*7f2fe78bSCy Schubert 
194*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
195*7f2fe78bSCy Schubert 	case XDR_ENCODE:
196*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*ulp);
197*7f2fe78bSCy Schubert 		if (*ulp > 0xffffffffUL)
198*7f2fe78bSCy Schubert 			return (FALSE);
199*7f2fe78bSCy Schubert 
200*7f2fe78bSCy Schubert 		return (XDR_PUTLONG(xdrs, (long *) ulp));
201*7f2fe78bSCy Schubert 
202*7f2fe78bSCy Schubert 	case XDR_DECODE:
203*7f2fe78bSCy Schubert 		return (XDR_GETLONG(xdrs, (long *) ulp));
204*7f2fe78bSCy Schubert 
205*7f2fe78bSCy Schubert 	case XDR_FREE:
206*7f2fe78bSCy Schubert 		return (TRUE);
207*7f2fe78bSCy Schubert 	}
208*7f2fe78bSCy Schubert 	return (FALSE);
209*7f2fe78bSCy Schubert }
210*7f2fe78bSCy Schubert 
211*7f2fe78bSCy Schubert /*
212*7f2fe78bSCy Schubert  * XDR short integers
213*7f2fe78bSCy Schubert  */
214*7f2fe78bSCy Schubert bool_t
xdr_short(XDR * xdrs,short * sp)215*7f2fe78bSCy Schubert xdr_short(XDR *xdrs, short *sp)
216*7f2fe78bSCy Schubert {
217*7f2fe78bSCy Schubert 	long l;
218*7f2fe78bSCy Schubert 
219*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
220*7f2fe78bSCy Schubert 
221*7f2fe78bSCy Schubert 	case XDR_ENCODE:
222*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*sp);
223*7f2fe78bSCy Schubert 		l = (long) *sp;
224*7f2fe78bSCy Schubert 		return (XDR_PUTLONG(xdrs, &l));
225*7f2fe78bSCy Schubert 
226*7f2fe78bSCy Schubert 	case XDR_DECODE:
227*7f2fe78bSCy Schubert 		if (!XDR_GETLONG(xdrs, &l)) {
228*7f2fe78bSCy Schubert 			return (FALSE);
229*7f2fe78bSCy Schubert 		}
230*7f2fe78bSCy Schubert 		if (l > SHRT_MAX || l < SHRT_MIN)
231*7f2fe78bSCy Schubert 			return (FALSE);
232*7f2fe78bSCy Schubert 
233*7f2fe78bSCy Schubert 		*sp = (short) l;
234*7f2fe78bSCy Schubert 		return (TRUE);
235*7f2fe78bSCy Schubert 
236*7f2fe78bSCy Schubert 	case XDR_FREE:
237*7f2fe78bSCy Schubert 		return (TRUE);
238*7f2fe78bSCy Schubert 	}
239*7f2fe78bSCy Schubert 	return (FALSE);
240*7f2fe78bSCy Schubert }
241*7f2fe78bSCy Schubert 
242*7f2fe78bSCy Schubert /*
243*7f2fe78bSCy Schubert  * XDR unsigned short integers
244*7f2fe78bSCy Schubert  */
245*7f2fe78bSCy Schubert bool_t
xdr_u_short(XDR * xdrs,u_short * usp)246*7f2fe78bSCy Schubert xdr_u_short(XDR *xdrs, u_short *usp)
247*7f2fe78bSCy Schubert {
248*7f2fe78bSCy Schubert 	u_long l;
249*7f2fe78bSCy Schubert 
250*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
251*7f2fe78bSCy Schubert 
252*7f2fe78bSCy Schubert 	case XDR_ENCODE:
253*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*usp);
254*7f2fe78bSCy Schubert 		l = (u_long) *usp;
255*7f2fe78bSCy Schubert 		return (XDR_PUTLONG(xdrs, (long *) &l));
256*7f2fe78bSCy Schubert 
257*7f2fe78bSCy Schubert 	case XDR_DECODE:
258*7f2fe78bSCy Schubert 		if (!XDR_GETLONG(xdrs, (long *) &l)) {
259*7f2fe78bSCy Schubert 			return (FALSE);
260*7f2fe78bSCy Schubert 		}
261*7f2fe78bSCy Schubert 		*usp = (u_short) l;
262*7f2fe78bSCy Schubert 		return (TRUE);
263*7f2fe78bSCy Schubert 
264*7f2fe78bSCy Schubert 	case XDR_FREE:
265*7f2fe78bSCy Schubert 		return (TRUE);
266*7f2fe78bSCy Schubert 	}
267*7f2fe78bSCy Schubert 	return (FALSE);
268*7f2fe78bSCy Schubert }
269*7f2fe78bSCy Schubert 
270*7f2fe78bSCy Schubert 
271*7f2fe78bSCy Schubert /*
272*7f2fe78bSCy Schubert  * XDR a char
273*7f2fe78bSCy Schubert  */
274*7f2fe78bSCy Schubert bool_t
xdr_char(XDR * xdrs,char * cp)275*7f2fe78bSCy Schubert xdr_char(XDR *xdrs, char *cp)
276*7f2fe78bSCy Schubert {
277*7f2fe78bSCy Schubert 	int i;
278*7f2fe78bSCy Schubert 
279*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
280*7f2fe78bSCy Schubert 	case XDR_ENCODE:
281*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*cp);
282*7f2fe78bSCy Schubert 		break;
283*7f2fe78bSCy Schubert 	default:
284*7f2fe78bSCy Schubert 		break;
285*7f2fe78bSCy Schubert 	}
286*7f2fe78bSCy Schubert 	i = (*cp);
287*7f2fe78bSCy Schubert 	if (!xdr_int(xdrs, &i)) {
288*7f2fe78bSCy Schubert 		return (FALSE);
289*7f2fe78bSCy Schubert 	}
290*7f2fe78bSCy Schubert 	*cp = i;
291*7f2fe78bSCy Schubert 	return (TRUE);
292*7f2fe78bSCy Schubert }
293*7f2fe78bSCy Schubert 
294*7f2fe78bSCy Schubert /*
295*7f2fe78bSCy Schubert  * XDR an unsigned char
296*7f2fe78bSCy Schubert  */
297*7f2fe78bSCy Schubert bool_t
xdr_u_char(XDR * xdrs,u_char * cp)298*7f2fe78bSCy Schubert xdr_u_char(XDR *xdrs, u_char *cp)
299*7f2fe78bSCy Schubert {
300*7f2fe78bSCy Schubert 	u_int u;
301*7f2fe78bSCy Schubert 
302*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
303*7f2fe78bSCy Schubert 	case XDR_ENCODE:
304*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*cp);
305*7f2fe78bSCy Schubert 		break;
306*7f2fe78bSCy Schubert 	default:
307*7f2fe78bSCy Schubert 		break;
308*7f2fe78bSCy Schubert 	}
309*7f2fe78bSCy Schubert 	u = (*cp);
310*7f2fe78bSCy Schubert 	if (!xdr_u_int(xdrs, &u)) {
311*7f2fe78bSCy Schubert 		return (FALSE);
312*7f2fe78bSCy Schubert 	}
313*7f2fe78bSCy Schubert 	*cp = u;
314*7f2fe78bSCy Schubert 	return (TRUE);
315*7f2fe78bSCy Schubert }
316*7f2fe78bSCy Schubert 
317*7f2fe78bSCy Schubert /*
318*7f2fe78bSCy Schubert  * XDR booleans
319*7f2fe78bSCy Schubert  */
320*7f2fe78bSCy Schubert bool_t
xdr_bool(XDR * xdrs,bool_t * bp)321*7f2fe78bSCy Schubert xdr_bool(XDR *xdrs, bool_t *bp)
322*7f2fe78bSCy Schubert {
323*7f2fe78bSCy Schubert 	long lb;
324*7f2fe78bSCy Schubert 
325*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
326*7f2fe78bSCy Schubert 
327*7f2fe78bSCy Schubert 	case XDR_ENCODE:
328*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*bp);
329*7f2fe78bSCy Schubert 		lb = *bp ? XDR_TRUE : XDR_FALSE;
330*7f2fe78bSCy Schubert 		return (XDR_PUTLONG(xdrs, &lb));
331*7f2fe78bSCy Schubert 
332*7f2fe78bSCy Schubert 	case XDR_DECODE:
333*7f2fe78bSCy Schubert 		if (!XDR_GETLONG(xdrs, &lb)) {
334*7f2fe78bSCy Schubert 			return (FALSE);
335*7f2fe78bSCy Schubert 		}
336*7f2fe78bSCy Schubert 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
337*7f2fe78bSCy Schubert 		return (TRUE);
338*7f2fe78bSCy Schubert 
339*7f2fe78bSCy Schubert 	case XDR_FREE:
340*7f2fe78bSCy Schubert 		return (TRUE);
341*7f2fe78bSCy Schubert 	}
342*7f2fe78bSCy Schubert 	return (FALSE);
343*7f2fe78bSCy Schubert }
344*7f2fe78bSCy Schubert 
345*7f2fe78bSCy Schubert /*
346*7f2fe78bSCy Schubert  * XDR enumerations
347*7f2fe78bSCy Schubert  */
348*7f2fe78bSCy Schubert bool_t
xdr_enum(XDR * xdrs,enum_t * ep)349*7f2fe78bSCy Schubert xdr_enum(XDR *xdrs, enum_t *ep)
350*7f2fe78bSCy Schubert {
351*7f2fe78bSCy Schubert #ifndef lint
352*7f2fe78bSCy Schubert 	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
353*7f2fe78bSCy Schubert 
354*7f2fe78bSCy Schubert 	/*
355*7f2fe78bSCy Schubert 	 * enums are treated as ints
356*7f2fe78bSCy Schubert 	 */
357*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
358*7f2fe78bSCy Schubert 	case XDR_ENCODE:
359*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*ep);
360*7f2fe78bSCy Schubert 		break;
361*7f2fe78bSCy Schubert 	default:
362*7f2fe78bSCy Schubert 		break;
363*7f2fe78bSCy Schubert 	}
364*7f2fe78bSCy Schubert 	if (sizeof (enum sizecheck) == sizeof (long)) {
365*7f2fe78bSCy Schubert 		return (xdr_long(xdrs, (long *)(void *)ep));
366*7f2fe78bSCy Schubert 	} else if (sizeof (enum sizecheck) == sizeof (int)) {
367*7f2fe78bSCy Schubert 		return (xdr_int(xdrs, (int *)(void *)ep));
368*7f2fe78bSCy Schubert 	} else if (sizeof (enum sizecheck) == sizeof (short)) {
369*7f2fe78bSCy Schubert 		return (xdr_short(xdrs, (short *)(void *)ep));
370*7f2fe78bSCy Schubert 	} else {
371*7f2fe78bSCy Schubert 		return (FALSE);
372*7f2fe78bSCy Schubert 	}
373*7f2fe78bSCy Schubert #else
374*7f2fe78bSCy Schubert 	(void) (xdr_short(xdrs, (short *)(void *)ep));
375*7f2fe78bSCy Schubert 	return (xdr_long(xdrs, (long *)(void *)ep));
376*7f2fe78bSCy Schubert #endif
377*7f2fe78bSCy Schubert }
378*7f2fe78bSCy Schubert 
379*7f2fe78bSCy Schubert /*
380*7f2fe78bSCy Schubert  * XDR opaque data
381*7f2fe78bSCy Schubert  * Allows the specification of a fixed size sequence of opaque bytes.
382*7f2fe78bSCy Schubert  * cp points to the opaque object and cnt gives the byte length.
383*7f2fe78bSCy Schubert  */
384*7f2fe78bSCy Schubert bool_t
xdr_opaque(XDR * xdrs,caddr_t cp,u_int cnt)385*7f2fe78bSCy Schubert xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
386*7f2fe78bSCy Schubert {
387*7f2fe78bSCy Schubert 	u_int rndup;
388*7f2fe78bSCy Schubert 	static int crud[BYTES_PER_XDR_UNIT];
389*7f2fe78bSCy Schubert 
390*7f2fe78bSCy Schubert 	/*
391*7f2fe78bSCy Schubert 	 * if no data we are done
392*7f2fe78bSCy Schubert 	 */
393*7f2fe78bSCy Schubert 	if (cnt == 0)
394*7f2fe78bSCy Schubert 		return (TRUE);
395*7f2fe78bSCy Schubert 
396*7f2fe78bSCy Schubert 	/*
397*7f2fe78bSCy Schubert 	 * round byte count to full xdr units
398*7f2fe78bSCy Schubert 	 */
399*7f2fe78bSCy Schubert 	rndup = cnt % BYTES_PER_XDR_UNIT;
400*7f2fe78bSCy Schubert 	if (rndup > 0)
401*7f2fe78bSCy Schubert 		rndup = BYTES_PER_XDR_UNIT - rndup;
402*7f2fe78bSCy Schubert 
403*7f2fe78bSCy Schubert 	if (xdrs->x_op == XDR_DECODE) {
404*7f2fe78bSCy Schubert 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
405*7f2fe78bSCy Schubert 			return (FALSE);
406*7f2fe78bSCy Schubert 		}
407*7f2fe78bSCy Schubert 		if (rndup == 0)
408*7f2fe78bSCy Schubert 			return (TRUE);
409*7f2fe78bSCy Schubert 		return (XDR_GETBYTES(xdrs, (caddr_t) (void *)crud, rndup));
410*7f2fe78bSCy Schubert 	}
411*7f2fe78bSCy Schubert 
412*7f2fe78bSCy Schubert 	if (xdrs->x_op == XDR_ENCODE) {
413*7f2fe78bSCy Schubert 		VALGRIND_CHECK_READABLE((volatile void *)cp, cnt);
414*7f2fe78bSCy Schubert 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
415*7f2fe78bSCy Schubert 			return (FALSE);
416*7f2fe78bSCy Schubert 		}
417*7f2fe78bSCy Schubert 		if (rndup == 0)
418*7f2fe78bSCy Schubert 			return (TRUE);
419*7f2fe78bSCy Schubert 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
420*7f2fe78bSCy Schubert 	}
421*7f2fe78bSCy Schubert 
422*7f2fe78bSCy Schubert 	if (xdrs->x_op == XDR_FREE) {
423*7f2fe78bSCy Schubert 		return (TRUE);
424*7f2fe78bSCy Schubert 	}
425*7f2fe78bSCy Schubert 
426*7f2fe78bSCy Schubert 	return (FALSE);
427*7f2fe78bSCy Schubert }
428*7f2fe78bSCy Schubert 
429*7f2fe78bSCy Schubert /*
430*7f2fe78bSCy Schubert  * XDR counted bytes
431*7f2fe78bSCy Schubert  * *cpp is a pointer to the bytes, *sizep is the count.
432*7f2fe78bSCy Schubert  * If *cpp is NULL maxsize bytes are allocated
433*7f2fe78bSCy Schubert  */
434*7f2fe78bSCy Schubert bool_t
xdr_bytes(XDR * xdrs,char ** cpp,u_int * sizep,u_int maxsize)435*7f2fe78bSCy Schubert xdr_bytes(
436*7f2fe78bSCy Schubert 	XDR *xdrs,
437*7f2fe78bSCy Schubert 	char **cpp,
438*7f2fe78bSCy Schubert 	u_int *sizep,
439*7f2fe78bSCy Schubert 	u_int maxsize)
440*7f2fe78bSCy Schubert {
441*7f2fe78bSCy Schubert 	char *sp = *cpp;  /* sp is the actual string pointer */
442*7f2fe78bSCy Schubert 	u_int nodesize;
443*7f2fe78bSCy Schubert 
444*7f2fe78bSCy Schubert 	/*
445*7f2fe78bSCy Schubert 	 * first deal with the length since xdr bytes are counted
446*7f2fe78bSCy Schubert 	 */
447*7f2fe78bSCy Schubert 	if (! xdr_u_int(xdrs, sizep)) {
448*7f2fe78bSCy Schubert 		return (FALSE);
449*7f2fe78bSCy Schubert 	}
450*7f2fe78bSCy Schubert 	nodesize = *sizep;
451*7f2fe78bSCy Schubert 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
452*7f2fe78bSCy Schubert 		return (FALSE);
453*7f2fe78bSCy Schubert 	}
454*7f2fe78bSCy Schubert 
455*7f2fe78bSCy Schubert 	/*
456*7f2fe78bSCy Schubert 	 * now deal with the actual bytes
457*7f2fe78bSCy Schubert 	 */
458*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
459*7f2fe78bSCy Schubert 
460*7f2fe78bSCy Schubert 	case XDR_DECODE:
461*7f2fe78bSCy Schubert 		if (nodesize == 0) {
462*7f2fe78bSCy Schubert 			return (TRUE);
463*7f2fe78bSCy Schubert 		}
464*7f2fe78bSCy Schubert 		if (sp == NULL) {
465*7f2fe78bSCy Schubert 			*cpp = sp = (char *)mem_alloc(nodesize);
466*7f2fe78bSCy Schubert 		}
467*7f2fe78bSCy Schubert 		if (sp == NULL) {
468*7f2fe78bSCy Schubert 			(void) fprintf(stderr, "xdr_bytes: out of memory\n");
469*7f2fe78bSCy Schubert 			return (FALSE);
470*7f2fe78bSCy Schubert 		}
471*7f2fe78bSCy Schubert 		/* fall into ... */
472*7f2fe78bSCy Schubert 
473*7f2fe78bSCy Schubert 	case XDR_ENCODE:
474*7f2fe78bSCy Schubert 		return (xdr_opaque(xdrs, sp, nodesize));
475*7f2fe78bSCy Schubert 
476*7f2fe78bSCy Schubert 	case XDR_FREE:
477*7f2fe78bSCy Schubert 		if (sp != NULL) {
478*7f2fe78bSCy Schubert 			mem_free(sp, nodesize);
479*7f2fe78bSCy Schubert 			*cpp = NULL;
480*7f2fe78bSCy Schubert 		}
481*7f2fe78bSCy Schubert 		return (TRUE);
482*7f2fe78bSCy Schubert 	}
483*7f2fe78bSCy Schubert 	return (FALSE);
484*7f2fe78bSCy Schubert }
485*7f2fe78bSCy Schubert 
486*7f2fe78bSCy Schubert /*
487*7f2fe78bSCy Schubert  * Implemented here due to commonality of the object.
488*7f2fe78bSCy Schubert  */
489*7f2fe78bSCy Schubert bool_t
xdr_netobj(XDR * xdrs,struct netobj * np)490*7f2fe78bSCy Schubert xdr_netobj(XDR *xdrs, struct netobj *np)
491*7f2fe78bSCy Schubert {
492*7f2fe78bSCy Schubert 
493*7f2fe78bSCy Schubert 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
494*7f2fe78bSCy Schubert }
495*7f2fe78bSCy Schubert 
496*7f2fe78bSCy Schubert bool_t
xdr_int32(XDR * xdrs,int32_t * ip)497*7f2fe78bSCy Schubert xdr_int32(XDR *xdrs, int32_t *ip)
498*7f2fe78bSCy Schubert {
499*7f2fe78bSCy Schubert 	long l;
500*7f2fe78bSCy Schubert 
501*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
502*7f2fe78bSCy Schubert 
503*7f2fe78bSCy Schubert 	case XDR_ENCODE:
504*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*ip);
505*7f2fe78bSCy Schubert 		l = *ip;
506*7f2fe78bSCy Schubert 		return (xdr_long(xdrs, &l));
507*7f2fe78bSCy Schubert 
508*7f2fe78bSCy Schubert 	case XDR_DECODE:
509*7f2fe78bSCy Schubert 		if (!xdr_long(xdrs, &l)) {
510*7f2fe78bSCy Schubert 			return (FALSE);
511*7f2fe78bSCy Schubert 		}
512*7f2fe78bSCy Schubert 		*ip = l;
513*7f2fe78bSCy Schubert 		return (TRUE);
514*7f2fe78bSCy Schubert 
515*7f2fe78bSCy Schubert 	case XDR_FREE:
516*7f2fe78bSCy Schubert 		return (TRUE);
517*7f2fe78bSCy Schubert 	}
518*7f2fe78bSCy Schubert 	return (FALSE);
519*7f2fe78bSCy Schubert }
520*7f2fe78bSCy Schubert 
521*7f2fe78bSCy Schubert bool_t
xdr_u_int32(XDR * xdrs,uint32_t * up)522*7f2fe78bSCy Schubert xdr_u_int32(XDR *xdrs, uint32_t *up)
523*7f2fe78bSCy Schubert {
524*7f2fe78bSCy Schubert 	u_long ul;
525*7f2fe78bSCy Schubert 
526*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
527*7f2fe78bSCy Schubert 
528*7f2fe78bSCy Schubert 	case XDR_ENCODE:
529*7f2fe78bSCy Schubert 		VALGRIND_CHECK_DEFINED(*up);
530*7f2fe78bSCy Schubert 		ul = *up;
531*7f2fe78bSCy Schubert 		return (xdr_u_long(xdrs, &ul));
532*7f2fe78bSCy Schubert 
533*7f2fe78bSCy Schubert 	case XDR_DECODE:
534*7f2fe78bSCy Schubert 		if (!xdr_u_long(xdrs, &ul)) {
535*7f2fe78bSCy Schubert 			return (FALSE);
536*7f2fe78bSCy Schubert 		}
537*7f2fe78bSCy Schubert 		*up = ul;
538*7f2fe78bSCy Schubert 		return (TRUE);
539*7f2fe78bSCy Schubert 
540*7f2fe78bSCy Schubert 	case XDR_FREE:
541*7f2fe78bSCy Schubert 		return (TRUE);
542*7f2fe78bSCy Schubert 	}
543*7f2fe78bSCy Schubert 	return (FALSE);
544*7f2fe78bSCy Schubert }
545*7f2fe78bSCy Schubert 
546*7f2fe78bSCy Schubert /*
547*7f2fe78bSCy Schubert  * XDR a discriminated union
548*7f2fe78bSCy Schubert  * Support routine for discriminated unions.
549*7f2fe78bSCy Schubert  * You create an array of xdrdiscrim structures, terminated with
550*7f2fe78bSCy Schubert  * an entry with a null procedure pointer.  The routine gets
551*7f2fe78bSCy Schubert  * the discriminant value and then searches the array of xdrdiscrims
552*7f2fe78bSCy Schubert  * looking for that value.  It calls the procedure given in the xdrdiscrim
553*7f2fe78bSCy Schubert  * to handle the discriminant.  If there is no specific routine a default
554*7f2fe78bSCy Schubert  * routine may be called.
555*7f2fe78bSCy Schubert  * If there is no specific or default routine an error is returned.
556*7f2fe78bSCy Schubert  */
557*7f2fe78bSCy Schubert bool_t
xdr_union(XDR * xdrs,enum_t * dscmp,char * unp,struct xdr_discrim * choices,xdrproc_t dfault)558*7f2fe78bSCy Schubert xdr_union(
559*7f2fe78bSCy Schubert 	XDR *xdrs,
560*7f2fe78bSCy Schubert 	enum_t *dscmp,		/* enum to decide which arm to work on */
561*7f2fe78bSCy Schubert 	char *unp,		/* the union itself */
562*7f2fe78bSCy Schubert 	struct xdr_discrim *choices,	/* [value, xdr proc] for each arm */
563*7f2fe78bSCy Schubert 	xdrproc_t dfault	/* default xdr routine */
564*7f2fe78bSCy Schubert 	)
565*7f2fe78bSCy Schubert {
566*7f2fe78bSCy Schubert 	enum_t dscm;
567*7f2fe78bSCy Schubert 
568*7f2fe78bSCy Schubert 	/*
569*7f2fe78bSCy Schubert 	 * we deal with the discriminator;  it's an enum
570*7f2fe78bSCy Schubert 	 */
571*7f2fe78bSCy Schubert 	if (! xdr_enum(xdrs, dscmp)) {
572*7f2fe78bSCy Schubert 		return (FALSE);
573*7f2fe78bSCy Schubert 	}
574*7f2fe78bSCy Schubert 	dscm = *dscmp;
575*7f2fe78bSCy Schubert 
576*7f2fe78bSCy Schubert 	/*
577*7f2fe78bSCy Schubert 	 * search choices for a value that matches the discriminator.
578*7f2fe78bSCy Schubert 	 * if we find one, execute the xdr routine for that value.
579*7f2fe78bSCy Schubert 	 */
580*7f2fe78bSCy Schubert 	for (; choices->proc != NULL_xdrproc_t; choices++) {
581*7f2fe78bSCy Schubert 		if (choices->value == dscm)
582*7f2fe78bSCy Schubert 			return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
583*7f2fe78bSCy Schubert 	}
584*7f2fe78bSCy Schubert 
585*7f2fe78bSCy Schubert 	/*
586*7f2fe78bSCy Schubert 	 * no match - execute the default xdr routine if there is one
587*7f2fe78bSCy Schubert 	 */
588*7f2fe78bSCy Schubert 	return ((dfault == NULL_xdrproc_t) ? FALSE :
589*7f2fe78bSCy Schubert 	    (*dfault)(xdrs, unp, LASTUNSIGNED));
590*7f2fe78bSCy Schubert }
591*7f2fe78bSCy Schubert 
592*7f2fe78bSCy Schubert 
593*7f2fe78bSCy Schubert /*
594*7f2fe78bSCy Schubert  * Non-portable xdr primitives.
595*7f2fe78bSCy Schubert  * Care should be taken when moving these routines to new architectures.
596*7f2fe78bSCy Schubert  */
597*7f2fe78bSCy Schubert 
598*7f2fe78bSCy Schubert 
599*7f2fe78bSCy Schubert /*
600*7f2fe78bSCy Schubert  * XDR null terminated ASCII strings
601*7f2fe78bSCy Schubert  * xdr_string deals with "C strings" - arrays of bytes that are
602*7f2fe78bSCy Schubert  * terminated by a NULL character.  The parameter cpp references a
603*7f2fe78bSCy Schubert  * pointer to storage; If the pointer is null, then the necessary
604*7f2fe78bSCy Schubert  * storage is allocated.  The last parameter is the max allowed length
605*7f2fe78bSCy Schubert  * of the string as specified by a protocol.
606*7f2fe78bSCy Schubert  */
607*7f2fe78bSCy Schubert bool_t
xdr_string(XDR * xdrs,char ** cpp,u_int maxsize)608*7f2fe78bSCy Schubert xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
609*7f2fe78bSCy Schubert {
610*7f2fe78bSCy Schubert 	char *sp = *cpp;	/* sp is the actual string pointer */
611*7f2fe78bSCy Schubert 	u_int size;
612*7f2fe78bSCy Schubert 	u_int nodesize;
613*7f2fe78bSCy Schubert 
614*7f2fe78bSCy Schubert 	/*
615*7f2fe78bSCy Schubert 	 * first deal with the length since xdr strings are counted-strings
616*7f2fe78bSCy Schubert 	 */
617*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
618*7f2fe78bSCy Schubert 	case XDR_FREE:
619*7f2fe78bSCy Schubert 		if (sp == NULL) {
620*7f2fe78bSCy Schubert 			return(TRUE);	/* already free */
621*7f2fe78bSCy Schubert 		}
622*7f2fe78bSCy Schubert 		/* fall through... */
623*7f2fe78bSCy Schubert 	case XDR_ENCODE:
624*7f2fe78bSCy Schubert 		size = strlen(sp);
625*7f2fe78bSCy Schubert 		break;
626*7f2fe78bSCy Schubert 	case XDR_DECODE:
627*7f2fe78bSCy Schubert 		break;
628*7f2fe78bSCy Schubert 	}
629*7f2fe78bSCy Schubert 	if (! xdr_u_int(xdrs, &size)) {
630*7f2fe78bSCy Schubert 		return (FALSE);
631*7f2fe78bSCy Schubert 	}
632*7f2fe78bSCy Schubert 	if (size >= maxsize) {
633*7f2fe78bSCy Schubert 		return (FALSE);
634*7f2fe78bSCy Schubert 	}
635*7f2fe78bSCy Schubert 	nodesize = size + 1;
636*7f2fe78bSCy Schubert 
637*7f2fe78bSCy Schubert 	/*
638*7f2fe78bSCy Schubert 	 * now deal with the actual bytes
639*7f2fe78bSCy Schubert 	 */
640*7f2fe78bSCy Schubert 	switch (xdrs->x_op) {
641*7f2fe78bSCy Schubert 
642*7f2fe78bSCy Schubert 	case XDR_DECODE:
643*7f2fe78bSCy Schubert 		if (nodesize == 0) {
644*7f2fe78bSCy Schubert 			return (TRUE);
645*7f2fe78bSCy Schubert 		}
646*7f2fe78bSCy Schubert 		if (sp == NULL)
647*7f2fe78bSCy Schubert 			*cpp = sp = (char *)mem_alloc(nodesize);
648*7f2fe78bSCy Schubert 		if (sp == NULL) {
649*7f2fe78bSCy Schubert 			(void) fprintf(stderr, "xdr_string: out of memory\n");
650*7f2fe78bSCy Schubert 			return (FALSE);
651*7f2fe78bSCy Schubert 		}
652*7f2fe78bSCy Schubert 		sp[size] = 0;
653*7f2fe78bSCy Schubert 		/* fall into ... */
654*7f2fe78bSCy Schubert 
655*7f2fe78bSCy Schubert 	case XDR_ENCODE:
656*7f2fe78bSCy Schubert 		return (xdr_opaque(xdrs, sp, size));
657*7f2fe78bSCy Schubert 
658*7f2fe78bSCy Schubert 	case XDR_FREE:
659*7f2fe78bSCy Schubert 		mem_free(sp, nodesize);
660*7f2fe78bSCy Schubert 		*cpp = NULL;
661*7f2fe78bSCy Schubert 		return (TRUE);
662*7f2fe78bSCy Schubert 	}
663*7f2fe78bSCy Schubert 	return (FALSE);
664*7f2fe78bSCy Schubert }
665*7f2fe78bSCy Schubert 
666*7f2fe78bSCy Schubert /*
667*7f2fe78bSCy Schubert  * Wrapper for xdr_string that can be called directly from
668*7f2fe78bSCy Schubert  * routines like clnt_call
669*7f2fe78bSCy Schubert  */
670*7f2fe78bSCy Schubert bool_t
xdr_wrapstring(XDR * xdrs,char ** cpp)671*7f2fe78bSCy Schubert xdr_wrapstring(XDR *xdrs, char **cpp)
672*7f2fe78bSCy Schubert {
673*7f2fe78bSCy Schubert 	if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
674*7f2fe78bSCy Schubert 		return (TRUE);
675*7f2fe78bSCy Schubert 	}
676*7f2fe78bSCy Schubert 	return (FALSE);
677*7f2fe78bSCy Schubert }
678