1177633Sdfr/* $NetBSD: xdr_mem.c,v 1.15 2000/01/22 22:19:18 mycroft Exp $ */ 2177633Sdfr 3177633Sdfr/* 4177633Sdfr * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5177633Sdfr * unrestricted use provided that this legend is included on all tape 6177633Sdfr * media and as a part of the software program in whole or part. Users 7177633Sdfr * may copy or modify Sun RPC without charge, but are not authorized 8177633Sdfr * to license or distribute it to anyone else except as part of a product or 9177633Sdfr * program developed by the user. 10177633Sdfr * 11177633Sdfr * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12177633Sdfr * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13177633Sdfr * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14177633Sdfr * 15177633Sdfr * Sun RPC is provided with no support and without any obligation on the 16177633Sdfr * part of Sun Microsystems, Inc. to assist in its use, correction, 17177633Sdfr * modification or enhancement. 18177633Sdfr * 19177633Sdfr * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20177633Sdfr * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21177633Sdfr * OR ANY PART THEREOF. 22177633Sdfr * 23177633Sdfr * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24177633Sdfr * or profits or other special, indirect and consequential damages, even if 25177633Sdfr * Sun has been advised of the possibility of such damages. 26177633Sdfr * 27177633Sdfr * Sun Microsystems, Inc. 28177633Sdfr * 2550 Garcia Avenue 29177633Sdfr * Mountain View, California 94043 30177633Sdfr */ 31177633Sdfr 32177633Sdfr#if defined(LIBC_SCCS) && !defined(lint) 33177633Sdfrstatic char *sccsid2 = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; 34177633Sdfrstatic char *sccsid = "@(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC"; 35177633Sdfr#endif 36177633Sdfr#include <sys/cdefs.h> 37177633Sdfr__FBSDID("$FreeBSD$"); 38177633Sdfr 39177633Sdfr/* 40177633Sdfr * xdr_mem.h, XDR implementation using memory buffers. 41177633Sdfr * 42177633Sdfr * Copyright (C) 1984, Sun Microsystems, Inc. 43177633Sdfr * 44177633Sdfr * If you have some data to be interpreted as external data representation 45177633Sdfr * or to be converted to external data representation in a memory buffer, 46177633Sdfr * then this is the package for you. 47177633Sdfr * 48177633Sdfr */ 49177633Sdfr 50177633Sdfr#include <sys/param.h> 51177633Sdfr#include <sys/systm.h> 52177633Sdfr#include <sys/malloc.h> 53177633Sdfr 54177633Sdfr#include <rpc/types.h> 55177633Sdfr#include <rpc/xdr.h> 56177633Sdfr 57177633Sdfrstatic void xdrmem_destroy(XDR *); 58177633Sdfrstatic bool_t xdrmem_getlong_aligned(XDR *, long *); 59177633Sdfrstatic bool_t xdrmem_putlong_aligned(XDR *, const long *); 60177633Sdfrstatic bool_t xdrmem_getlong_unaligned(XDR *, long *); 61177633Sdfrstatic bool_t xdrmem_putlong_unaligned(XDR *, const long *); 62177633Sdfrstatic bool_t xdrmem_getbytes(XDR *, char *, u_int); 63177633Sdfrstatic bool_t xdrmem_putbytes(XDR *, const char *, u_int); 64177633Sdfr/* XXX: w/64-bit pointers, u_int not enough! */ 65177633Sdfrstatic u_int xdrmem_getpos(XDR *); 66177633Sdfrstatic bool_t xdrmem_setpos(XDR *, u_int); 67177633Sdfrstatic int32_t *xdrmem_inline_aligned(XDR *, u_int); 68177633Sdfrstatic int32_t *xdrmem_inline_unaligned(XDR *, u_int); 69192971Skmacystatic bool_t xdrmem_control(XDR *xdrs, int request, void *info); 70192971Skmacy 71177633Sdfrstatic const struct xdr_ops xdrmem_ops_aligned = { 72177633Sdfr xdrmem_getlong_aligned, 73177633Sdfr xdrmem_putlong_aligned, 74177633Sdfr xdrmem_getbytes, 75177633Sdfr xdrmem_putbytes, 76177633Sdfr xdrmem_getpos, 77177633Sdfr xdrmem_setpos, 78177633Sdfr xdrmem_inline_aligned, 79192971Skmacy xdrmem_destroy, 80192971Skmacy xdrmem_control 81177633Sdfr}; 82177633Sdfr 83177633Sdfrstatic const struct xdr_ops xdrmem_ops_unaligned = { 84177633Sdfr xdrmem_getlong_unaligned, 85177633Sdfr xdrmem_putlong_unaligned, 86177633Sdfr xdrmem_getbytes, 87177633Sdfr xdrmem_putbytes, 88177633Sdfr xdrmem_getpos, 89177633Sdfr xdrmem_setpos, 90177633Sdfr xdrmem_inline_unaligned, 91192971Skmacy xdrmem_destroy, 92192971Skmacy xdrmem_control 93177633Sdfr}; 94177633Sdfr 95177633Sdfr/* 96177633Sdfr * The procedure xdrmem_create initializes a stream descriptor for a 97177633Sdfr * memory buffer. 98177633Sdfr */ 99177633Sdfrvoid 100177633Sdfrxdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op) 101177633Sdfr{ 102177633Sdfr 103177633Sdfr xdrs->x_op = op; 104177633Sdfr xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1)) 105177633Sdfr ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned; 106177633Sdfr xdrs->x_private = xdrs->x_base = addr; 107177633Sdfr xdrs->x_handy = size; 108177633Sdfr} 109177633Sdfr 110177633Sdfr/*ARGSUSED*/ 111177633Sdfrstatic void 112177633Sdfrxdrmem_destroy(XDR *xdrs) 113177633Sdfr{ 114177633Sdfr 115177633Sdfr} 116177633Sdfr 117177633Sdfrstatic bool_t 118177633Sdfrxdrmem_getlong_aligned(XDR *xdrs, long *lp) 119177633Sdfr{ 120177633Sdfr 121177633Sdfr if (xdrs->x_handy < sizeof(int32_t)) 122177633Sdfr return (FALSE); 123177633Sdfr xdrs->x_handy -= sizeof(int32_t); 124177633Sdfr *lp = ntohl(*(u_int32_t *)xdrs->x_private); 125177633Sdfr xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 126177633Sdfr return (TRUE); 127177633Sdfr} 128177633Sdfr 129177633Sdfrstatic bool_t 130177633Sdfrxdrmem_putlong_aligned(XDR *xdrs, const long *lp) 131177633Sdfr{ 132177633Sdfr 133177633Sdfr if (xdrs->x_handy < sizeof(int32_t)) 134177633Sdfr return (FALSE); 135177633Sdfr xdrs->x_handy -= sizeof(int32_t); 136177633Sdfr *(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp); 137177633Sdfr xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 138177633Sdfr return (TRUE); 139177633Sdfr} 140177633Sdfr 141177633Sdfrstatic bool_t 142177633Sdfrxdrmem_getlong_unaligned(XDR *xdrs, long *lp) 143177633Sdfr{ 144177633Sdfr u_int32_t l; 145177633Sdfr 146177633Sdfr if (xdrs->x_handy < sizeof(int32_t)) 147177633Sdfr return (FALSE); 148177633Sdfr xdrs->x_handy -= sizeof(int32_t); 149177633Sdfr memmove(&l, xdrs->x_private, sizeof(int32_t)); 150177633Sdfr *lp = ntohl(l); 151177633Sdfr xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 152177633Sdfr return (TRUE); 153177633Sdfr} 154177633Sdfr 155177633Sdfrstatic bool_t 156177633Sdfrxdrmem_putlong_unaligned(XDR *xdrs, const long *lp) 157177633Sdfr{ 158177633Sdfr u_int32_t l; 159177633Sdfr 160177633Sdfr if (xdrs->x_handy < sizeof(int32_t)) 161177633Sdfr return (FALSE); 162177633Sdfr xdrs->x_handy -= sizeof(int32_t); 163177633Sdfr l = htonl((u_int32_t)*lp); 164177633Sdfr memmove(xdrs->x_private, &l, sizeof(int32_t)); 165177633Sdfr xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 166177633Sdfr return (TRUE); 167177633Sdfr} 168177633Sdfr 169177633Sdfrstatic bool_t 170177633Sdfrxdrmem_getbytes(XDR *xdrs, char *addr, u_int len) 171177633Sdfr{ 172177633Sdfr 173177633Sdfr if (xdrs->x_handy < len) 174177633Sdfr return (FALSE); 175177633Sdfr xdrs->x_handy -= len; 176177633Sdfr memmove(addr, xdrs->x_private, len); 177177633Sdfr xdrs->x_private = (char *)xdrs->x_private + len; 178177633Sdfr return (TRUE); 179177633Sdfr} 180177633Sdfr 181177633Sdfrstatic bool_t 182177633Sdfrxdrmem_putbytes(XDR *xdrs, const char *addr, u_int len) 183177633Sdfr{ 184177633Sdfr 185177633Sdfr if (xdrs->x_handy < len) 186177633Sdfr return (FALSE); 187177633Sdfr xdrs->x_handy -= len; 188177633Sdfr memmove(xdrs->x_private, addr, len); 189177633Sdfr xdrs->x_private = (char *)xdrs->x_private + len; 190177633Sdfr return (TRUE); 191177633Sdfr} 192177633Sdfr 193177633Sdfrstatic u_int 194177633Sdfrxdrmem_getpos(XDR *xdrs) 195177633Sdfr{ 196177633Sdfr 197177633Sdfr /* XXX w/64-bit pointers, u_int not enough! */ 198177633Sdfr return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base); 199177633Sdfr} 200177633Sdfr 201177633Sdfrstatic bool_t 202177633Sdfrxdrmem_setpos(XDR *xdrs, u_int pos) 203177633Sdfr{ 204177633Sdfr char *newaddr = xdrs->x_base + pos; 205177633Sdfr char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy; 206177633Sdfr 207177633Sdfr if (newaddr > lastaddr) 208177633Sdfr return (FALSE); 209177633Sdfr xdrs->x_private = newaddr; 210177633Sdfr xdrs->x_handy = (u_int)(lastaddr - newaddr); /* XXX sizeof(u_int) <? sizeof(ptrdiff_t) */ 211177633Sdfr return (TRUE); 212177633Sdfr} 213177633Sdfr 214177633Sdfrstatic int32_t * 215177633Sdfrxdrmem_inline_aligned(XDR *xdrs, u_int len) 216177633Sdfr{ 217177633Sdfr int32_t *buf = 0; 218177633Sdfr 219177633Sdfr if (xdrs->x_handy >= len) { 220177633Sdfr xdrs->x_handy -= len; 221177633Sdfr buf = (int32_t *)xdrs->x_private; 222177633Sdfr xdrs->x_private = (char *)xdrs->x_private + len; 223177633Sdfr } 224177633Sdfr return (buf); 225177633Sdfr} 226177633Sdfr 227177633Sdfr/* ARGSUSED */ 228177633Sdfrstatic int32_t * 229177633Sdfrxdrmem_inline_unaligned(XDR *xdrs, u_int len) 230177633Sdfr{ 231177633Sdfr 232177633Sdfr return (0); 233177633Sdfr} 234192971Skmacy 235192971Skmacystatic bool_t 236192971Skmacyxdrmem_control(XDR *xdrs, int request, void *info) 237192971Skmacy{ 238192971Skmacy xdr_bytesrec *xptr; 239192971Skmacy int32_t *l; 240192971Skmacy int len; 241192971Skmacy 242192971Skmacy switch (request) { 243192971Skmacy 244192971Skmacy case XDR_GET_BYTES_AVAIL: 245192971Skmacy xptr = (xdr_bytesrec *)info; 246192971Skmacy xptr->xc_is_last_record = TRUE; 247192971Skmacy xptr->xc_num_avail = xdrs->x_handy; 248192971Skmacy return (TRUE); 249192971Skmacy 250192971Skmacy case XDR_PEEK: 251192971Skmacy /* 252192971Skmacy * Return the next 4 byte unit in the XDR stream. 253192971Skmacy */ 254192971Skmacy if (xdrs->x_handy < sizeof (int32_t)) 255192971Skmacy return (FALSE); 256192971Skmacy l = (int32_t *)info; 257192971Skmacy *l = (int32_t)ntohl((uint32_t) 258192971Skmacy (*((int32_t *)(xdrs->x_private)))); 259192971Skmacy return (TRUE); 260192971Skmacy 261192971Skmacy case XDR_SKIPBYTES: 262192971Skmacy /* 263192971Skmacy * Skip the next N bytes in the XDR stream. 264192971Skmacy */ 265192971Skmacy l = (int32_t *)info; 266192971Skmacy len = RNDUP((int)(*l)); 267192971Skmacy if (xdrs->x_handy < len) 268192971Skmacy return (FALSE); 269192971Skmacy xdrs->x_handy -= len; 270192971Skmacy xdrs->x_private = (char *)xdrs->x_private + len; 271192971Skmacy return (TRUE); 272192971Skmacy 273192971Skmacy } 274192971Skmacy return (FALSE); 275192971Skmacy} 276