1 /* 2 * Copyright (c) 2010, Oracle America, Inc. 3 * 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * * Neither the name of the "Oracle America, Inc." nor the names of 18 * its contributors may be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 /* 34 * xdr_sizeof.c 35 * 36 * General purpose routine to see how much space something will use 37 * when serialized using XDR. 38 */ 39 40 #include <gssrpc/types.h> 41 #include <gssrpc/xdr.h> 42 #include <sys/types.h> 43 44 /* ARGSUSED */ 45 static bool_t 46 x_putlong(xdrs, longp) 47 XDR *xdrs; 48 long *longp; 49 { 50 xdrs->x_handy += BYTES_PER_XDR_UNIT; 51 return (TRUE); 52 } 53 54 /* ARGSUSED */ 55 static bool_t 56 x_putbytes(xdrs, bp, len) 57 XDR *xdrs; 58 char *bp; 59 int len; 60 { 61 xdrs->x_handy += len; 62 63 return (TRUE); 64 } 65 66 static u_int 67 x_getpostn(xdrs) 68 XDR *xdrs; 69 { 70 return (xdrs->x_handy); 71 } 72 73 /* ARGSUSED */ 74 static bool_t 75 x_setpostn(xdrs, pos) 76 XDR *xdrs; 77 u_int pos; 78 { 79 /* This is not allowed */ 80 return (FALSE); 81 } 82 83 static rpc_inline_t * 84 x_inline(xdrs, len) 85 XDR *xdrs; 86 int len; 87 { 88 if (len == 0) { 89 return (NULL); 90 } 91 if (xdrs->x_op != XDR_ENCODE) { 92 return (NULL); 93 } 94 if (len < (int) ((caddr_t) xdrs->x_private - xdrs->x_base)) { 95 /* x_private was already allocated */ 96 xdrs->x_handy += len; 97 return ((rpc_inline_t *) xdrs->x_private); 98 } else { 99 /* Free the earlier space and allocate new area */ 100 if (xdrs->x_base) 101 free(xdrs->x_base); 102 if ((xdrs->x_base = (caddr_t) malloc(len)) == NULL) { 103 xdrs->x_private = NULL; 104 return (NULL); 105 } 106 xdrs->x_private = xdrs->x_base + len; 107 xdrs->x_handy += len; 108 return ((rpc_inline_t *) (void *) xdrs->x_base); 109 } 110 } 111 112 static int 113 harmless() 114 { 115 /* Always return FALSE/NULL, as the case may be */ 116 return (0); 117 } 118 119 static void 120 x_destroy(xdrs) 121 XDR *xdrs; 122 { 123 xdrs->x_handy = 0; 124 xdrs->x_private = NULL; 125 if (xdrs->x_base) { 126 free(xdrs->x_base); 127 xdrs->x_base = NULL; 128 } 129 return; 130 } 131 132 unsigned long 133 xdr_sizeof(func, data) 134 xdrproc_t func; 135 void *data; 136 { 137 XDR x; 138 struct xdr_ops ops; 139 bool_t stat; 140 /* to stop ANSI-C compiler from complaining */ 141 typedef bool_t (* dummyfunc1)(XDR *, long *); 142 typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int); 143 144 ops.x_putlong = x_putlong; 145 ops.x_putbytes = x_putbytes; 146 ops.x_inline = x_inline; 147 ops.x_getpostn = x_getpostn; 148 ops.x_setpostn = x_setpostn; 149 ops.x_destroy = x_destroy; 150 151 /* the other harmless ones */ 152 ops.x_getlong = (dummyfunc1) harmless; 153 ops.x_getbytes = (dummyfunc2) harmless; 154 155 x.x_op = XDR_ENCODE; 156 x.x_ops = &ops; 157 x.x_handy = 0; 158 x.x_private = (caddr_t) NULL; 159 x.x_base = (caddr_t) 0; 160 161 stat = func(&x, data); 162 if (x.x_base) 163 free(x.x_base); 164 return (stat == TRUE ? (unsigned) x.x_handy: 0); 165 } 166