xref: /titanic_41/usr/src/lib/libsmbfs/smb/mbuf.c (revision 4bff34e37def8a90f9194d81bc345c52ba20086a)
1*4bff34e3Sthurlow /*
2*4bff34e3Sthurlow  * Copyright (c) 2000, Boris Popov
3*4bff34e3Sthurlow  * All rights reserved.
4*4bff34e3Sthurlow  *
5*4bff34e3Sthurlow  * Redistribution and use in source and binary forms, with or without
6*4bff34e3Sthurlow  * modification, are permitted provided that the following conditions
7*4bff34e3Sthurlow  * are met:
8*4bff34e3Sthurlow  * 1. Redistributions of source code must retain the above copyright
9*4bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer.
10*4bff34e3Sthurlow  * 2. Redistributions in binary form must reproduce the above copyright
11*4bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer in the
12*4bff34e3Sthurlow  *    documentation and/or other materials provided with the distribution.
13*4bff34e3Sthurlow  * 3. All advertising materials mentioning features or use of this software
14*4bff34e3Sthurlow  *    must display the following acknowledgement:
15*4bff34e3Sthurlow  *    This product includes software developed by Boris Popov.
16*4bff34e3Sthurlow  * 4. Neither the name of the author nor the names of any co-contributors
17*4bff34e3Sthurlow  *    may be used to endorse or promote products derived from this software
18*4bff34e3Sthurlow  *    without specific prior written permission.
19*4bff34e3Sthurlow  *
20*4bff34e3Sthurlow  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21*4bff34e3Sthurlow  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*4bff34e3Sthurlow  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*4bff34e3Sthurlow  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24*4bff34e3Sthurlow  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25*4bff34e3Sthurlow  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26*4bff34e3Sthurlow  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*4bff34e3Sthurlow  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*4bff34e3Sthurlow  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29*4bff34e3Sthurlow  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*4bff34e3Sthurlow  * SUCH DAMAGE.
31*4bff34e3Sthurlow  *
32*4bff34e3Sthurlow  * $Id: mbuf.c,v 1.3 2004/12/13 00:25:22 lindak Exp $
33*4bff34e3Sthurlow  */
34*4bff34e3Sthurlow 
35*4bff34e3Sthurlow #pragma ident	"%Z%%M%	%I%	%E% SMI"
36*4bff34e3Sthurlow 
37*4bff34e3Sthurlow #include <sys/types.h>
38*4bff34e3Sthurlow #include <ctype.h>
39*4bff34e3Sthurlow #include <errno.h>
40*4bff34e3Sthurlow #include <stdio.h>
41*4bff34e3Sthurlow #include <stdlib.h>
42*4bff34e3Sthurlow #include <string.h>
43*4bff34e3Sthurlow #include <strings.h>
44*4bff34e3Sthurlow #include <libintl.h>
45*4bff34e3Sthurlow 
46*4bff34e3Sthurlow #include <netsmb/smb.h>
47*4bff34e3Sthurlow #include <netsmb/smb_lib.h>
48*4bff34e3Sthurlow #include <netsmb/mchain.h>
49*4bff34e3Sthurlow 
50*4bff34e3Sthurlow #ifdef APPLE
51*4bff34e3Sthurlow #define	__func__ ""
52*4bff34e3Sthurlow #define	MBERROR(format, args...) \
53*4bff34e3Sthurlow 	printf("%s(%d): "format, __func__, __LINE__, ## args)
54*4bff34e3Sthurlow #endif
55*4bff34e3Sthurlow 
56*4bff34e3Sthurlow static int
57*4bff34e3Sthurlow m_get(size_t len, struct mbuf **mpp)
58*4bff34e3Sthurlow {
59*4bff34e3Sthurlow 	struct mbuf *m;
60*4bff34e3Sthurlow 
61*4bff34e3Sthurlow 	len = M_ALIGN(len);
62*4bff34e3Sthurlow 	if (len < M_MINSIZE)
63*4bff34e3Sthurlow 		len = M_MINSIZE;
64*4bff34e3Sthurlow 	m = malloc(M_BASESIZE + len);
65*4bff34e3Sthurlow 	if (m == NULL)
66*4bff34e3Sthurlow 		return (ENOMEM);
67*4bff34e3Sthurlow 	bzero(m, M_BASESIZE + len);
68*4bff34e3Sthurlow 	m->m_maxlen = len;
69*4bff34e3Sthurlow 	m->m_data = M_TOP(m);
70*4bff34e3Sthurlow 	*mpp = m;
71*4bff34e3Sthurlow 	return (0);
72*4bff34e3Sthurlow }
73*4bff34e3Sthurlow 
74*4bff34e3Sthurlow static void
75*4bff34e3Sthurlow m_free(struct mbuf *m)
76*4bff34e3Sthurlow {
77*4bff34e3Sthurlow 	free(m);
78*4bff34e3Sthurlow }
79*4bff34e3Sthurlow 
80*4bff34e3Sthurlow static void
81*4bff34e3Sthurlow m_freem(struct mbuf *m0)
82*4bff34e3Sthurlow {
83*4bff34e3Sthurlow 	struct mbuf *m;
84*4bff34e3Sthurlow 
85*4bff34e3Sthurlow 	while (m0) {
86*4bff34e3Sthurlow 		m = m0->m_next;
87*4bff34e3Sthurlow 		m_free(m0);
88*4bff34e3Sthurlow 		m0 = m;
89*4bff34e3Sthurlow 	}
90*4bff34e3Sthurlow }
91*4bff34e3Sthurlow 
92*4bff34e3Sthurlow static size_t
93*4bff34e3Sthurlow m_totlen(struct mbuf *m0)
94*4bff34e3Sthurlow {
95*4bff34e3Sthurlow 	struct mbuf *m = m0;
96*4bff34e3Sthurlow 	int len = 0;
97*4bff34e3Sthurlow 
98*4bff34e3Sthurlow 	while (m) {
99*4bff34e3Sthurlow 		len += m->m_len;
100*4bff34e3Sthurlow 		m = m->m_next;
101*4bff34e3Sthurlow 	}
102*4bff34e3Sthurlow 	return (len);
103*4bff34e3Sthurlow }
104*4bff34e3Sthurlow 
105*4bff34e3Sthurlow int
106*4bff34e3Sthurlow m_lineup(struct mbuf *m0, struct mbuf **mpp)
107*4bff34e3Sthurlow {
108*4bff34e3Sthurlow 	struct mbuf *nm, *m;
109*4bff34e3Sthurlow 	char *dp;
110*4bff34e3Sthurlow 	size_t len;
111*4bff34e3Sthurlow 	int error;
112*4bff34e3Sthurlow 
113*4bff34e3Sthurlow 	if (m0->m_next == NULL) {
114*4bff34e3Sthurlow 		*mpp = m0;
115*4bff34e3Sthurlow 		return (0);
116*4bff34e3Sthurlow 	}
117*4bff34e3Sthurlow 	if ((error = m_get(m_totlen(m0), &nm)) != 0)
118*4bff34e3Sthurlow 		return (error);
119*4bff34e3Sthurlow 	dp = mtod(nm, char *);
120*4bff34e3Sthurlow 	while (m0) {
121*4bff34e3Sthurlow 		len = m0->m_len;
122*4bff34e3Sthurlow 		bcopy(m0->m_data, dp, len);
123*4bff34e3Sthurlow 		dp += len;
124*4bff34e3Sthurlow 		m = m0->m_next;
125*4bff34e3Sthurlow 		m_free(m0);
126*4bff34e3Sthurlow 		m0 = m;
127*4bff34e3Sthurlow 	}
128*4bff34e3Sthurlow 	*mpp = nm;
129*4bff34e3Sthurlow 	return (0);
130*4bff34e3Sthurlow }
131*4bff34e3Sthurlow 
132*4bff34e3Sthurlow int
133*4bff34e3Sthurlow mb_init(struct mbdata *mbp, size_t size)
134*4bff34e3Sthurlow {
135*4bff34e3Sthurlow 	struct mbuf *m;
136*4bff34e3Sthurlow 	int error;
137*4bff34e3Sthurlow 
138*4bff34e3Sthurlow 	if ((error = m_get(size, &m)) != 0)
139*4bff34e3Sthurlow 		return (error);
140*4bff34e3Sthurlow 	return (mb_initm(mbp, m));
141*4bff34e3Sthurlow }
142*4bff34e3Sthurlow 
143*4bff34e3Sthurlow int
144*4bff34e3Sthurlow mb_initm(struct mbdata *mbp, struct mbuf *m)
145*4bff34e3Sthurlow {
146*4bff34e3Sthurlow 	bzero(mbp, sizeof (*mbp));
147*4bff34e3Sthurlow 	mbp->mb_top = mbp->mb_cur = m;
148*4bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *);
149*4bff34e3Sthurlow 	return (0);
150*4bff34e3Sthurlow }
151*4bff34e3Sthurlow 
152*4bff34e3Sthurlow int
153*4bff34e3Sthurlow mb_done(struct mbdata *mbp)
154*4bff34e3Sthurlow {
155*4bff34e3Sthurlow 	if (mbp->mb_top) {
156*4bff34e3Sthurlow 		m_freem(mbp->mb_top);
157*4bff34e3Sthurlow 		mbp->mb_top = NULL;
158*4bff34e3Sthurlow 	}
159*4bff34e3Sthurlow 	return (0);
160*4bff34e3Sthurlow }
161*4bff34e3Sthurlow 
162*4bff34e3Sthurlow int
163*4bff34e3Sthurlow m_getm(struct mbuf *top, size_t len, struct mbuf **mpp)
164*4bff34e3Sthurlow {
165*4bff34e3Sthurlow 	struct mbuf *m, *mp;
166*4bff34e3Sthurlow 	int error;
167*4bff34e3Sthurlow 
168*4bff34e3Sthurlow 	for (mp = top; ; mp = mp->m_next) {
169*4bff34e3Sthurlow 		len -= M_TRAILINGSPACE(mp);
170*4bff34e3Sthurlow 		if (mp->m_next == NULL)
171*4bff34e3Sthurlow 			break;
172*4bff34e3Sthurlow 
173*4bff34e3Sthurlow 	}
174*4bff34e3Sthurlow 	if (len > 0) {
175*4bff34e3Sthurlow 		if ((error = m_get(len, &m)) != 0)
176*4bff34e3Sthurlow 			return (error);
177*4bff34e3Sthurlow 		mp->m_next = m;
178*4bff34e3Sthurlow 	}
179*4bff34e3Sthurlow 	*mpp = top;
180*4bff34e3Sthurlow 	return (0);
181*4bff34e3Sthurlow }
182*4bff34e3Sthurlow 
183*4bff34e3Sthurlow /*
184*4bff34e3Sthurlow  * Routines to put data in a buffer
185*4bff34e3Sthurlow  */
186*4bff34e3Sthurlow #define	MB_PUT(t)	int error; t *p; \
187*4bff34e3Sthurlow 		if ((error = mb_fit(mbp, sizeof (t), (char **)&p)) != 0) \
188*4bff34e3Sthurlow 			return (error)
189*4bff34e3Sthurlow 
190*4bff34e3Sthurlow /*
191*4bff34e3Sthurlow  * Check if object of size 'size' fit to the current position and
192*4bff34e3Sthurlow  * allocate new mbuf if not. Advance pointers and increase length of mbuf(s).
193*4bff34e3Sthurlow  * Return pointer to the object placeholder or NULL if any error occured.
194*4bff34e3Sthurlow  */
195*4bff34e3Sthurlow int
196*4bff34e3Sthurlow mb_fit(struct mbdata *mbp, size_t size, char **pp)
197*4bff34e3Sthurlow {
198*4bff34e3Sthurlow 	struct mbuf *m, *mn;
199*4bff34e3Sthurlow 	int error;
200*4bff34e3Sthurlow 
201*4bff34e3Sthurlow 	m = mbp->mb_cur;
202*4bff34e3Sthurlow 	if (M_TRAILINGSPACE(m) < (int)size) {
203*4bff34e3Sthurlow 		if ((error = m_get(size, &mn)) != 0)
204*4bff34e3Sthurlow 			return (error);
205*4bff34e3Sthurlow 		mbp->mb_pos = mtod(mn, char *);
206*4bff34e3Sthurlow 		mbp->mb_cur = m->m_next = mn;
207*4bff34e3Sthurlow 		m = mn;
208*4bff34e3Sthurlow 	}
209*4bff34e3Sthurlow 	m->m_len += size;
210*4bff34e3Sthurlow 	*pp = mbp->mb_pos;
211*4bff34e3Sthurlow 	mbp->mb_pos += size;
212*4bff34e3Sthurlow 	mbp->mb_count += size;
213*4bff34e3Sthurlow 	return (0);
214*4bff34e3Sthurlow }
215*4bff34e3Sthurlow 
216*4bff34e3Sthurlow int
217*4bff34e3Sthurlow mb_put_uint8(struct mbdata *mbp, uint8_t x)
218*4bff34e3Sthurlow {
219*4bff34e3Sthurlow 	MB_PUT(uint8_t);
220*4bff34e3Sthurlow 	*p = x;
221*4bff34e3Sthurlow 	return (0);
222*4bff34e3Sthurlow }
223*4bff34e3Sthurlow 
224*4bff34e3Sthurlow int
225*4bff34e3Sthurlow mb_put_uint16be(struct mbdata *mbp, uint16_t x)
226*4bff34e3Sthurlow {
227*4bff34e3Sthurlow 	MB_PUT(uint16_t);
228*4bff34e3Sthurlow 	/* LINTED */
229*4bff34e3Sthurlow 	setwbe(p, 0, x);
230*4bff34e3Sthurlow 	return (0);
231*4bff34e3Sthurlow }
232*4bff34e3Sthurlow 
233*4bff34e3Sthurlow int
234*4bff34e3Sthurlow mb_put_uint16le(struct mbdata *mbp, uint16_t x)
235*4bff34e3Sthurlow {
236*4bff34e3Sthurlow 	MB_PUT(uint16_t);
237*4bff34e3Sthurlow 	/* LINTED */
238*4bff34e3Sthurlow 	setwle(p, 0, x);
239*4bff34e3Sthurlow 	return (0);
240*4bff34e3Sthurlow }
241*4bff34e3Sthurlow 
242*4bff34e3Sthurlow int
243*4bff34e3Sthurlow mb_put_uint32be(struct mbdata *mbp, uint32_t x)
244*4bff34e3Sthurlow {
245*4bff34e3Sthurlow 	MB_PUT(uint32_t);
246*4bff34e3Sthurlow 	/* LINTED */
247*4bff34e3Sthurlow 	setdbe(p, 0, x);
248*4bff34e3Sthurlow 	return (0);
249*4bff34e3Sthurlow }
250*4bff34e3Sthurlow 
251*4bff34e3Sthurlow int
252*4bff34e3Sthurlow mb_put_uint32le(struct mbdata *mbp, uint32_t x)
253*4bff34e3Sthurlow {
254*4bff34e3Sthurlow 	MB_PUT(uint32_t);
255*4bff34e3Sthurlow 	/* LINTED */
256*4bff34e3Sthurlow 	setdle(p, 0, x);
257*4bff34e3Sthurlow 	return (0);
258*4bff34e3Sthurlow }
259*4bff34e3Sthurlow 
260*4bff34e3Sthurlow int
261*4bff34e3Sthurlow mb_put_uint64be(struct mbdata *mbp, uint64_t x)
262*4bff34e3Sthurlow {
263*4bff34e3Sthurlow 	MB_PUT(uint64_t);
264*4bff34e3Sthurlow 	*p = htobeq(x);
265*4bff34e3Sthurlow 	return (0);
266*4bff34e3Sthurlow }
267*4bff34e3Sthurlow 
268*4bff34e3Sthurlow int
269*4bff34e3Sthurlow mb_put_uint64le(struct mbdata *mbp, uint64_t x)
270*4bff34e3Sthurlow {
271*4bff34e3Sthurlow 	MB_PUT(uint64_t);
272*4bff34e3Sthurlow 	*p = htoleq(x);
273*4bff34e3Sthurlow 	return (0);
274*4bff34e3Sthurlow }
275*4bff34e3Sthurlow 
276*4bff34e3Sthurlow int
277*4bff34e3Sthurlow mb_put_mem(struct mbdata *mbp, const char *source, size_t size)
278*4bff34e3Sthurlow {
279*4bff34e3Sthurlow 	struct mbuf *m;
280*4bff34e3Sthurlow 	char  *dst;
281*4bff34e3Sthurlow 	size_t cplen;
282*4bff34e3Sthurlow 	int error;
283*4bff34e3Sthurlow 
284*4bff34e3Sthurlow 	if (size == 0)
285*4bff34e3Sthurlow 		return (0);
286*4bff34e3Sthurlow 	m = mbp->mb_cur;
287*4bff34e3Sthurlow 	if ((error = m_getm(m, size, &m)) != 0)
288*4bff34e3Sthurlow 		return (error);
289*4bff34e3Sthurlow 	while (size > 0) {
290*4bff34e3Sthurlow 		cplen = M_TRAILINGSPACE(m);
291*4bff34e3Sthurlow 		if (cplen == 0) {
292*4bff34e3Sthurlow 			m = m->m_next;
293*4bff34e3Sthurlow 			continue;
294*4bff34e3Sthurlow 		}
295*4bff34e3Sthurlow 		if (cplen > size)
296*4bff34e3Sthurlow 			cplen = size;
297*4bff34e3Sthurlow 		dst = mtod(m, char *) + m->m_len;
298*4bff34e3Sthurlow 		if (source) {
299*4bff34e3Sthurlow 			bcopy(source, dst, cplen);
300*4bff34e3Sthurlow 			source += cplen;
301*4bff34e3Sthurlow 		} else
302*4bff34e3Sthurlow 			bzero(dst, cplen);
303*4bff34e3Sthurlow 		size -= cplen;
304*4bff34e3Sthurlow 		m->m_len += cplen;
305*4bff34e3Sthurlow 		mbp->mb_count += cplen;
306*4bff34e3Sthurlow 	}
307*4bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
308*4bff34e3Sthurlow 	mbp->mb_cur = m;
309*4bff34e3Sthurlow 	return (0);
310*4bff34e3Sthurlow }
311*4bff34e3Sthurlow 
312*4bff34e3Sthurlow int
313*4bff34e3Sthurlow mb_put_mbuf(struct mbdata *mbp, struct mbuf *m)
314*4bff34e3Sthurlow {
315*4bff34e3Sthurlow 	mbp->mb_cur->m_next = m;
316*4bff34e3Sthurlow 	while (m) {
317*4bff34e3Sthurlow 		mbp->mb_count += m->m_len;
318*4bff34e3Sthurlow 		if (m->m_next == NULL)
319*4bff34e3Sthurlow 			break;
320*4bff34e3Sthurlow 		m = m->m_next;
321*4bff34e3Sthurlow 	}
322*4bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
323*4bff34e3Sthurlow 	mbp->mb_cur = m;
324*4bff34e3Sthurlow 	return (0);
325*4bff34e3Sthurlow }
326*4bff34e3Sthurlow 
327*4bff34e3Sthurlow int
328*4bff34e3Sthurlow mb_put_pstring(struct mbdata *mbp, const char *s)
329*4bff34e3Sthurlow {
330*4bff34e3Sthurlow 	int error, len = strlen(s);
331*4bff34e3Sthurlow 
332*4bff34e3Sthurlow 	if (len > 255) {
333*4bff34e3Sthurlow 		len = 255;
334*4bff34e3Sthurlow 	}
335*4bff34e3Sthurlow 	if ((error = mb_put_uint8(mbp, len)) != 0)
336*4bff34e3Sthurlow 		return (error);
337*4bff34e3Sthurlow 	return (mb_put_mem(mbp, s, len));
338*4bff34e3Sthurlow }
339*4bff34e3Sthurlow 
340*4bff34e3Sthurlow /*
341*4bff34e3Sthurlow  * Routines for fetching data from an mbuf chain
342*4bff34e3Sthurlow  */
343*4bff34e3Sthurlow #define	mb_left(m, p)	(mtod(m, char *) + (m)->m_len - (p))
344*4bff34e3Sthurlow 
345*4bff34e3Sthurlow int
346*4bff34e3Sthurlow mb_get_uint8(struct mbdata *mbp, uint8_t *x)
347*4bff34e3Sthurlow {
348*4bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 1));
349*4bff34e3Sthurlow }
350*4bff34e3Sthurlow 
351*4bff34e3Sthurlow int
352*4bff34e3Sthurlow mb_get_uint16(struct mbdata *mbp, uint16_t *x)
353*4bff34e3Sthurlow {
354*4bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 2));
355*4bff34e3Sthurlow }
356*4bff34e3Sthurlow 
357*4bff34e3Sthurlow int
358*4bff34e3Sthurlow mb_get_uint16le(struct mbdata *mbp, uint16_t *x)
359*4bff34e3Sthurlow {
360*4bff34e3Sthurlow 	uint16_t v;
361*4bff34e3Sthurlow 	int error = mb_get_uint16(mbp, &v);
362*4bff34e3Sthurlow 
363*4bff34e3Sthurlow 	if (x != NULL)
364*4bff34e3Sthurlow 		*x = letohs(v);
365*4bff34e3Sthurlow 	return (error);
366*4bff34e3Sthurlow }
367*4bff34e3Sthurlow 
368*4bff34e3Sthurlow int
369*4bff34e3Sthurlow mb_get_uint16be(struct mbdata *mbp, uint16_t *x) {
370*4bff34e3Sthurlow 	uint16_t v;
371*4bff34e3Sthurlow 	int error = mb_get_uint16(mbp, &v);
372*4bff34e3Sthurlow 
373*4bff34e3Sthurlow 	if (x != NULL)
374*4bff34e3Sthurlow 		*x = betohs(v);
375*4bff34e3Sthurlow 	return (error);
376*4bff34e3Sthurlow }
377*4bff34e3Sthurlow 
378*4bff34e3Sthurlow int
379*4bff34e3Sthurlow mb_get_uint32(struct mbdata *mbp, uint32_t *x)
380*4bff34e3Sthurlow {
381*4bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 4));
382*4bff34e3Sthurlow }
383*4bff34e3Sthurlow 
384*4bff34e3Sthurlow int
385*4bff34e3Sthurlow mb_get_uint32be(struct mbdata *mbp, uint32_t *x)
386*4bff34e3Sthurlow {
387*4bff34e3Sthurlow 	uint32_t v;
388*4bff34e3Sthurlow 	int error;
389*4bff34e3Sthurlow 
390*4bff34e3Sthurlow 	error = mb_get_uint32(mbp, &v);
391*4bff34e3Sthurlow 	if (x != NULL)
392*4bff34e3Sthurlow 		*x = betohl(v);
393*4bff34e3Sthurlow 	return (error);
394*4bff34e3Sthurlow }
395*4bff34e3Sthurlow 
396*4bff34e3Sthurlow int
397*4bff34e3Sthurlow mb_get_uint32le(struct mbdata *mbp, uint32_t *x)
398*4bff34e3Sthurlow {
399*4bff34e3Sthurlow 	uint32_t v;
400*4bff34e3Sthurlow 	int error;
401*4bff34e3Sthurlow 
402*4bff34e3Sthurlow 	error = mb_get_uint32(mbp, &v);
403*4bff34e3Sthurlow 	if (x != NULL)
404*4bff34e3Sthurlow 		*x = letohl(v);
405*4bff34e3Sthurlow 	return (error);
406*4bff34e3Sthurlow }
407*4bff34e3Sthurlow 
408*4bff34e3Sthurlow int
409*4bff34e3Sthurlow mb_get_uint64(struct mbdata *mbp, uint64_t *x)
410*4bff34e3Sthurlow {
411*4bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 8));
412*4bff34e3Sthurlow }
413*4bff34e3Sthurlow 
414*4bff34e3Sthurlow int
415*4bff34e3Sthurlow mb_get_uint64be(struct mbdata *mbp, uint64_t *x)
416*4bff34e3Sthurlow {
417*4bff34e3Sthurlow 	uint64_t v;
418*4bff34e3Sthurlow 	int error;
419*4bff34e3Sthurlow 
420*4bff34e3Sthurlow 	error = mb_get_uint64(mbp, &v);
421*4bff34e3Sthurlow 	if (x != NULL)
422*4bff34e3Sthurlow 		*x = betohq(v);
423*4bff34e3Sthurlow 	return (error);
424*4bff34e3Sthurlow }
425*4bff34e3Sthurlow 
426*4bff34e3Sthurlow int
427*4bff34e3Sthurlow mb_get_uint64le(struct mbdata *mbp, uint64_t *x)
428*4bff34e3Sthurlow {
429*4bff34e3Sthurlow 	uint64_t v;
430*4bff34e3Sthurlow 	int error;
431*4bff34e3Sthurlow 
432*4bff34e3Sthurlow 	error = mb_get_uint64(mbp, &v);
433*4bff34e3Sthurlow 	if (x != NULL)
434*4bff34e3Sthurlow 		*x = letohq(v);
435*4bff34e3Sthurlow 	return (error);
436*4bff34e3Sthurlow }
437*4bff34e3Sthurlow 
438*4bff34e3Sthurlow int
439*4bff34e3Sthurlow mb_get_mem(struct mbdata *mbp, char *target, size_t size)
440*4bff34e3Sthurlow {
441*4bff34e3Sthurlow 	struct mbuf *m = mbp->mb_cur;
442*4bff34e3Sthurlow 	uint_t count;
443*4bff34e3Sthurlow 
444*4bff34e3Sthurlow 	while (size > 0) {
445*4bff34e3Sthurlow 		if (m == NULL) {
446*4bff34e3Sthurlow #ifdef DEBUG
447*4bff34e3Sthurlow 			printf(
448*4bff34e3Sthurlow 			    dgettext(TEXT_DOMAIN, "incomplete copy\n"));
449*4bff34e3Sthurlow #endif
450*4bff34e3Sthurlow #ifdef APPLE
451*4bff34e3Sthurlow 			MBERROR("incomplete copy\n");
452*4bff34e3Sthurlow #endif
453*4bff34e3Sthurlow 			return (EBADRPC);
454*4bff34e3Sthurlow 		}
455*4bff34e3Sthurlow 		count = mb_left(m, mbp->mb_pos);
456*4bff34e3Sthurlow 		if (count == 0) {
457*4bff34e3Sthurlow 			mbp->mb_cur = m = m->m_next;
458*4bff34e3Sthurlow 			if (m)
459*4bff34e3Sthurlow 				mbp->mb_pos = mtod(m, char *);
460*4bff34e3Sthurlow 			continue;
461*4bff34e3Sthurlow 		}
462*4bff34e3Sthurlow 		if (count > size)
463*4bff34e3Sthurlow 			count = size;
464*4bff34e3Sthurlow 		size -= count;
465*4bff34e3Sthurlow 		if (target) {
466*4bff34e3Sthurlow 			if (count == 1) {
467*4bff34e3Sthurlow 				*target++ = *mbp->mb_pos;
468*4bff34e3Sthurlow 			} else {
469*4bff34e3Sthurlow 				bcopy(mbp->mb_pos, target, count);
470*4bff34e3Sthurlow 				target += count;
471*4bff34e3Sthurlow 			}
472*4bff34e3Sthurlow 		}
473*4bff34e3Sthurlow 		mbp->mb_pos += count;
474*4bff34e3Sthurlow 	}
475*4bff34e3Sthurlow 	return (0);
476*4bff34e3Sthurlow }
477