1 /*
2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
8 *
9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12 *
13 * Sun RPC is provided with no support and without any obligation on the
14 * part of Sun Microsystems, Inc. to assist in its use, correction,
15 * modification or enhancement.
16 *
17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19 * OR ANY PART THEREOF.
20 *
21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22 * or profits or other special, indirect and consequential damages, even if
23 * Sun has been advised of the possibility of such damages.
24 *
25 * Sun Microsystems, Inc.
26 * 2550 Garcia Avenue
27 * Mountain View, California 94043
28 */
29
30 /*
31 * xdr_mem.h, XDR implementation using memory buffers.
32 *
33 * Copyright (C) 1984, Sun Microsystems, Inc.
34 *
35 * If you have some data to be interpreted as external data representation
36 * or to be converted to external data representation in a memory buffer,
37 * then this is the package for you.
38 *
39 */
40
41 #include <features.h>
42 #include <string.h>
43 #include <limits.h>
44 #include <rpc/rpc.h>
45
46
47 static bool_t xdrmem_getlong (XDR *, long *);
48 static bool_t xdrmem_putlong (XDR *, const long *);
49 static bool_t xdrmem_getbytes (XDR *, caddr_t, u_int);
50 static bool_t xdrmem_putbytes (XDR *, const char *, u_int);
51 static u_int xdrmem_getpos (const XDR *);
52 static bool_t xdrmem_setpos (XDR *, u_int);
53 static int32_t *xdrmem_inline (XDR *, u_int);
54 static void xdrmem_destroy (XDR *);
55 static bool_t xdrmem_getint32 (XDR *, int32_t *);
56 static bool_t xdrmem_putint32 (XDR *, const int32_t *);
57
58 static const struct xdr_ops xdrmem_ops =
59 {
60 xdrmem_getlong,
61 xdrmem_putlong,
62 xdrmem_getbytes,
63 xdrmem_putbytes,
64 xdrmem_getpos,
65 xdrmem_setpos,
66 xdrmem_inline,
67 xdrmem_destroy,
68 xdrmem_getint32,
69 xdrmem_putint32
70 };
71
72 /*
73 * The procedure xdrmem_create initializes a stream descriptor for a
74 * memory buffer.
75 */
76 void
xdrmem_create(XDR * xdrs,const caddr_t addr,u_int size,enum xdr_op op)77 xdrmem_create (XDR *xdrs, const caddr_t addr, u_int size, enum xdr_op op)
78 {
79 xdrs->x_op = op;
80 xdrs->x_ops = &xdrmem_ops;
81 xdrs->x_private = xdrs->x_base = addr;
82 xdrs->x_handy = size;
83 }
libc_hidden_def(xdrmem_create)84 libc_hidden_def(xdrmem_create)
85
86 /*
87 * Nothing needs to be done for the memory case. The argument is clearly
88 * const.
89 */
90
91 static void
92 xdrmem_destroy (XDR *xdrs attribute_unused)
93 {
94 }
95
96 /*
97 * Gets the next word from the memory referenced by xdrs and places it
98 * in the long pointed to by lp. It then increments the private word to
99 * point at the next element. Neither object pointed to is const
100 */
101 static bool_t
xdrmem_getlong(XDR * xdrs,long * lp)102 xdrmem_getlong (XDR *xdrs, long *lp)
103 {
104 if (xdrs->x_handy < 4)
105 return FALSE;
106 xdrs->x_handy -= 4;
107 *lp = (int32_t) ntohl ((*((int32_t *) (xdrs->x_private))));
108 xdrs->x_private += 4;
109 return TRUE;
110 }
111
112 /*
113 * Puts the long pointed to by lp in the memory referenced by xdrs. It
114 * then increments the private word to point at the next element. The
115 * long pointed at is const
116 */
117 static bool_t
xdrmem_putlong(XDR * xdrs,const long * lp)118 xdrmem_putlong (XDR *xdrs, const long *lp)
119 {
120 if (xdrs->x_handy < 4)
121 return FALSE;
122 xdrs->x_handy -= 4;
123 *(int32_t *) xdrs->x_private = htonl (*lp);
124 xdrs->x_private += 4;
125 return TRUE;
126 }
127
128 /*
129 * Gets an unaligned number of bytes from the xdrs structure and writes them
130 * to the address passed in addr. Be very careful when calling this routine
131 * as it could leave the xdrs pointing to an unaligned structure which is not
132 * a good idea. None of the things pointed to are const.
133 */
134 static bool_t
xdrmem_getbytes(XDR * xdrs,caddr_t addr,u_int len)135 xdrmem_getbytes (XDR *xdrs, caddr_t addr, u_int len)
136 {
137 if (xdrs->x_handy < len)
138 return FALSE;
139 xdrs->x_handy -= len;
140 memcpy (addr, xdrs->x_private, len);
141 xdrs->x_private += len;
142 return TRUE;
143 }
144
145 /*
146 * The complementary function to the above. The same warnings apply about
147 * unaligned data. The source address is const.
148 */
149 static bool_t
xdrmem_putbytes(XDR * xdrs,const char * addr,u_int len)150 xdrmem_putbytes (XDR *xdrs, const char *addr, u_int len)
151 {
152 if (xdrs->x_handy < len)
153 return FALSE;
154 xdrs->x_handy -= len;
155 memcpy (xdrs->x_private, addr, len);
156 xdrs->x_private += len;
157 return TRUE;
158 }
159
160 /*
161 * Not sure what this one does. But it clearly doesn't modify the contents
162 * of xdrs. **FIXME** does this not assume u_int == u_long?
163 */
164 static u_int
xdrmem_getpos(const XDR * xdrs)165 xdrmem_getpos (const XDR *xdrs)
166 {
167 return (u_long) xdrs->x_private - (u_long) xdrs->x_base;
168 }
169
170 /*
171 * xdrs modified
172 */
173 static bool_t
xdrmem_setpos(XDR * xdrs,u_int pos)174 xdrmem_setpos (XDR *xdrs, u_int pos)
175 {
176 caddr_t newaddr = xdrs->x_base + pos;
177 caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
178
179 if ((long) newaddr > (long) lastaddr
180 || (UINT_MAX < LONG_MAX
181 && (long) UINT_MAX < (long) lastaddr - (long) newaddr))
182 return FALSE;
183 xdrs->x_private = newaddr;
184 xdrs->x_handy = (long) lastaddr - (long) newaddr;
185 return TRUE;
186 }
187
188 /*
189 * xdrs modified
190 */
191 static int32_t *
xdrmem_inline(XDR * xdrs,u_int len)192 xdrmem_inline (XDR *xdrs, u_int len)
193 {
194 int32_t *buf = 0;
195
196 if (xdrs->x_handy >= len)
197 {
198 xdrs->x_handy -= len;
199 buf = (int32_t *) xdrs->x_private;
200 xdrs->x_private += len;
201 }
202 return buf;
203 }
204
205 /*
206 * Gets the next word from the memory referenced by xdrs and places it
207 * in the int pointed to by ip. It then increments the private word to
208 * point at the next element. Neither object pointed to is const
209 */
210 static bool_t
xdrmem_getint32(XDR * xdrs,int32_t * ip)211 xdrmem_getint32 (XDR *xdrs, int32_t *ip)
212 {
213 if (xdrs->x_handy < 4)
214 return FALSE;
215 xdrs->x_handy -= 4;
216 *ip = ntohl ((*((int32_t *) (xdrs->x_private))));
217 xdrs->x_private += 4;
218 return TRUE;
219 }
220
221 /*
222 * Puts the long pointed to by lp in the memory referenced by xdrs. It
223 * then increments the private word to point at the next element. The
224 * long pointed at is const
225 */
226 static bool_t
xdrmem_putint32(XDR * xdrs,const int32_t * ip)227 xdrmem_putint32 (XDR *xdrs, const int32_t *ip)
228 {
229 if (xdrs->x_handy < 4)
230 return FALSE;
231 xdrs->x_handy -= 4;
232 *(int32_t *) xdrs->x_private = htonl (*ip);
233 xdrs->x_private += 4;
234 return TRUE;
235 }
236