1/* 2 * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* $NetBSD: xdr_mem.c,v 1.15 2000/01/22 22:19:18 mycroft Exp $ */ 25 26/* 27 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 28 * unrestricted use provided that this legend is included on all tape 29 * media and as a part of the software program in whole or part. Users 30 * may copy or modify Sun RPC without charge, but are not authorized 31 * to license or distribute it to anyone else except as part of a product or 32 * program developed by the user. 33 * 34 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 35 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 36 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 37 * 38 * Sun RPC is provided with no support and without any obligation on the 39 * part of Sun Microsystems, Inc. to assist in its use, correction, 40 * modification or enhancement. 41 * 42 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 43 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 44 * OR ANY PART THEREOF. 45 * 46 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 47 * or profits or other special, indirect and consequential damages, even if 48 * Sun has been advised of the possibility of such damages. 49 * 50 * Sun Microsystems, Inc. 51 * 2550 Garcia Avenue 52 * Mountain View, California 94043 53 */ 54 55#if defined(LIBC_SCCS) && !defined(lint) 56static char *sccsid = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; 57static char *sccsid = "@(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC"; 58#endif 59#include <sys/cdefs.h> 60 61/* 62 * xdr_mem.h, XDR implementation using memory buffers. 63 * 64 * Copyright (C) 1984, Sun Microsystems, Inc. 65 * 66 * If you have some data to be interpreted as external data representation 67 * or to be converted to external data representation in a memory buffer, 68 * then this is the package for you. 69 * 70 */ 71 72#include <sys/types.h> 73 74#include <netinet/in.h> 75 76#include <string.h> 77 78#include "sec_xdr.h" 79 80static void sec_xdrmem_destroy(XDR *); 81 82#ifdef __LP64__ 83#define long_callback_ptr_t int * 84#else 85#define long_callback_ptr_t long * 86#endif 87static bool_t sec_xdrmem_getlong_aligned(XDR *, long_callback_ptr_t); 88static bool_t sec_xdrmem_putlong_aligned(XDR *, const long_callback_ptr_t); 89static bool_t sec_xdrmem_getlong_unaligned(XDR *, long_callback_ptr_t); 90static bool_t sec_xdrmem_putlong_unaligned(XDR *, const long_callback_ptr_t); 91 92static bool_t sec_xdrmem_getbytes(XDR *, char *, u_int); 93static bool_t sec_xdrmem_putbytes(XDR *, const char *, u_int); 94/* XXX: w/64-bit pointers, u_int not enough! */ 95static u_int sec_xdrmem_getpos(XDR *); 96static bool_t sec_xdrmem_setpos(XDR *, u_int); 97static int32_t *sec_xdrmem_inline_aligned(XDR *, u_int); 98static int32_t *sec_xdrmem_inline_unaligned(XDR *, u_int); 99 100static const struct xdr_ops sec_xdrmem_ops_aligned = { 101 sec_xdrmem_getlong_aligned, 102 sec_xdrmem_putlong_aligned, 103 sec_xdrmem_getbytes, 104 sec_xdrmem_putbytes, 105 sec_xdrmem_getpos, 106 sec_xdrmem_setpos, 107 sec_xdrmem_inline_aligned, 108 sec_xdrmem_destroy 109}; 110 111static const struct xdr_ops sec_xdrmem_ops_unaligned = { 112 sec_xdrmem_getlong_unaligned, 113 sec_xdrmem_putlong_unaligned, 114 sec_xdrmem_getbytes, 115 sec_xdrmem_putbytes, 116 sec_xdrmem_getpos, 117 sec_xdrmem_setpos, 118 sec_xdrmem_inline_unaligned, 119 sec_xdrmem_destroy 120}; 121 122/* 123 * The procedure sec_xdrmem_create initializes a stream descriptor for a 124 * memory buffer. 125 */ 126void 127sec_xdrmem_create(xdrs, addr, size, op) 128 XDR *xdrs; 129 char *addr; 130 u_int size; 131 enum xdr_op op; 132{ 133 xdrs->x_op = op; 134 xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1)) 135 ? &sec_xdrmem_ops_unaligned : &sec_xdrmem_ops_aligned; 136 xdrs->x_private = xdrs->x_base = addr; 137 xdrs->x_public = NULL; 138 xdrs->x_handy = size; 139} 140 141/*ARGSUSED*/ 142static void 143sec_xdrmem_destroy(xdrs) 144 XDR *xdrs; 145{ 146 147} 148 149static bool_t 150sec_xdrmem_getlong_aligned(xdrs, lp) 151 XDR *xdrs; 152 long_callback_ptr_t lp; 153{ 154 if (xdrs->x_handy < sizeof(int32_t)) 155 return (FALSE); 156 xdrs->x_handy -= sizeof(int32_t); 157 if (lp) *lp = ntohl(*(u_int32_t *)xdrs->x_private); 158 xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 159 return (TRUE); 160} 161 162static bool_t 163sec_xdrmem_putlong_aligned(xdrs, lp) 164 XDR *xdrs; 165 const long_callback_ptr_t lp; 166{ 167 if (xdrs->x_handy < sizeof(int32_t)) 168 return (FALSE); 169 xdrs->x_handy -= sizeof(int32_t); 170 if (lp) *(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp); 171 xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 172 return (TRUE); 173} 174 175static bool_t 176sec_xdrmem_getlong_unaligned(xdrs, lp) 177 XDR *xdrs; 178 long_callback_ptr_t lp; 179{ 180 u_int32_t l; 181 182 if (xdrs->x_handy < sizeof(int32_t)) 183 return (FALSE); 184 xdrs->x_handy -= sizeof(int32_t); 185 memmove(&l, xdrs->x_private, sizeof(int32_t)); 186 if (lp) *lp = ntohl(l); 187 xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 188 return (TRUE); 189} 190 191static bool_t 192sec_xdrmem_putlong_unaligned(xdrs, lp) 193 XDR *xdrs; 194 const long_callback_ptr_t lp; 195{ 196 u_int32_t l = 0; 197 198 if (xdrs->x_handy < sizeof(int32_t)) 199 return (FALSE); 200 xdrs->x_handy -= sizeof(int32_t); 201 if (lp) l = htonl((u_int32_t)*lp); 202 memmove(xdrs->x_private, &l, sizeof(int32_t)); 203 xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); 204 return (TRUE); 205} 206 207static bool_t 208sec_xdrmem_getbytes(xdrs, addr, len) 209 XDR *xdrs; 210 char *addr; 211 u_int len; 212{ 213 if (xdrs->x_handy < len) 214 return (FALSE); 215 xdrs->x_handy -= len; 216 if (addr) memmove(addr, xdrs->x_private, len); 217 xdrs->x_private = (char *)xdrs->x_private + len; 218 return (TRUE); 219} 220 221static bool_t 222sec_xdrmem_putbytes(xdrs, addr, len) 223 XDR *xdrs; 224 const char *addr; 225 u_int len; 226{ 227 if (xdrs->x_handy < len) 228 return (FALSE); 229 xdrs->x_handy -= len; 230 if (addr) memmove(xdrs->x_private, addr, len); 231 xdrs->x_private = (char *)xdrs->x_private + len; 232 return (TRUE); 233} 234 235static u_int 236sec_xdrmem_getpos(xdrs) 237 XDR *xdrs; 238{ 239 /* XXX w/64-bit pointers, u_int not enough! */ 240 return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base); 241} 242 243static bool_t 244sec_xdrmem_setpos(xdrs, pos) 245 XDR *xdrs; 246 u_int pos; 247{ 248 char *newaddr = xdrs->x_base + pos; 249 char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy; 250 251 if (newaddr > lastaddr) 252 return (FALSE); 253 xdrs->x_private = newaddr; 254 xdrs->x_handy = (u_int)(lastaddr - newaddr); /* XXX sizeof(u_int) <? sizeof(ptrdiff_t) */ 255 return (TRUE); 256} 257 258static int32_t * 259sec_xdrmem_inline_aligned(xdrs, len) 260 XDR *xdrs; 261 u_int len; 262{ 263 int32_t *buf = 0; 264 265 if (xdrs->x_handy >= len) { 266 xdrs->x_handy -= len; 267 buf = (int32_t *)xdrs->x_private; 268 xdrs->x_private = (char *)xdrs->x_private + len; 269 } 270 return (buf); 271} 272 273/* ARGSUSED */ 274static int32_t * 275sec_xdrmem_inline_unaligned(xdrs, len) 276 XDR *xdrs; 277 u_int len; 278{ 279 return (0); 280} 281 282/** 283 * This is almost a straight copy of the standard implementation, except 284 * that all calls made that move memory don't do so if passed a NULL dest. 285 * getbytes in particular when called from xdr_bytes during sizing of a decode 286 * needs this. 287 */ 288