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