174462Salfred/* $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ */ 274462Salfred 3261046Smav/*- 4261046Smav * Copyright (c) 2009, Sun Microsystems, Inc. 5261046Smav * All rights reserved. 68858Srgrimes * 7261046Smav * Redistribution and use in source and binary forms, with or without 8261046Smav * modification, are permitted provided that the following conditions are met: 9261046Smav * - Redistributions of source code must retain the above copyright notice, 10261046Smav * this list of conditions and the following disclaimer. 11261046Smav * - Redistributions in binary form must reproduce the above copyright notice, 12261046Smav * this list of conditions and the following disclaimer in the documentation 13261046Smav * and/or other materials provided with the distribution. 14261046Smav * - Neither the name of Sun Microsystems, Inc. nor the names of its 15261046Smav * contributors may be used to endorse or promote products derived 16261046Smav * from this software without specific prior written permission. 178858Srgrimes * 18261046Smav * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19261046Smav * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20261046Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21261046Smav * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22261046Smav * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23261046Smav * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24261046Smav * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25261046Smav * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26261046Smav * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27261046Smav * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28261046Smav * POSSIBILITY OF SUCH DAMAGE. 298858Srgrimes * 301903Swollman * from: @(#)xdr.h 1.19 87/04/22 SMI 311903Swollman * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC 3250473Speter * $FreeBSD$ 331839Swollman */ 341839Swollman 351839Swollman/* 361839Swollman * xdr.h, External Data Representation Serialization Routines. 371839Swollman * 381839Swollman * Copyright (C) 1984, Sun Microsystems, Inc. 391839Swollman */ 401839Swollman 411903Swollman#ifndef _RPC_XDR_H 421903Swollman#define _RPC_XDR_H 431903Swollman#include <sys/cdefs.h> 441839Swollman 451839Swollman/* 461839Swollman * XDR provides a conventional way for converting between C data 471839Swollman * types and an external bit-string representation. Library supplied 481839Swollman * routines provide for the conversion on built-in C data types. These 491839Swollman * routines and utility routines defined here are used to help implement 501839Swollman * a type encode/decode routine for each user-defined type. 511839Swollman * 521839Swollman * Each data type provides a single procedure which takes two arguments: 531839Swollman * 541839Swollman * bool_t 551839Swollman * xdrproc(xdrs, argresp) 561839Swollman * XDR *xdrs; 571839Swollman * <type> *argresp; 581839Swollman * 591839Swollman * xdrs is an instance of a XDR handle, to which or from which the data 601839Swollman * type is to be converted. argresp is a pointer to the structure to be 611839Swollman * converted. The XDR handle contains an operation field which indicates 621839Swollman * which of the operations (ENCODE, DECODE * or FREE) is to be performed. 631839Swollman * 641839Swollman * XDR_DECODE may allocate space if the pointer argresp is null. This 651839Swollman * data can be freed with the XDR_FREE operation. 661839Swollman * 671839Swollman * We write only one procedure per data type to make it easy 681839Swollman * to keep the encode and decode procedures for a data type consistent. 691839Swollman * In many cases the same code performs all operations on a user defined type, 701839Swollman * because all the hard work is done in the component type routines. 711839Swollman * decode as a series of calls on the nested data types. 721839Swollman */ 731839Swollman 741839Swollman/* 751839Swollman * Xdr operations. XDR_ENCODE causes the type to be encoded into the 761839Swollman * stream. XDR_DECODE causes the type to be extracted from the stream. 771839Swollman * XDR_FREE can be used to release the space allocated by an XDR_DECODE 781839Swollman * request. 791839Swollman */ 801839Swollmanenum xdr_op { 811839Swollman XDR_ENCODE=0, 821839Swollman XDR_DECODE=1, 831839Swollman XDR_FREE=2 841839Swollman}; 851839Swollman 861839Swollman/* 871839Swollman * This is the number of bytes per unit of external data. 881839Swollman */ 891839Swollman#define BYTES_PER_XDR_UNIT (4) 901839Swollman#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ 911839Swollman * BYTES_PER_XDR_UNIT) 921839Swollman 931839Swollman/* 941839Swollman * The XDR handle. 951839Swollman * Contains operation which is being applied to the stream, 9613771Smpp * an operations vector for the particular implementation (e.g. see xdr_mem.c), 9713771Smpp * and two private fields for the use of the particular implementation. 981839Swollman */ 99240060Spfgtypedef struct XDR { 1001839Swollman enum xdr_op x_op; /* operation; fast additional param */ 10174462Salfred const struct xdr_ops { 10221059Speter /* get a long from underlying stream */ 103240060Spfg bool_t (*x_getlong)(struct XDR *, long *); 10474462Salfred /* put a long to " */ 105240060Spfg bool_t (*x_putlong)(struct XDR *, const long *); 10674462Salfred /* get some bytes from " */ 107240060Spfg bool_t (*x_getbytes)(struct XDR *, char *, u_int); 10874462Salfred /* put some bytes to " */ 109240060Spfg bool_t (*x_putbytes)(struct XDR *, const char *, u_int); 11021059Speter /* returns bytes off from beginning */ 111240060Spfg u_int (*x_getpostn)(struct XDR *); 11221059Speter /* lets you reposition the stream */ 113240060Spfg bool_t (*x_setpostn)(struct XDR *, u_int); 11421059Speter /* buf quick ptr to buffered data */ 115240060Spfg int32_t *(*x_inline)(struct XDR *, u_int); 11621059Speter /* free privates of this xdr_stream */ 117240060Spfg void (*x_destroy)(struct XDR *); 118240060Spfg bool_t (*x_control)(struct XDR *, int, void *); 1191839Swollman } *x_ops; 12074462Salfred char * x_public; /* users' data */ 12174462Salfred void * x_private; /* pointer to private data */ 12274462Salfred char * x_base; /* private used for position info */ 123111962Snectar u_int x_handy; /* extra private word */ 1241839Swollman} XDR; 1251839Swollman 1261839Swollman/* 12721059Speter * A xdrproc_t exists for each data type which is to be encoded or decoded. 12821059Speter * 12921059Speter * The second argument to the xdrproc_t is a pointer to an opaque pointer. 13021059Speter * The opaque pointer generally points to a structure of the data type 13121059Speter * to be decoded. If this pointer is 0, then the type routines should 13221059Speter * allocate dynamic storage of the appropriate size and return it. 13374510Salfred */ 13474510Salfred#ifdef _KERNEL 13593032Simptypedef bool_t (*xdrproc_t)(XDR *, void *, u_int); 13674510Salfred#else 13774510Salfred/* 13874462Salfred * XXX can't actually prototype it, because some take three args!!! 13921059Speter */ 14095658Sdestypedef bool_t (*xdrproc_t)(XDR *, ...); 14174510Salfred#endif 14221059Speter 14321059Speter/* 1441839Swollman * Operations defined on a XDR handle 1451839Swollman * 1461839Swollman * XDR *xdrs; 1471839Swollman * long *longp; 14874462Salfred * char * addr; 1491839Swollman * u_int len; 1501839Swollman * u_int pos; 1511839Swollman */ 1521839Swollman#define XDR_GETLONG(xdrs, longp) \ 1531839Swollman (*(xdrs)->x_ops->x_getlong)(xdrs, longp) 1541839Swollman#define xdr_getlong(xdrs, longp) \ 1551839Swollman (*(xdrs)->x_ops->x_getlong)(xdrs, longp) 1561839Swollman 1571839Swollman#define XDR_PUTLONG(xdrs, longp) \ 1581839Swollman (*(xdrs)->x_ops->x_putlong)(xdrs, longp) 1591839Swollman#define xdr_putlong(xdrs, longp) \ 1601839Swollman (*(xdrs)->x_ops->x_putlong)(xdrs, longp) 1611839Swollman 16274462Salfredstatic __inline int 16374462Salfredxdr_getint32(XDR *xdrs, int32_t *ip) 16474462Salfred{ 16574462Salfred long l; 16674462Salfred 16774462Salfred if (!xdr_getlong(xdrs, &l)) 16874462Salfred return (FALSE); 16974462Salfred *ip = (int32_t)l; 17074462Salfred return (TRUE); 17174462Salfred} 17274462Salfred 17374462Salfredstatic __inline int 17474462Salfredxdr_putint32(XDR *xdrs, int32_t *ip) 17574462Salfred{ 17674462Salfred long l; 17774462Salfred 17874462Salfred l = (long)*ip; 17974462Salfred return xdr_putlong(xdrs, &l); 18074462Salfred} 18174462Salfred 18274462Salfred#define XDR_GETINT32(xdrs, int32p) xdr_getint32(xdrs, int32p) 18374462Salfred#define XDR_PUTINT32(xdrs, int32p) xdr_putint32(xdrs, int32p) 18474462Salfred 1851839Swollman#define XDR_GETBYTES(xdrs, addr, len) \ 1861839Swollman (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) 1871839Swollman#define xdr_getbytes(xdrs, addr, len) \ 1881839Swollman (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) 1891839Swollman 1901839Swollman#define XDR_PUTBYTES(xdrs, addr, len) \ 1911839Swollman (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) 1921839Swollman#define xdr_putbytes(xdrs, addr, len) \ 1931839Swollman (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) 1941839Swollman 1951839Swollman#define XDR_GETPOS(xdrs) \ 1961839Swollman (*(xdrs)->x_ops->x_getpostn)(xdrs) 1971839Swollman#define xdr_getpos(xdrs) \ 1981839Swollman (*(xdrs)->x_ops->x_getpostn)(xdrs) 1991839Swollman 2001839Swollman#define XDR_SETPOS(xdrs, pos) \ 2011839Swollman (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) 2021839Swollman#define xdr_setpos(xdrs, pos) \ 2031839Swollman (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) 2041839Swollman 2051839Swollman#define XDR_INLINE(xdrs, len) \ 2061839Swollman (*(xdrs)->x_ops->x_inline)(xdrs, len) 2071839Swollman#define xdr_inline(xdrs, len) \ 2081839Swollman (*(xdrs)->x_ops->x_inline)(xdrs, len) 2091839Swollman 2101839Swollman#define XDR_DESTROY(xdrs) \ 2111839Swollman if ((xdrs)->x_ops->x_destroy) \ 2121839Swollman (*(xdrs)->x_ops->x_destroy)(xdrs) 2131839Swollman#define xdr_destroy(xdrs) \ 2141839Swollman if ((xdrs)->x_ops->x_destroy) \ 2151839Swollman (*(xdrs)->x_ops->x_destroy)(xdrs) 2161839Swollman 21774462Salfred#define XDR_CONTROL(xdrs, req, op) \ 21874462Salfred if ((xdrs)->x_ops->x_control) \ 21974462Salfred (*(xdrs)->x_ops->x_control)(xdrs, req, op) 22074462Salfred#define xdr_control(xdrs, req, op) XDR_CONTROL(xdrs, req, op) 22174462Salfred 222297259Spfg#define xdr_rpcvers(xdrs, versp) xdr_u_int32_t(xdrs, versp) 223297259Spfg#define xdr_rpcprog(xdrs, progp) xdr_u_int32_t(xdrs, progp) 224297259Spfg#define xdr_rpcproc(xdrs, procp) xdr_u_int32_t(xdrs, procp) 225297259Spfg#define xdr_rpcprot(xdrs, protp) xdr_u_int32_t(xdrs, protp) 226297259Spfg#define xdr_rpcport(xdrs, portp) xdr_u_int32_t(xdrs, portp) 22774462Salfred 22874462Salfred/* 2291839Swollman * Support struct for discriminated unions. 2301839Swollman * You create an array of xdrdiscrim structures, terminated with 231108533Sschweikh * an entry with a null procedure pointer. The xdr_union routine gets 2321839Swollman * the discriminant value and then searches the array of structures 2331839Swollman * for a matching value. If a match is found the associated xdr routine 2341839Swollman * is called to handle that part of the union. If there is 2351839Swollman * no match, then a default routine may be called. 2361839Swollman * If there is no match and no default routine it is an error. 2371839Swollman */ 2381839Swollman#define NULL_xdrproc_t ((xdrproc_t)0) 2391839Swollmanstruct xdr_discrim { 2401839Swollman int value; 2411839Swollman xdrproc_t proc; 2421839Swollman}; 2431839Swollman 2441839Swollman/* 24513771Smpp * In-line routines for fast encode/decode of primitive data types. 2461839Swollman * Caveat emptor: these use single memory cycles to get the 2471839Swollman * data from the underlying buffer, and will fail to operate 2481839Swollman * properly if the data is not aligned. The standard way to use these 2491839Swollman * is to say: 2501839Swollman * if ((buf = XDR_INLINE(xdrs, count)) == NULL) 2511839Swollman * return (FALSE); 2521839Swollman * <<< macro calls >>> 2531839Swollman * where ``count'' is the number of bytes of data occupied 2541839Swollman * by the primitive data types. 2551839Swollman * 2561839Swollman * N.B. and frozen for all time: each data type here uses 4 bytes 2571839Swollman * of external representation. 2581839Swollman */ 25990868Smike#define IXDR_GET_INT32(buf) ((int32_t)__ntohl((u_int32_t)*(buf)++)) 26090868Smike#define IXDR_PUT_INT32(buf, v) (*(buf)++ =(int32_t)__htonl((u_int32_t)v)) 26174462Salfred#define IXDR_GET_U_INT32(buf) ((u_int32_t)IXDR_GET_INT32(buf)) 26274462Salfred#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32((buf), ((int32_t)(v))) 2631839Swollman 26490868Smike#define IXDR_GET_LONG(buf) ((long)__ntohl((u_int32_t)*(buf)++)) 26590868Smike#define IXDR_PUT_LONG(buf, v) (*(buf)++ =(int32_t)__htonl((u_int32_t)v)) 26674462Salfred 2671839Swollman#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) 2681839Swollman#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) 2691839Swollman#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) 2701839Swollman#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) 2711839Swollman#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) 2721839Swollman 27374462Salfred#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), (v)) 27474462Salfred#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), (v)) 27574462Salfred#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), (v)) 27674462Salfred#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), (v)) 27774462Salfred#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), (v)) 2781839Swollman 2791839Swollman/* 2801839Swollman * These are the "generic" xdr routines. 2811839Swollman */ 2821903Swollman__BEGIN_DECLS 283223906Skevloextern bool_t xdr_void(void); 284223906Skevloextern bool_t xdr_int(XDR *, int *); 285223906Skevloextern bool_t xdr_u_int(XDR *, u_int *); 286223906Skevloextern bool_t xdr_long(XDR *, long *); 287223906Skevloextern bool_t xdr_u_long(XDR *, u_long *); 288223906Skevloextern bool_t xdr_short(XDR *, short *); 289223906Skevloextern bool_t xdr_u_short(XDR *, u_short *); 290223906Skevloextern bool_t xdr_int16_t(XDR *, int16_t *); 291223906Skevloextern bool_t xdr_u_int16_t(XDR *, u_int16_t *); 292223906Skevloextern bool_t xdr_uint16_t(XDR *, u_int16_t *); 293223906Skevloextern bool_t xdr_int32_t(XDR *, int32_t *); 294223906Skevloextern bool_t xdr_u_int32_t(XDR *, u_int32_t *); 295223906Skevloextern bool_t xdr_uint32_t(XDR *, u_int32_t *); 296223906Skevloextern bool_t xdr_int64_t(XDR *, int64_t *); 297223906Skevloextern bool_t xdr_u_int64_t(XDR *, u_int64_t *); 298223906Skevloextern bool_t xdr_uint64_t(XDR *, u_int64_t *); 299223906Skevloextern bool_t xdr_bool(XDR *, bool_t *); 300223906Skevloextern bool_t xdr_enum(XDR *, enum_t *); 301223906Skevloextern bool_t xdr_array(XDR *, char **, u_int *, u_int, u_int, xdrproc_t); 302223906Skevloextern bool_t xdr_bytes(XDR *, char **, u_int *, u_int); 303223906Skevloextern bool_t xdr_opaque(XDR *, char *, u_int); 304223906Skevloextern bool_t xdr_string(XDR *, char **, u_int); 305223906Skevloextern bool_t xdr_union(XDR *, enum_t *, char *, const struct xdr_discrim *, xdrproc_t); 306223906Skevloextern bool_t xdr_char(XDR *, char *); 307223906Skevloextern bool_t xdr_u_char(XDR *, u_char *); 308223906Skevloextern bool_t xdr_vector(XDR *, char *, u_int, u_int, xdrproc_t); 309223906Skevloextern bool_t xdr_float(XDR *, float *); 310223906Skevloextern bool_t xdr_double(XDR *, double *); 311223906Skevloextern bool_t xdr_quadruple(XDR *, long double *); 312223906Skevloextern bool_t xdr_reference(XDR *, char **, u_int, xdrproc_t); 313223906Skevloextern bool_t xdr_pointer(XDR *, char **, u_int, xdrproc_t); 314223906Skevloextern bool_t xdr_wrapstring(XDR *, char **); 315223906Skevloextern void xdr_free(xdrproc_t, void *); 316223906Skevloextern bool_t xdr_hyper(XDR *, quad_t *); 317223906Skevloextern bool_t xdr_u_hyper(XDR *, u_quad_t *); 318223906Skevloextern bool_t xdr_longlong_t(XDR *, quad_t *); 319223906Skevloextern bool_t xdr_u_longlong_t(XDR *, u_quad_t *); 320223877Skevloextern unsigned long xdr_sizeof(xdrproc_t, void *); 3211903Swollman__END_DECLS 3221839Swollman 3231839Swollman/* 3241839Swollman * Common opaque bytes objects used by many rpc protocols; 3251839Swollman * declared here due to commonality. 3261839Swollman */ 3278858Srgrimes#define MAX_NETOBJ_SZ 1024 3281839Swollmanstruct netobj { 3291839Swollman u_int n_len; 3301839Swollman char *n_bytes; 3311839Swollman}; 3321839Swollmantypedef struct netobj netobj; 33393032Simpextern bool_t xdr_netobj(XDR *, struct netobj *); 3341839Swollman 3351839Swollman/* 3361839Swollman * These are the public routines for the various implementations of 3371839Swollman * xdr streams. 3381839Swollman */ 3391903Swollman__BEGIN_DECLS 3401903Swollman/* XDR using memory buffers */ 34193032Simpextern void xdrmem_create(XDR *, char *, u_int, enum xdr_op); 3421839Swollman 34374462Salfred/* XDR using stdio library */ 3441903Swollman#ifdef _STDIO_H_ 34593032Simpextern void xdrstdio_create(XDR *, FILE *, enum xdr_op); 3461903Swollman#endif 3471903Swollman 3481903Swollman/* XDR pseudo records for tcp */ 34995658Sdesextern void xdrrec_create(XDR *, u_int, u_int, void *, 35095658Sdes int (*)(void *, void *, int), 35195658Sdes int (*)(void *, void *, int)); 3521903Swollman 3531903Swollman/* make end of xdr record */ 35493032Simpextern bool_t xdrrec_endofrecord(XDR *, int); 3551903Swollman 3561903Swollman/* move to beginning of next record */ 35793032Simpextern bool_t xdrrec_skiprecord(XDR *); 3581903Swollman 3591903Swollman/* true if no more input */ 36093032Simpextern bool_t xdrrec_eof(XDR *); 36193032Simpextern u_int xdrrec_readbytes(XDR *, caddr_t, u_int); 3621903Swollman__END_DECLS 3631903Swollman 3641903Swollman#endif /* !_RPC_XDR_H */ 365