1 /* @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC */ 2 /* 3 * Copyright (c) 2010, Oracle America, Inc. 4 * 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * * Neither the name of the "Oracle America, Inc." nor the names of 19 * its contributors may be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 23 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 28 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 #if !defined(lint) && defined(SCCSIDS) 35 static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; 36 #endif 37 38 /* 39 * xdr_mem.h, XDR implementation using memory buffers. 40 * 41 * If you have some data to be interpreted as external data representation 42 * or to be converted to external data representation in a memory buffer, 43 * then this is the package for you. 44 * 45 */ 46 47 48 #include <gssrpc/types.h> 49 #include <gssrpc/xdr.h> 50 #include <netinet/in.h> 51 #include <stdio.h> 52 #include <string.h> 53 #include <limits.h> 54 55 static bool_t xdrmem_getlong(XDR *, long *); 56 static bool_t xdrmem_putlong(XDR *, long *); 57 static bool_t xdrmem_getbytes(XDR *, caddr_t, u_int); 58 static bool_t xdrmem_putbytes(XDR *, caddr_t, u_int); 59 static u_int xdrmem_getpos(XDR *); 60 static bool_t xdrmem_setpos(XDR *, u_int); 61 static rpc_inline_t * xdrmem_inline(XDR *, int); 62 static void xdrmem_destroy(XDR *); 63 64 static struct xdr_ops xdrmem_ops = { 65 xdrmem_getlong, 66 xdrmem_putlong, 67 xdrmem_getbytes, 68 xdrmem_putbytes, 69 xdrmem_getpos, 70 xdrmem_setpos, 71 xdrmem_inline, 72 xdrmem_destroy 73 }; 74 75 /* 76 * The procedure xdrmem_create initializes a stream descriptor for a 77 * memory buffer. 78 */ 79 void 80 xdrmem_create( 81 XDR *xdrs, 82 caddr_t addr, 83 u_int size, 84 enum xdr_op op) 85 { 86 87 xdrs->x_op = op; 88 xdrs->x_ops = &xdrmem_ops; 89 xdrs->x_private = xdrs->x_base = addr; 90 xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */ 91 } 92 93 static void 94 xdrmem_destroy(XDR *xdrs) 95 { 96 } 97 98 static bool_t 99 xdrmem_getlong(XDR *xdrs, long *lp) 100 { 101 102 if (xdrs->x_handy < BYTES_PER_XDR_UNIT) 103 return (FALSE); 104 else 105 xdrs->x_handy -= BYTES_PER_XDR_UNIT; 106 *lp = (long)(int32_t)ntohl(*((uint32_t *)(xdrs->x_private))); 107 xdrs->x_private = (char *)xdrs->x_private + BYTES_PER_XDR_UNIT; 108 return (TRUE); 109 } 110 111 static bool_t 112 xdrmem_putlong(XDR *xdrs, long *lp) 113 { 114 115 if (xdrs->x_handy < BYTES_PER_XDR_UNIT) 116 return (FALSE); 117 else 118 xdrs->x_handy -= BYTES_PER_XDR_UNIT; 119 *(int32_t *)xdrs->x_private = (int32_t)htonl((uint32_t)(*lp)); 120 xdrs->x_private = (char *)xdrs->x_private + BYTES_PER_XDR_UNIT; 121 return (TRUE); 122 } 123 124 static bool_t 125 xdrmem_getbytes(XDR *xdrs, caddr_t addr, u_int len) 126 { 127 128 if ((u_int)xdrs->x_handy < len) 129 return (FALSE); 130 else 131 xdrs->x_handy -= len; 132 memmove(addr, xdrs->x_private, len); 133 xdrs->x_private = (char *)xdrs->x_private + len; 134 return (TRUE); 135 } 136 137 static bool_t 138 xdrmem_putbytes(XDR *xdrs, caddr_t addr, u_int len) 139 { 140 141 if ((u_int)xdrs->x_handy < len) 142 return (FALSE); 143 else 144 xdrs->x_handy -= len; 145 memmove(xdrs->x_private, addr, len); 146 xdrs->x_private = (char *)xdrs->x_private + len; 147 return (TRUE); 148 } 149 150 static u_int 151 xdrmem_getpos(XDR *xdrs) 152 { 153 /* 154 * 11/3/95 - JRG - Rather than recast everything for 64 bit, just convert 155 * pointers to longs, then cast to int. 156 */ 157 return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base); 158 } 159 160 static bool_t 161 xdrmem_setpos(XDR *xdrs, u_int pos) 162 { 163 caddr_t newaddr = xdrs->x_base + pos; 164 caddr_t lastaddr = (char *)xdrs->x_private + xdrs->x_handy; 165 166 if ((long)newaddr > (long)lastaddr) 167 return (FALSE); 168 xdrs->x_private = newaddr; 169 xdrs->x_handy = (int)((long)lastaddr - (long)newaddr); 170 return (TRUE); 171 } 172 173 static rpc_inline_t * 174 xdrmem_inline(XDR *xdrs, int len) 175 { 176 rpc_inline_t *buf = 0; 177 178 if (len >= 0 && xdrs->x_handy >= len) { 179 xdrs->x_handy -= len; 180 buf = (rpc_inline_t *) xdrs->x_private; 181 xdrs->x_private = (char *)xdrs->x_private + len; 182 } 183 return (buf); 184 } 185