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