xref: /onnv-gate/usr/src/lib/libbc/inc/include/rpc/xdr.h (revision 722:636b850d4ee9)
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
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
22*722Smuffin /*
23*722Smuffin  * Copyright 1984 Sun Microsystems, Inc.  All rights reserved.
24*722Smuffin  * Use is subject to license terms.
25*722Smuffin  */
26*722Smuffin 
27*722Smuffin #ifndef _rpc_xdr_h
28*722Smuffin #define	_rpc_xdr_h
29*722Smuffin 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
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 #include <rpc/types.h>
370Sstevel@tonic-gate /*
380Sstevel@tonic-gate  * XDR provides a conventional way for converting between C data
390Sstevel@tonic-gate  * types and an external bit-string representation.  Library supplied
400Sstevel@tonic-gate  * routines provide for the conversion on built-in C data types.  These
410Sstevel@tonic-gate  * routines and utility routines defined here are used to help implement
420Sstevel@tonic-gate  * a type encode/decode routine for each user-defined type.
430Sstevel@tonic-gate  *
440Sstevel@tonic-gate  * Each data type provides a single procedure which takes two arguments:
450Sstevel@tonic-gate  *
460Sstevel@tonic-gate  *	bool_t
470Sstevel@tonic-gate  *	xdrproc(xdrs, argresp)
480Sstevel@tonic-gate  *		XDR *xdrs;
490Sstevel@tonic-gate  *		<type> *argresp;
500Sstevel@tonic-gate  *
510Sstevel@tonic-gate  * xdrs is an instance of a XDR handle, to which or from which the data
520Sstevel@tonic-gate  * type is to be converted.  argresp is a pointer to the structure to be
530Sstevel@tonic-gate  * converted.  The XDR handle contains an operation field which indicates
540Sstevel@tonic-gate  * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
550Sstevel@tonic-gate  *
560Sstevel@tonic-gate  * XDR_DECODE may allocate space if the pointer argresp is null.  This
570Sstevel@tonic-gate  * data can be freed with the XDR_FREE operation.
580Sstevel@tonic-gate  *
590Sstevel@tonic-gate  * We write only one procedure per data type to make it easy
600Sstevel@tonic-gate  * to keep the encode and decode procedures for a data type consistent.
610Sstevel@tonic-gate  * In many cases the same code performs all operations on a user defined type,
620Sstevel@tonic-gate  * because all the hard work is done in the component type routines.
630Sstevel@tonic-gate  * decode as a series of calls on the nested data types.
640Sstevel@tonic-gate  */
650Sstevel@tonic-gate 
660Sstevel@tonic-gate /*
670Sstevel@tonic-gate  * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
680Sstevel@tonic-gate  * stream.  XDR_DECODE causes the type to be extracted from the stream.
690Sstevel@tonic-gate  * XDR_FREE can be used to release the space allocated by an XDR_DECODE
700Sstevel@tonic-gate  * request.
710Sstevel@tonic-gate  */
720Sstevel@tonic-gate enum xdr_op {
730Sstevel@tonic-gate 	XDR_ENCODE=0,
740Sstevel@tonic-gate 	XDR_DECODE=1,
750Sstevel@tonic-gate 	XDR_FREE=2
760Sstevel@tonic-gate };
770Sstevel@tonic-gate 
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate  * This is the number of bytes per unit of external data.
800Sstevel@tonic-gate  */
810Sstevel@tonic-gate #define	BYTES_PER_XDR_UNIT	(4)
820Sstevel@tonic-gate #define	RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
830Sstevel@tonic-gate 			* BYTES_PER_XDR_UNIT)
840Sstevel@tonic-gate 
850Sstevel@tonic-gate /*
860Sstevel@tonic-gate  * A xdrproc_t exists for each data type which is to be encoded or decoded.
870Sstevel@tonic-gate  *
880Sstevel@tonic-gate  * The second argument to the xdrproc_t is a pointer to an opaque pointer.
890Sstevel@tonic-gate  * The opaque pointer generally points to a structure of the data type
900Sstevel@tonic-gate  * to be decoded.  If this pointer is 0, then the type routines should
910Sstevel@tonic-gate  * allocate dynamic storage of the appropriate size and return it.
920Sstevel@tonic-gate  * bool_t	(*xdrproc_t)(XDR *, caddr_t *);
930Sstevel@tonic-gate  */
940Sstevel@tonic-gate typedef	bool_t (*xdrproc_t)();
950Sstevel@tonic-gate 
960Sstevel@tonic-gate /*
970Sstevel@tonic-gate  * The XDR handle.
980Sstevel@tonic-gate  * Contains operation which is being applied to the stream,
990Sstevel@tonic-gate  * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
1000Sstevel@tonic-gate  * and two private fields for the use of the particular impelementation.
1010Sstevel@tonic-gate  */
1020Sstevel@tonic-gate typedef struct {
1030Sstevel@tonic-gate 	enum xdr_op	x_op;		/* operation; fast additional param */
1040Sstevel@tonic-gate 	struct xdr_ops {
1050Sstevel@tonic-gate 		bool_t	(*x_getlong)();	/* get a long from underlying stream */
1060Sstevel@tonic-gate 		bool_t	(*x_putlong)();	/* put a long to " */
1070Sstevel@tonic-gate 		bool_t	(*x_getbytes)(); /* get some bytes from " */
1080Sstevel@tonic-gate 		bool_t	(*x_putbytes)(); /* put some bytes to " */
1090Sstevel@tonic-gate 		u_int	(*x_getpostn)(); /* returns bytes off from beginning */
1100Sstevel@tonic-gate 		bool_t	(*x_setpostn)(); /* lets you reposition the stream */
1110Sstevel@tonic-gate 		long *	(*x_inline)();	/* buf quick ptr to buffered data */
1120Sstevel@tonic-gate 		void	(*x_destroy)();	/* free privates of this xdr_stream */
1130Sstevel@tonic-gate 	} *x_ops;
1140Sstevel@tonic-gate 	caddr_t 	x_public;	/* users' data */
1150Sstevel@tonic-gate 	caddr_t		x_private;	/* pointer to private data */
1160Sstevel@tonic-gate 	caddr_t 	x_base;		/* private used for position info */
1170Sstevel@tonic-gate 	int		x_handy;	/* extra private word */
1180Sstevel@tonic-gate } XDR;
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate /*
1210Sstevel@tonic-gate  * Operations defined on a XDR handle
1220Sstevel@tonic-gate  *
1230Sstevel@tonic-gate  * XDR		*xdrs;
1240Sstevel@tonic-gate  * long		*longp;
1250Sstevel@tonic-gate  * caddr_t	 addr;
1260Sstevel@tonic-gate  * u_int	 len;
1270Sstevel@tonic-gate  * u_int	 pos;
1280Sstevel@tonic-gate  */
1290Sstevel@tonic-gate #define	XDR_GETLONG(xdrs, longp)			\
1300Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
1310Sstevel@tonic-gate #define	xdr_getlong(xdrs, longp)			\
1320Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate #define	XDR_PUTLONG(xdrs, longp)			\
1350Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
1360Sstevel@tonic-gate #define	xdr_putlong(xdrs, longp)			\
1370Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate #define	XDR_GETBYTES(xdrs, addr, len)			\
1400Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
1410Sstevel@tonic-gate #define	xdr_getbytes(xdrs, addr, len)			\
1420Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
1430Sstevel@tonic-gate 
1440Sstevel@tonic-gate #define	XDR_PUTBYTES(xdrs, addr, len)			\
1450Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
1460Sstevel@tonic-gate #define	xdr_putbytes(xdrs, addr, len)			\
1470Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate #define	XDR_GETPOS(xdrs)				\
1500Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getpostn)(xdrs)
1510Sstevel@tonic-gate #define	xdr_getpos(xdrs)				\
1520Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_getpostn)(xdrs)
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate #define	XDR_SETPOS(xdrs, pos)				\
1550Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
1560Sstevel@tonic-gate #define	xdr_setpos(xdrs, pos)				\
1570Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate #define	XDR_INLINE(xdrs, len)				\
1600Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_inline)(xdrs, len)
1610Sstevel@tonic-gate #define	xdr_inline(xdrs, len)				\
1620Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_inline)(xdrs, len)
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate #define	XDR_DESTROY(xdrs)				\
1650Sstevel@tonic-gate 	(*(xdrs)->x_ops->x_destroy)(xdrs)
1660Sstevel@tonic-gate #define	xdr_destroy(xdrs) XDR_DESTROY(xdrs)
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate /*
1690Sstevel@tonic-gate  * Support struct for discriminated unions.
1700Sstevel@tonic-gate  * You create an array of xdrdiscrim structures, terminated with
1710Sstevel@tonic-gate  * a entry with a null procedure pointer.  The xdr_union routine gets
1720Sstevel@tonic-gate  * the discriminant value and then searches the array of structures
1730Sstevel@tonic-gate  * for a matching value.  If a match is found the associated xdr routine
1740Sstevel@tonic-gate  * is called to handle that part of the union.  If there is
1750Sstevel@tonic-gate  * no match, then a default routine may be called.
1760Sstevel@tonic-gate  * If there is no match and no default routine it is an error.
1770Sstevel@tonic-gate  */
1780Sstevel@tonic-gate #define	NULL_xdrproc_t ((xdrproc_t)0)
1790Sstevel@tonic-gate struct xdr_discrim {
1800Sstevel@tonic-gate 	int	value;
1810Sstevel@tonic-gate 	xdrproc_t proc;
1820Sstevel@tonic-gate };
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate /*
1850Sstevel@tonic-gate  * In-line routines for fast encode/decode of primitve data types.
1860Sstevel@tonic-gate  * Caveat emptor: these use single memory cycles to get the
1870Sstevel@tonic-gate  * data from the underlying buffer, and will fail to operate
1880Sstevel@tonic-gate  * properly if the data is not aligned.  The standard way to use these
1890Sstevel@tonic-gate  * is to say:
1900Sstevel@tonic-gate  *	if ((buf = XDR_INLINE(xdrs, count)) == NULL)
1910Sstevel@tonic-gate  *		return (FALSE);
1920Sstevel@tonic-gate  *	<<< macro calls >>>
1930Sstevel@tonic-gate  * where ``count'' is the number of bytes of data occupied
1940Sstevel@tonic-gate  * by the primitive data types.
1950Sstevel@tonic-gate  *
1960Sstevel@tonic-gate  * N.B. and frozen for all time: each data type here uses 4 bytes
1970Sstevel@tonic-gate  * of external representation.
1980Sstevel@tonic-gate  */
1990Sstevel@tonic-gate #define	IXDR_GET_LONG(buf)		((long)ntohl((u_long)*(buf)++))
2000Sstevel@tonic-gate #define	IXDR_PUT_LONG(buf, v)		(*(buf)++ = (long)htonl((u_long)v))
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate #define	IXDR_GET_BOOL(buf)		((bool_t)IXDR_GET_LONG(buf))
2030Sstevel@tonic-gate #define	IXDR_GET_ENUM(buf, t)		((t)IXDR_GET_LONG(buf))
2040Sstevel@tonic-gate #define	IXDR_GET_U_LONG(buf)		((u_long)IXDR_GET_LONG(buf))
2050Sstevel@tonic-gate #define	IXDR_GET_SHORT(buf)		((short)IXDR_GET_LONG(buf))
2060Sstevel@tonic-gate #define	IXDR_GET_U_SHORT(buf)		((u_short)IXDR_GET_LONG(buf))
2070Sstevel@tonic-gate 
2080Sstevel@tonic-gate #define	IXDR_PUT_BOOL(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
2090Sstevel@tonic-gate #define	IXDR_PUT_ENUM(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
2100Sstevel@tonic-gate #define	IXDR_PUT_U_LONG(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
2110Sstevel@tonic-gate #define	IXDR_PUT_SHORT(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
2120Sstevel@tonic-gate #define	IXDR_PUT_U_SHORT(buf, v)	IXDR_PUT_LONG((buf), ((long)(v)))
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate /*
2150Sstevel@tonic-gate  * These are the "generic" xdr routines.
2160Sstevel@tonic-gate  */
2170Sstevel@tonic-gate extern bool_t	xdr_void();
2180Sstevel@tonic-gate extern bool_t	xdr_int();
2190Sstevel@tonic-gate extern bool_t	xdr_u_int();
2200Sstevel@tonic-gate extern bool_t	xdr_long();
2210Sstevel@tonic-gate extern bool_t	xdr_u_long();
2220Sstevel@tonic-gate extern bool_t	xdr_short();
2230Sstevel@tonic-gate extern bool_t	xdr_u_short();
2240Sstevel@tonic-gate extern bool_t	xdr_bool();
2250Sstevel@tonic-gate extern bool_t	xdr_enum();
2260Sstevel@tonic-gate extern bool_t	xdr_array();
2270Sstevel@tonic-gate extern bool_t	xdr_bytes();
2280Sstevel@tonic-gate extern bool_t	xdr_opaque();
2290Sstevel@tonic-gate extern bool_t	xdr_string();
2300Sstevel@tonic-gate extern bool_t	xdr_union();
2310Sstevel@tonic-gate extern void	xdr_free();
2320Sstevel@tonic-gate extern bool_t	xdr_char();
2330Sstevel@tonic-gate extern bool_t	xdr_u_char();
2340Sstevel@tonic-gate extern bool_t	xdr_vector();
2350Sstevel@tonic-gate extern bool_t	xdr_float();
2360Sstevel@tonic-gate extern bool_t	xdr_double();
2370Sstevel@tonic-gate extern bool_t	xdr_reference();
2380Sstevel@tonic-gate extern bool_t	xdr_pointer();
2390Sstevel@tonic-gate extern bool_t	xdr_wrapstring();
2400Sstevel@tonic-gate 
2410Sstevel@tonic-gate /*
2420Sstevel@tonic-gate  * Common opaque bytes objects used by many rpc protocols;
2430Sstevel@tonic-gate  * declared here due to commonality.
2440Sstevel@tonic-gate  */
2450Sstevel@tonic-gate #define	MAX_NETOBJ_SZ 1024
2460Sstevel@tonic-gate struct netobj {
2470Sstevel@tonic-gate 	u_int	n_len;
2480Sstevel@tonic-gate 	char	*n_bytes;
2490Sstevel@tonic-gate };
2500Sstevel@tonic-gate typedef struct netobj netobj;
2510Sstevel@tonic-gate extern bool_t	xdr_netobj();
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate /*
2540Sstevel@tonic-gate  * These are the public routines for the various implementations of
2550Sstevel@tonic-gate  * xdr streams.
2560Sstevel@tonic-gate  */
2570Sstevel@tonic-gate extern void	xdrmem_create();	/* XDR using memory buffers */
2580Sstevel@tonic-gate extern void	xdrstdio_create();	/* XDR using stdio library */
2590Sstevel@tonic-gate extern void	xdrrec_create();	/* XDR pseudo records for tcp */
2600Sstevel@tonic-gate extern bool_t	xdrrec_endofrecord();	/* make end of xdr record */
2610Sstevel@tonic-gate extern int	xdrrec_readbytes();	/* like a read on a pipe */
2620Sstevel@tonic-gate extern bool_t	xdrrec_skiprecord();	/* move to beginning of next record */
2630Sstevel@tonic-gate extern bool_t	xdrrec_eof();		/* true if no more input */
2640Sstevel@tonic-gate 
265*722Smuffin #endif /* !_rpc_xdr_h */
266