1 1.3 andvar /* $NetBSD: xdr.h,v 1.3 2024/02/05 21:46:04 andvar Exp $ */ 2 1.1 hannken 3 1.1 hannken /* 4 1.1 hannken * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 1.1 hannken * unrestricted use provided that this legend is included on all tape 6 1.1 hannken * media and as a part of the software program in whole or part. Users 7 1.1 hannken * may copy or modify Sun RPC without charge, but are not authorized 8 1.1 hannken * to license or distribute it to anyone else except as part of a product or 9 1.1 hannken * program developed by the user. 10 1.1 hannken * 11 1.1 hannken * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12 1.1 hannken * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13 1.1 hannken * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14 1.1 hannken * 15 1.1 hannken * Sun RPC is provided with no support and without any obligation on the 16 1.1 hannken * part of Sun Microsystems, Inc. to assist in its use, correction, 17 1.1 hannken * modification or enhancement. 18 1.1 hannken * 19 1.1 hannken * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20 1.1 hannken * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21 1.1 hannken * OR ANY PART THEREOF. 22 1.1 hannken * 23 1.1 hannken * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24 1.1 hannken * or profits or other special, indirect and consequential damages, even if 25 1.1 hannken * Sun has been advised of the possibility of such damages. 26 1.1 hannken * 27 1.1 hannken * Sun Microsystems, Inc. 28 1.1 hannken * 2550 Garcia Avenue 29 1.1 hannken * Mountain View, California 94043 30 1.1 hannken * 31 1.1 hannken * from: @(#)xdr.h 1.19 87/04/22 SMI 32 1.1 hannken * @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC 33 1.1 hannken */ 34 1.1 hannken 35 1.1 hannken /* 36 1.1 hannken * xdr.h, External Data Representation Serialization Routines. 37 1.1 hannken * 38 1.1 hannken * Copyright (C) 1984, Sun Microsystems, Inc. 39 1.1 hannken */ 40 1.1 hannken 41 1.1 hannken #ifndef _RPC_XDR_H_ 42 1.1 hannken #define _RPC_XDR_H_ 43 1.1 hannken #include <sys/cdefs.h> 44 1.1 hannken 45 1.1 hannken /* 46 1.1 hannken * XDR provides a conventional way for converting between C data 47 1.1 hannken * types and an external bit-string representation. Library supplied 48 1.1 hannken * routines provide for the conversion on built-in C data types. These 49 1.1 hannken * routines and utility routines defined here are used to help implement 50 1.1 hannken * a type encode/decode routine for each user-defined type. 51 1.1 hannken * 52 1.1 hannken * Each data type provides a single procedure which takes two arguments: 53 1.1 hannken * 54 1.1 hannken * bool_t 55 1.1 hannken * xdrproc(xdrs, argresp) 56 1.1 hannken * XDR *xdrs; 57 1.1 hannken * <type> *argresp; 58 1.1 hannken * 59 1.1 hannken * xdrs is an instance of a XDR handle, to which or from which the data 60 1.1 hannken * type is to be converted. argresp is a pointer to the structure to be 61 1.1 hannken * converted. The XDR handle contains an operation field which indicates 62 1.1 hannken * which of the operations (ENCODE, DECODE * or FREE) is to be performed. 63 1.1 hannken * 64 1.1 hannken * XDR_DECODE may allocate space if the pointer argresp is null. This 65 1.1 hannken * data can be freed with the XDR_FREE operation. 66 1.1 hannken * 67 1.1 hannken * We write only one procedure per data type to make it easy 68 1.1 hannken * to keep the encode and decode procedures for a data type consistent. 69 1.1 hannken * In many cases the same code performs all operations on a user defined type, 70 1.1 hannken * because all the hard work is done in the component type routines. 71 1.1 hannken * decode as a series of calls on the nested data types. 72 1.1 hannken */ 73 1.1 hannken 74 1.1 hannken /* 75 1.1 hannken * Xdr operations. XDR_ENCODE causes the type to be encoded into the 76 1.1 hannken * stream. XDR_DECODE causes the type to be extracted from the stream. 77 1.1 hannken * XDR_FREE can be used to release the space allocated by an XDR_DECODE 78 1.1 hannken * request. 79 1.1 hannken */ 80 1.1 hannken enum xdr_op { 81 1.1 hannken XDR_ENCODE=0, 82 1.1 hannken XDR_DECODE=1, 83 1.1 hannken XDR_FREE=2 84 1.1 hannken }; 85 1.1 hannken 86 1.1 hannken /* 87 1.1 hannken * This is the number of bytes per unit of external data. 88 1.1 hannken */ 89 1.1 hannken #define BYTES_PER_XDR_UNIT (4) 90 1.1 hannken #define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ 91 1.1 hannken * BYTES_PER_XDR_UNIT) 92 1.1 hannken 93 1.1 hannken /* 94 1.1 hannken * The XDR handle. 95 1.1 hannken * Contains operation which is being applied to the stream, 96 1.3 andvar * an operations vector for the particular implementation (e.g. see xdr_mem.c), 97 1.3 andvar * and two private fields for the use of the particular implementation. 98 1.1 hannken */ 99 1.1 hannken typedef struct __rpc_xdr { 100 1.1 hannken enum xdr_op x_op; /* operation; fast additional param */ 101 1.1 hannken const struct xdr_ops { 102 1.1 hannken /* get a long from underlying stream */ 103 1.1 hannken bool_t (*x_getlong)(struct __rpc_xdr *, long *); 104 1.1 hannken /* put a long to " */ 105 1.1 hannken bool_t (*x_putlong)(struct __rpc_xdr *, const long *); 106 1.1 hannken /* get some bytes from " */ 107 1.1 hannken bool_t (*x_getbytes)(struct __rpc_xdr *, char *, unsigned int); 108 1.1 hannken /* put some bytes to " */ 109 1.1 hannken bool_t (*x_putbytes)(struct __rpc_xdr *, const char *, 110 1.1 hannken unsigned int); 111 1.1 hannken /* returns bytes off from beginning */ 112 1.1 hannken unsigned (*x_getpostn)(struct __rpc_xdr *); 113 1.1 hannken /* lets you reposition the stream */ 114 1.1 hannken bool_t (*x_setpostn)(struct __rpc_xdr *, unsigned int); 115 1.1 hannken /* buf quick ptr to buffered data */ 116 1.1 hannken int32_t *(*x_inline)(struct __rpc_xdr *, unsigned int); 117 1.1 hannken /* free privates of this xdr_stream */ 118 1.1 hannken void (*x_destroy)(struct __rpc_xdr *); 119 1.1 hannken bool_t (*x_control)(struct __rpc_xdr *, int, void *); 120 1.1 hannken } *x_ops; 121 1.1 hannken char * x_public; /* users' data */ 122 1.1 hannken void * x_private; /* pointer to private data */ 123 1.1 hannken char * x_base; /* private used for position info */ 124 1.1 hannken unsigned int x_handy; /* extra private word */ 125 1.1 hannken } XDR; 126 1.1 hannken 127 1.1 hannken /* 128 1.1 hannken * A xdrproc_t exists for each data type which is to be encoded or decoded. 129 1.1 hannken * 130 1.1 hannken * The second argument to the xdrproc_t is a pointer to an opaque pointer. 131 1.1 hannken * The opaque pointer generally points to a structure of the data type 132 1.1 hannken * to be decoded. If this pointer is 0, then the type routines should 133 1.1 hannken * allocate dynamic storage of the appropriate size and return it. 134 1.1 hannken */ 135 1.1 hannken typedef bool_t (*xdrproc_t)(XDR *, const void *); 136 1.1 hannken 137 1.1 hannken /* 138 1.1 hannken * Operations defined on a XDR handle 139 1.1 hannken * 140 1.1 hannken * XDR *xdrs; 141 1.1 hannken * long *longp; 142 1.1 hannken * char * addr; 143 1.1 hannken * unsigned len; 144 1.1 hannken * unsigned pos; 145 1.1 hannken */ 146 1.1 hannken #define XDR_GETLONG(xdrs, longp) \ 147 1.1 hannken (*(xdrs)->x_ops->x_getlong)(xdrs, longp) 148 1.1 hannken #define xdr_getlong(xdrs, longp) \ 149 1.1 hannken (*(xdrs)->x_ops->x_getlong)(xdrs, longp) 150 1.1 hannken 151 1.1 hannken #define XDR_PUTLONG(xdrs, longp) \ 152 1.1 hannken (*(xdrs)->x_ops->x_putlong)(xdrs, longp) 153 1.1 hannken #define xdr_putlong(xdrs, longp) \ 154 1.1 hannken (*(xdrs)->x_ops->x_putlong)(xdrs, longp) 155 1.1 hannken 156 1.1 hannken static __inline int 157 1.1 hannken xdr_getint32(XDR *xdrs, int32_t *ip) 158 1.1 hannken { 159 1.1 hannken long l; 160 1.1 hannken 161 1.1 hannken if (!xdr_getlong(xdrs, &l)) 162 1.1 hannken return 0; 163 1.1 hannken *ip = (int32_t)l; 164 1.1 hannken return 1; 165 1.1 hannken } 166 1.1 hannken 167 1.1 hannken static __inline int 168 1.1 hannken xdr_putint32(XDR *xdrs, int32_t *ip) 169 1.1 hannken { 170 1.1 hannken long l; 171 1.1 hannken 172 1.1 hannken l = (long)*ip; 173 1.1 hannken return xdr_putlong(xdrs, &l); 174 1.1 hannken } 175 1.1 hannken 176 1.1 hannken #define XDR_GETINT32(xdrs, int32p) xdr_getint32(xdrs, int32p) 177 1.1 hannken #define XDR_PUTINT32(xdrs, int32p) xdr_putint32(xdrs, int32p) 178 1.1 hannken 179 1.1 hannken #define XDR_GETBYTES(xdrs, addr, len) \ 180 1.1 hannken (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) 181 1.1 hannken #define xdr_getbytes(xdrs, addr, len) \ 182 1.1 hannken (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) 183 1.1 hannken 184 1.1 hannken #define XDR_PUTBYTES(xdrs, addr, len) \ 185 1.1 hannken (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) 186 1.1 hannken #define xdr_putbytes(xdrs, addr, len) \ 187 1.1 hannken (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) 188 1.1 hannken 189 1.1 hannken #define XDR_GETPOS(xdrs) \ 190 1.1 hannken (*(xdrs)->x_ops->x_getpostn)(xdrs) 191 1.1 hannken #define xdr_getpos(xdrs) \ 192 1.1 hannken (*(xdrs)->x_ops->x_getpostn)(xdrs) 193 1.1 hannken 194 1.1 hannken #define XDR_SETPOS(xdrs, pos) \ 195 1.1 hannken (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) 196 1.1 hannken #define xdr_setpos(xdrs, pos) \ 197 1.1 hannken (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) 198 1.1 hannken 199 1.1 hannken #define XDR_INLINE(xdrs, len) \ 200 1.1 hannken (*(xdrs)->x_ops->x_inline)(xdrs, len) 201 1.1 hannken #define xdr_inline(xdrs, len) \ 202 1.1 hannken (*(xdrs)->x_ops->x_inline)(xdrs, len) 203 1.1 hannken 204 1.1 hannken #define XDR_DESTROY(xdrs) \ 205 1.1 hannken if ((xdrs)->x_ops->x_destroy) \ 206 1.1 hannken (*(xdrs)->x_ops->x_destroy)(xdrs) 207 1.1 hannken #define xdr_destroy(xdrs) \ 208 1.1 hannken if ((xdrs)->x_ops->x_destroy) \ 209 1.1 hannken (*(xdrs)->x_ops->x_destroy)(xdrs) 210 1.1 hannken 211 1.1 hannken #define XDR_CONTROL(xdrs, req, op) \ 212 1.1 hannken (((xdrs)->x_ops->x_control == NULL) ? (FALSE) : \ 213 1.1 hannken (*(xdrs)->x_ops->x_control)(xdrs, req, op)) 214 1.1 hannken #define xdr_control(xdrs, req, op) XDR_CONTROL(xdrs, req, op) 215 1.1 hannken 216 1.1 hannken #define xdr_rpcvers(xdrs, versp) xdr_u_int32_t(xdrs, versp) 217 1.1 hannken #define xdr_rpcprog(xdrs, progp) xdr_u_int32_t(xdrs, progp) 218 1.1 hannken #define xdr_rpcproc(xdrs, procp) xdr_u_int32_t(xdrs, procp) 219 1.1 hannken #define xdr_rpcprot(xdrs, protp) xdr_u_int32_t(xdrs, protp) 220 1.1 hannken #define xdr_rpcport(xdrs, portp) xdr_u_int32_t(xdrs, portp) 221 1.1 hannken 222 1.1 hannken /* 223 1.1 hannken * Support struct for discriminated unions. 224 1.1 hannken * You create an array of xdrdiscrim structures, terminated with 225 1.1 hannken * a entry with a null procedure pointer. The xdr_union routine gets 226 1.1 hannken * the discriminant value and then searches the array of structures 227 1.1 hannken * for a matching value. If a match is found the associated xdr routine 228 1.1 hannken * is called to handle that part of the union. If there is 229 1.1 hannken * no match, then a default routine may be called. 230 1.1 hannken * If there is no match and no default routine it is an error. 231 1.1 hannken */ 232 1.1 hannken #define NULL_xdrproc_t ((xdrproc_t)0) 233 1.1 hannken struct xdr_discrim { 234 1.1 hannken int value; 235 1.1 hannken xdrproc_t proc; 236 1.1 hannken }; 237 1.1 hannken 238 1.1 hannken /* 239 1.1 hannken * In-line routines for fast encode/decode of primitive data types. 240 1.1 hannken * Caveat emptor: these use single memory cycles to get the 241 1.1 hannken * data from the underlying buffer, and will fail to operate 242 1.1 hannken * properly if the data is not aligned. The standard way to use these 243 1.1 hannken * is to say: 244 1.1 hannken * if ((buf = XDR_INLINE(xdrs, count)) == NULL) 245 1.1 hannken * return (0); 246 1.1 hannken * <<< macro calls >>> 247 1.1 hannken * where ``count'' is the number of bytes of data occupied 248 1.1 hannken * by the primitive data types. 249 1.1 hannken * 250 1.1 hannken * N.B. and frozen for all time: each data type here uses 4 bytes 251 1.1 hannken * of external representation. 252 1.1 hannken */ 253 1.1 hannken #define IXDR_GET_INT32(buf) ((int32_t)ntohl((uint32_t)*(buf)++)) 254 1.1 hannken #define IXDR_PUT_INT32(buf, v) (*(buf)++ =(int32_t)htonl((uint32_t)v)) 255 1.1 hannken #define IXDR_GET_U_INT32(buf) ((uint32_t)IXDR_GET_INT32(buf)) 256 1.1 hannken #define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32((buf), ((int32_t)(v))) 257 1.1 hannken 258 1.1 hannken #define IXDR_GET_LONG(buf) ((long)ntohl((uint32_t)*(buf)++)) 259 1.1 hannken #define IXDR_PUT_LONG(buf, v) (*(buf)++ =(int32_t)htonl((uint32_t)v)) 260 1.1 hannken 261 1.1 hannken #define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) 262 1.1 hannken #define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) 263 1.1 hannken #define IXDR_GET_U_LONG(buf) ((unsigned long)IXDR_GET_LONG(buf)) 264 1.1 hannken #define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) 265 1.1 hannken #define IXDR_GET_U_SHORT(buf) ((unsigned short)IXDR_GET_LONG(buf)) 266 1.1 hannken 267 1.1 hannken #define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), (v)) 268 1.1 hannken #define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), (v)) 269 1.1 hannken #define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), (v)) 270 1.1 hannken #define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), (v)) 271 1.1 hannken #define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), (v)) 272 1.1 hannken 273 1.1 hannken /* 274 1.1 hannken * These are the "generic" xdr routines. 275 1.1 hannken */ 276 1.1 hannken __BEGIN_DECLS 277 1.1 hannken extern bool_t xdr_void(void); 278 1.1 hannken extern bool_t xdr_int(XDR *, int *); 279 1.1 hannken extern bool_t xdr_u_int(XDR *, unsigned int *); 280 1.1 hannken extern bool_t xdr_long(XDR *, long *); 281 1.1 hannken extern bool_t xdr_u_long(XDR *, unsigned long *); 282 1.1 hannken extern bool_t xdr_short(XDR *, short *); 283 1.1 hannken extern bool_t xdr_u_short(XDR *, unsigned short *); 284 1.1 hannken extern bool_t xdr_int16_t(XDR *, int16_t *); 285 1.1 hannken extern bool_t xdr_u_int16_t(XDR *, uint16_t *); 286 1.1 hannken extern bool_t xdr_int32_t(XDR *, int32_t *); 287 1.1 hannken extern bool_t xdr_u_int32_t(XDR *, uint32_t *); 288 1.1 hannken extern bool_t xdr_int64_t(XDR *, int64_t *); 289 1.1 hannken extern bool_t xdr_u_int64_t(XDR *, uint64_t *); 290 1.1 hannken extern bool_t xdr_bool(XDR *, bool_t *); 291 1.1 hannken extern bool_t xdr_enum(XDR *, enum_t *); 292 1.1 hannken extern bool_t xdr_array(XDR *, char **, unsigned int *, unsigned int, 293 1.1 hannken unsigned int, xdrproc_t); 294 1.1 hannken extern bool_t xdr_bytes(XDR *, char **, unsigned int *, unsigned int); 295 1.1 hannken extern bool_t xdr_opaque(XDR *, char *, unsigned int); 296 1.1 hannken extern bool_t xdr_string(XDR *, char **, unsigned int); 297 1.1 hannken extern bool_t xdr_union(XDR *, enum_t *, char *, const struct xdr_discrim *, xdrproc_t); 298 1.1 hannken extern bool_t xdr_char(XDR *, char *); 299 1.1 hannken extern bool_t xdr_u_char(XDR *, unsigned char *); 300 1.1 hannken extern bool_t xdr_vector(XDR *, char *, unsigned int, unsigned int, 301 1.1 hannken xdrproc_t); 302 1.1 hannken extern bool_t xdr_float(XDR *, float *); 303 1.1 hannken extern bool_t xdr_double(XDR *, double *); 304 1.1 hannken extern bool_t xdr_quadruple(XDR *, long double *); 305 1.1 hannken extern bool_t xdr_reference(XDR *, char **, unsigned int, xdrproc_t); 306 1.1 hannken extern bool_t xdr_pointer(XDR *, char **, unsigned int, xdrproc_t); 307 1.1 hannken extern bool_t xdr_wrapstring(XDR *, char **); 308 1.1 hannken extern void xdr_free(xdrproc_t, char *); 309 1.1 hannken extern bool_t xdr_hyper(XDR *, longlong_t *); 310 1.1 hannken extern bool_t xdr_u_hyper(XDR *, u_longlong_t *); 311 1.1 hannken extern bool_t xdr_longlong_t(XDR *, longlong_t *); 312 1.1 hannken extern bool_t xdr_u_longlong_t(XDR *, u_longlong_t *); 313 1.1 hannken extern unsigned long xdr_sizeof(xdrproc_t, void *); 314 1.1 hannken __END_DECLS 315 1.1 hannken 316 1.1 hannken /* 317 1.1 hannken * Common opaque bytes objects used by many rpc protocols; 318 1.1 hannken * declared here due to commonality. 319 1.1 hannken */ 320 1.1 hannken #define MAX_NETOBJ_SZ 1024 321 1.1 hannken struct netobj { 322 1.1 hannken unsigned int n_len; 323 1.1 hannken char *n_bytes; 324 1.1 hannken }; 325 1.1 hannken typedef struct netobj netobj; 326 1.1 hannken extern bool_t xdr_netobj(XDR *, struct netobj *); 327 1.1 hannken 328 1.1 hannken /* 329 1.1 hannken * These are XDR control operators 330 1.1 hannken */ 331 1.1 hannken 332 1.1 hannken #define XDR_GET_BYTES_AVAIL 1 333 1.1 hannken 334 1.1 hannken struct xdr_bytesrec { 335 1.1 hannken bool_t xc_is_last_record; 336 1.1 hannken size_t xc_num_avail; 337 1.1 hannken }; 338 1.1 hannken 339 1.1 hannken typedef struct xdr_bytesrec xdr_bytesrec; 340 1.1 hannken 341 1.1 hannken /* 342 1.1 hannken * These are the public routines for the various implementations of 343 1.1 hannken * xdr streams. 344 1.1 hannken */ 345 1.1 hannken __BEGIN_DECLS 346 1.1 hannken /* XDR using memory buffers */ 347 1.1 hannken extern void xdrmem_create(XDR *, char *, unsigned int, enum xdr_op); 348 1.1 hannken 349 1.1 hannken /* XDR using stdio library */ 350 1.1 hannken #ifdef _STDIO_H_ 351 1.1 hannken extern void xdrstdio_create(XDR *, FILE *, enum xdr_op); 352 1.1 hannken #endif 353 1.1 hannken 354 1.1 hannken /* XDR pseudo records for tcp */ 355 1.1 hannken extern void xdrrec_create(XDR *, unsigned int, unsigned int, char *, 356 1.1 hannken int (*)(char *, char *, int), 357 1.1 hannken int (*)(char *, char *, int)); 358 1.1 hannken 359 1.1 hannken /* make end of xdr record */ 360 1.1 hannken extern bool_t xdrrec_endofrecord(XDR *, int); 361 1.1 hannken 362 1.1 hannken /* move to beginning of next record */ 363 1.1 hannken extern bool_t xdrrec_skiprecord(XDR *); 364 1.1 hannken 365 1.1 hannken /* true if no more input */ 366 1.1 hannken extern bool_t xdrrec_eof(XDR *); 367 1.2 christos extern unsigned xdrrec_readbytes(XDR *, char *, unsigned int); 368 1.1 hannken __END_DECLS 369 1.1 hannken 370 1.1 hannken #endif /* !_RPC_XDR_H_ */ 371