xref: /titanic_54/usr/src/lib/libnsl/rpc/xdr.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  *
22*7c478bd9Sstevel@tonic-gate  * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
23*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*7c478bd9Sstevel@tonic-gate  */
25*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
29*7c478bd9Sstevel@tonic-gate  * 4.3 BSD under license from the Regents of the University of
30*7c478bd9Sstevel@tonic-gate  * California.
31*7c478bd9Sstevel@tonic-gate  */
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate /*
36*7c478bd9Sstevel@tonic-gate  * xdr.c, Generic XDR routines implementation.
37*7c478bd9Sstevel@tonic-gate  *
38*7c478bd9Sstevel@tonic-gate  * These are the "generic" xdr routines used to serialize and de-serialize
39*7c478bd9Sstevel@tonic-gate  * most common data items.  See xdr.h for more info on the interface to
40*7c478bd9Sstevel@tonic-gate  * xdr.
41*7c478bd9Sstevel@tonic-gate  */
42*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
43*7c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
44*7c478bd9Sstevel@tonic-gate #include <rpc/trace.h>
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
47*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/systm.h>
49*7c478bd9Sstevel@tonic-gate #else
50*7c478bd9Sstevel@tonic-gate #include <syslog.h>
51*7c478bd9Sstevel@tonic-gate #include <stdio.h>
52*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
53*7c478bd9Sstevel@tonic-gate #include <string.h>
54*7c478bd9Sstevel@tonic-gate #endif
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate #include <limits.h>
57*7c478bd9Sstevel@tonic-gate #include <rpc/types.h>
58*7c478bd9Sstevel@tonic-gate #include <rpc/xdr.h>
59*7c478bd9Sstevel@tonic-gate #include <inttypes.h>
60*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int64_t = xdr_hyper
63*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint64_t = xdr_u_hyper
64*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int32_t = xdr_int
65*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint32_t = xdr_u_int
66*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int16_t = xdr_short
67*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint16_t = xdr_u_short
68*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int8_t = xdr_char
69*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint8_t = xdr_u_char
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate /*
72*7c478bd9Sstevel@tonic-gate  * constants specific to the xdr "protocol"
73*7c478bd9Sstevel@tonic-gate  */
74*7c478bd9Sstevel@tonic-gate #define	XDR_FALSE	((uint_t)0)
75*7c478bd9Sstevel@tonic-gate #define	XDR_TRUE	((uint_t)1)
76*7c478bd9Sstevel@tonic-gate #define	LASTUNSIGNED	((uint_t)0-1)
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate /* fragment size to use when doing an xdr_string() */
79*7c478bd9Sstevel@tonic-gate #define	FRAGMENT	65536
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate /*
82*7c478bd9Sstevel@tonic-gate  * for unit alignment
83*7c478bd9Sstevel@tonic-gate  */
84*7c478bd9Sstevel@tonic-gate static const char xdr_zero[BYTES_PER_XDR_UNIT]	= { 0 };
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate #ifndef KERNEL
87*7c478bd9Sstevel@tonic-gate /*
88*7c478bd9Sstevel@tonic-gate  * Free a data structure using XDR
89*7c478bd9Sstevel@tonic-gate  * Not a filter, but a convenient utility nonetheless
90*7c478bd9Sstevel@tonic-gate  */
91*7c478bd9Sstevel@tonic-gate void
92*7c478bd9Sstevel@tonic-gate xdr_free(xdrproc_t proc, char *objp)
93*7c478bd9Sstevel@tonic-gate {
94*7c478bd9Sstevel@tonic-gate 	XDR x;
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_free, 0);
97*7c478bd9Sstevel@tonic-gate 	x.x_op = XDR_FREE;
98*7c478bd9Sstevel@tonic-gate 	(*proc)(&x, objp);
99*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_free, 1);
100*7c478bd9Sstevel@tonic-gate }
101*7c478bd9Sstevel@tonic-gate #endif
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate /*
104*7c478bd9Sstevel@tonic-gate  * XDR nothing
105*7c478bd9Sstevel@tonic-gate  */
106*7c478bd9Sstevel@tonic-gate bool_t
107*7c478bd9Sstevel@tonic-gate xdr_void()
108*7c478bd9Sstevel@tonic-gate {
109*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_void, 0);
110*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_void, 1);
111*7c478bd9Sstevel@tonic-gate 	return (TRUE);
112*7c478bd9Sstevel@tonic-gate }
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate /*
115*7c478bd9Sstevel@tonic-gate  * xdr_time_t  sends time_t value over the wire.
116*7c478bd9Sstevel@tonic-gate  * Due to RPC Protocol limitation, it can only send
117*7c478bd9Sstevel@tonic-gate  * up to 32-bit integer quantity over the wire.
118*7c478bd9Sstevel@tonic-gate  *
119*7c478bd9Sstevel@tonic-gate  */
120*7c478bd9Sstevel@tonic-gate bool_t
121*7c478bd9Sstevel@tonic-gate xdr_time_t(XDR *xdrs, time_t *tp)
122*7c478bd9Sstevel@tonic-gate {
123*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
124*7c478bd9Sstevel@tonic-gate 	int32_t i;
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_time_t, 0);
127*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
128*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
129*7c478bd9Sstevel@tonic-gate 	/*
130*7c478bd9Sstevel@tonic-gate 	 * Check for the time overflow, when encoding it.
131*7c478bd9Sstevel@tonic-gate 	 * Don't want to send OTW the time value too large to
132*7c478bd9Sstevel@tonic-gate 	 * handle by the protocol.
133*7c478bd9Sstevel@tonic-gate 	 */
134*7c478bd9Sstevel@tonic-gate #if defined(_LP64)
135*7c478bd9Sstevel@tonic-gate 	if (*tp > INT32_MAX)
136*7c478bd9Sstevel@tonic-gate 		*tp = INT32_MAX;
137*7c478bd9Sstevel@tonic-gate 	else if (*tp < INT32_MIN)
138*7c478bd9Sstevel@tonic-gate 		*tp = INT32_MIN;
139*7c478bd9Sstevel@tonic-gate #endif
140*7c478bd9Sstevel@tonic-gate 		i =  (int32_t)*tp;
141*7c478bd9Sstevel@tonic-gate 		dummy = XDR_PUTINT32(xdrs, &i);
142*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_time_t, 1);
143*7c478bd9Sstevel@tonic-gate 		return (dummy);
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
146*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, &i)) {
147*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_time_t, 1);
148*7c478bd9Sstevel@tonic-gate 			return (FALSE);
149*7c478bd9Sstevel@tonic-gate 		}
150*7c478bd9Sstevel@tonic-gate 		*tp = (time_t)i;
151*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_time_t, 1);
152*7c478bd9Sstevel@tonic-gate 		return (TRUE);
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
155*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_time_t, 1);
156*7c478bd9Sstevel@tonic-gate 		return (TRUE);
157*7c478bd9Sstevel@tonic-gate 	}
158*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_time_t, 1);
159*7c478bd9Sstevel@tonic-gate 	return (FALSE);
160*7c478bd9Sstevel@tonic-gate }
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate /*
163*7c478bd9Sstevel@tonic-gate  * XDR integers
164*7c478bd9Sstevel@tonic-gate  */
165*7c478bd9Sstevel@tonic-gate bool_t
166*7c478bd9Sstevel@tonic-gate xdr_int(XDR *xdrs, int *ip)
167*7c478bd9Sstevel@tonic-gate {
168*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_int, 0);
169*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
170*7c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs, ip));
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
173*7c478bd9Sstevel@tonic-gate 		return (XDR_GETINT32(xdrs, ip));
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
176*7c478bd9Sstevel@tonic-gate 		return (TRUE);
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_int, 1);
179*7c478bd9Sstevel@tonic-gate 	return (FALSE);
180*7c478bd9Sstevel@tonic-gate }
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate /*
183*7c478bd9Sstevel@tonic-gate  * XDR unsigned integers
184*7c478bd9Sstevel@tonic-gate  */
185*7c478bd9Sstevel@tonic-gate bool_t
186*7c478bd9Sstevel@tonic-gate xdr_u_int(XDR *xdrs, uint_t *up)
187*7c478bd9Sstevel@tonic-gate {
188*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_int, 0);
189*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
190*7c478bd9Sstevel@tonic-gate 		return (XDR_PUTINT32(xdrs, (int *)up));
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
193*7c478bd9Sstevel@tonic-gate 		return (XDR_GETINT32(xdrs, (int *)up));
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE)
196*7c478bd9Sstevel@tonic-gate 		return (TRUE);
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_int, 1);
199*7c478bd9Sstevel@tonic-gate 	return (FALSE);
200*7c478bd9Sstevel@tonic-gate }
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate #ifndef KERNEL
203*7c478bd9Sstevel@tonic-gate static const char xdrlong_err[] =
204*7c478bd9Sstevel@tonic-gate 			"xdr_%s: value too large to be stored in data type";
205*7c478bd9Sstevel@tonic-gate #endif
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate /*
208*7c478bd9Sstevel@tonic-gate  * The definition of xdr_long()/xdr_u_long() is kept for backward
209*7c478bd9Sstevel@tonic-gate  * compatibitlity.
210*7c478bd9Sstevel@tonic-gate  * XDR long integers, same as xdr_u_long
211*7c478bd9Sstevel@tonic-gate  */
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate bool_t
214*7c478bd9Sstevel@tonic-gate xdr_long(XDR *xdrs, long *lp)
215*7c478bd9Sstevel@tonic-gate {
216*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
217*7c478bd9Sstevel@tonic-gate 	int32_t i;
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_long, 0);
220*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
221*7c478bd9Sstevel@tonic-gate #if defined(_LP64)
222*7c478bd9Sstevel@tonic-gate 		if ((*lp > INT32_MAX) || (*lp < INT32_MIN)) {
223*7c478bd9Sstevel@tonic-gate 			return (FALSE);
224*7c478bd9Sstevel@tonic-gate 		}
225*7c478bd9Sstevel@tonic-gate #endif
226*7c478bd9Sstevel@tonic-gate 		i = (int32_t)*lp;
227*7c478bd9Sstevel@tonic-gate 		dummy = XDR_PUTINT32(xdrs, &i);
228*7c478bd9Sstevel@tonic-gate 	} else if (xdrs->x_op == XDR_DECODE) {
229*7c478bd9Sstevel@tonic-gate 		dummy = XDR_GETINT32(xdrs, &i);
230*7c478bd9Sstevel@tonic-gate 		*lp = (long)i;
231*7c478bd9Sstevel@tonic-gate 	} else if (xdrs->x_op == XDR_FREE)
232*7c478bd9Sstevel@tonic-gate 		dummy = TRUE;
233*7c478bd9Sstevel@tonic-gate 	else
234*7c478bd9Sstevel@tonic-gate 		dummy = FALSE;
235*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_long, 1);
236*7c478bd9Sstevel@tonic-gate 	return (dummy);
237*7c478bd9Sstevel@tonic-gate }
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate /*
240*7c478bd9Sstevel@tonic-gate  * XDR unsigned long integers
241*7c478bd9Sstevel@tonic-gate  * same as xdr_long
242*7c478bd9Sstevel@tonic-gate  */
243*7c478bd9Sstevel@tonic-gate bool_t
244*7c478bd9Sstevel@tonic-gate xdr_u_long(XDR *xdrs, ulong_t *ulp)
245*7c478bd9Sstevel@tonic-gate {
246*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
247*7c478bd9Sstevel@tonic-gate 	uint32_t ui;
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_long, 0);
250*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
251*7c478bd9Sstevel@tonic-gate #if defined(_LP64)
252*7c478bd9Sstevel@tonic-gate 		if (*ulp > UINT32_MAX) {
253*7c478bd9Sstevel@tonic-gate 			return (FALSE);
254*7c478bd9Sstevel@tonic-gate 		}
255*7c478bd9Sstevel@tonic-gate #endif
256*7c478bd9Sstevel@tonic-gate 		ui = (uint32_t)*ulp;
257*7c478bd9Sstevel@tonic-gate 		dummy = XDR_PUTINT32(xdrs, (int32_t *)&ui);
258*7c478bd9Sstevel@tonic-gate 	} else if (xdrs->x_op == XDR_DECODE) {
259*7c478bd9Sstevel@tonic-gate 		dummy = XDR_GETINT32(xdrs, (int32_t *)&ui);
260*7c478bd9Sstevel@tonic-gate 		*ulp = (ulong_t)ui;
261*7c478bd9Sstevel@tonic-gate 	} else if (xdrs->x_op == XDR_FREE)
262*7c478bd9Sstevel@tonic-gate 		dummy = TRUE;
263*7c478bd9Sstevel@tonic-gate 	else
264*7c478bd9Sstevel@tonic-gate 		dummy = FALSE;
265*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_long, 1);
266*7c478bd9Sstevel@tonic-gate 	return (dummy);
267*7c478bd9Sstevel@tonic-gate }
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate /*
270*7c478bd9Sstevel@tonic-gate  * XDR short integers
271*7c478bd9Sstevel@tonic-gate  */
272*7c478bd9Sstevel@tonic-gate bool_t
273*7c478bd9Sstevel@tonic-gate xdr_short(XDR *xdrs, short *sp)
274*7c478bd9Sstevel@tonic-gate {
275*7c478bd9Sstevel@tonic-gate 	int32_t l;
276*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_short, 0);
279*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
282*7c478bd9Sstevel@tonic-gate 		l = (int32_t)*sp;
283*7c478bd9Sstevel@tonic-gate 		dummy = XDR_PUTINT32(xdrs, &l);
284*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_short, 1);
285*7c478bd9Sstevel@tonic-gate 		return (dummy);
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
288*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, &l)) {
289*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_short, 1);
290*7c478bd9Sstevel@tonic-gate 			return (FALSE);
291*7c478bd9Sstevel@tonic-gate 		}
292*7c478bd9Sstevel@tonic-gate 		*sp = (short)l;
293*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_short, 1);
294*7c478bd9Sstevel@tonic-gate 		return (TRUE);
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
297*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_short, 1);
298*7c478bd9Sstevel@tonic-gate 		return (TRUE);
299*7c478bd9Sstevel@tonic-gate 	}
300*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_short, 1);
301*7c478bd9Sstevel@tonic-gate 	return (FALSE);
302*7c478bd9Sstevel@tonic-gate }
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate /*
305*7c478bd9Sstevel@tonic-gate  * XDR unsigned short integers
306*7c478bd9Sstevel@tonic-gate  */
307*7c478bd9Sstevel@tonic-gate bool_t
308*7c478bd9Sstevel@tonic-gate xdr_u_short(XDR *xdrs, ushort_t *usp)
309*7c478bd9Sstevel@tonic-gate {
310*7c478bd9Sstevel@tonic-gate 	uint_t i;
311*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
312*7c478bd9Sstevel@tonic-gate 
313*7c478bd9Sstevel@tonic-gate 
314*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_short, 0);
315*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
316*7c478bd9Sstevel@tonic-gate 
317*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
318*7c478bd9Sstevel@tonic-gate 		i = (uint_t)*usp;
319*7c478bd9Sstevel@tonic-gate 		dummy = XDR_PUTINT32(xdrs, (int *)&i);
320*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_u_short, 1);
321*7c478bd9Sstevel@tonic-gate 		return (dummy);
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
324*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, (int *)&i)) {
325*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
326*7c478bd9Sstevel@tonic-gate 			printf("xdr_u_short: decode FAILED\n");
327*7c478bd9Sstevel@tonic-gate #endif
328*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_u_short, 1);
329*7c478bd9Sstevel@tonic-gate 			return (FALSE);
330*7c478bd9Sstevel@tonic-gate 		}
331*7c478bd9Sstevel@tonic-gate 		*usp = (ushort_t)i;
332*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_u_short, 1);
333*7c478bd9Sstevel@tonic-gate 		return (TRUE);
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
336*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_u_short, 1);
337*7c478bd9Sstevel@tonic-gate 		return (TRUE);
338*7c478bd9Sstevel@tonic-gate 	}
339*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
340*7c478bd9Sstevel@tonic-gate 	printf("xdr_u_short: bad op FAILED\n");
341*7c478bd9Sstevel@tonic-gate #endif
342*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_short, 1);
343*7c478bd9Sstevel@tonic-gate 	return (FALSE);
344*7c478bd9Sstevel@tonic-gate }
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 
347*7c478bd9Sstevel@tonic-gate /*
348*7c478bd9Sstevel@tonic-gate  * XDR a char
349*7c478bd9Sstevel@tonic-gate  */
350*7c478bd9Sstevel@tonic-gate bool_t
351*7c478bd9Sstevel@tonic-gate xdr_char(XDR *xdrs, char *cp)
352*7c478bd9Sstevel@tonic-gate {
353*7c478bd9Sstevel@tonic-gate 	int i;
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_char, 0);
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
358*7c478bd9Sstevel@tonic-gate 		i = (*cp);
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate 	if (! xdr_int(xdrs, &i)) {
361*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_char, 1);
362*7c478bd9Sstevel@tonic-gate 		return (FALSE);
363*7c478bd9Sstevel@tonic-gate 	}
364*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
365*7c478bd9Sstevel@tonic-gate 		*cp = (char)i;
366*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_char, 1);
367*7c478bd9Sstevel@tonic-gate 	return (TRUE);
368*7c478bd9Sstevel@tonic-gate }
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate #ifndef KERNEL
371*7c478bd9Sstevel@tonic-gate /*
372*7c478bd9Sstevel@tonic-gate  * XDR an unsigned char
373*7c478bd9Sstevel@tonic-gate  */
374*7c478bd9Sstevel@tonic-gate bool_t
375*7c478bd9Sstevel@tonic-gate xdr_u_char(XDR *xdrs, uchar_t *cp)
376*7c478bd9Sstevel@tonic-gate {
377*7c478bd9Sstevel@tonic-gate 	int i;
378*7c478bd9Sstevel@tonic-gate 
379*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_char, 0);
380*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE)
381*7c478bd9Sstevel@tonic-gate 		i = (*cp);
382*7c478bd9Sstevel@tonic-gate 	if (! xdr_int(xdrs, &i)) {
383*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_u_char, 1);
384*7c478bd9Sstevel@tonic-gate 		return (FALSE);
385*7c478bd9Sstevel@tonic-gate 	}
386*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE)
387*7c478bd9Sstevel@tonic-gate 		*cp = (uchar_t)i;
388*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_char, 1);
389*7c478bd9Sstevel@tonic-gate 	return (TRUE);
390*7c478bd9Sstevel@tonic-gate }
391*7c478bd9Sstevel@tonic-gate #endif /* !KERNEL */
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate /*
394*7c478bd9Sstevel@tonic-gate  * XDR booleans
395*7c478bd9Sstevel@tonic-gate  */
396*7c478bd9Sstevel@tonic-gate bool_t
397*7c478bd9Sstevel@tonic-gate xdr_bool(XDR *xdrs, bool_t *bp)
398*7c478bd9Sstevel@tonic-gate {
399*7c478bd9Sstevel@tonic-gate 	int i;
400*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_bool, 0);
403*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
406*7c478bd9Sstevel@tonic-gate 		i = *bp ? XDR_TRUE : XDR_FALSE;
407*7c478bd9Sstevel@tonic-gate 		dummy = XDR_PUTINT32(xdrs, &i);
408*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_bool, 1);
409*7c478bd9Sstevel@tonic-gate 		return (dummy);
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
412*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETINT32(xdrs, &i)) {
413*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
414*7c478bd9Sstevel@tonic-gate 			printf("xdr_bool: decode FAILED\n");
415*7c478bd9Sstevel@tonic-gate #endif
416*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_bool, 1);
417*7c478bd9Sstevel@tonic-gate 			return (FALSE);
418*7c478bd9Sstevel@tonic-gate 		}
419*7c478bd9Sstevel@tonic-gate 		*bp = (i == XDR_FALSE) ? FALSE : TRUE;
420*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_bool, 1);
421*7c478bd9Sstevel@tonic-gate 		return (TRUE);
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
424*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_bool, 1);
425*7c478bd9Sstevel@tonic-gate 		return (TRUE);
426*7c478bd9Sstevel@tonic-gate 	}
427*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
428*7c478bd9Sstevel@tonic-gate 	printf("xdr_bool: bad op FAILED\n");
429*7c478bd9Sstevel@tonic-gate #endif
430*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_bool, 1);
431*7c478bd9Sstevel@tonic-gate 	return (FALSE);
432*7c478bd9Sstevel@tonic-gate }
433*7c478bd9Sstevel@tonic-gate 
434*7c478bd9Sstevel@tonic-gate /*
435*7c478bd9Sstevel@tonic-gate  * XDR enumerations
436*7c478bd9Sstevel@tonic-gate  */
437*7c478bd9Sstevel@tonic-gate bool_t
438*7c478bd9Sstevel@tonic-gate xdr_enum(XDR *xdrs, enum_t *ep)
439*7c478bd9Sstevel@tonic-gate {
440*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
441*7c478bd9Sstevel@tonic-gate 
442*7c478bd9Sstevel@tonic-gate #ifndef lint
443*7c478bd9Sstevel@tonic-gate 	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 	/*
446*7c478bd9Sstevel@tonic-gate 	 * enums are treated as ints
447*7c478bd9Sstevel@tonic-gate 	 */
448*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_enum, 0);
449*7c478bd9Sstevel@tonic-gate 	if (sizeof (enum sizecheck) == sizeof (int32_t)) {
450*7c478bd9Sstevel@tonic-gate 		dummy = xdr_int(xdrs, (int *)ep);
451*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_enum, 1);
452*7c478bd9Sstevel@tonic-gate 		return (dummy);
453*7c478bd9Sstevel@tonic-gate 	} else if (sizeof (enum sizecheck) == sizeof (short)) {
454*7c478bd9Sstevel@tonic-gate 		dummy = xdr_short(xdrs, (short *)ep);
455*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_enum, 1);
456*7c478bd9Sstevel@tonic-gate 		return (dummy);
457*7c478bd9Sstevel@tonic-gate 	} else if (sizeof (enum sizecheck) == sizeof (char)) {
458*7c478bd9Sstevel@tonic-gate 		dummy = xdr_char(xdrs, (char *)ep);
459*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_enum, 1);
460*7c478bd9Sstevel@tonic-gate 		return (dummy);
461*7c478bd9Sstevel@tonic-gate 	} else {
462*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_enum, 1);
463*7c478bd9Sstevel@tonic-gate 		return (FALSE);
464*7c478bd9Sstevel@tonic-gate 	}
465*7c478bd9Sstevel@tonic-gate #else
466*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_enum, 0);
467*7c478bd9Sstevel@tonic-gate 	(void) (xdr_char(xdrs, (char *)ep));
468*7c478bd9Sstevel@tonic-gate 	(void) (xdr_short(xdrs, (short *)ep));
469*7c478bd9Sstevel@tonic-gate 	dummy = xdr_int(xdrs, (int32_t *)ep);
470*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_enum, 1);
471*7c478bd9Sstevel@tonic-gate 	return (dummy);
472*7c478bd9Sstevel@tonic-gate #endif
473*7c478bd9Sstevel@tonic-gate }
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate /*
476*7c478bd9Sstevel@tonic-gate  * XDR opaque data
477*7c478bd9Sstevel@tonic-gate  * Allows the specification of a fixed size sequence of opaque bytes.
478*7c478bd9Sstevel@tonic-gate  * cp points to the opaque object and cnt gives the byte length.
479*7c478bd9Sstevel@tonic-gate  */
480*7c478bd9Sstevel@tonic-gate bool_t
481*7c478bd9Sstevel@tonic-gate xdr_opaque(XDR *xdrs, caddr_t cp, uint_t cnt)
482*7c478bd9Sstevel@tonic-gate {
483*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
484*7c478bd9Sstevel@tonic-gate 	register uint_t rndup;
485*7c478bd9Sstevel@tonic-gate 	char crud[BYTES_PER_XDR_UNIT];
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 	/*
488*7c478bd9Sstevel@tonic-gate 	 * if no data we are done
489*7c478bd9Sstevel@tonic-gate 	 */
490*7c478bd9Sstevel@tonic-gate 	trace2(TR_xdr_opaque, 0, cnt);
491*7c478bd9Sstevel@tonic-gate 	if (cnt == 0) {
492*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_opaque, 1);
493*7c478bd9Sstevel@tonic-gate 		return (TRUE);
494*7c478bd9Sstevel@tonic-gate 	}
495*7c478bd9Sstevel@tonic-gate 
496*7c478bd9Sstevel@tonic-gate 	/*
497*7c478bd9Sstevel@tonic-gate 	 * round byte count to full xdr units
498*7c478bd9Sstevel@tonic-gate 	 */
499*7c478bd9Sstevel@tonic-gate 	rndup = cnt % BYTES_PER_XDR_UNIT;
500*7c478bd9Sstevel@tonic-gate 	if ((int)rndup > 0)
501*7c478bd9Sstevel@tonic-gate 		rndup = BYTES_PER_XDR_UNIT - rndup;
502*7c478bd9Sstevel@tonic-gate 
503*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_DECODE) {
504*7c478bd9Sstevel@tonic-gate 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
505*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
506*7c478bd9Sstevel@tonic-gate 			printf("xdr_opaque: decode FAILED\n");
507*7c478bd9Sstevel@tonic-gate #endif
508*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_opaque, 1);
509*7c478bd9Sstevel@tonic-gate 			return (FALSE);
510*7c478bd9Sstevel@tonic-gate 		}
511*7c478bd9Sstevel@tonic-gate 		if (rndup == 0) {
512*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_opaque, 1);
513*7c478bd9Sstevel@tonic-gate 			return (TRUE);
514*7c478bd9Sstevel@tonic-gate 		}
515*7c478bd9Sstevel@tonic-gate 		dummy = XDR_GETBYTES(xdrs, crud, rndup);
516*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_opaque, 1);
517*7c478bd9Sstevel@tonic-gate 		return (dummy);
518*7c478bd9Sstevel@tonic-gate 	}
519*7c478bd9Sstevel@tonic-gate 
520*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
521*7c478bd9Sstevel@tonic-gate 
522*7c478bd9Sstevel@tonic-gate 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
523*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
524*7c478bd9Sstevel@tonic-gate 			printf("xdr_opaque: encode FAILED\n");
525*7c478bd9Sstevel@tonic-gate #endif
526*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_opaque, 1);
527*7c478bd9Sstevel@tonic-gate 			return (FALSE);
528*7c478bd9Sstevel@tonic-gate 		}
529*7c478bd9Sstevel@tonic-gate 		if (rndup == 0) {
530*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_opaque, 1);
531*7c478bd9Sstevel@tonic-gate 			return (TRUE);
532*7c478bd9Sstevel@tonic-gate 		}
533*7c478bd9Sstevel@tonic-gate 		dummy = XDR_PUTBYTES(xdrs, (caddr_t)&xdr_zero[0], rndup);
534*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_opaque, 1);
535*7c478bd9Sstevel@tonic-gate 		return (dummy);
536*7c478bd9Sstevel@tonic-gate 	}
537*7c478bd9Sstevel@tonic-gate 
538*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_FREE) {
539*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_opaque, 1);
540*7c478bd9Sstevel@tonic-gate 		return (TRUE);
541*7c478bd9Sstevel@tonic-gate 	}
542*7c478bd9Sstevel@tonic-gate 
543*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
544*7c478bd9Sstevel@tonic-gate 	printf("xdr_opaque: bad op FAILED\n");
545*7c478bd9Sstevel@tonic-gate #endif
546*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_opaque, 1);
547*7c478bd9Sstevel@tonic-gate 	return (FALSE);
548*7c478bd9Sstevel@tonic-gate }
549*7c478bd9Sstevel@tonic-gate 
550*7c478bd9Sstevel@tonic-gate /*
551*7c478bd9Sstevel@tonic-gate  * XDR counted bytes
552*7c478bd9Sstevel@tonic-gate  * *cpp is a pointer to the bytes, *sizep is the count.
553*7c478bd9Sstevel@tonic-gate  * If *cpp is NULL maxsize bytes are allocated
554*7c478bd9Sstevel@tonic-gate  */
555*7c478bd9Sstevel@tonic-gate 
556*7c478bd9Sstevel@tonic-gate #ifndef KERNEL
557*7c478bd9Sstevel@tonic-gate static const char xdr_err[] = "xdr_%s: out of memory";
558*7c478bd9Sstevel@tonic-gate #endif
559*7c478bd9Sstevel@tonic-gate 
560*7c478bd9Sstevel@tonic-gate bool_t
561*7c478bd9Sstevel@tonic-gate xdr_bytes(XDR *xdrs, char **cpp, uint_t *sizep, uint_t maxsize)
562*7c478bd9Sstevel@tonic-gate {
563*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
564*7c478bd9Sstevel@tonic-gate 	register char *sp = *cpp;  /* sp is the actual string pointer */
565*7c478bd9Sstevel@tonic-gate 	register uint_t nodesize;
566*7c478bd9Sstevel@tonic-gate 
567*7c478bd9Sstevel@tonic-gate 	/*
568*7c478bd9Sstevel@tonic-gate 	 * first deal with the length since xdr bytes are counted
569*7c478bd9Sstevel@tonic-gate 	 * We decided not to use MACRO XDR_U_INT here, because the
570*7c478bd9Sstevel@tonic-gate 	 * advantages here will be miniscule compared to xdr_bytes.
571*7c478bd9Sstevel@tonic-gate 	 * This saved us 100 bytes in the library size.
572*7c478bd9Sstevel@tonic-gate 	 */
573*7c478bd9Sstevel@tonic-gate 	trace2(TR_xdr_bytes, 0, maxsize);
574*7c478bd9Sstevel@tonic-gate 	if (! xdr_u_int(xdrs, sizep)) {
575*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
576*7c478bd9Sstevel@tonic-gate 		printf("xdr_bytes: size FAILED\n");
577*7c478bd9Sstevel@tonic-gate #endif
578*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_bytes, 1);
579*7c478bd9Sstevel@tonic-gate 		return (FALSE);
580*7c478bd9Sstevel@tonic-gate 	}
581*7c478bd9Sstevel@tonic-gate 	nodesize = *sizep;
582*7c478bd9Sstevel@tonic-gate 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
583*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
584*7c478bd9Sstevel@tonic-gate 		printf("xdr_bytes: bad size FAILED\n");
585*7c478bd9Sstevel@tonic-gate #endif
586*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_bytes, 1);
587*7c478bd9Sstevel@tonic-gate 		return (FALSE);
588*7c478bd9Sstevel@tonic-gate 	}
589*7c478bd9Sstevel@tonic-gate 
590*7c478bd9Sstevel@tonic-gate 	/*
591*7c478bd9Sstevel@tonic-gate 	 * now deal with the actual bytes
592*7c478bd9Sstevel@tonic-gate 	 */
593*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
594*7c478bd9Sstevel@tonic-gate 
595*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
596*7c478bd9Sstevel@tonic-gate 		if (nodesize == 0) {
597*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_bytes, 1);
598*7c478bd9Sstevel@tonic-gate 			return (TRUE);
599*7c478bd9Sstevel@tonic-gate 		}
600*7c478bd9Sstevel@tonic-gate 		if (sp == NULL) {
601*7c478bd9Sstevel@tonic-gate 			*cpp = sp = (char *)mem_alloc(nodesize);
602*7c478bd9Sstevel@tonic-gate 		}
603*7c478bd9Sstevel@tonic-gate #ifndef KERNEL
604*7c478bd9Sstevel@tonic-gate 		if (sp == NULL) {
605*7c478bd9Sstevel@tonic-gate 			(void) syslog(LOG_ERR, xdr_err, (const char *)"bytes");
606*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_bytes, 1);
607*7c478bd9Sstevel@tonic-gate 			return (FALSE);
608*7c478bd9Sstevel@tonic-gate 		}
609*7c478bd9Sstevel@tonic-gate #endif
610*7c478bd9Sstevel@tonic-gate 		/*FALLTHROUGH*/
611*7c478bd9Sstevel@tonic-gate 
612*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
613*7c478bd9Sstevel@tonic-gate 		dummy = xdr_opaque(xdrs, sp, nodesize);
614*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_bytes, 1);
615*7c478bd9Sstevel@tonic-gate 		return (dummy);
616*7c478bd9Sstevel@tonic-gate 
617*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
618*7c478bd9Sstevel@tonic-gate 		if (sp != NULL) {
619*7c478bd9Sstevel@tonic-gate 			mem_free(sp, nodesize);
620*7c478bd9Sstevel@tonic-gate 			*cpp = NULL;
621*7c478bd9Sstevel@tonic-gate 		}
622*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_bytes, 1);
623*7c478bd9Sstevel@tonic-gate 		return (TRUE);
624*7c478bd9Sstevel@tonic-gate 	}
625*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
626*7c478bd9Sstevel@tonic-gate 	printf("xdr_bytes: bad op FAILED\n");
627*7c478bd9Sstevel@tonic-gate #endif
628*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_bytes, 1);
629*7c478bd9Sstevel@tonic-gate 	return (FALSE);
630*7c478bd9Sstevel@tonic-gate }
631*7c478bd9Sstevel@tonic-gate 
632*7c478bd9Sstevel@tonic-gate /*
633*7c478bd9Sstevel@tonic-gate  * Implemented here due to commonality of the object.
634*7c478bd9Sstevel@tonic-gate  */
635*7c478bd9Sstevel@tonic-gate bool_t
636*7c478bd9Sstevel@tonic-gate xdr_netobj(XDR *xdrs, struct netobj *np)
637*7c478bd9Sstevel@tonic-gate {
638*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
639*7c478bd9Sstevel@tonic-gate 
640*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_netobj, 0);
641*7c478bd9Sstevel@tonic-gate 	dummy = xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ);
642*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_netobj, 1);
643*7c478bd9Sstevel@tonic-gate 	return (dummy);
644*7c478bd9Sstevel@tonic-gate }
645*7c478bd9Sstevel@tonic-gate 
646*7c478bd9Sstevel@tonic-gate /*
647*7c478bd9Sstevel@tonic-gate  * XDR a descriminated union
648*7c478bd9Sstevel@tonic-gate  * Support routine for discriminated unions.
649*7c478bd9Sstevel@tonic-gate  * You create an array of xdrdiscrim structures, terminated with
650*7c478bd9Sstevel@tonic-gate  * an entry with a null procedure pointer.  The routine gets
651*7c478bd9Sstevel@tonic-gate  * the discriminant value and then searches the array of xdrdiscrims
652*7c478bd9Sstevel@tonic-gate  * looking for that value.  It calls the procedure given in the xdrdiscrim
653*7c478bd9Sstevel@tonic-gate  * to handle the discriminant.  If there is no specific routine a default
654*7c478bd9Sstevel@tonic-gate  * routine may be called.
655*7c478bd9Sstevel@tonic-gate  * If there is no specific or default routine an error is returned.
656*7c478bd9Sstevel@tonic-gate  */
657*7c478bd9Sstevel@tonic-gate bool_t
658*7c478bd9Sstevel@tonic-gate xdr_union(XDR *xdrs, enum_t *dscmp, char *unp,
659*7c478bd9Sstevel@tonic-gate 		const struct xdr_discrim *choices, xdrproc_t dfault)
660*7c478bd9Sstevel@tonic-gate {
661*7c478bd9Sstevel@tonic-gate 	register enum_t dscm;
662*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
663*7c478bd9Sstevel@tonic-gate 
664*7c478bd9Sstevel@tonic-gate 	/*
665*7c478bd9Sstevel@tonic-gate 	 * we deal with the discriminator;  it's an enum
666*7c478bd9Sstevel@tonic-gate 	 */
667*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_union, 0);
668*7c478bd9Sstevel@tonic-gate 	if (! xdr_enum(xdrs, dscmp)) {
669*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
670*7c478bd9Sstevel@tonic-gate 		printf("xdr_enum: dscmp FAILED\n");
671*7c478bd9Sstevel@tonic-gate #endif
672*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_union, 1);
673*7c478bd9Sstevel@tonic-gate 		return (FALSE);
674*7c478bd9Sstevel@tonic-gate 	}
675*7c478bd9Sstevel@tonic-gate 	dscm = *dscmp;
676*7c478bd9Sstevel@tonic-gate 
677*7c478bd9Sstevel@tonic-gate 	/*
678*7c478bd9Sstevel@tonic-gate 	 * search choices for a value that matches the discriminator.
679*7c478bd9Sstevel@tonic-gate 	 * if we find one, execute the xdr routine for that value.
680*7c478bd9Sstevel@tonic-gate 	 */
681*7c478bd9Sstevel@tonic-gate 	for (; choices->proc != NULL_xdrproc_t; choices++) {
682*7c478bd9Sstevel@tonic-gate 		if (choices->value == dscm) {
683*7c478bd9Sstevel@tonic-gate 			dummy = (*(choices->proc))(xdrs, unp, LASTUNSIGNED);
684*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_union, 1);
685*7c478bd9Sstevel@tonic-gate 			return (dummy);
686*7c478bd9Sstevel@tonic-gate 		}
687*7c478bd9Sstevel@tonic-gate 	}
688*7c478bd9Sstevel@tonic-gate 
689*7c478bd9Sstevel@tonic-gate 	/*
690*7c478bd9Sstevel@tonic-gate 	 * no match - execute the default xdr routine if there is one
691*7c478bd9Sstevel@tonic-gate 	 */
692*7c478bd9Sstevel@tonic-gate 	dummy = (dfault == NULL_xdrproc_t) ? FALSE :
693*7c478bd9Sstevel@tonic-gate 	    (*dfault)(xdrs, unp, LASTUNSIGNED);
694*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_union, 1);
695*7c478bd9Sstevel@tonic-gate 	return (dummy);
696*7c478bd9Sstevel@tonic-gate }
697*7c478bd9Sstevel@tonic-gate 
698*7c478bd9Sstevel@tonic-gate 
699*7c478bd9Sstevel@tonic-gate /*
700*7c478bd9Sstevel@tonic-gate  * Non-portable xdr primitives.
701*7c478bd9Sstevel@tonic-gate  * Care should be taken when moving these routines to new architectures.
702*7c478bd9Sstevel@tonic-gate  */
703*7c478bd9Sstevel@tonic-gate 
704*7c478bd9Sstevel@tonic-gate 
705*7c478bd9Sstevel@tonic-gate /*
706*7c478bd9Sstevel@tonic-gate  * XDR null terminated ASCII strings
707*7c478bd9Sstevel@tonic-gate  * xdr_string deals with "C strings" - arrays of bytes that are
708*7c478bd9Sstevel@tonic-gate  * terminated by a NULL character.  The parameter cpp references a
709*7c478bd9Sstevel@tonic-gate  * pointer to storage; If the pointer is null, then the necessary
710*7c478bd9Sstevel@tonic-gate  * storage is allocated.  The last parameter is the max allowed length
711*7c478bd9Sstevel@tonic-gate  * of the string as specified by a protocol.
712*7c478bd9Sstevel@tonic-gate  */
713*7c478bd9Sstevel@tonic-gate bool_t
714*7c478bd9Sstevel@tonic-gate xdr_string(XDR *xdrs, char **cpp, uint_t maxsize)
715*7c478bd9Sstevel@tonic-gate {
716*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
717*7c478bd9Sstevel@tonic-gate 	register char *newsp, *sp = *cpp;  /* sp is the actual string pointer */
718*7c478bd9Sstevel@tonic-gate 	uint_t size, block;
719*7c478bd9Sstevel@tonic-gate 	uint64_t bytesread;
720*7c478bd9Sstevel@tonic-gate 
721*7c478bd9Sstevel@tonic-gate 	/*
722*7c478bd9Sstevel@tonic-gate 	 * first deal with the length since xdr strings are counted-strings
723*7c478bd9Sstevel@tonic-gate 	 */
724*7c478bd9Sstevel@tonic-gate 	trace2(TR_xdr_string, 0, maxsize);
725*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
726*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
727*7c478bd9Sstevel@tonic-gate 		if (sp == NULL) {
728*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_string, 1);
729*7c478bd9Sstevel@tonic-gate 			return (TRUE);	/* already free */
730*7c478bd9Sstevel@tonic-gate 		}
731*7c478bd9Sstevel@tonic-gate 		/*FALLTHROUGH*/
732*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
733*7c478bd9Sstevel@tonic-gate 		size = (sp != NULL) ? (uint_t)strlen(sp) : 0;
734*7c478bd9Sstevel@tonic-gate 		break;
735*7c478bd9Sstevel@tonic-gate 	}
736*7c478bd9Sstevel@tonic-gate 	/*
737*7c478bd9Sstevel@tonic-gate 	 * We decided not to use MACRO XDR_U_INT here, because the
738*7c478bd9Sstevel@tonic-gate 	 * advantages here will be miniscule compared to xdr_string.
739*7c478bd9Sstevel@tonic-gate 	 * This saved us 100 bytes in the library size.
740*7c478bd9Sstevel@tonic-gate 	 */
741*7c478bd9Sstevel@tonic-gate 	if (! xdr_u_int(xdrs, &size)) {
742*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_string, 1);
743*7c478bd9Sstevel@tonic-gate 		return (FALSE);
744*7c478bd9Sstevel@tonic-gate 	}
745*7c478bd9Sstevel@tonic-gate 	if (size > maxsize) {
746*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_string, 1);
747*7c478bd9Sstevel@tonic-gate 		return (FALSE);
748*7c478bd9Sstevel@tonic-gate 	}
749*7c478bd9Sstevel@tonic-gate 
750*7c478bd9Sstevel@tonic-gate 	/*
751*7c478bd9Sstevel@tonic-gate 	 * now deal with the actual bytes
752*7c478bd9Sstevel@tonic-gate 	 */
753*7c478bd9Sstevel@tonic-gate 	switch (xdrs->x_op) {
754*7c478bd9Sstevel@tonic-gate 
755*7c478bd9Sstevel@tonic-gate 	case XDR_DECODE:
756*7c478bd9Sstevel@tonic-gate 		/* if buffer is already given, call xdr_opaque() directly */
757*7c478bd9Sstevel@tonic-gate 		if (sp != NULL) {
758*7c478bd9Sstevel@tonic-gate 			dummy = xdr_opaque(xdrs, sp, size);
759*7c478bd9Sstevel@tonic-gate 			sp[size] = 0;
760*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_string, 1);
761*7c478bd9Sstevel@tonic-gate 			return (dummy);
762*7c478bd9Sstevel@tonic-gate 		}
763*7c478bd9Sstevel@tonic-gate 
764*7c478bd9Sstevel@tonic-gate 		/*
765*7c478bd9Sstevel@tonic-gate 		 * We have to allocate a buffer of size 'size'. To avoid
766*7c478bd9Sstevel@tonic-gate 		 * malloc()ing one huge chunk, we'll read the bytes in max
767*7c478bd9Sstevel@tonic-gate 		 * FRAGMENT size blocks and keep realloc()ing. 'block' is
768*7c478bd9Sstevel@tonic-gate 		 * the number of bytes to read in each xdr_opaque() and
769*7c478bd9Sstevel@tonic-gate 		 * 'bytesread' is what we have already read. sp is NULL
770*7c478bd9Sstevel@tonic-gate 		 * when we are in the loop for the first time.
771*7c478bd9Sstevel@tonic-gate 		 */
772*7c478bd9Sstevel@tonic-gate 		bytesread = 0;
773*7c478bd9Sstevel@tonic-gate 		do {
774*7c478bd9Sstevel@tonic-gate 			block = MIN(size - bytesread, FRAGMENT);
775*7c478bd9Sstevel@tonic-gate 			/*
776*7c478bd9Sstevel@tonic-gate 			 * allocate enough for 'bytesread + block' bytes and
777*7c478bd9Sstevel@tonic-gate 			 * one extra for the terminating NULL.
778*7c478bd9Sstevel@tonic-gate 			 */
779*7c478bd9Sstevel@tonic-gate 			newsp = realloc(sp, bytesread + block + 1);
780*7c478bd9Sstevel@tonic-gate 			if (newsp == NULL) {
781*7c478bd9Sstevel@tonic-gate 				if (sp != NULL)
782*7c478bd9Sstevel@tonic-gate 					free(sp);
783*7c478bd9Sstevel@tonic-gate 				trace1(TR_xdr_string, 1);
784*7c478bd9Sstevel@tonic-gate 				return (FALSE);
785*7c478bd9Sstevel@tonic-gate 			}
786*7c478bd9Sstevel@tonic-gate 			sp = newsp;
787*7c478bd9Sstevel@tonic-gate 			if (!xdr_opaque(xdrs, &sp[bytesread], block)) {
788*7c478bd9Sstevel@tonic-gate 				free(sp);
789*7c478bd9Sstevel@tonic-gate 				trace1(TR_xdr_string, 1);
790*7c478bd9Sstevel@tonic-gate 				return (FALSE);
791*7c478bd9Sstevel@tonic-gate 			}
792*7c478bd9Sstevel@tonic-gate 			bytesread += block;
793*7c478bd9Sstevel@tonic-gate 		} while (bytesread < size);
794*7c478bd9Sstevel@tonic-gate 
795*7c478bd9Sstevel@tonic-gate 		sp[bytesread] = 0; /* terminate the string with a NULL */
796*7c478bd9Sstevel@tonic-gate 		*cpp = sp;
797*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_string, 1);
798*7c478bd9Sstevel@tonic-gate 		return (TRUE);
799*7c478bd9Sstevel@tonic-gate 	case XDR_ENCODE:
800*7c478bd9Sstevel@tonic-gate 		dummy = xdr_opaque(xdrs, sp, size);
801*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_string, 1);
802*7c478bd9Sstevel@tonic-gate 		return (dummy);
803*7c478bd9Sstevel@tonic-gate 	case XDR_FREE:
804*7c478bd9Sstevel@tonic-gate 		free(sp);
805*7c478bd9Sstevel@tonic-gate 		*cpp = NULL;
806*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_string, 1);
807*7c478bd9Sstevel@tonic-gate 		return (TRUE);
808*7c478bd9Sstevel@tonic-gate 	}
809*7c478bd9Sstevel@tonic-gate #ifdef KERNEL
810*7c478bd9Sstevel@tonic-gate 	printf("xdr_string: bad op FAILED\n");
811*7c478bd9Sstevel@tonic-gate #endif
812*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_string, 1);
813*7c478bd9Sstevel@tonic-gate 	return (FALSE);
814*7c478bd9Sstevel@tonic-gate }
815*7c478bd9Sstevel@tonic-gate 
816*7c478bd9Sstevel@tonic-gate bool_t
817*7c478bd9Sstevel@tonic-gate xdr_hyper(XDR *xdrs, longlong_t *hp)
818*7c478bd9Sstevel@tonic-gate {
819*7c478bd9Sstevel@tonic-gate 	bool_t	dummy;
820*7c478bd9Sstevel@tonic-gate 
821*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_hyper, 0);
822*7c478bd9Sstevel@tonic-gate 	if (xdrs->x_op == XDR_ENCODE) {
823*7c478bd9Sstevel@tonic-gate #if defined(_LONG_LONG_HTOL)
824*7c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int *)hp) == TRUE) {
825*7c478bd9Sstevel@tonic-gate 			dummy = XDR_PUTINT32(xdrs, (int *)((char *)hp +
826*7c478bd9Sstevel@tonic-gate 				BYTES_PER_XDR_UNIT));
827*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_hyper, 1);
828*7c478bd9Sstevel@tonic-gate 			return (dummy);
829*7c478bd9Sstevel@tonic-gate 		}
830*7c478bd9Sstevel@tonic-gate 
831*7c478bd9Sstevel@tonic-gate #else
832*7c478bd9Sstevel@tonic-gate 		if (XDR_PUTINT32(xdrs, (int *)((char *)hp +
833*7c478bd9Sstevel@tonic-gate 			BYTES_PER_XDR_UNIT)) == TRUE) {
834*7c478bd9Sstevel@tonic-gate 			dummy = XDR_PUTINT32(xdrs, (int32_t *)hp);
835*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_hyper, 1);
836*7c478bd9Sstevel@tonic-gate 			return (dummy);
837*7c478bd9Sstevel@tonic-gate 		}
838*7c478bd9Sstevel@tonic-gate 
839*7c478bd9Sstevel@tonic-gate #endif
840*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_hyper, 1);
841*7c478bd9Sstevel@tonic-gate 		return (FALSE);
842*7c478bd9Sstevel@tonic-gate 
843*7c478bd9Sstevel@tonic-gate 	} else if (xdrs->x_op == XDR_DECODE) {
844*7c478bd9Sstevel@tonic-gate #if defined(_LONG_LONG_HTOL)
845*7c478bd9Sstevel@tonic-gate 		if (XDR_GETINT32(xdrs, (int *)hp) == FALSE ||
846*7c478bd9Sstevel@tonic-gate 		    (XDR_GETINT32(xdrs, (int *)((char *)hp +
847*7c478bd9Sstevel@tonic-gate 				BYTES_PER_XDR_UNIT)) == FALSE)) {
848*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_hyper, 1);
849*7c478bd9Sstevel@tonic-gate 			return (FALSE);
850*7c478bd9Sstevel@tonic-gate 		}
851*7c478bd9Sstevel@tonic-gate #else
852*7c478bd9Sstevel@tonic-gate 		if ((XDR_GETINT32(xdrs, (int *)((char *)hp +
853*7c478bd9Sstevel@tonic-gate 				BYTES_PER_XDR_UNIT)) == FALSE) ||
854*7c478bd9Sstevel@tonic-gate 				(XDR_GETINT32(xdrs, (int *)hp) == FALSE)) {
855*7c478bd9Sstevel@tonic-gate 			trace1(TR_xdr_hyper, 1);
856*7c478bd9Sstevel@tonic-gate 			return (FALSE);
857*7c478bd9Sstevel@tonic-gate 		}
858*7c478bd9Sstevel@tonic-gate #endif
859*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_hyper, 1);
860*7c478bd9Sstevel@tonic-gate 		return (TRUE);
861*7c478bd9Sstevel@tonic-gate 	}
862*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_hyper, 1);
863*7c478bd9Sstevel@tonic-gate 	return (TRUE);
864*7c478bd9Sstevel@tonic-gate }
865*7c478bd9Sstevel@tonic-gate 
866*7c478bd9Sstevel@tonic-gate bool_t
867*7c478bd9Sstevel@tonic-gate xdr_u_hyper(XDR *xdrs, u_longlong_t *hp)
868*7c478bd9Sstevel@tonic-gate {
869*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
870*7c478bd9Sstevel@tonic-gate 
871*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_hyper, 0);
872*7c478bd9Sstevel@tonic-gate 	dummy = xdr_hyper(xdrs, (longlong_t *)hp);
873*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_hyper, 1);
874*7c478bd9Sstevel@tonic-gate 	return (dummy);
875*7c478bd9Sstevel@tonic-gate }
876*7c478bd9Sstevel@tonic-gate 
877*7c478bd9Sstevel@tonic-gate bool_t
878*7c478bd9Sstevel@tonic-gate xdr_longlong_t(XDR *xdrs, longlong_t *hp)
879*7c478bd9Sstevel@tonic-gate {
880*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
881*7c478bd9Sstevel@tonic-gate 
882*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_longlong_t, 0);
883*7c478bd9Sstevel@tonic-gate 	dummy = xdr_hyper(xdrs, hp);
884*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_longlong_t, 1);
885*7c478bd9Sstevel@tonic-gate 	return (dummy);
886*7c478bd9Sstevel@tonic-gate }
887*7c478bd9Sstevel@tonic-gate 
888*7c478bd9Sstevel@tonic-gate bool_t
889*7c478bd9Sstevel@tonic-gate xdr_u_longlong_t(XDR *xdrs, u_longlong_t *hp)
890*7c478bd9Sstevel@tonic-gate {
891*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
892*7c478bd9Sstevel@tonic-gate 
893*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_longlong_t, 0);
894*7c478bd9Sstevel@tonic-gate 	dummy = xdr_hyper(xdrs, (longlong_t *)hp);
895*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_longlong_t, 1);
896*7c478bd9Sstevel@tonic-gate 	return (dummy);
897*7c478bd9Sstevel@tonic-gate }
898*7c478bd9Sstevel@tonic-gate /*
899*7c478bd9Sstevel@tonic-gate  * The following routine is part of a workaround for bug
900*7c478bd9Sstevel@tonic-gate  * #1128007.  When it is fixed, this routine should be
901*7c478bd9Sstevel@tonic-gate  * removed.
902*7c478bd9Sstevel@tonic-gate  */
903*7c478bd9Sstevel@tonic-gate bool_t
904*7c478bd9Sstevel@tonic-gate xdr_ulonglong_t(XDR *xdrs, u_longlong_t *hp)
905*7c478bd9Sstevel@tonic-gate {
906*7c478bd9Sstevel@tonic-gate 	bool_t dummy;
907*7c478bd9Sstevel@tonic-gate 
908*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_longlong_t, 0);
909*7c478bd9Sstevel@tonic-gate 	dummy = xdr_hyper(xdrs, (longlong_t *)hp);
910*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_u_longlong_t, 1);
911*7c478bd9Sstevel@tonic-gate 	return (dummy);
912*7c478bd9Sstevel@tonic-gate }
913*7c478bd9Sstevel@tonic-gate 
914*7c478bd9Sstevel@tonic-gate #ifndef KERNEL
915*7c478bd9Sstevel@tonic-gate /*
916*7c478bd9Sstevel@tonic-gate  * Wrapper for xdr_string that can be called directly from
917*7c478bd9Sstevel@tonic-gate  * routines like clnt_call
918*7c478bd9Sstevel@tonic-gate  */
919*7c478bd9Sstevel@tonic-gate bool_t
920*7c478bd9Sstevel@tonic-gate xdr_wrapstring(XDR *xdrs, char **cpp)
921*7c478bd9Sstevel@tonic-gate {
922*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_wrapstring, 0);
923*7c478bd9Sstevel@tonic-gate 	if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
924*7c478bd9Sstevel@tonic-gate 		trace1(TR_xdr_wrapstring, 1);
925*7c478bd9Sstevel@tonic-gate 		return (TRUE);
926*7c478bd9Sstevel@tonic-gate 	}
927*7c478bd9Sstevel@tonic-gate 	trace1(TR_xdr_wrapstring, 1);
928*7c478bd9Sstevel@tonic-gate 	return (FALSE);
929*7c478bd9Sstevel@tonic-gate }
930*7c478bd9Sstevel@tonic-gate #endif /* !KERNEL */
931