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(XDR *xdrs, long *longp) 47 { 48 xdrs->x_handy += BYTES_PER_XDR_UNIT; 49 return (TRUE); 50 } 51 52 /* ARGSUSED */ 53 static bool_t 54 x_putbytes(XDR *xdrs, char *bp, u_int len) 55 { 56 xdrs->x_handy += len; 57 58 return (TRUE); 59 } 60 61 static u_int 62 x_getpostn(XDR *xdrs) 63 { 64 return (xdrs->x_handy); 65 } 66 67 /* ARGSUSED */ 68 static bool_t 69 x_setpostn(XDR *xdrs, u_int pos) 70 { 71 /* This is not allowed */ 72 return (FALSE); 73 } 74 75 static rpc_inline_t * 76 x_inline(XDR *xdrs, int len) 77 { 78 if (len == 0) { 79 return (NULL); 80 } 81 if (xdrs->x_op != XDR_ENCODE) { 82 return (NULL); 83 } 84 if (len < (int) ((caddr_t) xdrs->x_private - xdrs->x_base)) { 85 /* x_private was already allocated */ 86 xdrs->x_handy += len; 87 return ((rpc_inline_t *) xdrs->x_private); 88 } else { 89 /* Free the earlier space and allocate new area */ 90 if (xdrs->x_base) 91 free(xdrs->x_base); 92 if ((xdrs->x_base = (caddr_t) malloc(len)) == NULL) { 93 xdrs->x_private = NULL; 94 return (NULL); 95 } 96 xdrs->x_private = xdrs->x_base + len; 97 xdrs->x_handy += len; 98 return ((rpc_inline_t *) (void *) xdrs->x_base); 99 } 100 } 101 102 static int 103 harmless(void) 104 { 105 /* Always return FALSE/NULL, as the case may be */ 106 return (0); 107 } 108 109 static void 110 x_destroy(XDR *xdrs) 111 { 112 xdrs->x_handy = 0; 113 xdrs->x_private = NULL; 114 if (xdrs->x_base) { 115 free(xdrs->x_base); 116 xdrs->x_base = NULL; 117 } 118 return; 119 } 120 121 unsigned long 122 xdr_sizeof(xdrproc_t func, void *data) 123 { 124 XDR x; 125 struct xdr_ops ops; 126 bool_t stat; 127 /* to stop ANSI-C compiler from complaining */ 128 typedef bool_t (* dummyfunc1)(XDR *, long *); 129 typedef bool_t (* dummyfunc2)(XDR *, caddr_t, u_int); 130 131 ops.x_putlong = x_putlong; 132 ops.x_putbytes = x_putbytes; 133 ops.x_inline = x_inline; 134 ops.x_getpostn = x_getpostn; 135 ops.x_setpostn = x_setpostn; 136 ops.x_destroy = x_destroy; 137 138 /* the other harmless ones */ 139 ops.x_getlong = (dummyfunc1) harmless; 140 ops.x_getbytes = (dummyfunc2) harmless; 141 142 x.x_op = XDR_ENCODE; 143 x.x_ops = &ops; 144 x.x_handy = 0; 145 x.x_private = (caddr_t) NULL; 146 x.x_base = (caddr_t) 0; 147 148 stat = func(&x, data); 149 if (x.x_base) 150 free(x.x_base); 151 return (stat == TRUE ? (unsigned) x.x_handy: 0); 152 } 153