17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
2161961e0fSrobinson */
2261961e0fSrobinson
2361961e0fSrobinson /*
24e8031f0aSraf * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
257c478bd9Sstevel@tonic-gate * Use is subject to license terms.
267c478bd9Sstevel@tonic-gate */
27e8031f0aSraf
287c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
297c478bd9Sstevel@tonic-gate /* All Rights Reserved */
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley
327c478bd9Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of
337c478bd9Sstevel@tonic-gate * California.
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate /*
37e8031f0aSraf * Generic XDR routines implementation.
387c478bd9Sstevel@tonic-gate *
397c478bd9Sstevel@tonic-gate * These are the "generic" xdr routines used to serialize and de-serialize
407c478bd9Sstevel@tonic-gate * most common data items. See xdr.h for more info on the interface to
417c478bd9Sstevel@tonic-gate * xdr.
427c478bd9Sstevel@tonic-gate */
43e8031f0aSraf #include "mt.h"
4461961e0fSrobinson #include <stdlib.h>
457c478bd9Sstevel@tonic-gate #include <sys/types.h>
467c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
477c478bd9Sstevel@tonic-gate #include <syslog.h>
487c478bd9Sstevel@tonic-gate #include <stdio.h>
497c478bd9Sstevel@tonic-gate #include <stdlib.h>
507c478bd9Sstevel@tonic-gate #include <string.h>
517c478bd9Sstevel@tonic-gate #include <limits.h>
527c478bd9Sstevel@tonic-gate #include <rpc/types.h>
537c478bd9Sstevel@tonic-gate #include <rpc/xdr.h>
547c478bd9Sstevel@tonic-gate #include <inttypes.h>
557c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
5661961e0fSrobinson #include <assert.h>
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate #pragma weak xdr_int64_t = xdr_hyper
597c478bd9Sstevel@tonic-gate #pragma weak xdr_uint64_t = xdr_u_hyper
607c478bd9Sstevel@tonic-gate #pragma weak xdr_int32_t = xdr_int
617c478bd9Sstevel@tonic-gate #pragma weak xdr_uint32_t = xdr_u_int
627c478bd9Sstevel@tonic-gate #pragma weak xdr_int16_t = xdr_short
637c478bd9Sstevel@tonic-gate #pragma weak xdr_uint16_t = xdr_u_short
647c478bd9Sstevel@tonic-gate #pragma weak xdr_int8_t = xdr_char
657c478bd9Sstevel@tonic-gate #pragma weak xdr_uint8_t = xdr_u_char
667c478bd9Sstevel@tonic-gate
6761961e0fSrobinson /*
6861961e0fSrobinson * The following routine was part of a workaround for an rpcgen
6961961e0fSrobinson * that was fixed, this routine should be removed sometime.
7061961e0fSrobinson */
7161961e0fSrobinson #pragma weak xdr_ulonglong_t = xdr_u_longlong_t
7261961e0fSrobinson
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate * constants specific to the xdr "protocol"
757c478bd9Sstevel@tonic-gate */
767c478bd9Sstevel@tonic-gate #define XDR_FALSE ((uint_t)0)
777c478bd9Sstevel@tonic-gate #define XDR_TRUE ((uint_t)1)
787c478bd9Sstevel@tonic-gate #define LASTUNSIGNED ((uint_t)0-1)
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate /* fragment size to use when doing an xdr_string() */
817c478bd9Sstevel@tonic-gate #define FRAGMENT 65536
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate /*
847c478bd9Sstevel@tonic-gate * for unit alignment
857c478bd9Sstevel@tonic-gate */
867c478bd9Sstevel@tonic-gate static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0 };
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate * Free a data structure using XDR
907c478bd9Sstevel@tonic-gate * Not a filter, but a convenient utility nonetheless
917c478bd9Sstevel@tonic-gate */
927c478bd9Sstevel@tonic-gate void
xdr_free(xdrproc_t proc,char * objp)937c478bd9Sstevel@tonic-gate xdr_free(xdrproc_t proc, char *objp)
947c478bd9Sstevel@tonic-gate {
957c478bd9Sstevel@tonic-gate XDR x;
967c478bd9Sstevel@tonic-gate
977c478bd9Sstevel@tonic-gate x.x_op = XDR_FREE;
987c478bd9Sstevel@tonic-gate (*proc)(&x, objp);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate * XDR nothing
1037c478bd9Sstevel@tonic-gate */
1047c478bd9Sstevel@tonic-gate bool_t
xdr_void(void)10561961e0fSrobinson xdr_void(void)
1067c478bd9Sstevel@tonic-gate {
1077c478bd9Sstevel@tonic-gate return (TRUE);
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate /*
1117c478bd9Sstevel@tonic-gate * xdr_time_t sends time_t value over the wire.
1127c478bd9Sstevel@tonic-gate * Due to RPC Protocol limitation, it can only send
1137c478bd9Sstevel@tonic-gate * up to 32-bit integer quantity over the wire.
1147c478bd9Sstevel@tonic-gate *
1157c478bd9Sstevel@tonic-gate */
1167c478bd9Sstevel@tonic-gate bool_t
xdr_time_t(XDR * xdrs,time_t * tp)1177c478bd9Sstevel@tonic-gate xdr_time_t(XDR *xdrs, time_t *tp)
1187c478bd9Sstevel@tonic-gate {
1197c478bd9Sstevel@tonic-gate int32_t i;
1207c478bd9Sstevel@tonic-gate
1217c478bd9Sstevel@tonic-gate switch (xdrs->x_op) {
1227c478bd9Sstevel@tonic-gate case XDR_ENCODE:
1237c478bd9Sstevel@tonic-gate /*
1247c478bd9Sstevel@tonic-gate * Check for the time overflow, when encoding it.
1257c478bd9Sstevel@tonic-gate * Don't want to send OTW the time value too large to
1267c478bd9Sstevel@tonic-gate * handle by the protocol.
1277c478bd9Sstevel@tonic-gate */
1287c478bd9Sstevel@tonic-gate #if defined(_LP64)
1297c478bd9Sstevel@tonic-gate if (*tp > INT32_MAX)
1307c478bd9Sstevel@tonic-gate *tp = INT32_MAX;
1317c478bd9Sstevel@tonic-gate else if (*tp < INT32_MIN)
1327c478bd9Sstevel@tonic-gate *tp = INT32_MIN;
1337c478bd9Sstevel@tonic-gate #endif
1347c478bd9Sstevel@tonic-gate i = (int32_t)*tp;
13561961e0fSrobinson return (XDR_PUTINT32(xdrs, &i));
1367c478bd9Sstevel@tonic-gate
1377c478bd9Sstevel@tonic-gate case XDR_DECODE:
13861961e0fSrobinson if (!XDR_GETINT32(xdrs, &i))
1397c478bd9Sstevel@tonic-gate return (FALSE);
1407c478bd9Sstevel@tonic-gate *tp = (time_t)i;
1417c478bd9Sstevel@tonic-gate return (TRUE);
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate case XDR_FREE:
1447c478bd9Sstevel@tonic-gate return (TRUE);
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate return (FALSE);
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate /*
1507c478bd9Sstevel@tonic-gate * XDR integers
1517c478bd9Sstevel@tonic-gate */
1527c478bd9Sstevel@tonic-gate bool_t
xdr_int(XDR * xdrs,int * ip)1537c478bd9Sstevel@tonic-gate xdr_int(XDR *xdrs, int *ip)
1547c478bd9Sstevel@tonic-gate {
15561961e0fSrobinson switch (xdrs->x_op) {
15661961e0fSrobinson case XDR_ENCODE:
1577c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, ip));
15861961e0fSrobinson case XDR_DECODE:
1597c478bd9Sstevel@tonic-gate return (XDR_GETINT32(xdrs, ip));
16061961e0fSrobinson case XDR_FREE:
1617c478bd9Sstevel@tonic-gate return (TRUE);
16261961e0fSrobinson }
1637c478bd9Sstevel@tonic-gate return (FALSE);
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate /*
1677c478bd9Sstevel@tonic-gate * XDR unsigned integers
1687c478bd9Sstevel@tonic-gate */
1697c478bd9Sstevel@tonic-gate bool_t
xdr_u_int(XDR * xdrs,uint_t * up)1707c478bd9Sstevel@tonic-gate xdr_u_int(XDR *xdrs, uint_t *up)
1717c478bd9Sstevel@tonic-gate {
17261961e0fSrobinson switch (xdrs->x_op) {
17361961e0fSrobinson case XDR_ENCODE:
1747c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, (int *)up));
17561961e0fSrobinson case XDR_DECODE:
1767c478bd9Sstevel@tonic-gate return (XDR_GETINT32(xdrs, (int *)up));
17761961e0fSrobinson case XDR_FREE:
1787c478bd9Sstevel@tonic-gate return (TRUE);
17961961e0fSrobinson }
1807c478bd9Sstevel@tonic-gate return (FALSE);
1817c478bd9Sstevel@tonic-gate }
1827c478bd9Sstevel@tonic-gate
1837c478bd9Sstevel@tonic-gate /*
1847c478bd9Sstevel@tonic-gate * The definition of xdr_long()/xdr_u_long() is kept for backward
1857c478bd9Sstevel@tonic-gate * compatibitlity.
1867c478bd9Sstevel@tonic-gate * XDR long integers, same as xdr_u_long
1877c478bd9Sstevel@tonic-gate */
1887c478bd9Sstevel@tonic-gate bool_t
xdr_long(XDR * xdrs,long * lp)1897c478bd9Sstevel@tonic-gate xdr_long(XDR *xdrs, long *lp)
1907c478bd9Sstevel@tonic-gate {
1917c478bd9Sstevel@tonic-gate int32_t i;
1927c478bd9Sstevel@tonic-gate
19361961e0fSrobinson switch (xdrs->x_op) {
19461961e0fSrobinson case XDR_ENCODE:
1957c478bd9Sstevel@tonic-gate #if defined(_LP64)
19661961e0fSrobinson if ((*lp > INT32_MAX) || (*lp < INT32_MIN))
1977c478bd9Sstevel@tonic-gate return (FALSE);
1987c478bd9Sstevel@tonic-gate #endif
1997c478bd9Sstevel@tonic-gate i = (int32_t)*lp;
20061961e0fSrobinson return (XDR_PUTINT32(xdrs, &i));
20161961e0fSrobinson case XDR_DECODE:
20261961e0fSrobinson if (!XDR_GETINT32(xdrs, &i))
20361961e0fSrobinson return (FALSE);
2047c478bd9Sstevel@tonic-gate *lp = (long)i;
20561961e0fSrobinson return (TRUE);
20661961e0fSrobinson case XDR_FREE:
20761961e0fSrobinson return (TRUE);
20861961e0fSrobinson }
20961961e0fSrobinson return (FALSE);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate
2127c478bd9Sstevel@tonic-gate /*
2137c478bd9Sstevel@tonic-gate * XDR unsigned long integers
2147c478bd9Sstevel@tonic-gate * same as xdr_long
2157c478bd9Sstevel@tonic-gate */
2167c478bd9Sstevel@tonic-gate bool_t
xdr_u_long(XDR * xdrs,ulong_t * ulp)2177c478bd9Sstevel@tonic-gate xdr_u_long(XDR *xdrs, ulong_t *ulp)
2187c478bd9Sstevel@tonic-gate {
2197c478bd9Sstevel@tonic-gate uint32_t ui;
2207c478bd9Sstevel@tonic-gate
22161961e0fSrobinson switch (xdrs->x_op) {
22261961e0fSrobinson case XDR_ENCODE:
2237c478bd9Sstevel@tonic-gate #if defined(_LP64)
22461961e0fSrobinson if (*ulp > UINT32_MAX)
2257c478bd9Sstevel@tonic-gate return (FALSE);
2267c478bd9Sstevel@tonic-gate #endif
2277c478bd9Sstevel@tonic-gate ui = (uint32_t)*ulp;
22861961e0fSrobinson return (XDR_PUTINT32(xdrs, (int32_t *)&ui));
22961961e0fSrobinson case XDR_DECODE:
23061961e0fSrobinson if (!XDR_GETINT32(xdrs, (int32_t *)&ui))
23161961e0fSrobinson return (FALSE);
2327c478bd9Sstevel@tonic-gate *ulp = (ulong_t)ui;
23361961e0fSrobinson return (TRUE);
23461961e0fSrobinson case XDR_FREE:
23561961e0fSrobinson return (TRUE);
23661961e0fSrobinson }
23761961e0fSrobinson return (FALSE);
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate /*
2417c478bd9Sstevel@tonic-gate * XDR short integers
2427c478bd9Sstevel@tonic-gate */
2437c478bd9Sstevel@tonic-gate bool_t
xdr_short(XDR * xdrs,short * sp)2447c478bd9Sstevel@tonic-gate xdr_short(XDR *xdrs, short *sp)
2457c478bd9Sstevel@tonic-gate {
2467c478bd9Sstevel@tonic-gate int32_t l;
2477c478bd9Sstevel@tonic-gate
2487c478bd9Sstevel@tonic-gate switch (xdrs->x_op) {
2497c478bd9Sstevel@tonic-gate case XDR_ENCODE:
2507c478bd9Sstevel@tonic-gate l = (int32_t)*sp;
25161961e0fSrobinson return (XDR_PUTINT32(xdrs, &l));
2527c478bd9Sstevel@tonic-gate case XDR_DECODE:
25361961e0fSrobinson if (!XDR_GETINT32(xdrs, &l))
2547c478bd9Sstevel@tonic-gate return (FALSE);
2557c478bd9Sstevel@tonic-gate *sp = (short)l;
2567c478bd9Sstevel@tonic-gate return (TRUE);
2577c478bd9Sstevel@tonic-gate case XDR_FREE:
2587c478bd9Sstevel@tonic-gate return (TRUE);
2597c478bd9Sstevel@tonic-gate }
2607c478bd9Sstevel@tonic-gate return (FALSE);
2617c478bd9Sstevel@tonic-gate }
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate /*
2647c478bd9Sstevel@tonic-gate * XDR unsigned short integers
2657c478bd9Sstevel@tonic-gate */
2667c478bd9Sstevel@tonic-gate bool_t
xdr_u_short(XDR * xdrs,ushort_t * usp)2677c478bd9Sstevel@tonic-gate xdr_u_short(XDR *xdrs, ushort_t *usp)
2687c478bd9Sstevel@tonic-gate {
2697c478bd9Sstevel@tonic-gate uint_t i;
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate switch (xdrs->x_op) {
2727c478bd9Sstevel@tonic-gate case XDR_ENCODE:
2737c478bd9Sstevel@tonic-gate i = (uint_t)*usp;
27461961e0fSrobinson return (XDR_PUTINT32(xdrs, (int *)&i));
2757c478bd9Sstevel@tonic-gate case XDR_DECODE:
27661961e0fSrobinson if (!XDR_GETINT32(xdrs, (int *)&i))
2777c478bd9Sstevel@tonic-gate return (FALSE);
2787c478bd9Sstevel@tonic-gate *usp = (ushort_t)i;
2797c478bd9Sstevel@tonic-gate return (TRUE);
2807c478bd9Sstevel@tonic-gate case XDR_FREE:
2817c478bd9Sstevel@tonic-gate return (TRUE);
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate return (FALSE);
2847c478bd9Sstevel@tonic-gate }
2857c478bd9Sstevel@tonic-gate
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate /*
2887c478bd9Sstevel@tonic-gate * XDR a char
2897c478bd9Sstevel@tonic-gate */
2907c478bd9Sstevel@tonic-gate bool_t
xdr_char(XDR * xdrs,char * cp)2917c478bd9Sstevel@tonic-gate xdr_char(XDR *xdrs, char *cp)
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate int i;
2947c478bd9Sstevel@tonic-gate
29561961e0fSrobinson switch (xdrs->x_op) {
29661961e0fSrobinson case XDR_ENCODE:
2977c478bd9Sstevel@tonic-gate i = (*cp);
29861961e0fSrobinson return (XDR_PUTINT32(xdrs, &i));
29961961e0fSrobinson case XDR_DECODE:
30061961e0fSrobinson if (!XDR_GETINT32(xdrs, &i))
30161961e0fSrobinson return (FALSE);
3027c478bd9Sstevel@tonic-gate *cp = (char)i;
30361961e0fSrobinson return (TRUE);
30461961e0fSrobinson case XDR_FREE:
30561961e0fSrobinson return (TRUE);
30661961e0fSrobinson }
30761961e0fSrobinson return (FALSE);
3087c478bd9Sstevel@tonic-gate }
3097c478bd9Sstevel@tonic-gate
3107c478bd9Sstevel@tonic-gate /*
3117c478bd9Sstevel@tonic-gate * XDR an unsigned char
3127c478bd9Sstevel@tonic-gate */
3137c478bd9Sstevel@tonic-gate bool_t
xdr_u_char(XDR * xdrs,uchar_t * cp)3147c478bd9Sstevel@tonic-gate xdr_u_char(XDR *xdrs, uchar_t *cp)
3157c478bd9Sstevel@tonic-gate {
3167c478bd9Sstevel@tonic-gate int i;
3177c478bd9Sstevel@tonic-gate
31861961e0fSrobinson switch (xdrs->x_op) {
31961961e0fSrobinson case XDR_ENCODE:
3207c478bd9Sstevel@tonic-gate i = (*cp);
32161961e0fSrobinson return (XDR_PUTINT32(xdrs, &i));
32261961e0fSrobinson case XDR_DECODE:
32361961e0fSrobinson if (!XDR_GETINT32(xdrs, &i))
32461961e0fSrobinson return (FALSE);
3257c478bd9Sstevel@tonic-gate *cp = (uchar_t)i;
32661961e0fSrobinson return (TRUE);
32761961e0fSrobinson case XDR_FREE:
32861961e0fSrobinson return (TRUE);
32961961e0fSrobinson }
33061961e0fSrobinson return (FALSE);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate /*
3347c478bd9Sstevel@tonic-gate * XDR booleans
3357c478bd9Sstevel@tonic-gate */
3367c478bd9Sstevel@tonic-gate bool_t
xdr_bool(XDR * xdrs,bool_t * bp)3377c478bd9Sstevel@tonic-gate xdr_bool(XDR *xdrs, bool_t *bp)
3387c478bd9Sstevel@tonic-gate {
3397c478bd9Sstevel@tonic-gate int i;
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate switch (xdrs->x_op) {
3427c478bd9Sstevel@tonic-gate case XDR_ENCODE:
3437c478bd9Sstevel@tonic-gate i = *bp ? XDR_TRUE : XDR_FALSE;
34461961e0fSrobinson return (XDR_PUTINT32(xdrs, &i));
3457c478bd9Sstevel@tonic-gate case XDR_DECODE:
34661961e0fSrobinson if (!XDR_GETINT32(xdrs, &i))
3477c478bd9Sstevel@tonic-gate return (FALSE);
3487c478bd9Sstevel@tonic-gate *bp = (i == XDR_FALSE) ? FALSE : TRUE;
3497c478bd9Sstevel@tonic-gate return (TRUE);
3507c478bd9Sstevel@tonic-gate case XDR_FREE:
3517c478bd9Sstevel@tonic-gate return (TRUE);
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate return (FALSE);
3547c478bd9Sstevel@tonic-gate }
3557c478bd9Sstevel@tonic-gate
3567c478bd9Sstevel@tonic-gate /*
3577c478bd9Sstevel@tonic-gate * XDR enumerations
3587c478bd9Sstevel@tonic-gate */
3597c478bd9Sstevel@tonic-gate bool_t
xdr_enum(XDR * xdrs,enum_t * ep)3607c478bd9Sstevel@tonic-gate xdr_enum(XDR *xdrs, enum_t *ep)
3617c478bd9Sstevel@tonic-gate {
3627c478bd9Sstevel@tonic-gate enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
3637c478bd9Sstevel@tonic-gate
3647c478bd9Sstevel@tonic-gate /*
3657c478bd9Sstevel@tonic-gate * enums are treated as ints
3667c478bd9Sstevel@tonic-gate */
36761961e0fSrobinson /* CONSTCOND */
36861961e0fSrobinson assert(sizeof (enum sizecheck) == sizeof (int32_t));
36961961e0fSrobinson return (xdr_int(xdrs, (int *)ep));
3707c478bd9Sstevel@tonic-gate }
3717c478bd9Sstevel@tonic-gate
3727c478bd9Sstevel@tonic-gate /*
3737c478bd9Sstevel@tonic-gate * XDR opaque data
3747c478bd9Sstevel@tonic-gate * Allows the specification of a fixed size sequence of opaque bytes.
3757c478bd9Sstevel@tonic-gate * cp points to the opaque object and cnt gives the byte length.
3767c478bd9Sstevel@tonic-gate */
3777c478bd9Sstevel@tonic-gate bool_t
xdr_opaque(XDR * xdrs,caddr_t cp,const uint_t cnt)37861961e0fSrobinson xdr_opaque(XDR *xdrs, caddr_t cp, const uint_t cnt)
3797c478bd9Sstevel@tonic-gate {
38061961e0fSrobinson uint_t rndup;
3817c478bd9Sstevel@tonic-gate char crud[BYTES_PER_XDR_UNIT];
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate /*
3847c478bd9Sstevel@tonic-gate * round byte count to full xdr units
3857c478bd9Sstevel@tonic-gate */
3867c478bd9Sstevel@tonic-gate rndup = cnt % BYTES_PER_XDR_UNIT;
3877c478bd9Sstevel@tonic-gate if ((int)rndup > 0)
3887c478bd9Sstevel@tonic-gate rndup = BYTES_PER_XDR_UNIT - rndup;
3897c478bd9Sstevel@tonic-gate
39061961e0fSrobinson switch (xdrs->x_op) {
39161961e0fSrobinson case XDR_DECODE:
39261961e0fSrobinson if (!XDR_GETBYTES(xdrs, cp, cnt))
3937c478bd9Sstevel@tonic-gate return (FALSE);
39461961e0fSrobinson if (rndup == 0)
3957c478bd9Sstevel@tonic-gate return (TRUE);
39661961e0fSrobinson return (XDR_GETBYTES(xdrs, crud, rndup));
39761961e0fSrobinson case XDR_ENCODE:
39861961e0fSrobinson if (!XDR_PUTBYTES(xdrs, cp, cnt))
3997c478bd9Sstevel@tonic-gate return (FALSE);
40061961e0fSrobinson if (rndup == 0)
4017c478bd9Sstevel@tonic-gate return (TRUE);
40261961e0fSrobinson return (XDR_PUTBYTES(xdrs, (caddr_t)&xdr_zero[0], rndup));
40361961e0fSrobinson case XDR_FREE:
4047c478bd9Sstevel@tonic-gate return (TRUE);
4057c478bd9Sstevel@tonic-gate }
4067c478bd9Sstevel@tonic-gate return (FALSE);
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate
4097c478bd9Sstevel@tonic-gate /*
4107c478bd9Sstevel@tonic-gate * XDR counted bytes
4117c478bd9Sstevel@tonic-gate * *cpp is a pointer to the bytes, *sizep is the count.
4127c478bd9Sstevel@tonic-gate * If *cpp is NULL maxsize bytes are allocated
4137c478bd9Sstevel@tonic-gate */
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate static const char xdr_err[] = "xdr_%s: out of memory";
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate bool_t
xdr_bytes(XDR * xdrs,char ** cpp,uint_t * sizep,const uint_t maxsize)41861961e0fSrobinson xdr_bytes(XDR *xdrs, char **cpp, uint_t *sizep, const uint_t maxsize)
4197c478bd9Sstevel@tonic-gate {
42061961e0fSrobinson char *sp = *cpp; /* sp is the actual string pointer */
42161961e0fSrobinson uint_t nodesize;
4227c478bd9Sstevel@tonic-gate
4237c478bd9Sstevel@tonic-gate /*
4247c478bd9Sstevel@tonic-gate * first deal with the length since xdr bytes are counted
4257c478bd9Sstevel@tonic-gate * We decided not to use MACRO XDR_U_INT here, because the
4267c478bd9Sstevel@tonic-gate * advantages here will be miniscule compared to xdr_bytes.
4277c478bd9Sstevel@tonic-gate * This saved us 100 bytes in the library size.
4287c478bd9Sstevel@tonic-gate */
42961961e0fSrobinson if (!xdr_u_int(xdrs, sizep))
4307c478bd9Sstevel@tonic-gate return (FALSE);
4317c478bd9Sstevel@tonic-gate nodesize = *sizep;
43261961e0fSrobinson if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE))
4337c478bd9Sstevel@tonic-gate return (FALSE);
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate /*
4367c478bd9Sstevel@tonic-gate * now deal with the actual bytes
4377c478bd9Sstevel@tonic-gate */
4387c478bd9Sstevel@tonic-gate switch (xdrs->x_op) {
4397c478bd9Sstevel@tonic-gate case XDR_DECODE:
44061961e0fSrobinson if (nodesize == 0)
4417c478bd9Sstevel@tonic-gate return (TRUE);
44261961e0fSrobinson if (sp == NULL)
44361961e0fSrobinson *cpp = sp = malloc(nodesize);
4447c478bd9Sstevel@tonic-gate if (sp == NULL) {
4457c478bd9Sstevel@tonic-gate (void) syslog(LOG_ERR, xdr_err, (const char *)"bytes");
4467c478bd9Sstevel@tonic-gate return (FALSE);
4477c478bd9Sstevel@tonic-gate }
4487c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
4497c478bd9Sstevel@tonic-gate case XDR_ENCODE:
45061961e0fSrobinson return (xdr_opaque(xdrs, sp, nodesize));
4517c478bd9Sstevel@tonic-gate case XDR_FREE:
4527c478bd9Sstevel@tonic-gate if (sp != NULL) {
45361961e0fSrobinson free(sp);
4547c478bd9Sstevel@tonic-gate *cpp = NULL;
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate return (TRUE);
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate return (FALSE);
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate
4617c478bd9Sstevel@tonic-gate /*
4627c478bd9Sstevel@tonic-gate * Implemented here due to commonality of the object.
4637c478bd9Sstevel@tonic-gate */
4647c478bd9Sstevel@tonic-gate bool_t
xdr_netobj(XDR * xdrs,struct netobj * np)4657c478bd9Sstevel@tonic-gate xdr_netobj(XDR *xdrs, struct netobj *np)
4667c478bd9Sstevel@tonic-gate {
46761961e0fSrobinson return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
4687c478bd9Sstevel@tonic-gate }
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate /*
4717c478bd9Sstevel@tonic-gate * XDR a descriminated union
4727c478bd9Sstevel@tonic-gate * Support routine for discriminated unions.
4737c478bd9Sstevel@tonic-gate * You create an array of xdrdiscrim structures, terminated with
4747c478bd9Sstevel@tonic-gate * an entry with a null procedure pointer. The routine gets
4757c478bd9Sstevel@tonic-gate * the discriminant value and then searches the array of xdrdiscrims
4767c478bd9Sstevel@tonic-gate * looking for that value. It calls the procedure given in the xdrdiscrim
4777c478bd9Sstevel@tonic-gate * to handle the discriminant. If there is no specific routine a default
4787c478bd9Sstevel@tonic-gate * routine may be called.
4797c478bd9Sstevel@tonic-gate * If there is no specific or default routine an error is returned.
4807c478bd9Sstevel@tonic-gate */
4817c478bd9Sstevel@tonic-gate bool_t
xdr_union(XDR * xdrs,enum_t * dscmp,char * unp,const struct xdr_discrim * choices,const xdrproc_t dfault)4827c478bd9Sstevel@tonic-gate xdr_union(XDR *xdrs, enum_t *dscmp, char *unp,
483*22cc5755SMarcel Telka const struct xdr_discrim *choices, const xdrproc_t dfault)
4847c478bd9Sstevel@tonic-gate {
48561961e0fSrobinson enum_t dscm;
4867c478bd9Sstevel@tonic-gate
4877c478bd9Sstevel@tonic-gate /*
4887c478bd9Sstevel@tonic-gate * we deal with the discriminator; it's an enum
4897c478bd9Sstevel@tonic-gate */
49061961e0fSrobinson if (!xdr_enum(xdrs, dscmp))
4917c478bd9Sstevel@tonic-gate return (FALSE);
4927c478bd9Sstevel@tonic-gate dscm = *dscmp;
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate /*
4957c478bd9Sstevel@tonic-gate * search choices for a value that matches the discriminator.
4967c478bd9Sstevel@tonic-gate * if we find one, execute the xdr routine for that value.
4977c478bd9Sstevel@tonic-gate */
4987c478bd9Sstevel@tonic-gate for (; choices->proc != NULL_xdrproc_t; choices++) {
49961961e0fSrobinson if (choices->value == dscm)
50061961e0fSrobinson return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate
5037c478bd9Sstevel@tonic-gate /*
5047c478bd9Sstevel@tonic-gate * no match - execute the default xdr routine if there is one
5057c478bd9Sstevel@tonic-gate */
50661961e0fSrobinson return ((dfault == NULL_xdrproc_t) ? FALSE :
50761961e0fSrobinson (*dfault)(xdrs, unp, LASTUNSIGNED));
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate
5117c478bd9Sstevel@tonic-gate /*
5127c478bd9Sstevel@tonic-gate * Non-portable xdr primitives.
5137c478bd9Sstevel@tonic-gate * Care should be taken when moving these routines to new architectures.
5147c478bd9Sstevel@tonic-gate */
5157c478bd9Sstevel@tonic-gate
5167c478bd9Sstevel@tonic-gate
5177c478bd9Sstevel@tonic-gate /*
5187c478bd9Sstevel@tonic-gate * XDR null terminated ASCII strings
5197c478bd9Sstevel@tonic-gate * xdr_string deals with "C strings" - arrays of bytes that are
5207c478bd9Sstevel@tonic-gate * terminated by a NULL character. The parameter cpp references a
5217c478bd9Sstevel@tonic-gate * pointer to storage; If the pointer is null, then the necessary
5227c478bd9Sstevel@tonic-gate * storage is allocated. The last parameter is the max allowed length
5237c478bd9Sstevel@tonic-gate * of the string as specified by a protocol.
5247c478bd9Sstevel@tonic-gate */
5257c478bd9Sstevel@tonic-gate bool_t
xdr_string(XDR * xdrs,char ** cpp,const uint_t maxsize)52661961e0fSrobinson xdr_string(XDR *xdrs, char **cpp, const uint_t maxsize)
5277c478bd9Sstevel@tonic-gate {
52861961e0fSrobinson char *newsp, *sp = *cpp; /* sp is the actual string pointer */
5297c478bd9Sstevel@tonic-gate uint_t size, block;
5307c478bd9Sstevel@tonic-gate uint64_t bytesread;
5317c478bd9Sstevel@tonic-gate
5327c478bd9Sstevel@tonic-gate /*
5337c478bd9Sstevel@tonic-gate * first deal with the length since xdr strings are counted-strings
5347c478bd9Sstevel@tonic-gate */
5357c478bd9Sstevel@tonic-gate switch (xdrs->x_op) {
5367c478bd9Sstevel@tonic-gate case XDR_FREE:
53761961e0fSrobinson if (sp == NULL)
5387c478bd9Sstevel@tonic-gate return (TRUE); /* already free */
5397c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/
5407c478bd9Sstevel@tonic-gate case XDR_ENCODE:
5417c478bd9Sstevel@tonic-gate size = (sp != NULL) ? (uint_t)strlen(sp) : 0;
5427c478bd9Sstevel@tonic-gate break;
5437c478bd9Sstevel@tonic-gate }
5447c478bd9Sstevel@tonic-gate /*
5457c478bd9Sstevel@tonic-gate * We decided not to use MACRO XDR_U_INT here, because the
5467c478bd9Sstevel@tonic-gate * advantages here will be miniscule compared to xdr_string.
5477c478bd9Sstevel@tonic-gate * This saved us 100 bytes in the library size.
5487c478bd9Sstevel@tonic-gate */
54961961e0fSrobinson if (!xdr_u_int(xdrs, &size))
5507c478bd9Sstevel@tonic-gate return (FALSE);
55161961e0fSrobinson if (size > maxsize)
5527c478bd9Sstevel@tonic-gate return (FALSE);
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate /*
5557c478bd9Sstevel@tonic-gate * now deal with the actual bytes
5567c478bd9Sstevel@tonic-gate */
5577c478bd9Sstevel@tonic-gate switch (xdrs->x_op) {
5587c478bd9Sstevel@tonic-gate case XDR_DECODE:
5597c478bd9Sstevel@tonic-gate /* if buffer is already given, call xdr_opaque() directly */
5607c478bd9Sstevel@tonic-gate if (sp != NULL) {
56161961e0fSrobinson if (!xdr_opaque(xdrs, sp, size))
56261961e0fSrobinson return (FALSE);
5637c478bd9Sstevel@tonic-gate sp[size] = 0;
56461961e0fSrobinson return (TRUE);
5657c478bd9Sstevel@tonic-gate }
5667c478bd9Sstevel@tonic-gate
5677c478bd9Sstevel@tonic-gate /*
5687c478bd9Sstevel@tonic-gate * We have to allocate a buffer of size 'size'. To avoid
5697c478bd9Sstevel@tonic-gate * malloc()ing one huge chunk, we'll read the bytes in max
5707c478bd9Sstevel@tonic-gate * FRAGMENT size blocks and keep realloc()ing. 'block' is
5717c478bd9Sstevel@tonic-gate * the number of bytes to read in each xdr_opaque() and
5727c478bd9Sstevel@tonic-gate * 'bytesread' is what we have already read. sp is NULL
5737c478bd9Sstevel@tonic-gate * when we are in the loop for the first time.
5747c478bd9Sstevel@tonic-gate */
5757c478bd9Sstevel@tonic-gate bytesread = 0;
5767c478bd9Sstevel@tonic-gate do {
5777c478bd9Sstevel@tonic-gate block = MIN(size - bytesread, FRAGMENT);
5787c478bd9Sstevel@tonic-gate /*
5797c478bd9Sstevel@tonic-gate * allocate enough for 'bytesread + block' bytes and
5807c478bd9Sstevel@tonic-gate * one extra for the terminating NULL.
5817c478bd9Sstevel@tonic-gate */
5827c478bd9Sstevel@tonic-gate newsp = realloc(sp, bytesread + block + 1);
5837c478bd9Sstevel@tonic-gate if (newsp == NULL) {
5847c478bd9Sstevel@tonic-gate if (sp != NULL)
5857c478bd9Sstevel@tonic-gate free(sp);
5867c478bd9Sstevel@tonic-gate return (FALSE);
5877c478bd9Sstevel@tonic-gate }
5887c478bd9Sstevel@tonic-gate sp = newsp;
5897c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, &sp[bytesread], block)) {
5907c478bd9Sstevel@tonic-gate free(sp);
5917c478bd9Sstevel@tonic-gate return (FALSE);
5927c478bd9Sstevel@tonic-gate }
5937c478bd9Sstevel@tonic-gate bytesread += block;
5947c478bd9Sstevel@tonic-gate } while (bytesread < size);
5957c478bd9Sstevel@tonic-gate
5967c478bd9Sstevel@tonic-gate sp[bytesread] = 0; /* terminate the string with a NULL */
5977c478bd9Sstevel@tonic-gate *cpp = sp;
5987c478bd9Sstevel@tonic-gate return (TRUE);
5997c478bd9Sstevel@tonic-gate case XDR_ENCODE:
60061961e0fSrobinson return (xdr_opaque(xdrs, sp, size));
6017c478bd9Sstevel@tonic-gate case XDR_FREE:
6027c478bd9Sstevel@tonic-gate free(sp);
6037c478bd9Sstevel@tonic-gate *cpp = NULL;
6047c478bd9Sstevel@tonic-gate return (TRUE);
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate return (FALSE);
6077c478bd9Sstevel@tonic-gate }
6087c478bd9Sstevel@tonic-gate
6097c478bd9Sstevel@tonic-gate bool_t
xdr_hyper(XDR * xdrs,longlong_t * hp)6107c478bd9Sstevel@tonic-gate xdr_hyper(XDR *xdrs, longlong_t *hp)
6117c478bd9Sstevel@tonic-gate {
612*22cc5755SMarcel Telka switch (xdrs->x_op) {
613*22cc5755SMarcel Telka case XDR_ENCODE:
6147c478bd9Sstevel@tonic-gate #if defined(_LONG_LONG_HTOL)
61561961e0fSrobinson if (XDR_PUTINT32(xdrs, (int *)hp) == TRUE)
61661961e0fSrobinson /* LINTED pointer cast */
61761961e0fSrobinson return (XDR_PUTINT32(xdrs, (int *)((char *)hp +
618*22cc5755SMarcel Telka BYTES_PER_XDR_UNIT)));
6197c478bd9Sstevel@tonic-gate #else
62061961e0fSrobinson /* LINTED pointer cast */
6217c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, (int *)((char *)hp +
622*22cc5755SMarcel Telka BYTES_PER_XDR_UNIT)) == TRUE)
62361961e0fSrobinson return (XDR_PUTINT32(xdrs, (int32_t *)hp));
6247c478bd9Sstevel@tonic-gate #endif
6257c478bd9Sstevel@tonic-gate return (FALSE);
626*22cc5755SMarcel Telka case XDR_DECODE:
6277c478bd9Sstevel@tonic-gate #if defined(_LONG_LONG_HTOL)
6287c478bd9Sstevel@tonic-gate if (XDR_GETINT32(xdrs, (int *)hp) == FALSE ||
62961961e0fSrobinson /* LINTED pointer cast */
6307c478bd9Sstevel@tonic-gate (XDR_GETINT32(xdrs, (int *)((char *)hp +
631*22cc5755SMarcel Telka BYTES_PER_XDR_UNIT)) == FALSE))
6327c478bd9Sstevel@tonic-gate return (FALSE);
6337c478bd9Sstevel@tonic-gate #else
63461961e0fSrobinson /* LINTED pointer cast */
6357c478bd9Sstevel@tonic-gate if ((XDR_GETINT32(xdrs, (int *)((char *)hp +
636*22cc5755SMarcel Telka BYTES_PER_XDR_UNIT)) == FALSE) ||
637*22cc5755SMarcel Telka (XDR_GETINT32(xdrs, (int *)hp) == FALSE))
6387c478bd9Sstevel@tonic-gate return (FALSE);
6397c478bd9Sstevel@tonic-gate #endif
6407c478bd9Sstevel@tonic-gate return (TRUE);
641*22cc5755SMarcel Telka case XDR_FREE:
642*22cc5755SMarcel Telka return (TRUE);
6437c478bd9Sstevel@tonic-gate }
644*22cc5755SMarcel Telka return (FALSE);
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate
6477c478bd9Sstevel@tonic-gate bool_t
xdr_u_hyper(XDR * xdrs,u_longlong_t * hp)6487c478bd9Sstevel@tonic-gate xdr_u_hyper(XDR *xdrs, u_longlong_t *hp)
6497c478bd9Sstevel@tonic-gate {
65061961e0fSrobinson return (xdr_hyper(xdrs, (longlong_t *)hp));
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate bool_t
xdr_longlong_t(XDR * xdrs,longlong_t * hp)6547c478bd9Sstevel@tonic-gate xdr_longlong_t(XDR *xdrs, longlong_t *hp)
6557c478bd9Sstevel@tonic-gate {
65661961e0fSrobinson return (xdr_hyper(xdrs, hp));
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate
6597c478bd9Sstevel@tonic-gate bool_t
xdr_u_longlong_t(XDR * xdrs,u_longlong_t * hp)6607c478bd9Sstevel@tonic-gate xdr_u_longlong_t(XDR *xdrs, u_longlong_t *hp)
6617c478bd9Sstevel@tonic-gate {
66261961e0fSrobinson return (xdr_hyper(xdrs, (longlong_t *)hp));
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate
6657c478bd9Sstevel@tonic-gate /*
6667c478bd9Sstevel@tonic-gate * Wrapper for xdr_string that can be called directly from
6677c478bd9Sstevel@tonic-gate * routines like clnt_call
6687c478bd9Sstevel@tonic-gate */
6697c478bd9Sstevel@tonic-gate bool_t
xdr_wrapstring(XDR * xdrs,char ** cpp)6707c478bd9Sstevel@tonic-gate xdr_wrapstring(XDR *xdrs, char **cpp)
6717c478bd9Sstevel@tonic-gate {
67261961e0fSrobinson return (xdr_string(xdrs, cpp, LASTUNSIGNED));
6737c478bd9Sstevel@tonic-gate }
674