1 1.2 hannken /* $NetBSD: xdr_mem.c,v 1.2 2019/06/05 16:25:43 hannken Exp $ */ 2 1.1 hannken 3 1.1 hannken /* 4 1.1 hannken * Copyright (c) 2010, Oracle America, Inc. 5 1.1 hannken * 6 1.1 hannken * Redistribution and use in source and binary forms, with or without 7 1.1 hannken * modification, are permitted provided that the following conditions are 8 1.1 hannken * met: 9 1.1 hannken * 10 1.1 hannken * * Redistributions of source code must retain the above copyright 11 1.1 hannken * notice, this list of conditions and the following disclaimer. 12 1.1 hannken * * Redistributions in binary form must reproduce the above 13 1.1 hannken * copyright notice, this list of conditions and the following 14 1.1 hannken * disclaimer in the documentation and/or other materials 15 1.1 hannken * provided with the distribution. 16 1.1 hannken * * Neither the name of the "Oracle America, Inc." nor the names of its 17 1.1 hannken * contributors may be used to endorse or promote products derived 18 1.1 hannken * from this software without specific prior written permission. 19 1.1 hannken * 20 1.1 hannken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 1.1 hannken * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 1.1 hannken * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 1.1 hannken * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 1.1 hannken * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 1.1 hannken * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 1.1 hannken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27 1.1 hannken * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 hannken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 1.1 hannken * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 1.1 hannken * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 1.1 hannken * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 hannken */ 33 1.1 hannken 34 1.1 hannken #include <sys/cdefs.h> 35 1.1 hannken #if defined(LIBC_SCCS) && !defined(lint) 36 1.1 hannken #if 0 37 1.1 hannken static char *sccsid = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; 38 1.1 hannken static char *sccsid = "@(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC"; 39 1.1 hannken #else 40 1.2 hannken __RCSID("$NetBSD: xdr_mem.c,v 1.2 2019/06/05 16:25:43 hannken Exp $"); 41 1.1 hannken #endif 42 1.1 hannken #endif 43 1.1 hannken 44 1.1 hannken /* 45 1.1 hannken * xdr_mem.h, XDR implementation using memory buffers. 46 1.1 hannken * 47 1.1 hannken * Copyright (C) 1984, Sun Microsystems, Inc. 48 1.1 hannken * 49 1.1 hannken * If you have some data to be interpreted as external data representation 50 1.1 hannken * or to be converted to external data representation in a memory buffer, 51 1.1 hannken * then this is the package for you. 52 1.1 hannken * 53 1.1 hannken */ 54 1.1 hannken 55 1.2 hannken #if defined(_KERNEL) || defined(_STANDALONE) 56 1.2 hannken 57 1.2 hannken #include <lib/libkern/libkern.h> 58 1.2 hannken #include <rpc/types.h> 59 1.2 hannken #include <rpc/xdr.h> 60 1.2 hannken 61 1.2 hannken #else /* _KERNEL || _STANDALONE */ 62 1.2 hannken 63 1.1 hannken #include "namespace.h" 64 1.1 hannken 65 1.1 hannken #include <sys/types.h> 66 1.1 hannken 67 1.1 hannken #include <netinet/in.h> 68 1.1 hannken 69 1.1 hannken #include <string.h> 70 1.1 hannken 71 1.1 hannken #include <rpc/types.h> 72 1.1 hannken #include <rpc/xdr.h> 73 1.1 hannken 74 1.1 hannken #ifdef __weak_alias 75 1.1 hannken __weak_alias(xdrmem_create,_xdrmem_create) 76 1.1 hannken #endif 77 1.1 hannken 78 1.2 hannken #endif /* _KERNEL || _STANDALONE */ 79 1.2 hannken 80 1.1 hannken static void xdrmem_destroy(XDR *); 81 1.1 hannken static bool_t xdrmem_getlong_aligned(XDR *, long *); 82 1.1 hannken static bool_t xdrmem_putlong_aligned(XDR *, const long *); 83 1.1 hannken static bool_t xdrmem_getlong_unaligned(XDR *, long *); 84 1.1 hannken static bool_t xdrmem_putlong_unaligned(XDR *, const long *); 85 1.1 hannken static bool_t xdrmem_getbytes(XDR *, char *, u_int); 86 1.1 hannken static bool_t xdrmem_putbytes(XDR *, const char *, u_int); 87 1.1 hannken /* XXX: w/64-bit pointers, u_int not enough! */ 88 1.1 hannken static u_int xdrmem_getpos(XDR *); 89 1.1 hannken static bool_t xdrmem_setpos(XDR *, u_int); 90 1.1 hannken static int32_t *xdrmem_inline_aligned(XDR *, u_int); 91 1.1 hannken static int32_t *xdrmem_inline_unaligned(XDR *, u_int); 92 1.1 hannken static bool_t xdrmem_control(XDR *xdrs, int request, void *info); 93 1.1 hannken 94 1.1 hannken static const struct xdr_ops xdrmem_ops_aligned = { 95 1.1 hannken xdrmem_getlong_aligned, 96 1.1 hannken xdrmem_putlong_aligned, 97 1.1 hannken xdrmem_getbytes, 98 1.1 hannken xdrmem_putbytes, 99 1.1 hannken xdrmem_getpos, 100 1.1 hannken xdrmem_setpos, 101 1.1 hannken xdrmem_inline_aligned, 102 1.1 hannken xdrmem_destroy, 103 1.1 hannken xdrmem_control 104 1.1 hannken }; 105 1.1 hannken 106 1.1 hannken static const struct xdr_ops xdrmem_ops_unaligned = { 107 1.1 hannken xdrmem_getlong_unaligned, 108 1.1 hannken xdrmem_putlong_unaligned, 109 1.1 hannken xdrmem_getbytes, 110 1.1 hannken xdrmem_putbytes, 111 1.1 hannken xdrmem_getpos, 112 1.1 hannken xdrmem_setpos, 113 1.1 hannken xdrmem_inline_unaligned, 114 1.1 hannken xdrmem_destroy, 115 1.1 hannken xdrmem_control 116 1.1 hannken }; 117 1.1 hannken 118 1.1 hannken /* 119 1.1 hannken * The procedure xdrmem_create initializes a stream descriptor for a 120 1.1 hannken * memory buffer. 121 1.1 hannken */ 122 1.1 hannken void 123 1.1 hannken xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op) 124 1.1 hannken { 125 1.1 hannken 126 1.1 hannken xdrs->x_op = op; 127 1.1 hannken xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1)) 128 1.1 hannken ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned; 129 1.1 hannken xdrs->x_private = xdrs->x_base = addr; 130 1.1 hannken xdrs->x_handy = size; 131 1.1 hannken } 132 1.1 hannken 133 1.1 hannken /*ARGSUSED*/ 134 1.1 hannken static void 135 1.1 hannken xdrmem_destroy(XDR *xdrs) 136 1.1 hannken { 137 1.1 hannken 138 1.1 hannken } 139 1.1 hannken 140 1.1 hannken static bool_t 141 1.1 hannken xdrmem_getlong_aligned(XDR *xdrs, long *lp) 142 1.1 hannken { 143 1.1 hannken 144 1.1 hannken if (xdrs->x_handy < sizeof(int32_t)) 145 1.1 hannken return (FALSE); 146 1.1 hannken xdrs->x_handy -= sizeof(int32_t); 147 1.1 hannken *lp = ntohl(*(u_int32_t *)xdrs->x_private); 148 1.1 hannken xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 149 1.1 hannken return (TRUE); 150 1.1 hannken } 151 1.1 hannken 152 1.1 hannken static bool_t 153 1.1 hannken xdrmem_putlong_aligned(XDR *xdrs, const long *lp) 154 1.1 hannken { 155 1.1 hannken 156 1.1 hannken if (xdrs->x_handy < sizeof(int32_t)) 157 1.1 hannken return (FALSE); 158 1.1 hannken xdrs->x_handy -= sizeof(int32_t); 159 1.1 hannken *(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp); 160 1.1 hannken xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 161 1.1 hannken return (TRUE); 162 1.1 hannken } 163 1.1 hannken 164 1.1 hannken static bool_t 165 1.1 hannken xdrmem_getlong_unaligned(XDR *xdrs, long *lp) 166 1.1 hannken { 167 1.1 hannken u_int32_t l; 168 1.1 hannken 169 1.1 hannken if (xdrs->x_handy < sizeof(int32_t)) 170 1.1 hannken return (FALSE); 171 1.1 hannken xdrs->x_handy -= sizeof(int32_t); 172 1.1 hannken memmove(&l, xdrs->x_private, sizeof(int32_t)); 173 1.1 hannken *lp = ntohl(l); 174 1.1 hannken xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 175 1.1 hannken return (TRUE); 176 1.1 hannken } 177 1.1 hannken 178 1.1 hannken static bool_t 179 1.1 hannken xdrmem_putlong_unaligned(XDR *xdrs, const long *lp) 180 1.1 hannken { 181 1.1 hannken u_int32_t l; 182 1.1 hannken 183 1.1 hannken if (xdrs->x_handy < sizeof(int32_t)) 184 1.1 hannken return (FALSE); 185 1.1 hannken xdrs->x_handy -= sizeof(int32_t); 186 1.1 hannken l = htonl((u_int32_t)*lp); 187 1.1 hannken memmove(xdrs->x_private, &l, sizeof(int32_t)); 188 1.1 hannken xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 189 1.1 hannken return (TRUE); 190 1.1 hannken } 191 1.1 hannken 192 1.1 hannken static bool_t 193 1.1 hannken xdrmem_getbytes(XDR *xdrs, char *addr, u_int len) 194 1.1 hannken { 195 1.1 hannken 196 1.1 hannken if (xdrs->x_handy < len) 197 1.1 hannken return (FALSE); 198 1.1 hannken xdrs->x_handy -= len; 199 1.1 hannken memmove(addr, xdrs->x_private, len); 200 1.1 hannken xdrs->x_private = (char *)xdrs->x_private + len; 201 1.1 hannken return (TRUE); 202 1.1 hannken } 203 1.1 hannken 204 1.1 hannken static bool_t 205 1.1 hannken xdrmem_putbytes(XDR *xdrs, const char *addr, u_int len) 206 1.1 hannken { 207 1.1 hannken 208 1.1 hannken if (xdrs->x_handy < len) 209 1.1 hannken return (FALSE); 210 1.1 hannken xdrs->x_handy -= len; 211 1.1 hannken memmove(xdrs->x_private, addr, len); 212 1.1 hannken xdrs->x_private = (char *)xdrs->x_private + len; 213 1.1 hannken return (TRUE); 214 1.1 hannken } 215 1.1 hannken 216 1.1 hannken static u_int 217 1.1 hannken xdrmem_getpos(XDR *xdrs) 218 1.1 hannken { 219 1.1 hannken 220 1.1 hannken /* XXX w/64-bit pointers, u_int not enough! */ 221 1.1 hannken return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base); 222 1.1 hannken } 223 1.1 hannken 224 1.1 hannken static bool_t 225 1.1 hannken xdrmem_setpos(XDR *xdrs, u_int pos) 226 1.1 hannken { 227 1.1 hannken char *newaddr = xdrs->x_base + pos; 228 1.1 hannken char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy; 229 1.1 hannken 230 1.1 hannken if ((long)newaddr > (long)lastaddr) 231 1.1 hannken return (FALSE); 232 1.1 hannken xdrs->x_private = newaddr; 233 1.1 hannken xdrs->x_handy = (int)((long)lastaddr - (long)newaddr); 234 1.1 hannken return (TRUE); 235 1.1 hannken } 236 1.1 hannken 237 1.1 hannken static int32_t * 238 1.1 hannken xdrmem_inline_aligned(XDR *xdrs, u_int len) 239 1.1 hannken { 240 1.1 hannken int32_t *buf = 0; 241 1.1 hannken 242 1.1 hannken if (xdrs->x_handy >= len) { 243 1.1 hannken xdrs->x_handy -= len; 244 1.1 hannken buf = (int32_t *)xdrs->x_private; 245 1.1 hannken xdrs->x_private = (char *)xdrs->x_private + len; 246 1.1 hannken } 247 1.1 hannken return (buf); 248 1.1 hannken } 249 1.1 hannken 250 1.1 hannken /* ARGSUSED */ 251 1.1 hannken static int32_t * 252 1.1 hannken xdrmem_inline_unaligned(XDR *xdrs, u_int len) 253 1.1 hannken { 254 1.1 hannken 255 1.1 hannken return (0); 256 1.1 hannken } 257 1.1 hannken 258 1.1 hannken static bool_t 259 1.1 hannken xdrmem_control(XDR *xdrs, int request, void *info) 260 1.1 hannken { 261 1.1 hannken xdr_bytesrec *xptr; 262 1.1 hannken 263 1.1 hannken switch (request) { 264 1.1 hannken 265 1.1 hannken case XDR_GET_BYTES_AVAIL: 266 1.1 hannken xptr = (xdr_bytesrec *)info; 267 1.1 hannken xptr->xc_is_last_record = TRUE; 268 1.1 hannken xptr->xc_num_avail = xdrs->x_handy; 269 1.1 hannken return (TRUE); 270 1.1 hannken 271 1.1 hannken } 272 1.1 hannken return (FALSE); 273 1.1 hannken } 274