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
xdrmem_create(xdrs,addr,size,op)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
xdrmem_destroy(xdrs)110 xdrmem_destroy(xdrs)
111 XDR *xdrs;
112 {
113
114 }
115
116 static bool_t
xdrmem_getlong_aligned(xdrs,lp)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
xdrmem_putlong_aligned(xdrs,lp)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
xdrmem_getlong_unaligned(xdrs,lp)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
xdrmem_putlong_unaligned(xdrs,lp)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
xdrmem_getbytes(xdrs,addr,len)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
xdrmem_putbytes(xdrs,addr,len)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
xdrmem_getpos(xdrs)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
xdrmem_setpos(xdrs,pos)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 *
xdrmem_inline_aligned(xdrs,len)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 *
xdrmem_inline_unaligned(xdrs,len)247 xdrmem_inline_unaligned(xdrs, len)
248 XDR *xdrs;
249 u_int len;
250 {
251
252 return (0);
253 }
254