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