xdr.h revision 61927
119304Speter/*
219304Speter * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
319304Speter * unrestricted use provided that this legend is included on all tape
419304Speter * media and as a part of the software program in whole or part.  Users
519304Speter * may copy or modify Sun RPC without charge, but are not authorized
619304Speter * to license or distribute it to anyone else except as part of a product or
719304Speter * program developed by the user.
819304Speter *
919304Speter * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1019304Speter * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1119304Speter * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1219304Speter *
13254225Speter * Sun RPC is provided with no support and without any obligation on the
1419304Speter * part of Sun Microsystems, Inc. to assist in its use, correction,
1519304Speter * modification or enhancement.
1619304Speter *
1719304Speter * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18254225Speter * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
1919304Speter * OR ANY PART THEREOF.
2019304Speter *
2119304Speter * In no event will Sun Microsystems, Inc. be liable for any lost revenue
2219304Speter * or profits or other special, indirect and consequential damages, even if
2319304Speter * Sun has been advised of the possibility of such damages.
2419304Speter *
2519304Speter * Sun Microsystems, Inc.
2619304Speter * 2550 Garcia Avenue
2719304Speter * Mountain View, California  94043
2819304Speter *
2919304Speter *	from: @(#)xdr.h 1.19 87/04/22 SMI
3019304Speter *	from: @(#)xdr.h	2.2 88/07/29 4.0 RPCSRC
3119304Speter * $FreeBSD: head/include/rpc/xdr.h 61927 2000-06-22 01:46:25Z nsayer $
3219304Speter */
3319304Speter
34281373Sbapt/*
35281373Sbapt * xdr.h, External Data Representation Serialization Routines.
3619304Speter *
3719304Speter * Copyright (C) 1984, Sun Microsystems, Inc.
38254225Speter */
39254225Speter
40254225Speter#ifndef _RPC_XDR_H
41254225Speter#define _RPC_XDR_H
42254225Speter#include <sys/cdefs.h>
43254225Speter
44254225Speter/*
45254225Speter * XDR provides a conventional way for converting between C data
46254225Speter * types and an external bit-string representation.  Library supplied
47254225Speter * routines provide for the conversion on built-in C data types.  These
4819304Speter * routines and utility routines defined here are used to help implement
4919304Speter * a type encode/decode routine for each user-defined type.
5019304Speter *
5119304Speter * Each data type provides a single procedure which takes two arguments:
5219304Speter *
5319304Speter *	bool_t
5419304Speter *	xdrproc(xdrs, argresp)
5519304Speter *		XDR *xdrs;
5619304Speter *		<type> *argresp;
5719304Speter *
5819304Speter * xdrs is an instance of a XDR handle, to which or from which the data
5919304Speter * type is to be converted.  argresp is a pointer to the structure to be
6019304Speter * converted.  The XDR handle contains an operation field which indicates
6119304Speter * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
6219304Speter *
6319304Speter * XDR_DECODE may allocate space if the pointer argresp is null.  This
6419304Speter * data can be freed with the XDR_FREE operation.
6519304Speter *
6619304Speter * We write only one procedure per data type to make it easy
67254225Speter * to keep the encode and decode procedures for a data type consistent.
6819304Speter * In many cases the same code performs all operations on a user defined type,
6919304Speter * because all the hard work is done in the component type routines.
7019304Speter * decode as a series of calls on the nested data types.
7119304Speter */
7219304Speter
7319304Speter/*
7419304Speter * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
7519304Speter * stream.  XDR_DECODE causes the type to be extracted from the stream.
7619304Speter * XDR_FREE can be used to release the space allocated by an XDR_DECODE
7719304Speter * request.
7819304Speter */
7919304Speterenum xdr_op {
8019304Speter	XDR_ENCODE=0,
8119304Speter	XDR_DECODE=1,
8219304Speter	XDR_FREE=2
8319304Speter};
8419304Speter
8519304Speter/*
8619304Speter * This is the number of bytes per unit of external data.
8719304Speter */
88254225Speter#define BYTES_PER_XDR_UNIT	(4)
8919304Speter#define RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
9019304Speter		    * BYTES_PER_XDR_UNIT)
9119304Speter
9219304Speter/*
9319304Speter * The XDR handle.
9419304Speter * Contains operation which is being applied to the stream,
95254225Speter * an operations vector for the particular implementation (e.g. see xdr_mem.c),
9619304Speter * and two private fields for the use of the particular implementation.
9719304Speter */
9819304Spetertypedef struct __rpc_xdr {
9919304Speter	enum xdr_op	x_op;		/* operation; fast additional param */
10019304Speter	struct xdr_ops {
10119304Speter		/* get a long from underlying stream */
10219304Speter		bool_t	(*x_getlong) __P((struct __rpc_xdr *, long *));
10319304Speter		/* put a long to underlying stream */
10419304Speter		bool_t	(*x_putlong) __P((struct __rpc_xdr *, long *));
105254225Speter		/* get some bytes from underlying stream */
10619304Speter		bool_t	(*x_getbytes) __P((struct __rpc_xdr *, caddr_t, u_int));
10719304Speter		/* put some bytes to underlying stream */
10819304Speter		bool_t	(*x_putbytes) __P((struct __rpc_xdr *, caddr_t, u_int));
10919304Speter		/* returns bytes off from beginning */
11019304Speter		u_int	(*x_getpostn) __P((struct __rpc_xdr *));
11119304Speter		/* lets you reposition the stream */
11219304Speter		bool_t  (*x_setpostn) __P((struct __rpc_xdr *, u_int));
11319304Speter		/* buf quick ptr to buffered data */
11419304Speter		int32_t *(*x_inline) __P((struct __rpc_xdr *, u_int));
11519304Speter		/* free privates of this xdr_stream */
11619304Speter		void	(*x_destroy) __P((struct __rpc_xdr *));
11719304Speter	} *x_ops;
11819304Speter	caddr_t 	x_public;	/* users' data */
11919304Speter	caddr_t		x_private;	/* pointer to private data */
12019304Speter	caddr_t 	x_base;		/* private used for position info */
12119304Speter	int		x_handy;	/* extra private word */
12219304Speter} XDR;
123254225Speter
12419304Speter/*
125254225Speter * A xdrproc_t exists for each data type which is to be encoded or decoded.
12619304Speter *
12719304Speter * The second argument to the xdrproc_t is a pointer to an opaque pointer.
12819304Speter * The opaque pointer generally points to a structure of the data type
129254225Speter * to be decoded.  If this pointer is 0, then the type routines should
13019304Speter * allocate dynamic storage of the appropriate size and return it.
13119304Speter *
13219304Speter * Sometimes there is a third argument, sometimes not. So for correct
13319304Speter * prototyping, ... is required.
13419304Speter */
13519304Speter#ifdef _KERNEL
13619304Spetertypedef	bool_t (*xdrproc_t) __P((XDR *, void *, u_int));
13719304Speter#else
13819304Spetertypedef	bool_t (*xdrproc_t) __P((XDR *, ...));
139281373Sbapt#endif
14019304Speter
14119304Speter/*
142254225Speter * Operations defined on a XDR handle
143254225Speter *
144254225Speter * XDR		*xdrs;
145254225Speter * long		*longp;
146254225Speter * caddr_t	 addr;
14719304Speter * u_int	 len;
148254225Speter * u_int	 pos;
149254225Speter */
15019304Speter#define XDR_GETLONG(xdrs, longp)			\
151254225Speter	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
152254225Speter#define xdr_getlong(xdrs, longp)			\
153254225Speter	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
154254225Speter
155254225Speter#define XDR_PUTLONG(xdrs, longp)			\
156254225Speter	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
157254225Speter#define xdr_putlong(xdrs, longp)			\
158254225Speter	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
159254225Speter
160254225Speter#define XDR_GETBYTES(xdrs, addr, len)			\
161254225Speter	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
162254225Speter#define xdr_getbytes(xdrs, addr, len)			\
163254225Speter	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
164254225Speter
165254225Speter#define XDR_PUTBYTES(xdrs, addr, len)			\
166254225Speter	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
167254225Speter#define xdr_putbytes(xdrs, addr, len)			\
168254225Speter	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
16919304Speter
17019304Speter#define XDR_GETPOS(xdrs)				\
17119304Speter	(*(xdrs)->x_ops->x_getpostn)(xdrs)
172254225Speter#define xdr_getpos(xdrs)				\
173254225Speter	(*(xdrs)->x_ops->x_getpostn)(xdrs)
17419304Speter
175281373Sbapt#define XDR_SETPOS(xdrs, pos)				\
17619304Speter	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
17719304Speter#define xdr_setpos(xdrs, pos)				\
178254225Speter	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
17919304Speter
18019304Speter#define	XDR_INLINE(xdrs, len)				\
18119304Speter	(*(xdrs)->x_ops->x_inline)(xdrs, len)
182254225Speter#define	xdr_inline(xdrs, len)				\
183254225Speter	(*(xdrs)->x_ops->x_inline)(xdrs, len)
18419304Speter
18519304Speter#define	XDR_DESTROY(xdrs)				\
18619304Speter	if ((xdrs)->x_ops->x_destroy) 			\
18719304Speter		(*(xdrs)->x_ops->x_destroy)(xdrs)
18819304Speter#define	xdr_destroy(xdrs)				\
18919304Speter	if ((xdrs)->x_ops->x_destroy) 			\
19019304Speter		(*(xdrs)->x_ops->x_destroy)(xdrs)
19119304Speter
19219304Speter/*
19319304Speter * Support struct for discriminated unions.
19419304Speter * You create an array of xdrdiscrim structures, terminated with
19519304Speter * a entry with a null procedure pointer.  The xdr_union routine gets
196281373Sbapt * the discriminant value and then searches the array of structures
19719304Speter * for a matching value.  If a match is found the associated xdr routine
19819304Speter * is called to handle that part of the union.  If there is
199254225Speter * no match, then a default routine may be called.
200254225Speter * If there is no match and no default routine it is an error.
201254225Speter */
202254225Speter#define NULL_xdrproc_t ((xdrproc_t)0)
203254225Speterstruct xdr_discrim {
204254225Speter	int	value;
205254225Speter	xdrproc_t proc;
206254225Speter};
20719304Speter
208254225Speter/*
20919304Speter * In-line routines for fast encode/decode of primitive data types.
21019304Speter * Caveat emptor: these use single memory cycles to get the
21119304Speter * data from the underlying buffer, and will fail to operate
21219304Speter * properly if the data is not aligned.  The standard way to use these
21319304Speter * is to say:
21419304Speter *	if ((buf = XDR_INLINE(xdrs, count)) == NULL)
21519304Speter *		return (FALSE);
21619304Speter *	<<< macro calls >>>
21719304Speter * where ``count'' is the number of bytes of data occupied
21819304Speter * by the primitive data types.
21919304Speter *
22019304Speter * N.B. and frozen for all time: each data type here uses 4 bytes
22119304Speter * of external representation.
22219304Speter */
223254225Speter#define IXDR_GET_LONG(buf)		((long)ntohl((u_long)*(buf)++))
224254225Speter#define IXDR_PUT_LONG(buf, v)		(*(buf)++ = (long)htonl((u_long)v))
22519304Speter
22619304Speter#define IXDR_GET_BOOL(buf)		((bool_t)IXDR_GET_LONG(buf))
22719304Speter#define IXDR_GET_ENUM(buf, t)		((t)IXDR_GET_LONG(buf))
22819304Speter#define IXDR_GET_U_LONG(buf)		((u_long)IXDR_GET_LONG(buf))
22919304Speter#define IXDR_GET_SHORT(buf)		((short)IXDR_GET_LONG(buf))
23019304Speter#define IXDR_GET_U_SHORT(buf)		((u_short)IXDR_GET_LONG(buf))
23119304Speter
23219304Speter#define IXDR_PUT_BOOL(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
23319304Speter#define IXDR_PUT_ENUM(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
23419304Speter#define IXDR_PUT_U_LONG(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
235254225Speter#define IXDR_PUT_SHORT(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
23619304Speter#define IXDR_PUT_U_SHORT(buf, v)	IXDR_PUT_LONG((buf), ((long)(v)))
23719304Speter
23819304Speter/*
23919304Speter * These are the "generic" xdr routines.
24019304Speter */
24119304Speter__BEGIN_DECLS
24219304Speterextern bool_t	xdr_void	__P((void));
24319304Speterextern bool_t	xdr_int		__P((XDR *, int *));
24419304Speterextern bool_t	xdr_u_int	__P((XDR *, u_int *));
24519304Speterextern bool_t	xdr_long	__P((XDR *, long *));
24619304Speterextern bool_t	xdr_u_long	__P((XDR *, u_long *));
24719304Speterextern bool_t	xdr_short	__P((XDR *, short *));
24819304Speterextern bool_t	xdr_u_short	__P((XDR *, u_short *));
24919304Speterextern bool_t	xdr_int16_t	__P((XDR *, int16_t *));
25019304Speterextern bool_t	xdr_u_int16_t	__P((XDR *, u_int16_t *));
25119304Speterextern bool_t	xdr_int32_t	__P((XDR *, int32_t *));
25219304Speterextern bool_t	xdr_u_int32_t	__P((XDR *, u_int32_t *));
25319304Speterextern bool_t	xdr_int64_t	__P((XDR *, int64_t *));
25419304Speterextern bool_t	xdr_u_int64_t	__P((XDR *, u_int64_t *));
25519304Speterextern bool_t	xdr_bool	__P((XDR *, bool_t *));
25619304Speterextern bool_t	xdr_enum	__P((XDR *, enum_t *));
25719304Speterextern bool_t	xdr_array	__P((XDR *, char **, u_int *, u_int, u_int, xdrproc_t));
25819304Speterextern bool_t	xdr_bytes	__P((XDR *, char **, u_int *, u_int));
25919304Speterextern bool_t	xdr_opaque	__P((XDR *, caddr_t, u_int));
26019304Speterextern bool_t	xdr_string	__P((XDR *, char **, u_int));
26119304Speterextern bool_t	xdr_union	__P((XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t));
26219304Speterextern unsigned long	xdr_sizeof __P((xdrproc_t, void *));
26319304Speterextern bool_t	xdr_char	__P((XDR *, char *));
26419304Speterextern bool_t	xdr_u_char	__P((XDR *, u_char *));
26519304Speterextern bool_t	xdr_vector	__P((XDR *, char *, u_int, u_int, xdrproc_t));
26619304Speterextern bool_t	xdr_float	__P((XDR *, float *));
26719304Speterextern bool_t	xdr_double	__P((XDR *, double *));
26819304Speterextern bool_t	xdr_reference	__P((XDR *, caddr_t *, u_int, xdrproc_t));
26919304Speterextern bool_t	xdr_pointer	__P((XDR *, caddr_t *, u_int, xdrproc_t));
27019304Speterextern bool_t	xdr_wrapstring	__P((XDR *, char **));
27119304Speterextern void	xdr_free 	__P((xdrproc_t, char *));
27219304Speter__END_DECLS
27319304Speter
27419304Speter/*
27519304Speter * Common opaque bytes objects used by many rpc protocols;
27619304Speter * declared here due to commonality.
27719304Speter */
27819304Speter#define MAX_NETOBJ_SZ 1024
27919304Speterstruct netobj {
28019304Speter	u_int	n_len;
281281373Sbapt	char	*n_bytes;
28219304Speter};
28319304Spetertypedef struct netobj netobj;
284254225Speterextern bool_t   xdr_netobj __P((XDR *, struct netobj *));
28519304Speter
28619304Speter/*
28719304Speter * These are the public routines for the various implementations of
288254225Speter * xdr streams.
289254225Speter */
290254225Speter__BEGIN_DECLS
29119304Speter/* XDR using memory buffers */
29219304Speterextern void   xdrmem_create	__P((XDR *, char *, u_int, enum xdr_op));
29319304Speter
29419304Speter#ifdef _STDIO_H_
29519304Speter/* XDR using stdio library */
29619304Speterextern void   xdrstdio_create	__P((XDR *, FILE *, enum xdr_op));
29719304Speter#endif
298281373Sbapt
29919304Speter/* XDR pseudo records for tcp */
30019304Speterextern void   xdrrec_create	__P((XDR *, u_int, u_int, char *,
301254225Speter				int (*) __P((caddr_t, caddr_t, int)),
302254225Speter				int (*) __P((caddr_t, caddr_t, int))));
303254225Speter
304254225Speter/* make end of xdr record */
30519304Speterextern bool_t xdrrec_endofrecord __P((XDR *, int));
30619304Speter
30719304Speter/* move to beginning of next record */
30819304Speterextern bool_t xdrrec_skiprecord	__P((XDR *));
30919304Speter
31019304Speter/* true if no more input */
31119304Speterextern bool_t xdrrec_eof	__P((XDR *));
31219304Speter__END_DECLS
313254225Speter
31419304Speter#endif /* !_RPC_XDR_H */
31519304Speter