174462Salfred/* $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ */ 274462Salfred 31839Swollman/* 41839Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 51839Swollman * unrestricted use provided that this legend is included on all tape 61839Swollman * media and as a part of the software program in whole or part. Users 71839Swollman * may copy or modify Sun RPC without charge, but are not authorized 81839Swollman * to license or distribute it to anyone else except as part of a product or 91839Swollman * program developed by the user. 108858Srgrimes * 111839Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1213771Smpp * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR 131839Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 148858Srgrimes * 151839Swollman * Sun RPC is provided with no support and without any obligation on the 161839Swollman * part of Sun Microsystems, Inc. to assist in its use, correction, 171839Swollman * modification or enhancement. 188858Srgrimes * 191839Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 201839Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 211839Swollman * OR ANY PART THEREOF. 228858Srgrimes * 231839Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 241839Swollman * or profits or other special, indirect and consequential damages, even if 251839Swollman * Sun has been advised of the possibility of such damages. 268858Srgrimes * 271839Swollman * Sun Microsystems, Inc. 281839Swollman * 2550 Garcia Avenue 291839Swollman * Mountain View, California 94043 301903Swollman * 311903Swollman * from: @(#)xdr.h 1.19 87/04/22 SMI 321903Swollman * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC 3350473Speter * $FreeBSD$ 341839Swollman */ 351839Swollman 361839Swollman/* 371839Swollman * xdr.h, External Data Representation Serialization Routines. 381839Swollman * 391839Swollman * Copyright (C) 1984, Sun Microsystems, Inc. 401839Swollman */ 411839Swollman 421903Swollman#ifndef _RPC_XDR_H 431903Swollman#define _RPC_XDR_H 441903Swollman#include <sys/cdefs.h> 451839Swollman 461839Swollman/* 471839Swollman * XDR provides a conventional way for converting between C data 481839Swollman * types and an external bit-string representation. Library supplied 491839Swollman * routines provide for the conversion on built-in C data types. These 501839Swollman * routines and utility routines defined here are used to help implement 511839Swollman * a type encode/decode routine for each user-defined type. 521839Swollman * 531839Swollman * Each data type provides a single procedure which takes two arguments: 541839Swollman * 551839Swollman * bool_t 561839Swollman * xdrproc(xdrs, argresp) 571839Swollman * XDR *xdrs; 581839Swollman * <type> *argresp; 591839Swollman * 601839Swollman * xdrs is an instance of a XDR handle, to which or from which the data 611839Swollman * type is to be converted. argresp is a pointer to the structure to be 621839Swollman * converted. The XDR handle contains an operation field which indicates 631839Swollman * which of the operations (ENCODE, DECODE * or FREE) is to be performed. 641839Swollman * 651839Swollman * XDR_DECODE may allocate space if the pointer argresp is null. This 661839Swollman * data can be freed with the XDR_FREE operation. 671839Swollman * 681839Swollman * We write only one procedure per data type to make it easy 691839Swollman * to keep the encode and decode procedures for a data type consistent. 701839Swollman * In many cases the same code performs all operations on a user defined type, 711839Swollman * because all the hard work is done in the component type routines. 721839Swollman * decode as a series of calls on the nested data types. 731839Swollman */ 741839Swollman 751839Swollman/* 761839Swollman * Xdr operations. XDR_ENCODE causes the type to be encoded into the 771839Swollman * stream. XDR_DECODE causes the type to be extracted from the stream. 781839Swollman * XDR_FREE can be used to release the space allocated by an XDR_DECODE 791839Swollman * request. 801839Swollman */ 811839Swollmanenum xdr_op { 821839Swollman XDR_ENCODE=0, 831839Swollman XDR_DECODE=1, 841839Swollman XDR_FREE=2 851839Swollman}; 861839Swollman 871839Swollman/* 881839Swollman * This is the number of bytes per unit of external data. 891839Swollman */ 901839Swollman#define BYTES_PER_XDR_UNIT (4) 911839Swollman#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ 921839Swollman * BYTES_PER_XDR_UNIT) 931839Swollman 941839Swollman/* 951839Swollman * The XDR handle. 961839Swollman * Contains operation which is being applied to the stream, 9713771Smpp * an operations vector for the particular implementation (e.g. see xdr_mem.c), 9813771Smpp * and two private fields for the use of the particular implementation. 991839Swollman */ 100240060Spfgtypedef struct XDR { 1011839Swollman enum xdr_op x_op; /* operation; fast additional param */ 10274462Salfred const struct xdr_ops { 10321059Speter /* get a long from underlying stream */ 104240060Spfg bool_t (*x_getlong)(struct XDR *, long *); 10574462Salfred /* put a long to " */ 106240060Spfg bool_t (*x_putlong)(struct XDR *, const long *); 10774462Salfred /* get some bytes from " */ 108240060Spfg bool_t (*x_getbytes)(struct XDR *, char *, u_int); 10974462Salfred /* put some bytes to " */ 110240060Spfg bool_t (*x_putbytes)(struct XDR *, const char *, u_int); 11121059Speter /* returns bytes off from beginning */ 112240060Spfg u_int (*x_getpostn)(struct XDR *); 11321059Speter /* lets you reposition the stream */ 114240060Spfg bool_t (*x_setpostn)(struct XDR *, u_int); 11521059Speter /* buf quick ptr to buffered data */ 116240060Spfg int32_t *(*x_inline)(struct XDR *, u_int); 11721059Speter /* free privates of this xdr_stream */ 118240060Spfg void (*x_destroy)(struct XDR *); 119240060Spfg bool_t (*x_control)(struct XDR *, int, void *); 1201839Swollman } *x_ops; 12174462Salfred char * x_public; /* users' data */ 12274462Salfred void * x_private; /* pointer to private data */ 12374462Salfred char * x_base; /* private used for position info */ 124111962Snectar u_int x_handy; /* extra private word */ 1251839Swollman} XDR; 1261839Swollman 1271839Swollman/* 12821059Speter * A xdrproc_t exists for each data type which is to be encoded or decoded. 12921059Speter * 13021059Speter * The second argument to the xdrproc_t is a pointer to an opaque pointer. 13121059Speter * The opaque pointer generally points to a structure of the data type 13221059Speter * to be decoded. If this pointer is 0, then the type routines should 13321059Speter * allocate dynamic storage of the appropriate size and return it. 13474510Salfred */ 13574510Salfred#ifdef _KERNEL 13693032Simptypedef bool_t (*xdrproc_t)(XDR *, void *, u_int); 13774510Salfred#else 13874510Salfred/* 13974462Salfred * XXX can't actually prototype it, because some take three args!!! 14021059Speter */ 14195658Sdestypedef bool_t (*xdrproc_t)(XDR *, ...); 14274510Salfred#endif 14321059Speter 14421059Speter/* 1451839Swollman * Operations defined on a XDR handle 1461839Swollman * 1471839Swollman * XDR *xdrs; 1481839Swollman * long *longp; 14974462Salfred * char * addr; 1501839Swollman * u_int len; 1511839Swollman * u_int pos; 1521839Swollman */ 1531839Swollman#define XDR_GETLONG(xdrs, longp) \ 1541839Swollman (*(xdrs)->x_ops->x_getlong)(xdrs, longp) 1551839Swollman#define xdr_getlong(xdrs, longp) \ 1561839Swollman (*(xdrs)->x_ops->x_getlong)(xdrs, longp) 1571839Swollman 1581839Swollman#define XDR_PUTLONG(xdrs, longp) \ 1591839Swollman (*(xdrs)->x_ops->x_putlong)(xdrs, longp) 1601839Swollman#define xdr_putlong(xdrs, longp) \ 1611839Swollman (*(xdrs)->x_ops->x_putlong)(xdrs, longp) 1621839Swollman 16374462Salfredstatic __inline int 16474462Salfredxdr_getint32(XDR *xdrs, int32_t *ip) 16574462Salfred{ 16674462Salfred long l; 16774462Salfred 16874462Salfred if (!xdr_getlong(xdrs, &l)) 16974462Salfred return (FALSE); 17074462Salfred *ip = (int32_t)l; 17174462Salfred return (TRUE); 17274462Salfred} 17374462Salfred 17474462Salfredstatic __inline int 17574462Salfredxdr_putint32(XDR *xdrs, int32_t *ip) 17674462Salfred{ 17774462Salfred long l; 17874462Salfred 17974462Salfred l = (long)*ip; 18074462Salfred return xdr_putlong(xdrs, &l); 18174462Salfred} 18274462Salfred 18374462Salfred#define XDR_GETINT32(xdrs, int32p) xdr_getint32(xdrs, int32p) 18474462Salfred#define XDR_PUTINT32(xdrs, int32p) xdr_putint32(xdrs, int32p) 18574462Salfred 1861839Swollman#define XDR_GETBYTES(xdrs, addr, len) \ 1871839Swollman (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) 1881839Swollman#define xdr_getbytes(xdrs, addr, len) \ 1891839Swollman (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) 1901839Swollman 1911839Swollman#define XDR_PUTBYTES(xdrs, addr, len) \ 1921839Swollman (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) 1931839Swollman#define xdr_putbytes(xdrs, addr, len) \ 1941839Swollman (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) 1951839Swollman 1961839Swollman#define XDR_GETPOS(xdrs) \ 1971839Swollman (*(xdrs)->x_ops->x_getpostn)(xdrs) 1981839Swollman#define xdr_getpos(xdrs) \ 1991839Swollman (*(xdrs)->x_ops->x_getpostn)(xdrs) 2001839Swollman 2011839Swollman#define XDR_SETPOS(xdrs, pos) \ 2021839Swollman (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) 2031839Swollman#define xdr_setpos(xdrs, pos) \ 2041839Swollman (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) 2051839Swollman 2061839Swollman#define XDR_INLINE(xdrs, len) \ 2071839Swollman (*(xdrs)->x_ops->x_inline)(xdrs, len) 2081839Swollman#define xdr_inline(xdrs, len) \ 2091839Swollman (*(xdrs)->x_ops->x_inline)(xdrs, len) 2101839Swollman 2111839Swollman#define XDR_DESTROY(xdrs) \ 2121839Swollman if ((xdrs)->x_ops->x_destroy) \ 2131839Swollman (*(xdrs)->x_ops->x_destroy)(xdrs) 2141839Swollman#define xdr_destroy(xdrs) \ 2151839Swollman if ((xdrs)->x_ops->x_destroy) \ 2161839Swollman (*(xdrs)->x_ops->x_destroy)(xdrs) 2171839Swollman 21874462Salfred#define XDR_CONTROL(xdrs, req, op) \ 21974462Salfred if ((xdrs)->x_ops->x_control) \ 22074462Salfred (*(xdrs)->x_ops->x_control)(xdrs, req, op) 22174462Salfred#define xdr_control(xdrs, req, op) XDR_CONTROL(xdrs, req, op) 22274462Salfred 2231839Swollman/* 22474462Salfred * Solaris strips the '_t' from these types -- not sure why. 22574462Salfred * But, let's be compatible. 22674462Salfred */ 22774462Salfred#define xdr_rpcvers(xdrs, versp) xdr_u_int32(xdrs, versp) 22874462Salfred#define xdr_rpcprog(xdrs, progp) xdr_u_int32(xdrs, progp) 22974462Salfred#define xdr_rpcproc(xdrs, procp) xdr_u_int32(xdrs, procp) 23074462Salfred#define xdr_rpcprot(xdrs, protp) xdr_u_int32(xdrs, protp) 23174462Salfred#define xdr_rpcport(xdrs, portp) xdr_u_int32(xdrs, portp) 23274462Salfred 23374462Salfred/* 2341839Swollman * Support struct for discriminated unions. 2351839Swollman * You create an array of xdrdiscrim structures, terminated with 236108533Sschweikh * an entry with a null procedure pointer. The xdr_union routine gets 2371839Swollman * the discriminant value and then searches the array of structures 2381839Swollman * for a matching value. If a match is found the associated xdr routine 2391839Swollman * is called to handle that part of the union. If there is 2401839Swollman * no match, then a default routine may be called. 2411839Swollman * If there is no match and no default routine it is an error. 2421839Swollman */ 2431839Swollman#define NULL_xdrproc_t ((xdrproc_t)0) 2441839Swollmanstruct xdr_discrim { 2451839Swollman int value; 2461839Swollman xdrproc_t proc; 2471839Swollman}; 2481839Swollman 2491839Swollman/* 25013771Smpp * In-line routines for fast encode/decode of primitive data types. 2511839Swollman * Caveat emptor: these use single memory cycles to get the 2521839Swollman * data from the underlying buffer, and will fail to operate 2531839Swollman * properly if the data is not aligned. The standard way to use these 2541839Swollman * is to say: 2551839Swollman * if ((buf = XDR_INLINE(xdrs, count)) == NULL) 2561839Swollman * return (FALSE); 2571839Swollman * <<< macro calls >>> 2581839Swollman * where ``count'' is the number of bytes of data occupied 2591839Swollman * by the primitive data types. 2601839Swollman * 2611839Swollman * N.B. and frozen for all time: each data type here uses 4 bytes 2621839Swollman * of external representation. 2631839Swollman */ 26490868Smike#define IXDR_GET_INT32(buf) ((int32_t)__ntohl((u_int32_t)*(buf)++)) 26590868Smike#define IXDR_PUT_INT32(buf, v) (*(buf)++ =(int32_t)__htonl((u_int32_t)v)) 26674462Salfred#define IXDR_GET_U_INT32(buf) ((u_int32_t)IXDR_GET_INT32(buf)) 26774462Salfred#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32((buf), ((int32_t)(v))) 2681839Swollman 26990868Smike#define IXDR_GET_LONG(buf) ((long)__ntohl((u_int32_t)*(buf)++)) 27090868Smike#define IXDR_PUT_LONG(buf, v) (*(buf)++ =(int32_t)__htonl((u_int32_t)v)) 27174462Salfred 2721839Swollman#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) 2731839Swollman#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) 2741839Swollman#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) 2751839Swollman#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) 2761839Swollman#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) 2771839Swollman 27874462Salfred#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), (v)) 27974462Salfred#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), (v)) 28074462Salfred#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), (v)) 28174462Salfred#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), (v)) 28274462Salfred#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), (v)) 2831839Swollman 2841839Swollman/* 2851839Swollman * These are the "generic" xdr routines. 2861839Swollman */ 2871903Swollman__BEGIN_DECLS 288223906Skevloextern bool_t xdr_void(void); 289223906Skevloextern bool_t xdr_int(XDR *, int *); 290223906Skevloextern bool_t xdr_u_int(XDR *, u_int *); 291223906Skevloextern bool_t xdr_long(XDR *, long *); 292223906Skevloextern bool_t xdr_u_long(XDR *, u_long *); 293223906Skevloextern bool_t xdr_short(XDR *, short *); 294223906Skevloextern bool_t xdr_u_short(XDR *, u_short *); 295223906Skevloextern bool_t xdr_int16_t(XDR *, int16_t *); 296223906Skevloextern bool_t xdr_u_int16_t(XDR *, u_int16_t *); 297223906Skevloextern bool_t xdr_uint16_t(XDR *, u_int16_t *); 298223906Skevloextern bool_t xdr_int32_t(XDR *, int32_t *); 299223906Skevloextern bool_t xdr_u_int32_t(XDR *, u_int32_t *); 300223906Skevloextern bool_t xdr_uint32_t(XDR *, u_int32_t *); 301223906Skevloextern bool_t xdr_int64_t(XDR *, int64_t *); 302223906Skevloextern bool_t xdr_u_int64_t(XDR *, u_int64_t *); 303223906Skevloextern bool_t xdr_uint64_t(XDR *, u_int64_t *); 304223906Skevloextern bool_t xdr_bool(XDR *, bool_t *); 305223906Skevloextern bool_t xdr_enum(XDR *, enum_t *); 306223906Skevloextern bool_t xdr_array(XDR *, char **, u_int *, u_int, u_int, xdrproc_t); 307223906Skevloextern bool_t xdr_bytes(XDR *, char **, u_int *, u_int); 308223906Skevloextern bool_t xdr_opaque(XDR *, char *, u_int); 309223906Skevloextern bool_t xdr_string(XDR *, char **, u_int); 310223906Skevloextern bool_t xdr_union(XDR *, enum_t *, char *, const struct xdr_discrim *, xdrproc_t); 311223906Skevloextern bool_t xdr_char(XDR *, char *); 312223906Skevloextern bool_t xdr_u_char(XDR *, u_char *); 313223906Skevloextern bool_t xdr_vector(XDR *, char *, u_int, u_int, xdrproc_t); 314223906Skevloextern bool_t xdr_float(XDR *, float *); 315223906Skevloextern bool_t xdr_double(XDR *, double *); 316223906Skevloextern bool_t xdr_quadruple(XDR *, long double *); 317223906Skevloextern bool_t xdr_reference(XDR *, char **, u_int, xdrproc_t); 318223906Skevloextern bool_t xdr_pointer(XDR *, char **, u_int, xdrproc_t); 319223906Skevloextern bool_t xdr_wrapstring(XDR *, char **); 320223906Skevloextern void xdr_free(xdrproc_t, void *); 321223906Skevloextern bool_t xdr_hyper(XDR *, quad_t *); 322223906Skevloextern bool_t xdr_u_hyper(XDR *, u_quad_t *); 323223906Skevloextern bool_t xdr_longlong_t(XDR *, quad_t *); 324223906Skevloextern bool_t xdr_u_longlong_t(XDR *, u_quad_t *); 325223877Skevloextern unsigned long xdr_sizeof(xdrproc_t, void *); 3261903Swollman__END_DECLS 3271839Swollman 3281839Swollman/* 3291839Swollman * Common opaque bytes objects used by many rpc protocols; 3301839Swollman * declared here due to commonality. 3311839Swollman */ 3328858Srgrimes#define MAX_NETOBJ_SZ 1024 3331839Swollmanstruct netobj { 3341839Swollman u_int n_len; 3351839Swollman char *n_bytes; 3361839Swollman}; 3371839Swollmantypedef struct netobj netobj; 33893032Simpextern bool_t xdr_netobj(XDR *, struct netobj *); 3391839Swollman 3401839Swollman/* 3411839Swollman * These are the public routines for the various implementations of 3421839Swollman * xdr streams. 3431839Swollman */ 3441903Swollman__BEGIN_DECLS 3451903Swollman/* XDR using memory buffers */ 34693032Simpextern void xdrmem_create(XDR *, char *, u_int, enum xdr_op); 3471839Swollman 34874462Salfred/* XDR using stdio library */ 3491903Swollman#ifdef _STDIO_H_ 35093032Simpextern void xdrstdio_create(XDR *, FILE *, enum xdr_op); 3511903Swollman#endif 3521903Swollman 3531903Swollman/* XDR pseudo records for tcp */ 35495658Sdesextern void xdrrec_create(XDR *, u_int, u_int, void *, 35595658Sdes int (*)(void *, void *, int), 35695658Sdes int (*)(void *, void *, int)); 3571903Swollman 3581903Swollman/* make end of xdr record */ 35993032Simpextern bool_t xdrrec_endofrecord(XDR *, int); 3601903Swollman 3611903Swollman/* move to beginning of next record */ 36293032Simpextern bool_t xdrrec_skiprecord(XDR *); 3631903Swollman 3641903Swollman/* true if no more input */ 36593032Simpextern bool_t xdrrec_eof(XDR *); 36693032Simpextern u_int xdrrec_readbytes(XDR *, caddr_t, u_int); 3671903Swollman__END_DECLS 3681903Swollman 3691903Swollman#endif /* !_RPC_XDR_H */ 370