xref: /netbsd-src/common/lib/libc/rpc/xdr_mem.c (revision c7814b62be2f229d674483004160059a283daab2)
1*c7814b62Shannken /*	$NetBSD: xdr_mem.c,v 1.2 2019/06/05 16:25:43 hannken Exp $	*/
26f60c4f9Shannken 
36f60c4f9Shannken /*
46f60c4f9Shannken  * Copyright (c) 2010, Oracle America, Inc.
56f60c4f9Shannken  *
66f60c4f9Shannken  * Redistribution and use in source and binary forms, with or without
76f60c4f9Shannken  * modification, are permitted provided that the following conditions are
86f60c4f9Shannken  * met:
96f60c4f9Shannken  *
106f60c4f9Shannken  *     * Redistributions of source code must retain the above copyright
116f60c4f9Shannken  *       notice, this list of conditions and the following disclaimer.
126f60c4f9Shannken  *     * Redistributions in binary form must reproduce the above
136f60c4f9Shannken  *       copyright notice, this list of conditions and the following
146f60c4f9Shannken  *       disclaimer in the documentation and/or other materials
156f60c4f9Shannken  *       provided with the distribution.
166f60c4f9Shannken  *     * Neither the name of the "Oracle America, Inc." nor the names of its
176f60c4f9Shannken  *       contributors may be used to endorse or promote products derived
186f60c4f9Shannken  *       from this software without specific prior written permission.
196f60c4f9Shannken  *
206f60c4f9Shannken  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
216f60c4f9Shannken  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
226f60c4f9Shannken  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
236f60c4f9Shannken  *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
246f60c4f9Shannken  *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
256f60c4f9Shannken  *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
266f60c4f9Shannken  *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
276f60c4f9Shannken  *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
286f60c4f9Shannken  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
296f60c4f9Shannken  *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
306f60c4f9Shannken  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
316f60c4f9Shannken  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
326f60c4f9Shannken  */
336f60c4f9Shannken 
346f60c4f9Shannken #include <sys/cdefs.h>
356f60c4f9Shannken #if defined(LIBC_SCCS) && !defined(lint)
366f60c4f9Shannken #if 0
376f60c4f9Shannken static char *sccsid = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
386f60c4f9Shannken static char *sccsid = "@(#)xdr_mem.c	2.1 88/07/29 4.0 RPCSRC";
396f60c4f9Shannken #else
40*c7814b62Shannken __RCSID("$NetBSD: xdr_mem.c,v 1.2 2019/06/05 16:25:43 hannken Exp $");
416f60c4f9Shannken #endif
426f60c4f9Shannken #endif
436f60c4f9Shannken 
446f60c4f9Shannken /*
456f60c4f9Shannken  * xdr_mem.h, XDR implementation using memory buffers.
466f60c4f9Shannken  *
476f60c4f9Shannken  * Copyright (C) 1984, Sun Microsystems, Inc.
486f60c4f9Shannken  *
496f60c4f9Shannken  * If you have some data to be interpreted as external data representation
506f60c4f9Shannken  * or to be converted to external data representation in a memory buffer,
516f60c4f9Shannken  * then this is the package for you.
526f60c4f9Shannken  *
536f60c4f9Shannken  */
546f60c4f9Shannken 
55*c7814b62Shannken #if defined(_KERNEL) || defined(_STANDALONE)
56*c7814b62Shannken 
57*c7814b62Shannken #include <lib/libkern/libkern.h>
58*c7814b62Shannken #include <rpc/types.h>
59*c7814b62Shannken #include <rpc/xdr.h>
60*c7814b62Shannken 
61*c7814b62Shannken #else /* _KERNEL || _STANDALONE */
62*c7814b62Shannken 
636f60c4f9Shannken #include "namespace.h"
646f60c4f9Shannken 
656f60c4f9Shannken #include <sys/types.h>
666f60c4f9Shannken 
676f60c4f9Shannken #include <netinet/in.h>
686f60c4f9Shannken 
696f60c4f9Shannken #include <string.h>
706f60c4f9Shannken 
716f60c4f9Shannken #include <rpc/types.h>
726f60c4f9Shannken #include <rpc/xdr.h>
736f60c4f9Shannken 
746f60c4f9Shannken #ifdef __weak_alias
756f60c4f9Shannken __weak_alias(xdrmem_create,_xdrmem_create)
766f60c4f9Shannken #endif
776f60c4f9Shannken 
78*c7814b62Shannken #endif /* _KERNEL || _STANDALONE */
79*c7814b62Shannken 
806f60c4f9Shannken static void xdrmem_destroy(XDR *);
816f60c4f9Shannken static bool_t xdrmem_getlong_aligned(XDR *, long *);
826f60c4f9Shannken static bool_t xdrmem_putlong_aligned(XDR *, const long *);
836f60c4f9Shannken static bool_t xdrmem_getlong_unaligned(XDR *, long *);
846f60c4f9Shannken static bool_t xdrmem_putlong_unaligned(XDR *, const long *);
856f60c4f9Shannken static bool_t xdrmem_getbytes(XDR *, char *, u_int);
866f60c4f9Shannken static bool_t xdrmem_putbytes(XDR *, const char *, u_int);
876f60c4f9Shannken /* XXX: w/64-bit pointers, u_int not enough! */
886f60c4f9Shannken static u_int xdrmem_getpos(XDR *);
896f60c4f9Shannken static bool_t xdrmem_setpos(XDR *, u_int);
906f60c4f9Shannken static int32_t *xdrmem_inline_aligned(XDR *, u_int);
916f60c4f9Shannken static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
926f60c4f9Shannken static bool_t xdrmem_control(XDR *xdrs, int request, void *info);
936f60c4f9Shannken 
946f60c4f9Shannken static const struct	xdr_ops xdrmem_ops_aligned = {
956f60c4f9Shannken 	xdrmem_getlong_aligned,
966f60c4f9Shannken 	xdrmem_putlong_aligned,
976f60c4f9Shannken 	xdrmem_getbytes,
986f60c4f9Shannken 	xdrmem_putbytes,
996f60c4f9Shannken 	xdrmem_getpos,
1006f60c4f9Shannken 	xdrmem_setpos,
1016f60c4f9Shannken 	xdrmem_inline_aligned,
1026f60c4f9Shannken 	xdrmem_destroy,
1036f60c4f9Shannken 	xdrmem_control
1046f60c4f9Shannken };
1056f60c4f9Shannken 
1066f60c4f9Shannken static const struct	xdr_ops xdrmem_ops_unaligned = {
1076f60c4f9Shannken 	xdrmem_getlong_unaligned,
1086f60c4f9Shannken 	xdrmem_putlong_unaligned,
1096f60c4f9Shannken 	xdrmem_getbytes,
1106f60c4f9Shannken 	xdrmem_putbytes,
1116f60c4f9Shannken 	xdrmem_getpos,
1126f60c4f9Shannken 	xdrmem_setpos,
1136f60c4f9Shannken 	xdrmem_inline_unaligned,
1146f60c4f9Shannken 	xdrmem_destroy,
1156f60c4f9Shannken 	xdrmem_control
1166f60c4f9Shannken };
1176f60c4f9Shannken 
1186f60c4f9Shannken /*
1196f60c4f9Shannken  * The procedure xdrmem_create initializes a stream descriptor for a
1206f60c4f9Shannken  * memory buffer.
1216f60c4f9Shannken  */
1226f60c4f9Shannken void
xdrmem_create(XDR * xdrs,char * addr,u_int size,enum xdr_op op)1236f60c4f9Shannken xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
1246f60c4f9Shannken {
1256f60c4f9Shannken 
1266f60c4f9Shannken 	xdrs->x_op = op;
1276f60c4f9Shannken 	xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1))
1286f60c4f9Shannken 	    ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
1296f60c4f9Shannken 	xdrs->x_private = xdrs->x_base = addr;
1306f60c4f9Shannken 	xdrs->x_handy = size;
1316f60c4f9Shannken }
1326f60c4f9Shannken 
1336f60c4f9Shannken /*ARGSUSED*/
1346f60c4f9Shannken static void
xdrmem_destroy(XDR * xdrs)1356f60c4f9Shannken xdrmem_destroy(XDR *xdrs)
1366f60c4f9Shannken {
1376f60c4f9Shannken 
1386f60c4f9Shannken }
1396f60c4f9Shannken 
1406f60c4f9Shannken static bool_t
xdrmem_getlong_aligned(XDR * xdrs,long * lp)1416f60c4f9Shannken xdrmem_getlong_aligned(XDR *xdrs, long *lp)
1426f60c4f9Shannken {
1436f60c4f9Shannken 
1446f60c4f9Shannken 	if (xdrs->x_handy < sizeof(int32_t))
1456f60c4f9Shannken 		return (FALSE);
1466f60c4f9Shannken 	xdrs->x_handy -= sizeof(int32_t);
1476f60c4f9Shannken 	*lp = ntohl(*(u_int32_t *)xdrs->x_private);
1486f60c4f9Shannken 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
1496f60c4f9Shannken 	return (TRUE);
1506f60c4f9Shannken }
1516f60c4f9Shannken 
1526f60c4f9Shannken static bool_t
xdrmem_putlong_aligned(XDR * xdrs,const long * lp)1536f60c4f9Shannken xdrmem_putlong_aligned(XDR *xdrs, const long *lp)
1546f60c4f9Shannken {
1556f60c4f9Shannken 
1566f60c4f9Shannken 	if (xdrs->x_handy < sizeof(int32_t))
1576f60c4f9Shannken 		return (FALSE);
1586f60c4f9Shannken 	xdrs->x_handy -= sizeof(int32_t);
1596f60c4f9Shannken 	*(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
1606f60c4f9Shannken 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
1616f60c4f9Shannken 	return (TRUE);
1626f60c4f9Shannken }
1636f60c4f9Shannken 
1646f60c4f9Shannken static bool_t
xdrmem_getlong_unaligned(XDR * xdrs,long * lp)1656f60c4f9Shannken xdrmem_getlong_unaligned(XDR *xdrs, long *lp)
1666f60c4f9Shannken {
1676f60c4f9Shannken 	u_int32_t l;
1686f60c4f9Shannken 
1696f60c4f9Shannken 	if (xdrs->x_handy < sizeof(int32_t))
1706f60c4f9Shannken 		return (FALSE);
1716f60c4f9Shannken 	xdrs->x_handy -= sizeof(int32_t);
1726f60c4f9Shannken 	memmove(&l, xdrs->x_private, sizeof(int32_t));
1736f60c4f9Shannken 	*lp = ntohl(l);
1746f60c4f9Shannken 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
1756f60c4f9Shannken 	return (TRUE);
1766f60c4f9Shannken }
1776f60c4f9Shannken 
1786f60c4f9Shannken static bool_t
xdrmem_putlong_unaligned(XDR * xdrs,const long * lp)1796f60c4f9Shannken xdrmem_putlong_unaligned(XDR *xdrs, const long *lp)
1806f60c4f9Shannken {
1816f60c4f9Shannken 	u_int32_t l;
1826f60c4f9Shannken 
1836f60c4f9Shannken 	if (xdrs->x_handy < sizeof(int32_t))
1846f60c4f9Shannken 		return (FALSE);
1856f60c4f9Shannken 	xdrs->x_handy -= sizeof(int32_t);
1866f60c4f9Shannken 	l = htonl((u_int32_t)*lp);
1876f60c4f9Shannken 	memmove(xdrs->x_private, &l, sizeof(int32_t));
1886f60c4f9Shannken 	xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
1896f60c4f9Shannken 	return (TRUE);
1906f60c4f9Shannken }
1916f60c4f9Shannken 
1926f60c4f9Shannken static bool_t
xdrmem_getbytes(XDR * xdrs,char * addr,u_int len)1936f60c4f9Shannken xdrmem_getbytes(XDR *xdrs, char *addr, u_int len)
1946f60c4f9Shannken {
1956f60c4f9Shannken 
1966f60c4f9Shannken 	if (xdrs->x_handy < len)
1976f60c4f9Shannken 		return (FALSE);
1986f60c4f9Shannken 	xdrs->x_handy -= len;
1996f60c4f9Shannken 	memmove(addr, xdrs->x_private, len);
2006f60c4f9Shannken 	xdrs->x_private = (char *)xdrs->x_private + len;
2016f60c4f9Shannken 	return (TRUE);
2026f60c4f9Shannken }
2036f60c4f9Shannken 
2046f60c4f9Shannken static bool_t
xdrmem_putbytes(XDR * xdrs,const char * addr,u_int len)2056f60c4f9Shannken xdrmem_putbytes(XDR *xdrs, const char *addr, u_int len)
2066f60c4f9Shannken {
2076f60c4f9Shannken 
2086f60c4f9Shannken 	if (xdrs->x_handy < len)
2096f60c4f9Shannken 		return (FALSE);
2106f60c4f9Shannken 	xdrs->x_handy -= len;
2116f60c4f9Shannken 	memmove(xdrs->x_private, addr, len);
2126f60c4f9Shannken 	xdrs->x_private = (char *)xdrs->x_private + len;
2136f60c4f9Shannken 	return (TRUE);
2146f60c4f9Shannken }
2156f60c4f9Shannken 
2166f60c4f9Shannken static u_int
xdrmem_getpos(XDR * xdrs)2176f60c4f9Shannken xdrmem_getpos(XDR *xdrs)
2186f60c4f9Shannken {
2196f60c4f9Shannken 
2206f60c4f9Shannken 	/* XXX w/64-bit pointers, u_int not enough! */
2216f60c4f9Shannken 	return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base);
2226f60c4f9Shannken }
2236f60c4f9Shannken 
2246f60c4f9Shannken static bool_t
xdrmem_setpos(XDR * xdrs,u_int pos)2256f60c4f9Shannken xdrmem_setpos(XDR *xdrs, u_int pos)
2266f60c4f9Shannken {
2276f60c4f9Shannken 	char *newaddr = xdrs->x_base + pos;
2286f60c4f9Shannken 	char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy;
2296f60c4f9Shannken 
2306f60c4f9Shannken 	if ((long)newaddr > (long)lastaddr)
2316f60c4f9Shannken 		return (FALSE);
2326f60c4f9Shannken 	xdrs->x_private = newaddr;
2336f60c4f9Shannken 	xdrs->x_handy = (int)((long)lastaddr - (long)newaddr);
2346f60c4f9Shannken 	return (TRUE);
2356f60c4f9Shannken }
2366f60c4f9Shannken 
2376f60c4f9Shannken static int32_t *
xdrmem_inline_aligned(XDR * xdrs,u_int len)2386f60c4f9Shannken xdrmem_inline_aligned(XDR *xdrs, u_int len)
2396f60c4f9Shannken {
2406f60c4f9Shannken 	int32_t *buf = 0;
2416f60c4f9Shannken 
2426f60c4f9Shannken 	if (xdrs->x_handy >= len) {
2436f60c4f9Shannken 		xdrs->x_handy -= len;
2446f60c4f9Shannken 		buf = (int32_t *)xdrs->x_private;
2456f60c4f9Shannken 		xdrs->x_private = (char *)xdrs->x_private + len;
2466f60c4f9Shannken 	}
2476f60c4f9Shannken 	return (buf);
2486f60c4f9Shannken }
2496f60c4f9Shannken 
2506f60c4f9Shannken /* ARGSUSED */
2516f60c4f9Shannken static int32_t *
xdrmem_inline_unaligned(XDR * xdrs,u_int len)2526f60c4f9Shannken xdrmem_inline_unaligned(XDR *xdrs, u_int len)
2536f60c4f9Shannken {
2546f60c4f9Shannken 
2556f60c4f9Shannken 	return (0);
2566f60c4f9Shannken }
2576f60c4f9Shannken 
2586f60c4f9Shannken static bool_t
xdrmem_control(XDR * xdrs,int request,void * info)2596f60c4f9Shannken xdrmem_control(XDR *xdrs, int request, void *info)
2606f60c4f9Shannken {
2616f60c4f9Shannken 	xdr_bytesrec *xptr;
2626f60c4f9Shannken 
2636f60c4f9Shannken 	switch (request) {
2646f60c4f9Shannken 
2656f60c4f9Shannken 	case XDR_GET_BYTES_AVAIL:
2666f60c4f9Shannken 		xptr = (xdr_bytesrec *)info;
2676f60c4f9Shannken 		xptr->xc_is_last_record = TRUE;
2686f60c4f9Shannken 		xptr->xc_num_avail = xdrs->x_handy;
2696f60c4f9Shannken 		return (TRUE);
2706f60c4f9Shannken 
2716f60c4f9Shannken 	}
2726f60c4f9Shannken 	return (FALSE);
2736f60c4f9Shannken }
274