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