xref: /freebsd/lib/libc/xdr/xdr_mem.c (revision dc36d6f9bb1753f3808552f3afd30eda9a7b206a)
18360efbdSAlfred Perlstein /*	$NetBSD: xdr_mem.c,v 1.15 2000/01/22 22:19:18 mycroft Exp $	*/
28360efbdSAlfred Perlstein 
3a204967aSHiroki Sato /*-
4*8a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
5*8a16b7a1SPedro F. Giffuni  *
6a204967aSHiroki Sato  * Copyright (c) 2010, Oracle America, Inc.
7eae561b3SGarrett Wollman  *
8a204967aSHiroki Sato  * Redistribution and use in source and binary forms, with or without
9a204967aSHiroki Sato  * modification, are permitted provided that the following conditions are
10a204967aSHiroki Sato  * met:
11eae561b3SGarrett Wollman  *
12a204967aSHiroki Sato  *     * Redistributions of source code must retain the above copyright
13a204967aSHiroki Sato  *       notice, this list of conditions and the following disclaimer.
14a204967aSHiroki Sato  *     * Redistributions in binary form must reproduce the above
15a204967aSHiroki Sato  *       copyright notice, this list of conditions and the following
16a204967aSHiroki Sato  *       disclaimer in the documentation and/or other materials
17a204967aSHiroki Sato  *       provided with the distribution.
18a204967aSHiroki Sato  *     * Neither the name of the "Oracle America, Inc." nor the names of its
19a204967aSHiroki Sato  *       contributors may be used to endorse or promote products derived
20a204967aSHiroki Sato  *       from this software without specific prior written permission.
21eae561b3SGarrett Wollman  *
22a204967aSHiroki Sato  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23a204967aSHiroki Sato  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24a204967aSHiroki Sato  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25a204967aSHiroki Sato  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26a204967aSHiroki Sato  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27a204967aSHiroki Sato  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28a204967aSHiroki Sato  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29a204967aSHiroki Sato  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30a204967aSHiroki Sato  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31a204967aSHiroki Sato  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32a204967aSHiroki Sato  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33a204967aSHiroki Sato  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34eae561b3SGarrett Wollman  */
35eae561b3SGarrett Wollman 
36eae561b3SGarrett Wollman /*
37eae561b3SGarrett Wollman  * xdr_mem.h, XDR implementation using memory buffers.
38eae561b3SGarrett Wollman  *
39eae561b3SGarrett Wollman  * If you have some data to be interpreted as external data representation
40eae561b3SGarrett Wollman  * or to be converted to external data representation in a memory buffer,
41eae561b3SGarrett Wollman  * then this is the package for you.
42eae561b3SGarrett Wollman  *
43eae561b3SGarrett Wollman  */
44eae561b3SGarrett Wollman 
458360efbdSAlfred Perlstein #include "namespace.h"
468360efbdSAlfred Perlstein #include <sys/types.h>
478360efbdSAlfred Perlstein 
48eae561b3SGarrett Wollman #include <netinet/in.h>
49eae561b3SGarrett Wollman 
508360efbdSAlfred Perlstein #include <string.h>
51eae561b3SGarrett Wollman 
528360efbdSAlfred Perlstein #include <rpc/types.h>
538360efbdSAlfred Perlstein #include <rpc/xdr.h>
548360efbdSAlfred Perlstein #include "un-namespace.h"
558360efbdSAlfred Perlstein 
56c05ac53bSDavid E. O'Brien static void xdrmem_destroy(XDR *);
57c05ac53bSDavid E. O'Brien static bool_t xdrmem_getlong_aligned(XDR *, long *);
58c05ac53bSDavid E. O'Brien static bool_t xdrmem_putlong_aligned(XDR *, const long *);
59c05ac53bSDavid E. O'Brien static bool_t xdrmem_getlong_unaligned(XDR *, long *);
60c05ac53bSDavid E. O'Brien static bool_t xdrmem_putlong_unaligned(XDR *, const long *);
61c05ac53bSDavid E. O'Brien static bool_t xdrmem_getbytes(XDR *, char *, u_int);
62c05ac53bSDavid E. O'Brien static bool_t xdrmem_putbytes(XDR *, const char *, u_int);
638360efbdSAlfred Perlstein /* XXX: w/64-bit pointers, u_int not enough! */
64c05ac53bSDavid E. O'Brien static u_int xdrmem_getpos(XDR *);
65c05ac53bSDavid E. O'Brien static bool_t xdrmem_setpos(XDR *, u_int);
66c05ac53bSDavid E. O'Brien static int32_t *xdrmem_inline_aligned(XDR *, u_int);
67c05ac53bSDavid E. O'Brien static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
688360efbdSAlfred Perlstein 
698360efbdSAlfred Perlstein static const struct	xdr_ops xdrmem_ops_aligned = {
701ad08a09SPeter Wemm 	xdrmem_getlong_aligned,
711ad08a09SPeter Wemm 	xdrmem_putlong_aligned,
72eae561b3SGarrett Wollman 	xdrmem_getbytes,
73eae561b3SGarrett Wollman 	xdrmem_putbytes,
74eae561b3SGarrett Wollman 	xdrmem_getpos,
75eae561b3SGarrett Wollman 	xdrmem_setpos,
761ad08a09SPeter Wemm 	xdrmem_inline_aligned,
771ad08a09SPeter Wemm 	xdrmem_destroy
781ad08a09SPeter Wemm };
791ad08a09SPeter Wemm 
808360efbdSAlfred Perlstein static const struct	xdr_ops xdrmem_ops_unaligned = {
811ad08a09SPeter Wemm 	xdrmem_getlong_unaligned,
821ad08a09SPeter Wemm 	xdrmem_putlong_unaligned,
831ad08a09SPeter Wemm 	xdrmem_getbytes,
841ad08a09SPeter Wemm 	xdrmem_putbytes,
851ad08a09SPeter Wemm 	xdrmem_getpos,
861ad08a09SPeter Wemm 	xdrmem_setpos,
871ad08a09SPeter Wemm 	xdrmem_inline_unaligned,
88eae561b3SGarrett Wollman 	xdrmem_destroy
89eae561b3SGarrett Wollman };
90eae561b3SGarrett Wollman 
91eae561b3SGarrett Wollman /*
92eae561b3SGarrett Wollman  * The procedure xdrmem_create initializes a stream descriptor for a
93eae561b3SGarrett Wollman  * memory buffer.
94eae561b3SGarrett Wollman  */
95eae561b3SGarrett Wollman void
xdrmem_create(XDR * xdrs,char * addr,u_int size,enum xdr_op op)96d660d38dSCraig Rodrigues xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
97eae561b3SGarrett Wollman {
98eae561b3SGarrett Wollman 
99eae561b3SGarrett Wollman 	xdrs->x_op = op;
1008360efbdSAlfred Perlstein 	xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1))
1011ad08a09SPeter Wemm 	    ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
102eae561b3SGarrett Wollman 	xdrs->x_private = xdrs->x_base = addr;
103eae561b3SGarrett Wollman 	xdrs->x_handy = size;
104eae561b3SGarrett Wollman }
105eae561b3SGarrett Wollman 
1068360efbdSAlfred Perlstein /*ARGSUSED*/
107eae561b3SGarrett Wollman static void
xdrmem_destroy(XDR * xdrs)108d660d38dSCraig Rodrigues xdrmem_destroy(XDR *xdrs)
109eae561b3SGarrett Wollman {
1101ad08a09SPeter Wemm 
111eae561b3SGarrett Wollman }
112eae561b3SGarrett Wollman 
113eae561b3SGarrett Wollman static bool_t
xdrmem_getlong_aligned(XDR * xdrs,long * lp)114d660d38dSCraig Rodrigues xdrmem_getlong_aligned(XDR *xdrs, long *lp)
115eae561b3SGarrett Wollman {
116eae561b3SGarrett Wollman 
117d7f15c94SJacques Vidrine 	if (xdrs->x_handy < sizeof(int32_t))
118eae561b3SGarrett Wollman 		return (FALSE);
119d7f15c94SJacques Vidrine 	xdrs->x_handy -= sizeof(int32_t);
1208360efbdSAlfred Perlstein 	*lp = ntohl(*(u_int32_t *)xdrs->x_private);
1218360efbdSAlfred Perlstein 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
122eae561b3SGarrett Wollman 	return (TRUE);
123eae561b3SGarrett Wollman }
124eae561b3SGarrett Wollman 
125eae561b3SGarrett Wollman static bool_t
xdrmem_putlong_aligned(XDR * xdrs,const long * lp)126d660d38dSCraig Rodrigues xdrmem_putlong_aligned(XDR *xdrs, const long *lp)
127eae561b3SGarrett Wollman {
128eae561b3SGarrett Wollman 
129d7f15c94SJacques Vidrine 	if (xdrs->x_handy < sizeof(int32_t))
130eae561b3SGarrett Wollman 		return (FALSE);
131d7f15c94SJacques Vidrine 	xdrs->x_handy -= sizeof(int32_t);
1328360efbdSAlfred Perlstein 	*(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
1338360efbdSAlfred Perlstein 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
1341ad08a09SPeter Wemm 	return (TRUE);
1351ad08a09SPeter Wemm }
1361ad08a09SPeter Wemm 
1371ad08a09SPeter Wemm static bool_t
xdrmem_getlong_unaligned(XDR * xdrs,long * lp)138d660d38dSCraig Rodrigues xdrmem_getlong_unaligned(XDR *xdrs, long *lp)
1391ad08a09SPeter Wemm {
1408360efbdSAlfred Perlstein 	u_int32_t l;
1411ad08a09SPeter Wemm 
142d7f15c94SJacques Vidrine 	if (xdrs->x_handy < sizeof(int32_t))
1431ad08a09SPeter Wemm 		return (FALSE);
144d7f15c94SJacques Vidrine 	xdrs->x_handy -= sizeof(int32_t);
1458360efbdSAlfred Perlstein 	memmove(&l, xdrs->x_private, sizeof(int32_t));
1461ad08a09SPeter Wemm 	*lp = ntohl(l);
1478360efbdSAlfred Perlstein 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
1481ad08a09SPeter Wemm 	return (TRUE);
1491ad08a09SPeter Wemm }
1501ad08a09SPeter Wemm 
1511ad08a09SPeter Wemm static bool_t
xdrmem_putlong_unaligned(XDR * xdrs,const long * lp)152d660d38dSCraig Rodrigues xdrmem_putlong_unaligned(XDR *xdrs, const long *lp)
1531ad08a09SPeter Wemm {
1548360efbdSAlfred Perlstein 	u_int32_t l;
1551ad08a09SPeter Wemm 
156d7f15c94SJacques Vidrine 	if (xdrs->x_handy < sizeof(int32_t))
1571ad08a09SPeter Wemm 		return (FALSE);
158d7f15c94SJacques Vidrine 	xdrs->x_handy -= sizeof(int32_t);
1598360efbdSAlfred Perlstein 	l = htonl((u_int32_t)*lp);
1608360efbdSAlfred Perlstein 	memmove(xdrs->x_private, &l, sizeof(int32_t));
1618360efbdSAlfred Perlstein 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
162eae561b3SGarrett Wollman 	return (TRUE);
163eae561b3SGarrett Wollman }
164eae561b3SGarrett Wollman 
165eae561b3SGarrett Wollman static bool_t
xdrmem_getbytes(XDR * xdrs,char * addr,u_int len)166d660d38dSCraig Rodrigues xdrmem_getbytes(XDR *xdrs, char *addr, u_int len)
167eae561b3SGarrett Wollman {
168eae561b3SGarrett Wollman 
169d7f15c94SJacques Vidrine 	if (xdrs->x_handy < len)
170eae561b3SGarrett Wollman 		return (FALSE);
171d7f15c94SJacques Vidrine 	xdrs->x_handy -= len;
1728360efbdSAlfred Perlstein 	memmove(addr, xdrs->x_private, len);
1738360efbdSAlfred Perlstein 	xdrs->x_private = (char *)xdrs->x_private + len;
174eae561b3SGarrett Wollman 	return (TRUE);
175eae561b3SGarrett Wollman }
176eae561b3SGarrett Wollman 
177eae561b3SGarrett Wollman static bool_t
xdrmem_putbytes(XDR * xdrs,const char * addr,u_int len)178d660d38dSCraig Rodrigues xdrmem_putbytes(XDR *xdrs, const char *addr, u_int len)
179eae561b3SGarrett Wollman {
180eae561b3SGarrett Wollman 
181d7f15c94SJacques Vidrine 	if (xdrs->x_handy < len)
182eae561b3SGarrett Wollman 		return (FALSE);
183d7f15c94SJacques Vidrine 	xdrs->x_handy -= len;
1848360efbdSAlfred Perlstein 	memmove(xdrs->x_private, addr, len);
1858360efbdSAlfred Perlstein 	xdrs->x_private = (char *)xdrs->x_private + len;
186eae561b3SGarrett Wollman 	return (TRUE);
187eae561b3SGarrett Wollman }
188eae561b3SGarrett Wollman 
189eae561b3SGarrett Wollman static u_int
xdrmem_getpos(XDR * xdrs)190d660d38dSCraig Rodrigues xdrmem_getpos(XDR *xdrs)
191eae561b3SGarrett Wollman {
192eae561b3SGarrett Wollman 
1931ad08a09SPeter Wemm 	/* XXX w/64-bit pointers, u_int not enough! */
1948360efbdSAlfred Perlstein 	return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base);
195eae561b3SGarrett Wollman }
196eae561b3SGarrett Wollman 
197eae561b3SGarrett Wollman static bool_t
xdrmem_setpos(XDR * xdrs,u_int pos)198d660d38dSCraig Rodrigues xdrmem_setpos(XDR *xdrs, u_int pos)
199eae561b3SGarrett Wollman {
2008360efbdSAlfred Perlstein 	char *newaddr = xdrs->x_base + pos;
2018360efbdSAlfred Perlstein 	char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy;
202eae561b3SGarrett Wollman 
203d7f15c94SJacques Vidrine 	if (newaddr > lastaddr)
204eae561b3SGarrett Wollman 		return (FALSE);
205eae561b3SGarrett Wollman 	xdrs->x_private = newaddr;
206d7f15c94SJacques Vidrine 	xdrs->x_handy = (u_int)(lastaddr - newaddr); /* XXX sizeof(u_int) <? sizeof(ptrdiff_t) */
207eae561b3SGarrett Wollman 	return (TRUE);
208eae561b3SGarrett Wollman }
209eae561b3SGarrett Wollman 
2101ad08a09SPeter Wemm static int32_t *
xdrmem_inline_aligned(XDR * xdrs,u_int len)211d660d38dSCraig Rodrigues xdrmem_inline_aligned(XDR *xdrs, u_int len)
212eae561b3SGarrett Wollman {
213513004a2SPedro F. Giffuni 	int32_t *buf = NULL;
214eae561b3SGarrett Wollman 
215eae561b3SGarrett Wollman 	if (xdrs->x_handy >= len) {
216eae561b3SGarrett Wollman 		xdrs->x_handy -= len;
2171ad08a09SPeter Wemm 		buf = (int32_t *)xdrs->x_private;
2188360efbdSAlfred Perlstein 		xdrs->x_private = (char *)xdrs->x_private + len;
219eae561b3SGarrett Wollman 	}
220eae561b3SGarrett Wollman 	return (buf);
221eae561b3SGarrett Wollman }
2221ad08a09SPeter Wemm 
2238360efbdSAlfred Perlstein /* ARGSUSED */
2241ad08a09SPeter Wemm static int32_t *
xdrmem_inline_unaligned(XDR * xdrs,u_int len)225d660d38dSCraig Rodrigues xdrmem_inline_unaligned(XDR *xdrs, u_int len)
2261ad08a09SPeter Wemm {
2271ad08a09SPeter Wemm 
2281ad08a09SPeter Wemm 	return (0);
2291ad08a09SPeter Wemm }
230