Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/xdr/xdr_mem.c
39476 views
1
/* $NetBSD: xdr_mem.c,v 1.15 2000/01/22 22:19:18 mycroft Exp $ */
2
3
/*-
4
* SPDX-License-Identifier: BSD-3-Clause
5
*
6
* Copyright (c) 2010, Oracle America, Inc.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions are
10
* met:
11
*
12
* * Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* * Redistributions in binary form must reproduce the above
15
* copyright notice, this list of conditions and the following
16
* disclaimer in the documentation and/or other materials
17
* provided with the distribution.
18
* * Neither the name of the "Oracle America, Inc." nor the names of its
19
* contributors may be used to endorse or promote products derived
20
* from this software without specific prior written permission.
21
*
22
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
/*
37
* xdr_mem.h, XDR implementation using memory buffers.
38
*
39
* If you have some data to be interpreted as external data representation
40
* or to be converted to external data representation in a memory buffer,
41
* then this is the package for you.
42
*
43
*/
44
45
#include "namespace.h"
46
#include <sys/types.h>
47
48
#include <netinet/in.h>
49
50
#include <string.h>
51
52
#include <rpc/types.h>
53
#include <rpc/xdr.h>
54
#include "un-namespace.h"
55
56
static void xdrmem_destroy(XDR *);
57
static bool_t xdrmem_getlong_aligned(XDR *, long *);
58
static bool_t xdrmem_putlong_aligned(XDR *, const long *);
59
static bool_t xdrmem_getlong_unaligned(XDR *, long *);
60
static bool_t xdrmem_putlong_unaligned(XDR *, const long *);
61
static bool_t xdrmem_getbytes(XDR *, char *, u_int);
62
static bool_t xdrmem_putbytes(XDR *, const char *, u_int);
63
/* XXX: w/64-bit pointers, u_int not enough! */
64
static u_int xdrmem_getpos(XDR *);
65
static bool_t xdrmem_setpos(XDR *, u_int);
66
static int32_t *xdrmem_inline_aligned(XDR *, u_int);
67
static int32_t *xdrmem_inline_unaligned(XDR *, u_int);
68
69
static const struct xdr_ops xdrmem_ops_aligned = {
70
xdrmem_getlong_aligned,
71
xdrmem_putlong_aligned,
72
xdrmem_getbytes,
73
xdrmem_putbytes,
74
xdrmem_getpos,
75
xdrmem_setpos,
76
xdrmem_inline_aligned,
77
xdrmem_destroy
78
};
79
80
static const struct xdr_ops xdrmem_ops_unaligned = {
81
xdrmem_getlong_unaligned,
82
xdrmem_putlong_unaligned,
83
xdrmem_getbytes,
84
xdrmem_putbytes,
85
xdrmem_getpos,
86
xdrmem_setpos,
87
xdrmem_inline_unaligned,
88
xdrmem_destroy
89
};
90
91
/*
92
* The procedure xdrmem_create initializes a stream descriptor for a
93
* memory buffer.
94
*/
95
void
96
xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op)
97
{
98
99
xdrs->x_op = op;
100
xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1))
101
? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
102
xdrs->x_private = xdrs->x_base = addr;
103
xdrs->x_handy = size;
104
}
105
106
/*ARGSUSED*/
107
static void
108
xdrmem_destroy(XDR *xdrs)
109
{
110
111
}
112
113
static bool_t
114
xdrmem_getlong_aligned(XDR *xdrs, long *lp)
115
{
116
117
if (xdrs->x_handy < sizeof(int32_t))
118
return (FALSE);
119
xdrs->x_handy -= sizeof(int32_t);
120
*lp = ntohl(*(u_int32_t *)xdrs->x_private);
121
xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
122
return (TRUE);
123
}
124
125
static bool_t
126
xdrmem_putlong_aligned(XDR *xdrs, const long *lp)
127
{
128
129
if (xdrs->x_handy < sizeof(int32_t))
130
return (FALSE);
131
xdrs->x_handy -= sizeof(int32_t);
132
*(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp);
133
xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
134
return (TRUE);
135
}
136
137
static bool_t
138
xdrmem_getlong_unaligned(XDR *xdrs, long *lp)
139
{
140
u_int32_t l;
141
142
if (xdrs->x_handy < sizeof(int32_t))
143
return (FALSE);
144
xdrs->x_handy -= sizeof(int32_t);
145
memmove(&l, xdrs->x_private, sizeof(int32_t));
146
*lp = ntohl(l);
147
xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
148
return (TRUE);
149
}
150
151
static bool_t
152
xdrmem_putlong_unaligned(XDR *xdrs, const long *lp)
153
{
154
u_int32_t l;
155
156
if (xdrs->x_handy < sizeof(int32_t))
157
return (FALSE);
158
xdrs->x_handy -= sizeof(int32_t);
159
l = htonl((u_int32_t)*lp);
160
memmove(xdrs->x_private, &l, sizeof(int32_t));
161
xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t);
162
return (TRUE);
163
}
164
165
static bool_t
166
xdrmem_getbytes(XDR *xdrs, char *addr, u_int len)
167
{
168
169
if (xdrs->x_handy < len)
170
return (FALSE);
171
xdrs->x_handy -= len;
172
memmove(addr, xdrs->x_private, len);
173
xdrs->x_private = (char *)xdrs->x_private + len;
174
return (TRUE);
175
}
176
177
static bool_t
178
xdrmem_putbytes(XDR *xdrs, const char *addr, u_int len)
179
{
180
181
if (xdrs->x_handy < len)
182
return (FALSE);
183
xdrs->x_handy -= len;
184
memmove(xdrs->x_private, addr, len);
185
xdrs->x_private = (char *)xdrs->x_private + len;
186
return (TRUE);
187
}
188
189
static u_int
190
xdrmem_getpos(XDR *xdrs)
191
{
192
193
/* XXX w/64-bit pointers, u_int not enough! */
194
return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base);
195
}
196
197
static bool_t
198
xdrmem_setpos(XDR *xdrs, u_int pos)
199
{
200
char *newaddr = xdrs->x_base + pos;
201
char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy;
202
203
if (newaddr > lastaddr)
204
return (FALSE);
205
xdrs->x_private = newaddr;
206
xdrs->x_handy = (u_int)(lastaddr - newaddr); /* XXX sizeof(u_int) <? sizeof(ptrdiff_t) */
207
return (TRUE);
208
}
209
210
static int32_t *
211
xdrmem_inline_aligned(XDR *xdrs, u_int len)
212
{
213
int32_t *buf = NULL;
214
215
if (xdrs->x_handy >= len) {
216
xdrs->x_handy -= len;
217
buf = (int32_t *)xdrs->x_private;
218
xdrs->x_private = (char *)xdrs->x_private + len;
219
}
220
return (buf);
221
}
222
223
/* ARGSUSED */
224
static int32_t *
225
xdrmem_inline_unaligned(XDR *xdrs, u_int len)
226
{
227
228
return (0);
229
}
230
231