xref: /onnv-gate/usr/src/uts/common/rpc/xdr.h (revision 11539:10d35fc3d7fd)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57387SRobert.Gordon@Sun.COM  * Common Development and Distribution License (the "License").
67387SRobert.Gordon@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  *
21*11539SChunli.Zhang@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
220Sstevel@tonic-gate  * Use is subject to license terms.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
250Sstevel@tonic-gate /* All Rights Reserved */
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
280Sstevel@tonic-gate  * 4.3 BSD under license from the Regents of the University of
290Sstevel@tonic-gate  * California.
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate 
320Sstevel@tonic-gate /*
330Sstevel@tonic-gate  * xdr.h, External Data Representation Serialization Routines.
340Sstevel@tonic-gate  *
350Sstevel@tonic-gate  */
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #ifndef _RPC_XDR_H
380Sstevel@tonic-gate #define	_RPC_XDR_H
390Sstevel@tonic-gate 
400Sstevel@tonic-gate #include <sys/byteorder.h>	/* For all ntoh* and hton*() kind of macros */
410Sstevel@tonic-gate #include <rpc/types.h>	/* For all ntoh* and hton*() kind of macros */
420Sstevel@tonic-gate #ifndef _KERNEL
430Sstevel@tonic-gate #include <stdio.h> /* defines FILE *, used in ANSI C function prototypes */
440Sstevel@tonic-gate #endif
450Sstevel@tonic-gate #ifdef _KERNEL
460Sstevel@tonic-gate #include <sys/stream.h>
470Sstevel@tonic-gate #endif
480Sstevel@tonic-gate 
490Sstevel@tonic-gate #ifdef __cplusplus
500Sstevel@tonic-gate extern "C" {
510Sstevel@tonic-gate #endif
520Sstevel@tonic-gate 
530Sstevel@tonic-gate /*
540Sstevel@tonic-gate  * XDR provides a conventional way for converting between C data
550Sstevel@tonic-gate  * types and an external bit-string representation.  Library supplied
560Sstevel@tonic-gate  * routines provide for the conversion on built-in C data types.  These
570Sstevel@tonic-gate  * routines and utility routines defined here are used to help implement
580Sstevel@tonic-gate  * a type encode/decode routine for each user-defined type.
590Sstevel@tonic-gate  *
600Sstevel@tonic-gate  * Each data type provides a single procedure which takes two arguments:
610Sstevel@tonic-gate  *
620Sstevel@tonic-gate  *	bool_t
630Sstevel@tonic-gate  *	xdrproc(xdrs, argresp)
640Sstevel@tonic-gate  *		XDR *xdrs;
650Sstevel@tonic-gate  *		<type> *argresp;
660Sstevel@tonic-gate  *
670Sstevel@tonic-gate  * xdrs is an instance of a XDR handle, to which or from which the data
680Sstevel@tonic-gate  * type is to be converted.  argresp is a pointer to the structure to be
690Sstevel@tonic-gate  * converted.  The XDR handle contains an operation field which indicates
700Sstevel@tonic-gate  * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
710Sstevel@tonic-gate  *
720Sstevel@tonic-gate  * XDR_DECODE may allocate space if the pointer argresp is null.  This
730Sstevel@tonic-gate  * data can be freed with the XDR_FREE operation.
740Sstevel@tonic-gate  *
750Sstevel@tonic-gate  * We write only one procedure per data type to make it easy
760Sstevel@tonic-gate  * to keep the encode and decode procedures for a data type consistent.
770Sstevel@tonic-gate  * In many cases the same code performs all operations on a user defined type,
780Sstevel@tonic-gate  * because all the hard work is done in the component type routines.
790Sstevel@tonic-gate  * decode as a series of calls on the nested data types.
800Sstevel@tonic-gate  */
810Sstevel@tonic-gate 
820Sstevel@tonic-gate /*
830Sstevel@tonic-gate  * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
840Sstevel@tonic-gate  * stream.  XDR_DECODE causes the type to be extracted from the stream.
850Sstevel@tonic-gate  * XDR_FREE can be used to release the space allocated by an XDR_DECODE
860Sstevel@tonic-gate  * request.
870Sstevel@tonic-gate  */
880Sstevel@tonic-gate enum xdr_op {
890Sstevel@tonic-gate 	XDR_ENCODE = 0,
900Sstevel@tonic-gate 	XDR_DECODE = 1,
910Sstevel@tonic-gate 	XDR_FREE = 2
920Sstevel@tonic-gate };
930Sstevel@tonic-gate 
940Sstevel@tonic-gate /*
950Sstevel@tonic-gate  * This is the number of bytes per unit of external data.
960Sstevel@tonic-gate  */
970Sstevel@tonic-gate #define	BYTES_PER_XDR_UNIT	(4)
980Sstevel@tonic-gate #define	RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
990Sstevel@tonic-gate 		    * BYTES_PER_XDR_UNIT)
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate /*
1020Sstevel@tonic-gate  * The XDR handle.
1030Sstevel@tonic-gate  * Contains operation which is being applied to the stream,
1040Sstevel@tonic-gate  * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
1050Sstevel@tonic-gate  * and two private fields for the use of the particular impelementation.
1060Sstevel@tonic-gate  *
1070Sstevel@tonic-gate  * PSARC 2003/523 Contract Private Interface
1080Sstevel@tonic-gate  * XDR
1090Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
1100Sstevel@tonic-gate  * Changes must be communicated to contract-2003-523@sun.com
1110Sstevel@tonic-gate  */
1120Sstevel@tonic-gate typedef struct XDR {
1130Sstevel@tonic-gate 	enum xdr_op	x_op;	/* operation; fast additional param */
1140Sstevel@tonic-gate 	struct xdr_ops *x_ops;
1150Sstevel@tonic-gate 	caddr_t 	x_public; /* users' data */
1160Sstevel@tonic-gate 	caddr_t		x_private; /* pointer to private data */
1170Sstevel@tonic-gate 	caddr_t 	x_base;	/* private used for position info */
1180Sstevel@tonic-gate 	int		x_handy; /* extra private word */
1190Sstevel@tonic-gate } XDR;
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate /*
1220Sstevel@tonic-gate  * PSARC 2003/523 Contract Private Interface
1230Sstevel@tonic-gate  * xdr_ops
1240Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
1250Sstevel@tonic-gate  * Changes must be communicated to contract-2003-523@sun.com
1260Sstevel@tonic-gate  */
1270Sstevel@tonic-gate struct xdr_ops {
1280Sstevel@tonic-gate #ifdef __STDC__
1290Sstevel@tonic-gate #if !defined(_KERNEL)
1300Sstevel@tonic-gate 		bool_t	(*x_getlong)(struct XDR *, long *);
1310Sstevel@tonic-gate 		/* get a long from underlying stream */
1320Sstevel@tonic-gate 		bool_t	(*x_putlong)(struct XDR *, long *);
1330Sstevel@tonic-gate 		/* put a long to " */
1340Sstevel@tonic-gate #endif /* KERNEL */
1350Sstevel@tonic-gate 		bool_t	(*x_getbytes)(struct XDR *, caddr_t, int);
1360Sstevel@tonic-gate 		/* get some bytes from " */
1370Sstevel@tonic-gate 		bool_t	(*x_putbytes)(struct XDR *, caddr_t, int);
1380Sstevel@tonic-gate 		/* put some bytes to " */
1390Sstevel@tonic-gate 		uint_t	(*x_getpostn)(struct XDR *);
1400Sstevel@tonic-gate 		/* returns bytes off from beginning */
1410Sstevel@tonic-gate 		bool_t  (*x_setpostn)(struct XDR *, uint_t);
1420Sstevel@tonic-gate 		/* lets you reposition the stream */
1430Sstevel@tonic-gate 		rpc_inline_t *(*x_inline)(struct XDR *, int);
1440Sstevel@tonic-gate 		/* buf quick ptr to buffered data */
1450Sstevel@tonic-gate 		void	(*x_destroy)(struct XDR *);
1460Sstevel@tonic-gate 		/* free privates of this xdr_stream */
1470Sstevel@tonic-gate 		bool_t	(*x_control)(struct XDR *, int, void *);
1480Sstevel@tonic-gate #if defined(_LP64) || defined(_KERNEL)
1490Sstevel@tonic-gate 		bool_t	(*x_getint32)(struct XDR *, int32_t *);
1500Sstevel@tonic-gate 		/* get a int from underlying stream */
1510Sstevel@tonic-gate 		bool_t	(*x_putint32)(struct XDR *, int32_t *);
1520Sstevel@tonic-gate 		/* put an int to " */
1530Sstevel@tonic-gate #endif /* _LP64 || _KERNEL */
1540Sstevel@tonic-gate #else
1550Sstevel@tonic-gate #if !defined(_KERNEL)
1560Sstevel@tonic-gate 		bool_t	(*x_getlong)();	/* get a long from underlying stream */
1570Sstevel@tonic-gate 		bool_t	(*x_putlong)();	/* put a long to " */
1580Sstevel@tonic-gate #endif /* KERNEL */
1590Sstevel@tonic-gate 		bool_t	(*x_getbytes)(); /* get some bytes from " */
1600Sstevel@tonic-gate 		bool_t	(*x_putbytes)(); /* put some bytes to " */
1610Sstevel@tonic-gate 		uint_t	(*x_getpostn)(); /* returns bytes off from beginning */
1620Sstevel@tonic-gate 		bool_t  (*x_setpostn)(); /* lets you reposition the stream */
1630Sstevel@tonic-gate 		rpc_inline_t *(*x_inline)();
1640Sstevel@tonic-gate 				/* buf quick ptr to buffered data */
1650Sstevel@tonic-gate 		void	(*x_destroy)();	/* free privates of this xdr_stream */
1660Sstevel@tonic-gate 		bool_t	(*x_control)();
1670Sstevel@tonic-gate #if defined(_LP64) || defined(_KERNEL)
1680Sstevel@tonic-gate 		bool_t	(*x_getint32)();
1690Sstevel@tonic-gate 		bool_t	(*x_putint32)();
1700Sstevel@tonic-gate #endif /* _LP64 || defined(_KERNEL) */
1710Sstevel@tonic-gate #endif
1720Sstevel@tonic-gate };
1730Sstevel@tonic-gate 
1740Sstevel@tonic-gate /*
1750Sstevel@tonic-gate  * Operations defined on a XDR handle
1760Sstevel@tonic-gate  *
1770Sstevel@tonic-gate  * XDR		*xdrs;
1780Sstevel@tonic-gate  * long		*longp;
1790Sstevel@tonic-gate  * caddr_t	 addr;
1800Sstevel@tonic-gate  * uint_t	 len;
1810Sstevel@tonic-gate  * uint_t	 pos;
1820Sstevel@tonic-gate  */
1830Sstevel@tonic-gate #if !defined(_KERNEL)
1840Sstevel@tonic-gate #define	XDR_GETLONG(xdrs, longp)			\
1850Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
1860Sstevel@tonic-gate #define	xdr_getlong(xdrs, longp)			\
1870Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate #define	XDR_PUTLONG(xdrs, longp)			\
1900Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
1910Sstevel@tonic-gate #define	xdr_putlong(xdrs, longp)			\
1920Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
1930Sstevel@tonic-gate #endif /* KERNEL */
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 
1960Sstevel@tonic-gate #if !defined(_LP64) && !defined(_KERNEL)
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate /*
1990Sstevel@tonic-gate  * For binary compatability on ILP32 we do not change the shape
2000Sstevel@tonic-gate  * of the XDR structure and the GET/PUTINT32 functions just use
2010Sstevel@tonic-gate  * the get/putlong vectors which operate on identically-sized
2020Sstevel@tonic-gate  * units of data.
2030Sstevel@tonic-gate  */
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate #define	XDR_GETINT32(xdrs, int32p)			\
2060Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getlong)(xdrs, (long *)int32p)
2070Sstevel@tonic-gate #define	xdr_getint32(xdrs, int32p)			\
2080Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getlong)(xdrs, (long *)int32p)
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate #define	XDR_PUTINT32(xdrs, int32p)			\
2110Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putlong)(xdrs, (long *)int32p)
2120Sstevel@tonic-gate #define	xdr_putint32(xdrs, int32p)			\
2130Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putlong)(xdrs, (long *)int32p)
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate #else /* !_LP64 && !_KERNEL */
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate #define	XDR_GETINT32(xdrs, int32p)			\
2180Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
2190Sstevel@tonic-gate #define	xdr_getint32(xdrs, int32p)			\
2200Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getint32)(xdrs, int32p)
2210Sstevel@tonic-gate 
2220Sstevel@tonic-gate #define	XDR_PUTINT32(xdrs, int32p)			\
2230Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
2240Sstevel@tonic-gate #define	xdr_putint32(xdrs, int32p)			\
2250Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putint32)(xdrs, int32p)
2260Sstevel@tonic-gate 
2270Sstevel@tonic-gate #endif /* !_LP64 && !_KERNEL */
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate #define	XDR_GETBYTES(xdrs, addr, len)			\
2300Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
2310Sstevel@tonic-gate #define	xdr_getbytes(xdrs, addr, len)			\
2320Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate #define	XDR_PUTBYTES(xdrs, addr, len)			\
2350Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
2360Sstevel@tonic-gate #define	xdr_putbytes(xdrs, addr, len)			\
2370Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate #define	XDR_GETPOS(xdrs)				\
2400Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getpostn)(xdrs)
2410Sstevel@tonic-gate #define	xdr_getpos(xdrs)				\
2420Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getpostn)(xdrs)
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate #define	XDR_SETPOS(xdrs, pos)				\
2450Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
2460Sstevel@tonic-gate #define	xdr_setpos(xdrs, pos)				\
2470Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate #define	XDR_INLINE(xdrs, len)				\
2500Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_inline)(xdrs, len)
2510Sstevel@tonic-gate #define	xdr_inline(xdrs, len)				\
2520Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_inline)(xdrs, len)
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate #define	XDR_DESTROY(xdrs)				\
2550Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_destroy)(xdrs)
2560Sstevel@tonic-gate #define	xdr_destroy(xdrs)				\
2570Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_destroy)(xdrs)
2580Sstevel@tonic-gate 
2590Sstevel@tonic-gate #define	XDR_CONTROL(xdrs, req, op)			\
2600Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_control)(xdrs, req, op)
2610Sstevel@tonic-gate #define	xdr_control(xdrs, req, op)			\
2620Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_control)(xdrs, req, op)
2630Sstevel@tonic-gate 
2640Sstevel@tonic-gate /*
2650Sstevel@tonic-gate  * Support struct for discriminated unions.
2660Sstevel@tonic-gate  * You create an array of xdrdiscrim structures, terminated with
2670Sstevel@tonic-gate  * a entry with a null procedure pointer.  The xdr_union routine gets
2680Sstevel@tonic-gate  * the discriminant value and then searches the array of structures
2690Sstevel@tonic-gate  * for a matching value.  If a match is found the associated xdr routine
2700Sstevel@tonic-gate  * is called to handle that part of the union.  If there is
2710Sstevel@tonic-gate  * no match, then a default routine may be called.
2720Sstevel@tonic-gate  * If there is no match and no default routine it is an error.
2730Sstevel@tonic-gate  */
2740Sstevel@tonic-gate 
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate /*
2770Sstevel@tonic-gate  * A xdrproc_t exists for each data type which is to be encoded or decoded.
2780Sstevel@tonic-gate  *
2790Sstevel@tonic-gate  * The second argument to the xdrproc_t is a pointer to an opaque pointer.
2800Sstevel@tonic-gate  * The opaque pointer generally points to a structure of the data type
2810Sstevel@tonic-gate  * to be decoded.  If this pointer is 0, then the type routines should
2820Sstevel@tonic-gate  * allocate dynamic storage of the appropriate size and return it.
2830Sstevel@tonic-gate  * bool_t	(*xdrproc_t)(XDR *, void *);
2840Sstevel@tonic-gate  */
2850Sstevel@tonic-gate #ifdef __cplusplus
2860Sstevel@tonic-gate typedef bool_t (*xdrproc_t)(XDR *, void *);
2870Sstevel@tonic-gate #else
2880Sstevel@tonic-gate #ifdef __STDC__
2890Sstevel@tonic-gate typedef bool_t (*xdrproc_t)(); /* For Backward compatibility */
2900Sstevel@tonic-gate #else
2910Sstevel@tonic-gate typedef	bool_t (*xdrproc_t)();
2920Sstevel@tonic-gate #endif
2930Sstevel@tonic-gate #endif
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate #define	NULL_xdrproc_t ((xdrproc_t)0)
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate #if defined(_LP64) || defined(_I32LPx)
2980Sstevel@tonic-gate #define	xdr_rpcvers(xdrs, versp)	xdr_u_int(xdrs, versp)
2990Sstevel@tonic-gate #define	xdr_rpcprog(xdrs, progp)	xdr_u_int(xdrs, progp)
3000Sstevel@tonic-gate #define	xdr_rpcproc(xdrs, procp)	xdr_u_int(xdrs, procp)
3010Sstevel@tonic-gate #define	xdr_rpcprot(xdrs, protp)	xdr_u_int(xdrs, protp)
3020Sstevel@tonic-gate #define	xdr_rpcport(xdrs, portp)	xdr_u_int(xdrs, portp)
3030Sstevel@tonic-gate #else
3040Sstevel@tonic-gate #define	xdr_rpcvers(xdrs, versp)	xdr_u_long(xdrs, versp)
3050Sstevel@tonic-gate #define	xdr_rpcprog(xdrs, progp)	xdr_u_long(xdrs, progp)
3060Sstevel@tonic-gate #define	xdr_rpcproc(xdrs, procp)	xdr_u_long(xdrs, procp)
3070Sstevel@tonic-gate #define	xdr_rpcprot(xdrs, protp)	xdr_u_long(xdrs, protp)
3080Sstevel@tonic-gate #define	xdr_rpcport(xdrs, portp)	xdr_u_long(xdrs, portp)
3090Sstevel@tonic-gate #endif
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate struct xdr_discrim {
3120Sstevel@tonic-gate 	int	value;
3130Sstevel@tonic-gate 	xdrproc_t proc;
3140Sstevel@tonic-gate };
3150Sstevel@tonic-gate 
3160Sstevel@tonic-gate /*
3170Sstevel@tonic-gate  * In-line routines for fast encode/decode of primitve data types.
3180Sstevel@tonic-gate  * Caveat emptor: these use single memory cycles to get the
3190Sstevel@tonic-gate  * data from the underlying buffer, and will fail to operate
3200Sstevel@tonic-gate  * properly if the data is not aligned.  The standard way to use these
3210Sstevel@tonic-gate  * is to say:
3220Sstevel@tonic-gate  *	if ((buf = XDR_INLINE(xdrs, count)) == NULL)
3230Sstevel@tonic-gate  *		return (FALSE);
3240Sstevel@tonic-gate  *	<<< macro calls >>>
3250Sstevel@tonic-gate  * where ``count'' is the number of bytes of data occupied
3260Sstevel@tonic-gate  * by the primitive data types.
3270Sstevel@tonic-gate  *
3280Sstevel@tonic-gate  * N.B. and frozen for all time: each data type here uses 4 bytes
3290Sstevel@tonic-gate  * of external representation.
3300Sstevel@tonic-gate  */
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate #define	IXDR_GET_INT32(buf)		((int32_t)ntohl((uint32_t)*(buf)++))
3330Sstevel@tonic-gate #define	IXDR_PUT_INT32(buf, v)		(*(buf)++ = (int32_t)htonl((uint32_t)v))
3340Sstevel@tonic-gate #define	IXDR_GET_U_INT32(buf)		((uint32_t)IXDR_GET_INT32(buf))
3350Sstevel@tonic-gate #define	IXDR_PUT_U_INT32(buf, v)	IXDR_PUT_INT32((buf), ((int32_t)(v)))
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate #if !defined(_KERNEL) && !defined(_LP64)
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate #define	IXDR_GET_LONG(buf)		((long)ntohl((ulong_t)*(buf)++))
3400Sstevel@tonic-gate #define	IXDR_PUT_LONG(buf, v)		(*(buf)++ = (long)htonl((ulong_t)v))
3410Sstevel@tonic-gate #define	IXDR_GET_U_LONG(buf)		((ulong_t)IXDR_GET_LONG(buf))
3420Sstevel@tonic-gate #define	IXDR_PUT_U_LONG(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate #define	IXDR_GET_BOOL(buf)		((bool_t)IXDR_GET_LONG(buf))
3450Sstevel@tonic-gate #define	IXDR_GET_ENUM(buf, t)		((t)IXDR_GET_LONG(buf))
3460Sstevel@tonic-gate #define	IXDR_GET_SHORT(buf)		((short)IXDR_GET_LONG(buf))
3470Sstevel@tonic-gate #define	IXDR_GET_U_SHORT(buf)		((ushort_t)IXDR_GET_LONG(buf))
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate #define	IXDR_PUT_BOOL(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
3500Sstevel@tonic-gate #define	IXDR_PUT_ENUM(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
3510Sstevel@tonic-gate #define	IXDR_PUT_SHORT(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
3520Sstevel@tonic-gate #define	IXDR_PUT_U_SHORT(buf, v)	IXDR_PUT_LONG((buf), ((long)(v)))
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate #else
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate #define	IXDR_GET_BOOL(buf)		((bool_t)IXDR_GET_INT32(buf))
3570Sstevel@tonic-gate #define	IXDR_GET_ENUM(buf, t)		((t)IXDR_GET_INT32(buf))
3580Sstevel@tonic-gate #define	IXDR_GET_SHORT(buf)		((short)IXDR_GET_INT32(buf))
3590Sstevel@tonic-gate #define	IXDR_GET_U_SHORT(buf)		((ushort_t)IXDR_GET_INT32(buf))
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate #define	IXDR_PUT_BOOL(buf, v)		IXDR_PUT_INT32((buf), ((int)(v)))
3620Sstevel@tonic-gate #define	IXDR_PUT_ENUM(buf, v)		IXDR_PUT_INT32((buf), ((int)(v)))
3630Sstevel@tonic-gate #define	IXDR_PUT_SHORT(buf, v)		IXDR_PUT_INT32((buf), ((int)(v)))
3640Sstevel@tonic-gate #define	IXDR_PUT_U_SHORT(buf, v)	IXDR_PUT_INT32((buf), ((int)(v)))
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate #endif
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate #ifndef _LITTLE_ENDIAN
3690Sstevel@tonic-gate #define	IXDR_GET_HYPER(buf, v)	{ \
3700Sstevel@tonic-gate 			*((int32_t *)(&v)) = ntohl(*(uint32_t *)buf++); \
3710Sstevel@tonic-gate 			*((int32_t *)(((char *)&v) + BYTES_PER_XDR_UNIT)) \
3720Sstevel@tonic-gate 			= ntohl(*(uint32_t *)buf++); \
3730Sstevel@tonic-gate 			}
3740Sstevel@tonic-gate #define	IXDR_PUT_HYPER(buf, v)	{ \
3750Sstevel@tonic-gate 			*(buf)++ = (int32_t)htonl(*(uint32_t *) \
3760Sstevel@tonic-gate 				((char *)&v)); \
3770Sstevel@tonic-gate 			*(buf)++ = \
3780Sstevel@tonic-gate 				(int32_t)htonl(*(uint32_t *)(((char *)&v) \
3790Sstevel@tonic-gate 				+ BYTES_PER_XDR_UNIT)); \
3800Sstevel@tonic-gate 			}
3810Sstevel@tonic-gate #else
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate #define	IXDR_GET_HYPER(buf, v)	{ \
3840Sstevel@tonic-gate 			*((int32_t *)(((char *)&v) + \
3850Sstevel@tonic-gate 				BYTES_PER_XDR_UNIT)) \
3860Sstevel@tonic-gate 				= ntohl(*(uint32_t *)buf++); \
3870Sstevel@tonic-gate 			*((int32_t *)(&v)) = \
3880Sstevel@tonic-gate 				ntohl(*(uint32_t *)buf++); \
3890Sstevel@tonic-gate 			}
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate #define	IXDR_PUT_HYPER(buf, v)	{ \
3920Sstevel@tonic-gate 			*(buf)++ = \
3930Sstevel@tonic-gate 				(int32_t)htonl(*(uint32_t *)(((char *)&v) + \
3940Sstevel@tonic-gate 				BYTES_PER_XDR_UNIT)); \
3950Sstevel@tonic-gate 			*(buf)++ = \
3960Sstevel@tonic-gate 				(int32_t)htonl(*(uint32_t *)((char *)&v)); \
3970Sstevel@tonic-gate 			}
3980Sstevel@tonic-gate #endif
3990Sstevel@tonic-gate #define	IXDR_GET_U_HYPER(buf, v)	IXDR_GET_HYPER(buf, v)
4000Sstevel@tonic-gate #define	IXDR_PUT_U_HYPER(buf, v)	IXDR_PUT_HYPER(buf, v)
4010Sstevel@tonic-gate 
4020Sstevel@tonic-gate 
4030Sstevel@tonic-gate /*
4040Sstevel@tonic-gate  * These are the "generic" xdr routines.
4050Sstevel@tonic-gate  */
4060Sstevel@tonic-gate #ifdef __STDC__
4070Sstevel@tonic-gate extern bool_t	xdr_void(void);
4080Sstevel@tonic-gate extern bool_t	xdr_int(XDR *, int *);
4090Sstevel@tonic-gate extern bool_t	xdr_u_int(XDR *, uint_t *);
4100Sstevel@tonic-gate extern bool_t	xdr_long(XDR *, long *);
4110Sstevel@tonic-gate extern bool_t	xdr_u_long(XDR *, ulong_t *);
4120Sstevel@tonic-gate extern bool_t	xdr_short(XDR *, short *);
4130Sstevel@tonic-gate extern bool_t	xdr_u_short(XDR *, ushort_t *);
4140Sstevel@tonic-gate extern bool_t	xdr_bool(XDR *, bool_t *);
4150Sstevel@tonic-gate extern bool_t	xdr_enum(XDR *, enum_t *);
4160Sstevel@tonic-gate extern bool_t	xdr_array(XDR *, caddr_t *, uint_t *, const uint_t,
4170Sstevel@tonic-gate 		    const uint_t, const xdrproc_t);
4180Sstevel@tonic-gate extern bool_t	xdr_bytes(XDR *, char **, uint_t *, const uint_t);
4190Sstevel@tonic-gate extern bool_t	xdr_opaque(XDR *, caddr_t, const uint_t);
4200Sstevel@tonic-gate extern bool_t	xdr_string(XDR *, char **, const uint_t);
4210Sstevel@tonic-gate extern bool_t	xdr_union(XDR *, enum_t *, char *,
4220Sstevel@tonic-gate 		    const struct xdr_discrim *, const xdrproc_t);
42310122SJordan.Brown@Sun.COM extern bool_t	xdr_vector(XDR *, char *, const uint_t, const uint_t,
42410122SJordan.Brown@Sun.COM     const xdrproc_t);
4250Sstevel@tonic-gate extern unsigned int  xdr_sizeof(xdrproc_t, void *);
4260Sstevel@tonic-gate 
4270Sstevel@tonic-gate extern bool_t   xdr_hyper(XDR *, longlong_t *);
4280Sstevel@tonic-gate extern bool_t   xdr_longlong_t(XDR *, longlong_t *);
4290Sstevel@tonic-gate extern bool_t   xdr_u_hyper(XDR *, u_longlong_t *);
4300Sstevel@tonic-gate extern bool_t   xdr_u_longlong_t(XDR *, u_longlong_t *);
4310Sstevel@tonic-gate 
4320Sstevel@tonic-gate extern bool_t	xdr_char(XDR *, char *);
43310122SJordan.Brown@Sun.COM extern bool_t	xdr_u_char(XDR *, uchar_t *);
4340Sstevel@tonic-gate extern bool_t	xdr_wrapstring(XDR *, char **);
4350Sstevel@tonic-gate extern bool_t	xdr_reference(XDR *, caddr_t *, uint_t, const xdrproc_t);
4360Sstevel@tonic-gate extern bool_t	xdr_pointer(XDR *, char **, uint_t, const xdrproc_t);
4370Sstevel@tonic-gate extern void	xdr_free(xdrproc_t, char *);
4380Sstevel@tonic-gate extern bool_t	xdr_time_t(XDR *, time_t *);
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate extern bool_t	xdr_int8_t(XDR *, int8_t *);
4410Sstevel@tonic-gate extern bool_t	xdr_uint8_t(XDR *, uint8_t *);
4420Sstevel@tonic-gate extern bool_t	xdr_int16_t(XDR *, int16_t *);
4430Sstevel@tonic-gate extern bool_t	xdr_uint16_t(XDR *, uint16_t *);
4440Sstevel@tonic-gate extern bool_t	xdr_int32_t(XDR *, int32_t *);
4450Sstevel@tonic-gate extern bool_t	xdr_uint32_t(XDR *, uint32_t *);
4460Sstevel@tonic-gate #if defined(_INT64_TYPE)
4470Sstevel@tonic-gate extern bool_t	xdr_int64_t(XDR *, int64_t *);
4480Sstevel@tonic-gate extern bool_t	xdr_uint64_t(XDR *, uint64_t *);
4490Sstevel@tonic-gate #endif
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate #ifndef _KERNEL
4520Sstevel@tonic-gate extern bool_t	xdr_float(XDR *, float *);
4530Sstevel@tonic-gate extern bool_t	xdr_double(XDR *, double *);
4540Sstevel@tonic-gate extern bool_t	xdr_quadruple(XDR *, long double *);
4550Sstevel@tonic-gate #endif /* !_KERNEL */
4560Sstevel@tonic-gate #else
4570Sstevel@tonic-gate extern bool_t	xdr_void();
4580Sstevel@tonic-gate extern bool_t	xdr_int();
4590Sstevel@tonic-gate extern bool_t	xdr_u_int();
4600Sstevel@tonic-gate extern bool_t	xdr_long();
4610Sstevel@tonic-gate extern bool_t	xdr_u_long();
4620Sstevel@tonic-gate extern bool_t	xdr_short();
4630Sstevel@tonic-gate extern bool_t	xdr_u_short();
4640Sstevel@tonic-gate extern bool_t	xdr_bool();
4650Sstevel@tonic-gate extern bool_t	xdr_enum();
4660Sstevel@tonic-gate extern bool_t	xdr_array();
4670Sstevel@tonic-gate extern bool_t	xdr_bytes();
4680Sstevel@tonic-gate extern bool_t	xdr_opaque();
4690Sstevel@tonic-gate extern bool_t	xdr_string();
4700Sstevel@tonic-gate extern bool_t	xdr_union();
47110122SJordan.Brown@Sun.COM extern bool_t	xdr_vector();
4720Sstevel@tonic-gate 
4730Sstevel@tonic-gate extern bool_t   xdr_hyper();
4740Sstevel@tonic-gate extern bool_t   xdr_longlong_t();
4750Sstevel@tonic-gate extern bool_t   xdr_u_hyper();
4760Sstevel@tonic-gate extern bool_t   xdr_u_longlong_t();
4770Sstevel@tonic-gate extern bool_t	xdr_char();
47810122SJordan.Brown@Sun.COM extern bool_t	xdr_u_char();
4790Sstevel@tonic-gate extern bool_t	xdr_reference();
4800Sstevel@tonic-gate extern bool_t	xdr_pointer();
4810Sstevel@tonic-gate extern void	xdr_free();
4820Sstevel@tonic-gate extern bool_t	xdr_wrapstring();
4830Sstevel@tonic-gate extern bool_t	xdr_time_t();
4840Sstevel@tonic-gate 
4850Sstevel@tonic-gate extern bool_t	xdr_int8_t();
4860Sstevel@tonic-gate extern bool_t	xdr_uint8_t();
4870Sstevel@tonic-gate extern bool_t	xdr_int16_t();
4880Sstevel@tonic-gate extern bool_t	xdr_uint16_t();
4890Sstevel@tonic-gate extern bool_t	xdr_int32_t();
4900Sstevel@tonic-gate extern bool_t	xdr_uint32_t();
4910Sstevel@tonic-gate #if defined(_INT64_TYPE)
4920Sstevel@tonic-gate extern bool_t	xdr_int64_t();
4930Sstevel@tonic-gate extern bool_t	xdr_uint64_t();
4940Sstevel@tonic-gate #endif
4950Sstevel@tonic-gate 
4960Sstevel@tonic-gate #ifndef _KERNEL
4970Sstevel@tonic-gate extern bool_t	xdr_float();
4980Sstevel@tonic-gate extern bool_t	xdr_double();
4990Sstevel@tonic-gate extern bool_t   xdr_quadruple();
5000Sstevel@tonic-gate #endif /* !_KERNEL */
5010Sstevel@tonic-gate #endif
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate /*
5040Sstevel@tonic-gate  * Common opaque bytes objects used by many rpc protocols;
5050Sstevel@tonic-gate  * declared here due to commonality.
5060Sstevel@tonic-gate  */
5070Sstevel@tonic-gate #define	MAX_NETOBJ_SZ 1024
5080Sstevel@tonic-gate struct netobj {
5090Sstevel@tonic-gate 	uint_t	n_len;
5100Sstevel@tonic-gate 	char	*n_bytes;
5110Sstevel@tonic-gate };
5120Sstevel@tonic-gate typedef struct netobj netobj;
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate #ifdef __STDC__
5150Sstevel@tonic-gate extern bool_t   xdr_netobj(XDR *, netobj *);
5160Sstevel@tonic-gate #else
5170Sstevel@tonic-gate extern bool_t   xdr_netobj();
5180Sstevel@tonic-gate #endif
5190Sstevel@tonic-gate 
5200Sstevel@tonic-gate /*
5210Sstevel@tonic-gate  * These are XDR control operators
5220Sstevel@tonic-gate  */
5230Sstevel@tonic-gate 
5240Sstevel@tonic-gate #define	XDR_GET_BYTES_AVAIL 1
5250Sstevel@tonic-gate 
5260Sstevel@tonic-gate struct xdr_bytesrec {
5270Sstevel@tonic-gate 	bool_t xc_is_last_record;
5280Sstevel@tonic-gate 	size_t xc_num_avail;
5290Sstevel@tonic-gate };
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate typedef struct xdr_bytesrec xdr_bytesrec;
5320Sstevel@tonic-gate 
5330Sstevel@tonic-gate /*
5340Sstevel@tonic-gate  * These are the request arguments to XDR_CONTROL.
5350Sstevel@tonic-gate  *
5360Sstevel@tonic-gate  * XDR_PEEK - returns the contents of the next XDR unit on the XDR stream.
5370Sstevel@tonic-gate  * XDR_SKIPBYTES - skips the next N bytes in the XDR stream.
5380Sstevel@tonic-gate  * XDR_RDMAGET - for xdr implementation over RDMA, gets private flags from
5390Sstevel@tonic-gate  *		 the XDR stream being moved over RDMA
5400Sstevel@tonic-gate  * XDR_RDMANOCHUNK - for xdr implementaion over RDMA, sets private flags in
5410Sstevel@tonic-gate  *                   the XDR stream moving over RDMA.
5420Sstevel@tonic-gate  */
5430Sstevel@tonic-gate #ifdef _KERNEL
5440Sstevel@tonic-gate #define	XDR_PEEK		2
5450Sstevel@tonic-gate #define	XDR_SKIPBYTES		3
5467387SRobert.Gordon@Sun.COM #define	XDR_RDMA_GET_FLAGS	4
5477387SRobert.Gordon@Sun.COM #define	XDR_RDMA_SET_FLAGS	5
5487387SRobert.Gordon@Sun.COM #define	XDR_RDMA_ADD_CHUNK	6
5497387SRobert.Gordon@Sun.COM #define	XDR_RDMA_GET_CHUNK_LEN	7
5507387SRobert.Gordon@Sun.COM #define	XDR_RDMA_SET_WLIST	8
5517387SRobert.Gordon@Sun.COM #define	XDR_RDMA_GET_WLIST	9
5527387SRobert.Gordon@Sun.COM #define	XDR_RDMA_GET_WCINFO	10
5537387SRobert.Gordon@Sun.COM #define	XDR_RDMA_GET_RLIST	11
5540Sstevel@tonic-gate #endif
5550Sstevel@tonic-gate 
5560Sstevel@tonic-gate /*
5570Sstevel@tonic-gate  * These are the public routines for the various implementations of
5580Sstevel@tonic-gate  * xdr streams.
5590Sstevel@tonic-gate  */
5600Sstevel@tonic-gate #ifndef _KERNEL
5610Sstevel@tonic-gate #ifdef __STDC__
5620Sstevel@tonic-gate extern void   xdrmem_create(XDR *, const caddr_t, const uint_t, const enum
5630Sstevel@tonic-gate xdr_op);
5640Sstevel@tonic-gate 	/* XDR using memory buffers */
5650Sstevel@tonic-gate extern void   xdrstdio_create(XDR *, FILE *, const enum xdr_op);
5660Sstevel@tonic-gate /* XDR using stdio library */
5670Sstevel@tonic-gate extern void   xdrrec_create(XDR *, const uint_t, const uint_t, const caddr_t,
5680Sstevel@tonic-gate int (*) (void *, caddr_t, int), int (*) (void *, caddr_t, int));
5690Sstevel@tonic-gate /* XDR pseudo records for tcp */
5700Sstevel@tonic-gate extern bool_t xdrrec_endofrecord(XDR *, bool_t);
5710Sstevel@tonic-gate /* make end of xdr record */
5720Sstevel@tonic-gate extern bool_t xdrrec_skiprecord(XDR *);
5730Sstevel@tonic-gate /* move to beginning of next record */
5740Sstevel@tonic-gate extern bool_t xdrrec_eof(XDR *);
5750Sstevel@tonic-gate extern uint_t xdrrec_readbytes(XDR *, caddr_t, uint_t);
5760Sstevel@tonic-gate /* true if no more input */
5770Sstevel@tonic-gate #else
5780Sstevel@tonic-gate extern void   xdrmem_create();
5790Sstevel@tonic-gate extern void   xdrstdio_create();
5800Sstevel@tonic-gate extern void   xdrrec_create();
5810Sstevel@tonic-gate extern bool_t xdrrec_endofrecord();
5820Sstevel@tonic-gate extern bool_t xdrrec_skiprecord();
5830Sstevel@tonic-gate extern bool_t xdrrec_eof();
5840Sstevel@tonic-gate extern uint_t xdrrec_readbytes();
5850Sstevel@tonic-gate #endif
5860Sstevel@tonic-gate #else
5870Sstevel@tonic-gate 
588*11539SChunli.Zhang@Sun.COM #define	DLEN(mp) (mp->b_cont ? msgdsize(mp) : (mp->b_wptr - mp->b_rptr))
589*11539SChunli.Zhang@Sun.COM 
5900Sstevel@tonic-gate extern void	xdrmem_create(XDR *, caddr_t, uint_t, enum xdr_op);
5910Sstevel@tonic-gate extern void	xdrmblk_init(XDR *, mblk_t *, enum xdr_op, int);
5920Sstevel@tonic-gate extern bool_t	xdrmblk_getmblk(XDR *, mblk_t **, uint_t *);
5930Sstevel@tonic-gate extern bool_t	xdrmblk_putmblk(XDR *, mblk_t *, uint_t);
5940Sstevel@tonic-gate extern struct xdr_ops xdrmblk_ops;
5957387SRobert.Gordon@Sun.COM extern struct xdr_ops xdrrdmablk_ops;
5967387SRobert.Gordon@Sun.COM extern struct xdr_ops xdrrdma_ops;
5970Sstevel@tonic-gate 
5980Sstevel@tonic-gate struct rpc_msg;
5990Sstevel@tonic-gate extern bool_t	xdr_callmsg(XDR *, struct rpc_msg *);
6000Sstevel@tonic-gate extern bool_t	xdr_replymsg_body(XDR *, struct rpc_msg *);
6010Sstevel@tonic-gate extern bool_t	xdr_replymsg_hdr(XDR *, struct rpc_msg *);
6020Sstevel@tonic-gate 
6030Sstevel@tonic-gate #endif /* !_KERNEL */
6040Sstevel@tonic-gate 
6050Sstevel@tonic-gate #ifdef __cplusplus
6060Sstevel@tonic-gate }
6070Sstevel@tonic-gate #endif
6080Sstevel@tonic-gate 
6090Sstevel@tonic-gate #endif	/* !_RPC_XDR_H */
610