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
x_putlong(XDR * xdrs,long * longp)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
x_putbytes(XDR * xdrs,char * bp,u_int len)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
x_getpostn(XDR * xdrs)62 x_getpostn(XDR *xdrs)
63 {
64 return (xdrs->x_handy);
65 }
66
67 /* ARGSUSED */
68 static bool_t
x_setpostn(XDR * xdrs,u_int pos)69 x_setpostn(XDR *xdrs, u_int pos)
70 {
71 /* This is not allowed */
72 return (FALSE);
73 }
74
75 static rpc_inline_t *
x_inline(XDR * xdrs,int len)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
harmless(void)103 harmless(void)
104 {
105 /* Always return FALSE/NULL, as the case may be */
106 return (0);
107 }
108
109 static void
x_destroy(XDR * xdrs)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
xdr_sizeof(xdrproc_t func,void * data)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