xref: /titanic_51/usr/src/lib/libsmbfs/smb/mbuf.c (revision 9c9af2590af49bb395bc8d2eace0f2d4ea16d165)
14bff34e3Sthurlow /*
24bff34e3Sthurlow  * Copyright (c) 2000, Boris Popov
34bff34e3Sthurlow  * All rights reserved.
44bff34e3Sthurlow  *
54bff34e3Sthurlow  * Redistribution and use in source and binary forms, with or without
64bff34e3Sthurlow  * modification, are permitted provided that the following conditions
74bff34e3Sthurlow  * are met:
84bff34e3Sthurlow  * 1. Redistributions of source code must retain the above copyright
94bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer.
104bff34e3Sthurlow  * 2. Redistributions in binary form must reproduce the above copyright
114bff34e3Sthurlow  *    notice, this list of conditions and the following disclaimer in the
124bff34e3Sthurlow  *    documentation and/or other materials provided with the distribution.
134bff34e3Sthurlow  * 3. All advertising materials mentioning features or use of this software
144bff34e3Sthurlow  *    must display the following acknowledgement:
154bff34e3Sthurlow  *    This product includes software developed by Boris Popov.
164bff34e3Sthurlow  * 4. Neither the name of the author nor the names of any co-contributors
174bff34e3Sthurlow  *    may be used to endorse or promote products derived from this software
184bff34e3Sthurlow  *    without specific prior written permission.
194bff34e3Sthurlow  *
204bff34e3Sthurlow  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
214bff34e3Sthurlow  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
224bff34e3Sthurlow  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234bff34e3Sthurlow  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
244bff34e3Sthurlow  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254bff34e3Sthurlow  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
264bff34e3Sthurlow  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274bff34e3Sthurlow  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
284bff34e3Sthurlow  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
294bff34e3Sthurlow  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
304bff34e3Sthurlow  * SUCH DAMAGE.
314bff34e3Sthurlow  *
324bff34e3Sthurlow  * $Id: mbuf.c,v 1.3 2004/12/13 00:25:22 lindak Exp $
334bff34e3Sthurlow  */
344bff34e3Sthurlow 
35*9c9af259SGordon Ross /*
36*9c9af259SGordon Ross  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37*9c9af259SGordon Ross  * Use is subject to license terms.
38*9c9af259SGordon Ross  */
394bff34e3Sthurlow 
404bff34e3Sthurlow #include <sys/types.h>
414bff34e3Sthurlow #include <ctype.h>
424bff34e3Sthurlow #include <errno.h>
434bff34e3Sthurlow #include <stdio.h>
444bff34e3Sthurlow #include <stdlib.h>
454bff34e3Sthurlow #include <string.h>
464bff34e3Sthurlow #include <strings.h>
474bff34e3Sthurlow #include <libintl.h>
487568150aSgwr #include <assert.h>
494bff34e3Sthurlow 
504bff34e3Sthurlow #include <netsmb/smb.h>
514bff34e3Sthurlow #include <netsmb/smb_lib.h>
524bff34e3Sthurlow #include <netsmb/mchain.h>
534bff34e3Sthurlow 
54*9c9af259SGordon Ross #include "private.h"
55*9c9af259SGordon Ross 
564bff34e3Sthurlow #ifdef APPLE
574bff34e3Sthurlow #define	__func__ ""
584bff34e3Sthurlow #define	MBERROR(format, args...) \
594bff34e3Sthurlow 	printf("%s(%d): "format, __func__, __LINE__, ## args)
604bff34e3Sthurlow #endif
614bff34e3Sthurlow 
624bff34e3Sthurlow static int
634bff34e3Sthurlow m_get(size_t len, struct mbuf **mpp)
644bff34e3Sthurlow {
654bff34e3Sthurlow 	struct mbuf *m;
664bff34e3Sthurlow 
677568150aSgwr 	assert(len < 0x100000); /* sanity */
687568150aSgwr 
694bff34e3Sthurlow 	len = M_ALIGN(len);
704bff34e3Sthurlow 	if (len < M_MINSIZE)
714bff34e3Sthurlow 		len = M_MINSIZE;
724bff34e3Sthurlow 	m = malloc(M_BASESIZE + len);
734bff34e3Sthurlow 	if (m == NULL)
744bff34e3Sthurlow 		return (ENOMEM);
754bff34e3Sthurlow 	bzero(m, M_BASESIZE + len);
764bff34e3Sthurlow 	m->m_maxlen = len;
774bff34e3Sthurlow 	m->m_data = M_TOP(m);
784bff34e3Sthurlow 	*mpp = m;
794bff34e3Sthurlow 	return (0);
804bff34e3Sthurlow }
814bff34e3Sthurlow 
824bff34e3Sthurlow static void
834bff34e3Sthurlow m_free(struct mbuf *m)
844bff34e3Sthurlow {
854bff34e3Sthurlow 	free(m);
864bff34e3Sthurlow }
874bff34e3Sthurlow 
884bff34e3Sthurlow static void
894bff34e3Sthurlow m_freem(struct mbuf *m0)
904bff34e3Sthurlow {
914bff34e3Sthurlow 	struct mbuf *m;
924bff34e3Sthurlow 
934bff34e3Sthurlow 	while (m0) {
944bff34e3Sthurlow 		m = m0->m_next;
954bff34e3Sthurlow 		m_free(m0);
964bff34e3Sthurlow 		m0 = m;
974bff34e3Sthurlow 	}
984bff34e3Sthurlow }
994bff34e3Sthurlow 
1004bff34e3Sthurlow static size_t
1014bff34e3Sthurlow m_totlen(struct mbuf *m0)
1024bff34e3Sthurlow {
1034bff34e3Sthurlow 	struct mbuf *m = m0;
1044bff34e3Sthurlow 	int len = 0;
1054bff34e3Sthurlow 
1064bff34e3Sthurlow 	while (m) {
1074bff34e3Sthurlow 		len += m->m_len;
1084bff34e3Sthurlow 		m = m->m_next;
1094bff34e3Sthurlow 	}
1104bff34e3Sthurlow 	return (len);
1114bff34e3Sthurlow }
1124bff34e3Sthurlow 
1134bff34e3Sthurlow int
1144bff34e3Sthurlow m_lineup(struct mbuf *m0, struct mbuf **mpp)
1154bff34e3Sthurlow {
1164bff34e3Sthurlow 	struct mbuf *nm, *m;
1174bff34e3Sthurlow 	char *dp;
1184bff34e3Sthurlow 	size_t len;
1194bff34e3Sthurlow 	int error;
1204bff34e3Sthurlow 
1214bff34e3Sthurlow 	if (m0->m_next == NULL) {
1224bff34e3Sthurlow 		*mpp = m0;
1234bff34e3Sthurlow 		return (0);
1244bff34e3Sthurlow 	}
1254bff34e3Sthurlow 	if ((error = m_get(m_totlen(m0), &nm)) != 0)
1264bff34e3Sthurlow 		return (error);
1274bff34e3Sthurlow 	dp = mtod(nm, char *);
1284bff34e3Sthurlow 	while (m0) {
1294bff34e3Sthurlow 		len = m0->m_len;
1304bff34e3Sthurlow 		bcopy(m0->m_data, dp, len);
1314bff34e3Sthurlow 		dp += len;
1324bff34e3Sthurlow 		m = m0->m_next;
1334bff34e3Sthurlow 		m_free(m0);
1344bff34e3Sthurlow 		m0 = m;
1354bff34e3Sthurlow 	}
1364bff34e3Sthurlow 	*mpp = nm;
1374bff34e3Sthurlow 	return (0);
1384bff34e3Sthurlow }
1394bff34e3Sthurlow 
1404bff34e3Sthurlow int
1414bff34e3Sthurlow mb_init(struct mbdata *mbp, size_t size)
1424bff34e3Sthurlow {
1434bff34e3Sthurlow 	struct mbuf *m;
1444bff34e3Sthurlow 	int error;
1454bff34e3Sthurlow 
1464bff34e3Sthurlow 	if ((error = m_get(size, &m)) != 0)
1474bff34e3Sthurlow 		return (error);
1484bff34e3Sthurlow 	return (mb_initm(mbp, m));
1494bff34e3Sthurlow }
1504bff34e3Sthurlow 
1514bff34e3Sthurlow int
1524bff34e3Sthurlow mb_initm(struct mbdata *mbp, struct mbuf *m)
1534bff34e3Sthurlow {
1544bff34e3Sthurlow 	bzero(mbp, sizeof (*mbp));
1554bff34e3Sthurlow 	mbp->mb_top = mbp->mb_cur = m;
1564bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *);
1574bff34e3Sthurlow 	return (0);
1584bff34e3Sthurlow }
1594bff34e3Sthurlow 
1604bff34e3Sthurlow int
1614bff34e3Sthurlow mb_done(struct mbdata *mbp)
1624bff34e3Sthurlow {
1634bff34e3Sthurlow 	if (mbp->mb_top) {
1644bff34e3Sthurlow 		m_freem(mbp->mb_top);
1654bff34e3Sthurlow 		mbp->mb_top = NULL;
1664bff34e3Sthurlow 	}
1674bff34e3Sthurlow 	return (0);
1684bff34e3Sthurlow }
1694bff34e3Sthurlow 
1704bff34e3Sthurlow int
1714bff34e3Sthurlow m_getm(struct mbuf *top, size_t len, struct mbuf **mpp)
1724bff34e3Sthurlow {
1734bff34e3Sthurlow 	struct mbuf *m, *mp;
1747568150aSgwr 	int  error, ts;
1754bff34e3Sthurlow 
1764bff34e3Sthurlow 	for (mp = top; ; mp = mp->m_next) {
1777568150aSgwr 		ts = M_TRAILINGSPACE(mp);
1787568150aSgwr 		if (len <= ts)
1797568150aSgwr 			goto out;
1807568150aSgwr 		len -= ts;
1814bff34e3Sthurlow 		if (mp->m_next == NULL)
1824bff34e3Sthurlow 			break;
1834bff34e3Sthurlow 
1844bff34e3Sthurlow 	}
1854bff34e3Sthurlow 	if (len > 0) {
1864bff34e3Sthurlow 		if ((error = m_get(len, &m)) != 0)
1874bff34e3Sthurlow 			return (error);
1884bff34e3Sthurlow 		mp->m_next = m;
1894bff34e3Sthurlow 	}
1907568150aSgwr out:
1914bff34e3Sthurlow 	*mpp = top;
1924bff34e3Sthurlow 	return (0);
1934bff34e3Sthurlow }
1944bff34e3Sthurlow 
1954bff34e3Sthurlow /*
1964bff34e3Sthurlow  * Routines to put data in a buffer
1974bff34e3Sthurlow  */
1984bff34e3Sthurlow 
1994bff34e3Sthurlow /*
2004bff34e3Sthurlow  * Check if object of size 'size' fit to the current position and
2014bff34e3Sthurlow  * allocate new mbuf if not. Advance pointers and increase length of mbuf(s).
2024bff34e3Sthurlow  * Return pointer to the object placeholder or NULL if any error occured.
2034bff34e3Sthurlow  */
2044bff34e3Sthurlow int
2054bff34e3Sthurlow mb_fit(struct mbdata *mbp, size_t size, char **pp)
2064bff34e3Sthurlow {
2074bff34e3Sthurlow 	struct mbuf *m, *mn;
2084bff34e3Sthurlow 	int error;
2094bff34e3Sthurlow 
2104bff34e3Sthurlow 	m = mbp->mb_cur;
2114bff34e3Sthurlow 	if (M_TRAILINGSPACE(m) < (int)size) {
2124bff34e3Sthurlow 		if ((error = m_get(size, &mn)) != 0)
2134bff34e3Sthurlow 			return (error);
2144bff34e3Sthurlow 		mbp->mb_pos = mtod(mn, char *);
2154bff34e3Sthurlow 		mbp->mb_cur = m->m_next = mn;
2164bff34e3Sthurlow 		m = mn;
2174bff34e3Sthurlow 	}
2184bff34e3Sthurlow 	m->m_len += size;
2194bff34e3Sthurlow 	*pp = mbp->mb_pos;
2204bff34e3Sthurlow 	mbp->mb_pos += size;
2214bff34e3Sthurlow 	mbp->mb_count += size;
2224bff34e3Sthurlow 	return (0);
2234bff34e3Sthurlow }
2244bff34e3Sthurlow 
2254bff34e3Sthurlow int
2264bff34e3Sthurlow mb_put_uint8(struct mbdata *mbp, uint8_t x)
2274bff34e3Sthurlow {
228*9c9af259SGordon Ross 	uint8_t y = x;
229*9c9af259SGordon Ross 	return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
2304bff34e3Sthurlow }
2314bff34e3Sthurlow 
2324bff34e3Sthurlow int
2334bff34e3Sthurlow mb_put_uint16be(struct mbdata *mbp, uint16_t x)
2344bff34e3Sthurlow {
235*9c9af259SGordon Ross 	uint16_t y = htobes(x);
236*9c9af259SGordon Ross 	return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
2374bff34e3Sthurlow }
2384bff34e3Sthurlow 
2394bff34e3Sthurlow int
2404bff34e3Sthurlow mb_put_uint16le(struct mbdata *mbp, uint16_t x)
2414bff34e3Sthurlow {
242*9c9af259SGordon Ross 	uint16_t y = htoles(x);
243*9c9af259SGordon Ross 	return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
2444bff34e3Sthurlow }
2454bff34e3Sthurlow 
2464bff34e3Sthurlow int
2474bff34e3Sthurlow mb_put_uint32be(struct mbdata *mbp, uint32_t x)
2484bff34e3Sthurlow {
249*9c9af259SGordon Ross 	uint32_t y = htobel(x);
250*9c9af259SGordon Ross 	return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
2514bff34e3Sthurlow }
2524bff34e3Sthurlow 
2534bff34e3Sthurlow int
2544bff34e3Sthurlow mb_put_uint32le(struct mbdata *mbp, uint32_t x)
2554bff34e3Sthurlow {
256*9c9af259SGordon Ross 	uint32_t y = htolel(x);
257*9c9af259SGordon Ross 	return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
2584bff34e3Sthurlow }
2594bff34e3Sthurlow 
2604bff34e3Sthurlow int
2614bff34e3Sthurlow mb_put_uint64be(struct mbdata *mbp, uint64_t x)
2624bff34e3Sthurlow {
263*9c9af259SGordon Ross 	uint64_t y = htobeq(x);
264*9c9af259SGordon Ross 	return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
2654bff34e3Sthurlow }
2664bff34e3Sthurlow 
2674bff34e3Sthurlow int
2684bff34e3Sthurlow mb_put_uint64le(struct mbdata *mbp, uint64_t x)
2694bff34e3Sthurlow {
270*9c9af259SGordon Ross 	uint64_t y = htoleq(x);
271*9c9af259SGordon Ross 	return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
2724bff34e3Sthurlow }
2734bff34e3Sthurlow 
2744bff34e3Sthurlow int
2754bff34e3Sthurlow mb_put_mem(struct mbdata *mbp, const char *source, size_t size)
2764bff34e3Sthurlow {
2774bff34e3Sthurlow 	struct mbuf *m;
2784bff34e3Sthurlow 	char  *dst;
2794bff34e3Sthurlow 	size_t cplen;
2804bff34e3Sthurlow 	int error;
2814bff34e3Sthurlow 
2824bff34e3Sthurlow 	if (size == 0)
2834bff34e3Sthurlow 		return (0);
2844bff34e3Sthurlow 	m = mbp->mb_cur;
2854bff34e3Sthurlow 	if ((error = m_getm(m, size, &m)) != 0)
2864bff34e3Sthurlow 		return (error);
2874bff34e3Sthurlow 	while (size > 0) {
2884bff34e3Sthurlow 		cplen = M_TRAILINGSPACE(m);
2894bff34e3Sthurlow 		if (cplen == 0) {
2904bff34e3Sthurlow 			m = m->m_next;
2914bff34e3Sthurlow 			continue;
2924bff34e3Sthurlow 		}
2934bff34e3Sthurlow 		if (cplen > size)
2944bff34e3Sthurlow 			cplen = size;
2954bff34e3Sthurlow 		dst = mtod(m, char *) + m->m_len;
2964bff34e3Sthurlow 		if (source) {
2974bff34e3Sthurlow 			bcopy(source, dst, cplen);
2984bff34e3Sthurlow 			source += cplen;
2994bff34e3Sthurlow 		} else
3004bff34e3Sthurlow 			bzero(dst, cplen);
3014bff34e3Sthurlow 		size -= cplen;
3024bff34e3Sthurlow 		m->m_len += cplen;
3034bff34e3Sthurlow 		mbp->mb_count += cplen;
3044bff34e3Sthurlow 	}
3054bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
3064bff34e3Sthurlow 	mbp->mb_cur = m;
3074bff34e3Sthurlow 	return (0);
3084bff34e3Sthurlow }
3094bff34e3Sthurlow 
3104bff34e3Sthurlow int
3114bff34e3Sthurlow mb_put_mbuf(struct mbdata *mbp, struct mbuf *m)
3124bff34e3Sthurlow {
3134bff34e3Sthurlow 	mbp->mb_cur->m_next = m;
3144bff34e3Sthurlow 	while (m) {
3154bff34e3Sthurlow 		mbp->mb_count += m->m_len;
3164bff34e3Sthurlow 		if (m->m_next == NULL)
3174bff34e3Sthurlow 			break;
3184bff34e3Sthurlow 		m = m->m_next;
3194bff34e3Sthurlow 	}
3204bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
3214bff34e3Sthurlow 	mbp->mb_cur = m;
3224bff34e3Sthurlow 	return (0);
3234bff34e3Sthurlow }
3244bff34e3Sthurlow 
3254bff34e3Sthurlow int
3264bff34e3Sthurlow mb_put_pstring(struct mbdata *mbp, const char *s)
3274bff34e3Sthurlow {
3284bff34e3Sthurlow 	int error, len = strlen(s);
3294bff34e3Sthurlow 
3304bff34e3Sthurlow 	if (len > 255) {
3314bff34e3Sthurlow 		len = 255;
3324bff34e3Sthurlow 	}
3334bff34e3Sthurlow 	if ((error = mb_put_uint8(mbp, len)) != 0)
3344bff34e3Sthurlow 		return (error);
3354bff34e3Sthurlow 	return (mb_put_mem(mbp, s, len));
3364bff34e3Sthurlow }
3374bff34e3Sthurlow 
3384bff34e3Sthurlow /*
3394bff34e3Sthurlow  * Routines for fetching data from an mbuf chain
3404bff34e3Sthurlow  */
3414bff34e3Sthurlow #define	mb_left(m, p)	(mtod(m, char *) + (m)->m_len - (p))
3424bff34e3Sthurlow 
3434bff34e3Sthurlow int
3444bff34e3Sthurlow mb_get_uint8(struct mbdata *mbp, uint8_t *x)
3454bff34e3Sthurlow {
3464bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 1));
3474bff34e3Sthurlow }
3484bff34e3Sthurlow 
3494bff34e3Sthurlow int
3504bff34e3Sthurlow mb_get_uint16(struct mbdata *mbp, uint16_t *x)
3514bff34e3Sthurlow {
3524bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 2));
3534bff34e3Sthurlow }
3544bff34e3Sthurlow 
3554bff34e3Sthurlow int
3564bff34e3Sthurlow mb_get_uint16le(struct mbdata *mbp, uint16_t *x)
3574bff34e3Sthurlow {
3584bff34e3Sthurlow 	uint16_t v;
3594bff34e3Sthurlow 	int error = mb_get_uint16(mbp, &v);
3604bff34e3Sthurlow 
3614bff34e3Sthurlow 	if (x != NULL)
3624bff34e3Sthurlow 		*x = letohs(v);
3634bff34e3Sthurlow 	return (error);
3644bff34e3Sthurlow }
3654bff34e3Sthurlow 
3664bff34e3Sthurlow int
3674bff34e3Sthurlow mb_get_uint16be(struct mbdata *mbp, uint16_t *x) {
3684bff34e3Sthurlow 	uint16_t v;
3694bff34e3Sthurlow 	int error = mb_get_uint16(mbp, &v);
3704bff34e3Sthurlow 
3714bff34e3Sthurlow 	if (x != NULL)
3724bff34e3Sthurlow 		*x = betohs(v);
3734bff34e3Sthurlow 	return (error);
3744bff34e3Sthurlow }
3754bff34e3Sthurlow 
3764bff34e3Sthurlow int
3774bff34e3Sthurlow mb_get_uint32(struct mbdata *mbp, uint32_t *x)
3784bff34e3Sthurlow {
3794bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 4));
3804bff34e3Sthurlow }
3814bff34e3Sthurlow 
3824bff34e3Sthurlow int
3834bff34e3Sthurlow mb_get_uint32be(struct mbdata *mbp, uint32_t *x)
3844bff34e3Sthurlow {
3854bff34e3Sthurlow 	uint32_t v;
3864bff34e3Sthurlow 	int error;
3874bff34e3Sthurlow 
3884bff34e3Sthurlow 	error = mb_get_uint32(mbp, &v);
3894bff34e3Sthurlow 	if (x != NULL)
3904bff34e3Sthurlow 		*x = betohl(v);
3914bff34e3Sthurlow 	return (error);
3924bff34e3Sthurlow }
3934bff34e3Sthurlow 
3944bff34e3Sthurlow int
3954bff34e3Sthurlow mb_get_uint32le(struct mbdata *mbp, uint32_t *x)
3964bff34e3Sthurlow {
3974bff34e3Sthurlow 	uint32_t v;
3984bff34e3Sthurlow 	int error;
3994bff34e3Sthurlow 
4004bff34e3Sthurlow 	error = mb_get_uint32(mbp, &v);
4014bff34e3Sthurlow 	if (x != NULL)
4024bff34e3Sthurlow 		*x = letohl(v);
4034bff34e3Sthurlow 	return (error);
4044bff34e3Sthurlow }
4054bff34e3Sthurlow 
4064bff34e3Sthurlow int
4074bff34e3Sthurlow mb_get_uint64(struct mbdata *mbp, uint64_t *x)
4084bff34e3Sthurlow {
4094bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 8));
4104bff34e3Sthurlow }
4114bff34e3Sthurlow 
4124bff34e3Sthurlow int
4134bff34e3Sthurlow mb_get_uint64be(struct mbdata *mbp, uint64_t *x)
4144bff34e3Sthurlow {
4154bff34e3Sthurlow 	uint64_t v;
4164bff34e3Sthurlow 	int error;
4174bff34e3Sthurlow 
4184bff34e3Sthurlow 	error = mb_get_uint64(mbp, &v);
4194bff34e3Sthurlow 	if (x != NULL)
4204bff34e3Sthurlow 		*x = betohq(v);
4214bff34e3Sthurlow 	return (error);
4224bff34e3Sthurlow }
4234bff34e3Sthurlow 
4244bff34e3Sthurlow int
4254bff34e3Sthurlow mb_get_uint64le(struct mbdata *mbp, uint64_t *x)
4264bff34e3Sthurlow {
4274bff34e3Sthurlow 	uint64_t v;
4284bff34e3Sthurlow 	int error;
4294bff34e3Sthurlow 
4304bff34e3Sthurlow 	error = mb_get_uint64(mbp, &v);
4314bff34e3Sthurlow 	if (x != NULL)
4324bff34e3Sthurlow 		*x = letohq(v);
4334bff34e3Sthurlow 	return (error);
4344bff34e3Sthurlow }
4354bff34e3Sthurlow 
4364bff34e3Sthurlow int
4374bff34e3Sthurlow mb_get_mem(struct mbdata *mbp, char *target, size_t size)
4384bff34e3Sthurlow {
4394bff34e3Sthurlow 	struct mbuf *m = mbp->mb_cur;
4404bff34e3Sthurlow 	uint_t count;
4414bff34e3Sthurlow 
4424bff34e3Sthurlow 	while (size > 0) {
4434bff34e3Sthurlow 		if (m == NULL) {
4444bff34e3Sthurlow #ifdef DEBUG
4454bff34e3Sthurlow 			printf(
4464bff34e3Sthurlow 			    dgettext(TEXT_DOMAIN, "incomplete copy\n"));
4474bff34e3Sthurlow #endif
4484bff34e3Sthurlow #ifdef APPLE
4494bff34e3Sthurlow 			MBERROR("incomplete copy\n");
4504bff34e3Sthurlow #endif
4514bff34e3Sthurlow 			return (EBADRPC);
4524bff34e3Sthurlow 		}
4534bff34e3Sthurlow 		count = mb_left(m, mbp->mb_pos);
4544bff34e3Sthurlow 		if (count == 0) {
4554bff34e3Sthurlow 			mbp->mb_cur = m = m->m_next;
4564bff34e3Sthurlow 			if (m)
4574bff34e3Sthurlow 				mbp->mb_pos = mtod(m, char *);
4584bff34e3Sthurlow 			continue;
4594bff34e3Sthurlow 		}
4604bff34e3Sthurlow 		if (count > size)
4614bff34e3Sthurlow 			count = size;
4624bff34e3Sthurlow 		size -= count;
4634bff34e3Sthurlow 		if (target) {
4644bff34e3Sthurlow 			if (count == 1) {
4654bff34e3Sthurlow 				*target++ = *mbp->mb_pos;
4664bff34e3Sthurlow 			} else {
4674bff34e3Sthurlow 				bcopy(mbp->mb_pos, target, count);
4684bff34e3Sthurlow 				target += count;
4694bff34e3Sthurlow 			}
4704bff34e3Sthurlow 		}
4714bff34e3Sthurlow 		mbp->mb_pos += count;
4724bff34e3Sthurlow 	}
4734bff34e3Sthurlow 	return (0);
4744bff34e3Sthurlow }
475