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