1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
7 * Reserved.  This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License").  You may not use this file
10 * except in compliance with the License.  Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25/*	$NetBSD: xdr_mem.c,v 1.15 2000/01/22 22:19:18 mycroft Exp $	*/
26
27/*
28 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
29 * unrestricted use provided that this legend is included on all tape
30 * media and as a part of the software program in whole or part.  Users
31 * may copy or modify Sun RPC without charge, but are not authorized
32 * to license or distribute it to anyone else except as part of a product or
33 * program developed by the user.
34 *
35 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
36 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
37 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
38 *
39 * Sun RPC is provided with no support and without any obligation on the
40 * part of Sun Microsystems, Inc. to assist in its use, correction,
41 * modification or enhancement.
42 *
43 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
44 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
45 * OR ANY PART THEREOF.
46 *
47 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
48 * or profits or other special, indirect and consequential damages, even if
49 * Sun has been advised of the possibility of such damages.
50 *
51 * Sun Microsystems, Inc.
52 * 2550 Garcia Avenue
53 * Mountain View, California  94043
54 */
55
56#if defined(LIBC_SCCS) && !defined(lint)
57static char *sccsid = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
58static char *sccsid = "@(#)xdr_mem.c	2.1 88/07/29 4.0 RPCSRC";
59#endif
60#include <sys/cdefs.h>
61
62/*
63 * xdr_mem.h, XDR implementation using memory buffers.
64 *
65 * Copyright (C) 1984, Sun Microsystems, Inc.
66 *
67 * If you have some data to be interpreted as external data representation
68 * or to be converted to external data representation in a memory buffer,
69 * then this is the package for you.
70 *
71 */
72
73#include <sys/types.h>
74#include <stddef.h>
75
76#include <netinet/in.h>
77
78#include <string.h>
79
80#include <rpc/types.h>
81#include <rpc/xdr.h>
82
83#ifdef __LP64__
84#define xdrlong_t int
85#else
86#define xdrlong_t long
87#endif
88
89static void xdrmem_destroy(XDR *);
90static bool_t xdrmem_getlong_aligned(XDR *, xdrlong_t *);
91static bool_t xdrmem_putlong_aligned(XDR *, const xdrlong_t *);
92static bool_t xdrmem_getlong_unaligned(XDR *, xdrlong_t *);
93static bool_t xdrmem_putlong_unaligned(XDR *, const xdrlong_t *);
94static bool_t xdrmem_getbytes(XDR *, char *, u_int);
95static bool_t xdrmem_putbytes(XDR *, const char *, u_int);
96/* XXX: w/64-bit pointers, u_int not enough! */
97static u_int xdrmem_getpos(XDR *);
98static bool_t xdrmem_setpos(XDR *, u_int);
99static int32_t *xdrmem_inline_aligned(XDR *, u_int);
100static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
101
102static const struct	xdr_ops xdrmem_ops_aligned = {
103	xdrmem_getlong_aligned,
104	xdrmem_putlong_aligned,
105	xdrmem_getbytes,
106	xdrmem_putbytes,
107	xdrmem_getpos,
108	xdrmem_setpos,
109	xdrmem_inline_aligned,
110	xdrmem_destroy
111};
112
113static const struct	xdr_ops xdrmem_ops_unaligned = {
114	xdrmem_getlong_unaligned,
115	xdrmem_putlong_unaligned,
116	xdrmem_getbytes,
117	xdrmem_putbytes,
118	xdrmem_getpos,
119	xdrmem_setpos,
120	xdrmem_inline_unaligned,
121	xdrmem_destroy
122};
123
124/*
125 * The procedure xdrmem_create initializes a stream descriptor for a
126 * memory buffer.
127 */
128void
129xdrmem_create(xdrs, addr, size, op)
130	XDR *xdrs;
131	char *addr;
132	u_int size;
133	enum xdr_op op;
134{
135	xdrs->x_op = op;
136	xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1))
137	    ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
138	xdrs->x_private = xdrs->x_base = addr;
139	xdrs->x_handy = size;
140}
141
142/*ARGSUSED*/
143static void
144xdrmem_destroy(xdrs)
145	XDR *xdrs;
146{
147}
148
149static bool_t
150xdrmem_getlong_aligned(xdrs, lp)
151	XDR *xdrs;
152	xdrlong_t *lp;
153{
154	if (xdrs->x_handy < sizeof(int32_t))
155		return (FALSE);
156	xdrs->x_handy -= sizeof(int32_t);
157	*lp = ntohl(*(u_int32_t *)xdrs->x_private);
158	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
159	return (TRUE);
160}
161
162static bool_t
163xdrmem_putlong_aligned(xdrs, lp)
164	XDR *xdrs;
165	const xdrlong_t *lp;
166{
167	if (xdrs->x_handy < sizeof(int32_t))
168		return (FALSE);
169	xdrs->x_handy -= sizeof(int32_t);
170	*(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
171	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
172	return (TRUE);
173}
174
175static bool_t
176xdrmem_getlong_unaligned(xdrs, lp)
177	XDR *xdrs;
178	xdrlong_t *lp;
179{
180	u_int32_t l;
181
182	if (xdrs->x_handy < sizeof(int32_t))
183		return (FALSE);
184	xdrs->x_handy -= sizeof(int32_t);
185	memmove(&l, xdrs->x_private, sizeof(int32_t));
186	*lp = ntohl(l);
187	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
188	return (TRUE);
189}
190
191static bool_t
192xdrmem_putlong_unaligned(xdrs, lp)
193	XDR *xdrs;
194	const xdrlong_t *lp;
195{
196	u_int32_t l;
197
198	if (xdrs->x_handy < sizeof(int32_t))
199		return (FALSE);
200	xdrs->x_handy -= sizeof(int32_t);
201	l = htonl((u_int32_t)*lp);
202	memmove(xdrs->x_private, &l, sizeof(int32_t));
203	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
204	return (TRUE);
205}
206
207static bool_t
208xdrmem_getbytes(xdrs, addr, len)
209	XDR *xdrs;
210	char *addr;
211	u_int len;
212{
213	if (xdrs->x_handy < len)
214		return (FALSE);
215	xdrs->x_handy -= len;
216	memmove(addr, xdrs->x_private, len);
217	xdrs->x_private = (char *)xdrs->x_private + len;
218	return (TRUE);
219}
220
221static bool_t
222xdrmem_putbytes(xdrs, addr, len)
223	XDR *xdrs;
224	const char *addr;
225	u_int len;
226{
227	if (xdrs->x_handy < len)
228		return (FALSE);
229	xdrs->x_handy -= len;
230	memmove(xdrs->x_private, addr, len);
231	xdrs->x_private = (char *)xdrs->x_private + len;
232	return (TRUE);
233}
234
235static u_int
236xdrmem_getpos(xdrs)
237	XDR *xdrs;
238{
239	ptrdiff_t delta;
240	u_int val;
241
242	delta = xdrs->x_private - (void *)(xdrs->x_base);
243#ifdef __LP64__
244	if (delta > UINT32_MAX) return -1;
245#endif
246
247	val = delta;
248	return val;
249}
250
251static bool_t
252xdrmem_setpos(xdrs, pos)
253	XDR *xdrs;
254	u_int pos;
255{
256	ptrdiff_t delta;
257	char *newaddr = xdrs->x_base + pos;
258	char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy;
259
260	if (newaddr > lastaddr)
261		return (FALSE);
262	xdrs->x_private = newaddr;
263	delta = lastaddr - newaddr;
264#ifdef __LP64__
265	if (delta > UINT32_MAX) return (FALSE);
266#endif
267	xdrs->x_handy = delta;
268	return (TRUE);
269}
270
271static int32_t *
272xdrmem_inline_aligned(xdrs, len)
273	XDR *xdrs;
274	u_int len;
275{
276	int32_t *buf = 0;
277
278	if (xdrs->x_handy >= len) {
279		xdrs->x_handy -= len;
280		buf = (int32_t *)xdrs->x_private;
281		xdrs->x_private = (char *)xdrs->x_private + len;
282	}
283	return (buf);
284}
285
286/* ARGSUSED */
287static int32_t *
288xdrmem_inline_unaligned(xdrs, len)
289	XDR *xdrs;
290	u_int len;
291{
292	return (0);
293}
294