xref: /openbsd/lib/libc/rpc/xdr_mem.c (revision 17df1aa7)
1 /*	$OpenBSD: xdr_mem.c,v 1.14 2008/12/09 19:40:10 otto 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 <sys/types.h>
43 #include <netinet/in.h>
44 #include <string.h>
45 
46 #include <rpc/types.h>
47 #include <rpc/xdr.h>
48 
49 static bool_t	xdrmem_getlong_aligned(XDR *, long *);
50 static bool_t	xdrmem_putlong_aligned(XDR *, long *);
51 static bool_t	xdrmem_getlong_unaligned(XDR *, long *);
52 static bool_t	xdrmem_putlong_unaligned(XDR *, long *);
53 static bool_t	xdrmem_getbytes(XDR *, caddr_t, u_int);
54 static bool_t	xdrmem_putbytes(XDR *, caddr_t, u_int);
55 static u_int	xdrmem_getpos(XDR *); /* XXX w/64-bit pointers, u_int not enough! */
56 static bool_t	xdrmem_setpos(XDR *, u_int);
57 static int32_t *xdrmem_inline_aligned(XDR *, u_int);
58 static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
59 static void	xdrmem_destroy(XDR *);
60 
61 static struct	xdr_ops xdrmem_ops_aligned = {
62 	xdrmem_getlong_aligned,
63 	xdrmem_putlong_aligned,
64 	xdrmem_getbytes,
65 	xdrmem_putbytes,
66 	xdrmem_getpos,
67 	xdrmem_setpos,
68 	xdrmem_inline_aligned,
69 	xdrmem_destroy,
70 	NULL,	/* xdrmem_control */
71 };
72 
73 static struct	xdr_ops xdrmem_ops_unaligned = {
74 	xdrmem_getlong_unaligned,
75 	xdrmem_putlong_unaligned,
76 	xdrmem_getbytes,
77 	xdrmem_putbytes,
78 	xdrmem_getpos,
79 	xdrmem_setpos,
80 	xdrmem_inline_unaligned,
81 	xdrmem_destroy,
82 	NULL,	/* xdrmem_control */
83 };
84 
85 /*
86  * The procedure xdrmem_create initializes a stream descriptor for a
87  * memory buffer.
88  */
89 void
90 xdrmem_create(XDR *xdrs, caddr_t addr, u_int size, enum xdr_op op)
91 {
92 
93 	xdrs->x_op = op;
94 	xdrs->x_ops = ((size_t)addr & (sizeof(int32_t) - 1))
95 	    ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
96 	xdrs->x_private = xdrs->x_base = addr;
97 	xdrs->x_handy = size;
98 }
99 
100 /*ARGSUSED*/
101 static void
102 xdrmem_destroy(XDR *xdrs)
103 {
104 }
105 
106 static bool_t
107 xdrmem_getlong_aligned(XDR *xdrs, long int *lp)
108 {
109 
110 	if (xdrs->x_handy < sizeof(int32_t))
111 		return (FALSE);
112 	xdrs->x_handy -= sizeof(int32_t);
113 	*lp = ntohl(*(int32_t *)xdrs->x_private);
114 	xdrs->x_private += sizeof(int32_t);
115 	return (TRUE);
116 }
117 
118 static bool_t
119 xdrmem_putlong_aligned(XDR *xdrs, long int *lp)
120 {
121 
122 	if (xdrs->x_handy < sizeof(int32_t))
123 		return (FALSE);
124 	xdrs->x_handy -= sizeof(int32_t);
125 	*(int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
126 	xdrs->x_private += sizeof(int32_t);
127 	return (TRUE);
128 }
129 
130 static bool_t
131 xdrmem_getlong_unaligned(XDR *xdrs, long int *lp)
132 {
133 	int32_t l;
134 
135 	if (xdrs->x_handy < sizeof(int32_t))
136 		return (FALSE);
137 	xdrs->x_handy -= sizeof(int32_t);
138 	memcpy(&l, xdrs->x_private, sizeof(int32_t));
139 	*lp = ntohl(l);
140 	xdrs->x_private += sizeof(int32_t);
141 	return (TRUE);
142 }
143 
144 static bool_t
145 xdrmem_putlong_unaligned(XDR *xdrs, long int *lp)
146 {
147 	int32_t l;
148 
149 	if (xdrs->x_handy < sizeof(int32_t))
150 		return (FALSE);
151 	xdrs->x_handy -= sizeof(int32_t);
152 	l = htonl((u_int32_t)*lp);
153 	memcpy(xdrs->x_private, &l, sizeof(int32_t));
154 	xdrs->x_private += sizeof(int32_t);
155 	return (TRUE);
156 }
157 
158 static bool_t
159 xdrmem_getbytes(XDR *xdrs, caddr_t addr, u_int len)
160 {
161 
162 	if (xdrs->x_handy < len)
163 		return (FALSE);
164 	xdrs->x_handy -= len;
165 	memcpy(addr, xdrs->x_private, len);
166 	xdrs->x_private += len;
167 	return (TRUE);
168 }
169 
170 static bool_t
171 xdrmem_putbytes(XDR *xdrs, caddr_t addr, u_int len)
172 {
173 
174 	if (xdrs->x_handy < len)
175 		return (FALSE);
176 	xdrs->x_handy -= len;
177 	memcpy(xdrs->x_private, addr, len);
178 	xdrs->x_private += len;
179 	return (TRUE);
180 }
181 
182 static u_int
183 xdrmem_getpos(XDR *xdrs)
184 {
185 
186 	/* XXX w/64-bit pointers, u_int not enough! */
187 	return ((u_long)xdrs->x_private - (u_long)xdrs->x_base);
188 }
189 
190 static bool_t
191 xdrmem_setpos(XDR *xdrs, u_int pos)
192 {
193 	caddr_t newaddr = xdrs->x_base + pos;
194 	caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
195 
196 	if (newaddr > lastaddr)
197 		return (FALSE);
198 	xdrs->x_private = newaddr;
199 	xdrs->x_handy = (u_int)(lastaddr - newaddr);	/* XXX w/64-bit pointers, u_int not enough! */
200 	return (TRUE);
201 }
202 
203 static int32_t *
204 xdrmem_inline_aligned(XDR *xdrs, u_int len)
205 {
206 	int32_t *buf = 0;
207 
208 	if (xdrs->x_handy >= len) {
209 		xdrs->x_handy -= len;
210 		buf = (int32_t *)xdrs->x_private;
211 		xdrs->x_private += len;
212 	}
213 	return (buf);
214 }
215 
216 /* ARGSUSED */
217 static int32_t *
218 xdrmem_inline_unaligned(XDR *xdrs, u_int len)
219 {
220 
221 	return (0);
222 }
223