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