Source code pulled from OpenBSD for OpenNTPD. The place to contribute to this code is via the OpenBSD CVS tree.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

316 lines
11 KiB

  1. /* $OpenBSD: xdr.h,v 1.12 2010/09/01 14:43:34 millert Exp $ */
  2. /* $NetBSD: xdr.h,v 1.7 1995/04/29 05:28:06 cgd Exp $ */
  3. /*
  4. * Copyright (c) 2010, Oracle America, Inc.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are
  8. * met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above
  13. * copyright notice, this list of conditions and the following
  14. * disclaimer in the documentation and/or other materials
  15. * provided with the distribution.
  16. * * Neither the name of the "Oracle America, Inc." nor the names of its
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  23. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  24. * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  25. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  27. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  28. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  29. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  31. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. *
  33. * from: @(#)xdr.h 1.19 87/04/22 SMI
  34. * @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC
  35. */
  36. /*
  37. * xdr.h, External Data Representation Serialization Routines.
  38. */
  39. #ifndef _RPC_XDR_H
  40. #define _RPC_XDR_H
  41. #include <sys/cdefs.h>
  42. /*
  43. * XDR provides a conventional way for converting between C data
  44. * types and an external bit-string representation. Library supplied
  45. * routines provide for the conversion on built-in C data types. These
  46. * routines and utility routines defined here are used to help implement
  47. * a type encode/decode routine for each user-defined type.
  48. *
  49. * Each data type provides a single procedure which takes two arguments:
  50. *
  51. * bool_t
  52. * xdrproc(xdrs, argresp)
  53. * XDR *xdrs;
  54. * <type> *argresp;
  55. *
  56. * xdrs is an instance of a XDR handle, to which or from which the data
  57. * type is to be converted. argresp is a pointer to the structure to be
  58. * converted. The XDR handle contains an operation field which indicates
  59. * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
  60. *
  61. * XDR_DECODE may allocate space if the pointer argresp is null. This
  62. * data can be freed with the XDR_FREE operation.
  63. *
  64. * We write only one procedure per data type to make it easy
  65. * to keep the encode and decode procedures for a data type consistent.
  66. * In many cases the same code performs all operations on a user defined type,
  67. * because all the hard work is done in the component type routines.
  68. * decode as a series of calls on the nested data types.
  69. */
  70. /*
  71. * Xdr operations. XDR_ENCODE causes the type to be encoded into the
  72. * stream. XDR_DECODE causes the type to be extracted from the stream.
  73. * XDR_FREE can be used to release the space allocated by an XDR_DECODE
  74. * request.
  75. */
  76. enum xdr_op {
  77. XDR_ENCODE=0,
  78. XDR_DECODE=1,
  79. XDR_FREE=2
  80. };
  81. /*
  82. * This is the number of bytes per unit of external data.
  83. */
  84. #define BYTES_PER_XDR_UNIT (4)
  85. #define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
  86. * BYTES_PER_XDR_UNIT)
  87. /*
  88. * The XDR handle.
  89. * Contains operation which is being applied to the stream,
  90. * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
  91. * and two private fields for the use of the particular impelementation.
  92. */
  93. typedef struct __rpc_xdr {
  94. enum xdr_op x_op; /* operation; fast additional param */
  95. struct xdr_ops {
  96. /* get a long from underlying stream */
  97. bool_t (*x_getlong)(struct __rpc_xdr *, long *);
  98. /* put a long to " */
  99. bool_t (*x_putlong)(struct __rpc_xdr *, long *);
  100. /* get some bytes from " */
  101. bool_t (*x_getbytes)(struct __rpc_xdr *, caddr_t,
  102. unsigned int);
  103. /* put some bytes to " */
  104. bool_t (*x_putbytes)(struct __rpc_xdr *, caddr_t,
  105. unsigned int);
  106. /* returns bytes off from beginning */
  107. unsigned int (*x_getpostn)(struct __rpc_xdr *);
  108. /* lets you reposition the stream */
  109. bool_t (*x_setpostn)(struct __rpc_xdr *, unsigned int);
  110. /* buf quick ptr to buffered data */
  111. int32_t *(*x_inline)(struct __rpc_xdr *, unsigned int);
  112. /* free privates of this xdr_stream */
  113. void (*x_destroy)(struct __rpc_xdr *);
  114. bool_t (*x_control)(struct __rpc_xdr *, int, void *);
  115. } *x_ops;
  116. caddr_t x_public; /* users' data */
  117. caddr_t x_private; /* pointer to private data */
  118. caddr_t x_base; /* private used for position info */
  119. unsigned int x_handy; /* extra private word */
  120. } XDR;
  121. /*
  122. * A xdrproc_t exists for each data type which is to be encoded or decoded.
  123. *
  124. * The second argument to the xdrproc_t is a pointer to an opaque pointer.
  125. * The opaque pointer generally points to a structure of the data type
  126. * to be decoded. If this pointer is 0, then the type routines should
  127. * allocate dynamic storage of the appropriate size and return it.
  128. *
  129. * XXX can't actually prototype it, because some take three args!!!
  130. */
  131. typedef bool_t (*xdrproc_t)(/* XDR *, void *, unsigned int */);
  132. /*
  133. * Operations defined on a XDR handle
  134. *
  135. * XDR *xdrs;
  136. * long *longp;
  137. * caddr_t addr;
  138. * unsigned int len;
  139. * unsigned int pos;
  140. */
  141. #define XDR_GETLONG(xdrs, longp) \
  142. (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
  143. #define xdr_getlong(xdrs, longp) \
  144. (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
  145. #define XDR_PUTLONG(xdrs, longp) \
  146. (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
  147. #define xdr_putlong(xdrs, longp) \
  148. (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
  149. #define XDR_GETBYTES(xdrs, addr, len) \
  150. (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
  151. #define xdr_getbytes(xdrs, addr, len) \
  152. (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
  153. #define XDR_PUTBYTES(xdrs, addr, len) \
  154. (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
  155. #define xdr_putbytes(xdrs, addr, len) \
  156. (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
  157. #define XDR_GETPOS(xdrs) \
  158. (*(xdrs)->x_ops->x_getpostn)(xdrs)
  159. #define xdr_getpos(xdrs) \
  160. (*(xdrs)->x_ops->x_getpostn)(xdrs)
  161. #define XDR_SETPOS(xdrs, pos) \
  162. (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
  163. #define xdr_setpos(xdrs, pos) \
  164. (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
  165. #define XDR_INLINE(xdrs, len) \
  166. (*(xdrs)->x_ops->x_inline)(xdrs, len)
  167. #define xdr_inline(xdrs, len) \
  168. (*(xdrs)->x_ops->x_inline)(xdrs, len)
  169. #define XDR_DESTROY(xdrs) \
  170. if ((xdrs)->x_ops->x_destroy) \
  171. (*(xdrs)->x_ops->x_destroy)(xdrs)
  172. #define xdr_destroy(xdrs) \
  173. if ((xdrs)->x_ops->x_destroy) \
  174. (*(xdrs)->x_ops->x_destroy)(xdrs)
  175. /*
  176. * Support struct for discriminated unions.
  177. * You create an array of xdrdiscrim structures, terminated with
  178. * a entry with a null procedure pointer. The xdr_union routine gets
  179. * the discriminant value and then searches the array of structures
  180. * for a matching value. If a match is found the associated xdr routine
  181. * is called to handle that part of the union. If there is
  182. * no match, then a default routine may be called.
  183. * If there is no match and no default routine it is an error.
  184. */
  185. #define NULL_xdrproc_t ((xdrproc_t)0)
  186. struct xdr_discrim {
  187. int value;
  188. xdrproc_t proc;
  189. };
  190. /*
  191. * In-line routines for fast encode/decode of primitive data types.
  192. * Caveat emptor: these use single memory cycles to get the
  193. * data from the underlying buffer, and will fail to operate
  194. * properly if the data is not aligned. The standard way to use these
  195. * is to say:
  196. * if ((buf = XDR_INLINE(xdrs, count)) == NULL)
  197. * return (FALSE);
  198. * <<< macro calls >>>
  199. * where ``count'' is the number of bytes of data occupied
  200. * by the primitive data types.
  201. *
  202. * N.B. and frozen for all time: each data type here uses 4 bytes
  203. * of external representation.
  204. */
  205. #define IXDR_GET_LONG(buf) ((long)ntohl((unsigned long)*(buf)++))
  206. #define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((unsigned long)v))
  207. #define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
  208. #define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
  209. #define IXDR_GET_U_LONG(buf) ((unsigned long)IXDR_GET_LONG(buf))
  210. #define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
  211. #define IXDR_GET_U_SHORT(buf) ((unsigned short)IXDR_GET_LONG(buf))
  212. #define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
  213. #define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
  214. #define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
  215. #define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
  216. #define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
  217. /*
  218. * These are the "generic" xdr routines.
  219. */
  220. __BEGIN_DECLS
  221. extern bool_t xdr_void(void);
  222. extern bool_t xdr_int(XDR *, int *);
  223. extern bool_t xdr_u_int(XDR *, unsigned int *);
  224. extern bool_t xdr_long(XDR *, long *);
  225. extern bool_t xdr_u_long(XDR *, unsigned long *);
  226. extern bool_t xdr_short(XDR *, short *);
  227. extern bool_t xdr_u_short(XDR *, unsigned short *);
  228. extern bool_t xdr_int16_t(XDR *, int16_t *);
  229. extern bool_t xdr_u_int16_t(XDR *, u_int16_t *);
  230. extern bool_t xdr_int32_t(XDR *, int32_t *);
  231. extern bool_t xdr_u_int32_t(XDR *, u_int32_t *);
  232. extern bool_t xdr_int64_t(XDR *, int64_t *);
  233. extern bool_t xdr_u_int64_t(XDR *, u_int64_t *);
  234. extern bool_t xdr_bool(XDR *, bool_t *);
  235. extern bool_t xdr_enum(XDR *, enum_t *);
  236. extern bool_t xdr_array(XDR *, char **, unsigned int *, unsigned int,
  237. unsigned int, xdrproc_t);
  238. extern bool_t xdr_bytes(XDR *, char **, unsigned int *, unsigned int);
  239. extern bool_t xdr_opaque(XDR *, caddr_t, unsigned int);
  240. extern bool_t xdr_string(XDR *, char **, unsigned int);
  241. extern bool_t xdr_union(XDR *, enum_t *, char *, struct xdr_discrim *,
  242. xdrproc_t);
  243. extern bool_t xdr_char(XDR *, char *);
  244. extern bool_t xdr_u_char(XDR *, unsigned char *);
  245. extern bool_t xdr_vector(XDR *, char *, unsigned int, unsigned int,
  246. xdrproc_t);
  247. extern bool_t xdr_float(XDR *, float *);
  248. extern bool_t xdr_double(XDR *, double *);
  249. extern bool_t xdr_reference(XDR *, caddr_t *, unsigned int, xdrproc_t);
  250. extern bool_t xdr_pointer(XDR *, caddr_t *, unsigned int, xdrproc_t);
  251. extern bool_t xdr_wrapstring(XDR *, char **);
  252. extern void xdr_free(xdrproc_t, char *);
  253. __END_DECLS
  254. /*
  255. * Common opaque bytes objects used by many rpc protocols;
  256. * declared here due to commonality.
  257. */
  258. #define MAX_NETOBJ_SZ 1024
  259. struct netobj {
  260. unsigned int n_len;
  261. char *n_bytes;
  262. };
  263. typedef struct netobj netobj;
  264. extern bool_t xdr_netobj(XDR *, struct netobj *);
  265. /*
  266. * These are the public routines for the various implementations of
  267. * xdr streams.
  268. */
  269. __BEGIN_DECLS
  270. /* XDR using memory buffers */
  271. extern void xdrmem_create(XDR *, char *, unsigned int, enum xdr_op);
  272. #ifdef _STDIO_H_
  273. /* XDR using stdio library */
  274. extern void xdrstdio_create(XDR *, FILE *, enum xdr_op);
  275. #endif
  276. /* XDR pseudo records for tcp */
  277. extern void xdrrec_create(XDR *, unsigned int, unsigned int, char *,
  278. int (*)(caddr_t, caddr_t, int),
  279. int (*)(caddr_t, caddr_t, int));
  280. /* make end of xdr record */
  281. extern bool_t xdrrec_endofrecord(XDR *, int);
  282. /* move to beginning of next record */
  283. extern bool_t xdrrec_skiprecord(XDR *);
  284. /* true if no more input */
  285. extern bool_t xdrrec_eof(XDR *);
  286. __END_DECLS
  287. #endif /* !_RPC_XDR_H */