xref: /openbsd-src/lib/libc/rpc/xdr_mem.c (revision 850e275390052b330d93020bf619a739a3c277ac)
1 /*	$OpenBSD: xdr_mem.c,v 1.13 2006/03/31 18:28:55 deraadt Exp $ */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
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 <string.h>
43 
44 #include <rpc/types.h>
45 #include <rpc/xdr.h>
46 #include <netinet/in.h>
47 
48 static bool_t	xdrmem_getlong_aligned(XDR *, long *);
49 static bool_t	xdrmem_putlong_aligned(XDR *, long *);
50 static bool_t	xdrmem_getlong_unaligned(XDR *, long *);
51 static bool_t	xdrmem_putlong_unaligned(XDR *, long *);
52 static bool_t	xdrmem_getbytes(XDR *, caddr_t, u_int);
53 static bool_t	xdrmem_putbytes(XDR *, caddr_t, u_int);
54 static u_int	xdrmem_getpos(XDR *); /* XXX w/64-bit pointers, u_int not enough! */
55 static bool_t	xdrmem_setpos(XDR *, u_int);
56 static int32_t *xdrmem_inline_aligned(XDR *, u_int);
57 static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
58 static void	xdrmem_destroy(XDR *);
59 
60 static struct	xdr_ops xdrmem_ops_aligned = {
61 	xdrmem_getlong_aligned,
62 	xdrmem_putlong_aligned,
63 	xdrmem_getbytes,
64 	xdrmem_putbytes,
65 	xdrmem_getpos,
66 	xdrmem_setpos,
67 	xdrmem_inline_aligned,
68 	xdrmem_destroy
69 };
70 
71 static struct	xdr_ops xdrmem_ops_unaligned = {
72 	xdrmem_getlong_unaligned,
73 	xdrmem_putlong_unaligned,
74 	xdrmem_getbytes,
75 	xdrmem_putbytes,
76 	xdrmem_getpos,
77 	xdrmem_setpos,
78 	xdrmem_inline_unaligned,
79 	xdrmem_destroy
80 };
81 
82 /*
83  * The procedure xdrmem_create initializes a stream descriptor for a
84  * memory buffer.
85  */
86 void
87 xdrmem_create(XDR *xdrs, caddr_t addr, u_int size, enum xdr_op op)
88 {
89 
90 	xdrs->x_op = op;
91 	xdrs->x_ops = ((size_t)addr & (sizeof(int32_t) - 1))
92 	    ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
93 	xdrs->x_private = xdrs->x_base = addr;
94 	xdrs->x_handy = size;
95 }
96 
97 /*ARGSUSED*/
98 static void
99 xdrmem_destroy(XDR *xdrs)
100 {
101 }
102 
103 static bool_t
104 xdrmem_getlong_aligned(XDR *xdrs, long int *lp)
105 {
106 
107 	if (xdrs->x_handy < sizeof(int32_t))
108 		return (FALSE);
109 	xdrs->x_handy -= sizeof(int32_t);
110 	*lp = ntohl(*(int32_t *)xdrs->x_private);
111 	xdrs->x_private += sizeof(int32_t);
112 	return (TRUE);
113 }
114 
115 static bool_t
116 xdrmem_putlong_aligned(XDR *xdrs, long int *lp)
117 {
118 
119 	if (xdrs->x_handy < sizeof(int32_t))
120 		return (FALSE);
121 	xdrs->x_handy -= sizeof(int32_t);
122 	*(int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
123 	xdrs->x_private += sizeof(int32_t);
124 	return (TRUE);
125 }
126 
127 static bool_t
128 xdrmem_getlong_unaligned(XDR *xdrs, long int *lp)
129 {
130 	int32_t l;
131 
132 	if (xdrs->x_handy < sizeof(int32_t))
133 		return (FALSE);
134 	xdrs->x_handy -= sizeof(int32_t);
135 	memcpy(&l, xdrs->x_private, sizeof(int32_t));
136 	*lp = ntohl(l);
137 	xdrs->x_private += sizeof(int32_t);
138 	return (TRUE);
139 }
140 
141 static bool_t
142 xdrmem_putlong_unaligned(XDR *xdrs, long int *lp)
143 {
144 	int32_t l;
145 
146 	if (xdrs->x_handy < sizeof(int32_t))
147 		return (FALSE);
148 	xdrs->x_handy -= sizeof(int32_t);
149 	l = htonl((u_int32_t)*lp);
150 	memcpy(xdrs->x_private, &l, sizeof(int32_t));
151 	xdrs->x_private += sizeof(int32_t);
152 	return (TRUE);
153 }
154 
155 static bool_t
156 xdrmem_getbytes(XDR *xdrs, caddr_t addr, u_int len)
157 {
158 
159 	if (xdrs->x_handy < len)
160 		return (FALSE);
161 	xdrs->x_handy -= len;
162 	memcpy(addr, xdrs->x_private, len);
163 	xdrs->x_private += len;
164 	return (TRUE);
165 }
166 
167 static bool_t
168 xdrmem_putbytes(XDR *xdrs, caddr_t addr, u_int len)
169 {
170 
171 	if (xdrs->x_handy < len)
172 		return (FALSE);
173 	xdrs->x_handy -= len;
174 	memcpy(xdrs->x_private, addr, len);
175 	xdrs->x_private += len;
176 	return (TRUE);
177 }
178 
179 static u_int
180 xdrmem_getpos(XDR *xdrs)
181 {
182 
183 	/* XXX w/64-bit pointers, u_int not enough! */
184 	return ((u_long)xdrs->x_private - (u_long)xdrs->x_base);
185 }
186 
187 static bool_t
188 xdrmem_setpos(XDR *xdrs, u_int pos)
189 {
190 	caddr_t newaddr = xdrs->x_base + pos;
191 	caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
192 
193 	if (newaddr > lastaddr)
194 		return (FALSE);
195 	xdrs->x_private = newaddr;
196 	xdrs->x_handy = (u_int)(lastaddr - newaddr);	/* XXX w/64-bit pointers, u_int not enough! */
197 	return (TRUE);
198 }
199 
200 static int32_t *
201 xdrmem_inline_aligned(XDR *xdrs, u_int len)
202 {
203 	int32_t *buf = 0;
204 
205 	if (xdrs->x_handy >= len) {
206 		xdrs->x_handy -= len;
207 		buf = (int32_t *)xdrs->x_private;
208 		xdrs->x_private += len;
209 	}
210 	return (buf);
211 }
212 
213 /* ARGSUSED */
214 static int32_t *
215 xdrmem_inline_unaligned(XDR *xdrs, u_int len)
216 {
217 
218 	return (0);
219 }
220