xref: /openbsd/lib/libc/rpc/xdr_mem.c (revision 8d4335cb)
1*8d4335cbSguenther /*	$OpenBSD: xdr_mem.c,v 1.18 2022/02/14 03:38:59 guenther Exp $ */
2cb7760d1Smillert 
3df930be7Sderaadt /*
4cb7760d1Smillert  * Copyright (c) 2010, Oracle America, Inc.
5df930be7Sderaadt  *
6cb7760d1Smillert  * Redistribution and use in source and binary forms, with or without
7cb7760d1Smillert  * modification, are permitted provided that the following conditions are
8cb7760d1Smillert  * met:
9df930be7Sderaadt  *
10cb7760d1Smillert  *     * Redistributions of source code must retain the above copyright
11cb7760d1Smillert  *       notice, this list of conditions and the following disclaimer.
12cb7760d1Smillert  *     * Redistributions in binary form must reproduce the above
13cb7760d1Smillert  *       copyright notice, this list of conditions and the following
14cb7760d1Smillert  *       disclaimer in the documentation and/or other materials
15cb7760d1Smillert  *       provided with the distribution.
16cb7760d1Smillert  *     * Neither the name of the "Oracle America, Inc." nor the names of its
17cb7760d1Smillert  *       contributors may be used to endorse or promote products derived
18cb7760d1Smillert  *       from this software without specific prior written permission.
19df930be7Sderaadt  *
20cb7760d1Smillert  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21cb7760d1Smillert  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22cb7760d1Smillert  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23cb7760d1Smillert  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24cb7760d1Smillert  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25cb7760d1Smillert  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26cb7760d1Smillert  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27cb7760d1Smillert  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28cb7760d1Smillert  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29cb7760d1Smillert  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30cb7760d1Smillert  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31cb7760d1Smillert  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32df930be7Sderaadt  */
33df930be7Sderaadt 
34df930be7Sderaadt /*
35df930be7Sderaadt  * xdr_mem.h, XDR implementation using memory buffers.
36df930be7Sderaadt  *
37df930be7Sderaadt  * If you have some data to be interpreted as external data representation
38df930be7Sderaadt  * or to be converted to external data representation in a memory buffer,
39df930be7Sderaadt  * then this is the package for you.
40df930be7Sderaadt  *
41df930be7Sderaadt  */
42df930be7Sderaadt 
43ee1a9978Sotto #include <sys/types.h>
44ee1a9978Sotto #include <netinet/in.h>
45f5c144acSetheisen #include <string.h>
46df930be7Sderaadt 
47df930be7Sderaadt #include <rpc/types.h>
48df930be7Sderaadt #include <rpc/xdr.h>
49df930be7Sderaadt 
5041aa8645Sderaadt static bool_t	xdrmem_getlong_aligned(XDR *, long *);
5141aa8645Sderaadt static bool_t	xdrmem_putlong_aligned(XDR *, long *);
5241aa8645Sderaadt static bool_t	xdrmem_getlong_unaligned(XDR *, long *);
5341aa8645Sderaadt static bool_t	xdrmem_putlong_unaligned(XDR *, long *);
5441aa8645Sderaadt static bool_t	xdrmem_getbytes(XDR *, caddr_t, u_int);
5541aa8645Sderaadt static bool_t	xdrmem_putbytes(XDR *, caddr_t, u_int);
5641aa8645Sderaadt static u_int	xdrmem_getpos(XDR *); /* XXX w/64-bit pointers, u_int not enough! */
5741aa8645Sderaadt static bool_t	xdrmem_setpos(XDR *, u_int);
5841aa8645Sderaadt static int32_t *xdrmem_inline_aligned(XDR *, u_int);
5941aa8645Sderaadt static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
6041aa8645Sderaadt static void	xdrmem_destroy(XDR *);
61df930be7Sderaadt 
62*8d4335cbSguenther static const struct xdr_ops xdrmem_ops_aligned = {
63a3320e1fSniklas 	xdrmem_getlong_aligned,
64a3320e1fSniklas 	xdrmem_putlong_aligned,
65df930be7Sderaadt 	xdrmem_getbytes,
66df930be7Sderaadt 	xdrmem_putbytes,
67df930be7Sderaadt 	xdrmem_getpos,
68df930be7Sderaadt 	xdrmem_setpos,
69a3320e1fSniklas 	xdrmem_inline_aligned,
70ee1a9978Sotto 	xdrmem_destroy,
71ee1a9978Sotto 	NULL,	/* xdrmem_control */
72a3320e1fSniklas };
73a3320e1fSniklas 
74*8d4335cbSguenther static const struct xdr_ops xdrmem_ops_unaligned = {
75a3320e1fSniklas 	xdrmem_getlong_unaligned,
76a3320e1fSniklas 	xdrmem_putlong_unaligned,
77a3320e1fSniklas 	xdrmem_getbytes,
78a3320e1fSniklas 	xdrmem_putbytes,
79a3320e1fSniklas 	xdrmem_getpos,
80a3320e1fSniklas 	xdrmem_setpos,
81a3320e1fSniklas 	xdrmem_inline_unaligned,
82ee1a9978Sotto 	xdrmem_destroy,
83ee1a9978Sotto 	NULL,	/* xdrmem_control */
84df930be7Sderaadt };
85df930be7Sderaadt 
86df930be7Sderaadt /*
87df930be7Sderaadt  * The procedure xdrmem_create initializes a stream descriptor for a
88df930be7Sderaadt  * memory buffer.
89df930be7Sderaadt  */
90df930be7Sderaadt void
xdrmem_create(XDR * xdrs,caddr_t addr,u_int size,enum xdr_op op)91384ec30aSotto xdrmem_create(XDR *xdrs, caddr_t addr, u_int size, enum xdr_op op)
92df930be7Sderaadt {
93df930be7Sderaadt 
94df930be7Sderaadt 	xdrs->x_op = op;
95a3320e1fSniklas 	xdrs->x_ops = ((size_t)addr & (sizeof(int32_t) - 1))
96a3320e1fSniklas 	    ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
97df930be7Sderaadt 	xdrs->x_private = xdrs->x_base = addr;
98df930be7Sderaadt 	xdrs->x_handy = size;
99df930be7Sderaadt }
10085858ec2Sguenther DEF_WEAK(xdrmem_create);
101df930be7Sderaadt 
102df930be7Sderaadt static void
xdrmem_destroy(XDR * xdrs)10341aa8645Sderaadt xdrmem_destroy(XDR *xdrs)
104df930be7Sderaadt {
105df930be7Sderaadt }
106df930be7Sderaadt 
107df930be7Sderaadt static bool_t
xdrmem_getlong_aligned(XDR * xdrs,long int * lp)108384ec30aSotto xdrmem_getlong_aligned(XDR *xdrs, long int *lp)
109df930be7Sderaadt {
110df930be7Sderaadt 
1112c51cfc0Smillert 	if (xdrs->x_handy < sizeof(int32_t))
112df930be7Sderaadt 		return (FALSE);
1132c51cfc0Smillert 	xdrs->x_handy -= sizeof(int32_t);
114a3320e1fSniklas 	*lp = ntohl(*(int32_t *)xdrs->x_private);
115df930be7Sderaadt 	xdrs->x_private += sizeof(int32_t);
116df930be7Sderaadt 	return (TRUE);
117df930be7Sderaadt }
118df930be7Sderaadt 
119df930be7Sderaadt static bool_t
xdrmem_putlong_aligned(XDR * xdrs,long int * lp)120384ec30aSotto xdrmem_putlong_aligned(XDR *xdrs, long int *lp)
121df930be7Sderaadt {
122df930be7Sderaadt 
1232c51cfc0Smillert 	if (xdrs->x_handy < sizeof(int32_t))
124df930be7Sderaadt 		return (FALSE);
1252c51cfc0Smillert 	xdrs->x_handy -= sizeof(int32_t);
126e16fc2b2Sjason 	*(int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
127a3320e1fSniklas 	xdrs->x_private += sizeof(int32_t);
128a3320e1fSniklas 	return (TRUE);
129a3320e1fSniklas }
130a3320e1fSniklas 
131a3320e1fSniklas static bool_t
xdrmem_getlong_unaligned(XDR * xdrs,long int * lp)132384ec30aSotto xdrmem_getlong_unaligned(XDR *xdrs, long int *lp)
133a3320e1fSniklas {
134a3320e1fSniklas 	int32_t l;
135a3320e1fSniklas 
1362c51cfc0Smillert 	if (xdrs->x_handy < sizeof(int32_t))
137a3320e1fSniklas 		return (FALSE);
1382c51cfc0Smillert 	xdrs->x_handy -= sizeof(int32_t);
13973b69cd9Sderaadt 	memcpy(&l, xdrs->x_private, sizeof(int32_t));
140a3320e1fSniklas 	*lp = ntohl(l);
141a3320e1fSniklas 	xdrs->x_private += sizeof(int32_t);
142a3320e1fSniklas 	return (TRUE);
143a3320e1fSniklas }
144a3320e1fSniklas 
145a3320e1fSniklas static bool_t
xdrmem_putlong_unaligned(XDR * xdrs,long int * lp)146384ec30aSotto xdrmem_putlong_unaligned(XDR *xdrs, long int *lp)
147a3320e1fSniklas {
148a3320e1fSniklas 	int32_t l;
149a3320e1fSniklas 
1502c51cfc0Smillert 	if (xdrs->x_handy < sizeof(int32_t))
151a3320e1fSniklas 		return (FALSE);
1522c51cfc0Smillert 	xdrs->x_handy -= sizeof(int32_t);
153e16fc2b2Sjason 	l = htonl((u_int32_t)*lp);
15473b69cd9Sderaadt 	memcpy(xdrs->x_private, &l, sizeof(int32_t));
155df930be7Sderaadt 	xdrs->x_private += sizeof(int32_t);
156df930be7Sderaadt 	return (TRUE);
157df930be7Sderaadt }
158df930be7Sderaadt 
159df930be7Sderaadt static bool_t
xdrmem_getbytes(XDR * xdrs,caddr_t addr,u_int len)160384ec30aSotto xdrmem_getbytes(XDR *xdrs, caddr_t addr, u_int len)
161df930be7Sderaadt {
162df930be7Sderaadt 
1632c51cfc0Smillert 	if (xdrs->x_handy < len)
164df930be7Sderaadt 		return (FALSE);
1652c51cfc0Smillert 	xdrs->x_handy -= len;
16673b69cd9Sderaadt 	memcpy(addr, xdrs->x_private, len);
167df930be7Sderaadt 	xdrs->x_private += len;
168df930be7Sderaadt 	return (TRUE);
169df930be7Sderaadt }
170df930be7Sderaadt 
171df930be7Sderaadt static bool_t
xdrmem_putbytes(XDR * xdrs,caddr_t addr,u_int len)172384ec30aSotto xdrmem_putbytes(XDR *xdrs, caddr_t addr, u_int len)
173df930be7Sderaadt {
174df930be7Sderaadt 
1752c51cfc0Smillert 	if (xdrs->x_handy < len)
176df930be7Sderaadt 		return (FALSE);
1772c51cfc0Smillert 	xdrs->x_handy -= len;
17873b69cd9Sderaadt 	memcpy(xdrs->x_private, addr, len);
179df930be7Sderaadt 	xdrs->x_private += len;
180df930be7Sderaadt 	return (TRUE);
181df930be7Sderaadt }
182df930be7Sderaadt 
183df930be7Sderaadt static u_int
xdrmem_getpos(XDR * xdrs)184384ec30aSotto xdrmem_getpos(XDR *xdrs)
185df930be7Sderaadt {
186df930be7Sderaadt 
187df930be7Sderaadt 	/* XXX w/64-bit pointers, u_int not enough! */
188df930be7Sderaadt 	return ((u_long)xdrs->x_private - (u_long)xdrs->x_base);
189df930be7Sderaadt }
190df930be7Sderaadt 
191df930be7Sderaadt static bool_t
xdrmem_setpos(XDR * xdrs,u_int pos)192384ec30aSotto xdrmem_setpos(XDR *xdrs, u_int pos)
193df930be7Sderaadt {
19441aa8645Sderaadt 	caddr_t newaddr = xdrs->x_base + pos;
19541aa8645Sderaadt 	caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
196df930be7Sderaadt 
1972c51cfc0Smillert 	if (newaddr > lastaddr)
198df930be7Sderaadt 		return (FALSE);
199df930be7Sderaadt 	xdrs->x_private = newaddr;
2002c51cfc0Smillert 	xdrs->x_handy = (u_int)(lastaddr - newaddr);	/* XXX w/64-bit pointers, u_int not enough! */
201df930be7Sderaadt 	return (TRUE);
202df930be7Sderaadt }
203df930be7Sderaadt 
204df930be7Sderaadt static int32_t *
xdrmem_inline_aligned(XDR * xdrs,u_int len)205384ec30aSotto xdrmem_inline_aligned(XDR *xdrs, u_int len)
206df930be7Sderaadt {
207df930be7Sderaadt 	int32_t *buf = 0;
208df930be7Sderaadt 
209df930be7Sderaadt 	if (xdrs->x_handy >= len) {
210df930be7Sderaadt 		xdrs->x_handy -= len;
211df930be7Sderaadt 		buf = (int32_t *)xdrs->x_private;
212df930be7Sderaadt 		xdrs->x_private += len;
213df930be7Sderaadt 	}
214df930be7Sderaadt 	return (buf);
215df930be7Sderaadt }
216a3320e1fSniklas 
217a3320e1fSniklas static int32_t *
xdrmem_inline_unaligned(XDR * xdrs,u_int len)218384ec30aSotto xdrmem_inline_unaligned(XDR *xdrs, u_int len)
219a3320e1fSniklas {
220a3320e1fSniklas 
221a3320e1fSniklas 	return (0);
222a3320e1fSniklas }
223