xref: /titanic_41/usr/src/lib/libsmbfs/smb/mbuf.c (revision 7568150a58e78021968b6c22bc28e9787b33496a)
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 
354bff34e3Sthurlow #pragma ident	"%Z%%M%	%I%	%E% SMI"
364bff34e3Sthurlow 
374bff34e3Sthurlow #include <sys/types.h>
384bff34e3Sthurlow #include <ctype.h>
394bff34e3Sthurlow #include <errno.h>
404bff34e3Sthurlow #include <stdio.h>
414bff34e3Sthurlow #include <stdlib.h>
424bff34e3Sthurlow #include <string.h>
434bff34e3Sthurlow #include <strings.h>
444bff34e3Sthurlow #include <libintl.h>
45*7568150aSgwr #include <assert.h>
464bff34e3Sthurlow 
474bff34e3Sthurlow #include <netsmb/smb.h>
484bff34e3Sthurlow #include <netsmb/smb_lib.h>
494bff34e3Sthurlow #include <netsmb/mchain.h>
504bff34e3Sthurlow 
514bff34e3Sthurlow #ifdef APPLE
524bff34e3Sthurlow #define	__func__ ""
534bff34e3Sthurlow #define	MBERROR(format, args...) \
544bff34e3Sthurlow 	printf("%s(%d): "format, __func__, __LINE__, ## args)
554bff34e3Sthurlow #endif
564bff34e3Sthurlow 
574bff34e3Sthurlow static int
584bff34e3Sthurlow m_get(size_t len, struct mbuf **mpp)
594bff34e3Sthurlow {
604bff34e3Sthurlow 	struct mbuf *m;
614bff34e3Sthurlow 
62*7568150aSgwr 	assert(len < 0x100000); /* sanity */
63*7568150aSgwr 
644bff34e3Sthurlow 	len = M_ALIGN(len);
654bff34e3Sthurlow 	if (len < M_MINSIZE)
664bff34e3Sthurlow 		len = M_MINSIZE;
674bff34e3Sthurlow 	m = malloc(M_BASESIZE + len);
684bff34e3Sthurlow 	if (m == NULL)
694bff34e3Sthurlow 		return (ENOMEM);
704bff34e3Sthurlow 	bzero(m, M_BASESIZE + len);
714bff34e3Sthurlow 	m->m_maxlen = len;
724bff34e3Sthurlow 	m->m_data = M_TOP(m);
734bff34e3Sthurlow 	*mpp = m;
744bff34e3Sthurlow 	return (0);
754bff34e3Sthurlow }
764bff34e3Sthurlow 
774bff34e3Sthurlow static void
784bff34e3Sthurlow m_free(struct mbuf *m)
794bff34e3Sthurlow {
804bff34e3Sthurlow 	free(m);
814bff34e3Sthurlow }
824bff34e3Sthurlow 
834bff34e3Sthurlow static void
844bff34e3Sthurlow m_freem(struct mbuf *m0)
854bff34e3Sthurlow {
864bff34e3Sthurlow 	struct mbuf *m;
874bff34e3Sthurlow 
884bff34e3Sthurlow 	while (m0) {
894bff34e3Sthurlow 		m = m0->m_next;
904bff34e3Sthurlow 		m_free(m0);
914bff34e3Sthurlow 		m0 = m;
924bff34e3Sthurlow 	}
934bff34e3Sthurlow }
944bff34e3Sthurlow 
954bff34e3Sthurlow static size_t
964bff34e3Sthurlow m_totlen(struct mbuf *m0)
974bff34e3Sthurlow {
984bff34e3Sthurlow 	struct mbuf *m = m0;
994bff34e3Sthurlow 	int len = 0;
1004bff34e3Sthurlow 
1014bff34e3Sthurlow 	while (m) {
1024bff34e3Sthurlow 		len += m->m_len;
1034bff34e3Sthurlow 		m = m->m_next;
1044bff34e3Sthurlow 	}
1054bff34e3Sthurlow 	return (len);
1064bff34e3Sthurlow }
1074bff34e3Sthurlow 
1084bff34e3Sthurlow int
1094bff34e3Sthurlow m_lineup(struct mbuf *m0, struct mbuf **mpp)
1104bff34e3Sthurlow {
1114bff34e3Sthurlow 	struct mbuf *nm, *m;
1124bff34e3Sthurlow 	char *dp;
1134bff34e3Sthurlow 	size_t len;
1144bff34e3Sthurlow 	int error;
1154bff34e3Sthurlow 
1164bff34e3Sthurlow 	if (m0->m_next == NULL) {
1174bff34e3Sthurlow 		*mpp = m0;
1184bff34e3Sthurlow 		return (0);
1194bff34e3Sthurlow 	}
1204bff34e3Sthurlow 	if ((error = m_get(m_totlen(m0), &nm)) != 0)
1214bff34e3Sthurlow 		return (error);
1224bff34e3Sthurlow 	dp = mtod(nm, char *);
1234bff34e3Sthurlow 	while (m0) {
1244bff34e3Sthurlow 		len = m0->m_len;
1254bff34e3Sthurlow 		bcopy(m0->m_data, dp, len);
1264bff34e3Sthurlow 		dp += len;
1274bff34e3Sthurlow 		m = m0->m_next;
1284bff34e3Sthurlow 		m_free(m0);
1294bff34e3Sthurlow 		m0 = m;
1304bff34e3Sthurlow 	}
1314bff34e3Sthurlow 	*mpp = nm;
1324bff34e3Sthurlow 	return (0);
1334bff34e3Sthurlow }
1344bff34e3Sthurlow 
1354bff34e3Sthurlow int
1364bff34e3Sthurlow mb_init(struct mbdata *mbp, size_t size)
1374bff34e3Sthurlow {
1384bff34e3Sthurlow 	struct mbuf *m;
1394bff34e3Sthurlow 	int error;
1404bff34e3Sthurlow 
1414bff34e3Sthurlow 	if ((error = m_get(size, &m)) != 0)
1424bff34e3Sthurlow 		return (error);
1434bff34e3Sthurlow 	return (mb_initm(mbp, m));
1444bff34e3Sthurlow }
1454bff34e3Sthurlow 
1464bff34e3Sthurlow int
1474bff34e3Sthurlow mb_initm(struct mbdata *mbp, struct mbuf *m)
1484bff34e3Sthurlow {
1494bff34e3Sthurlow 	bzero(mbp, sizeof (*mbp));
1504bff34e3Sthurlow 	mbp->mb_top = mbp->mb_cur = m;
1514bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *);
1524bff34e3Sthurlow 	return (0);
1534bff34e3Sthurlow }
1544bff34e3Sthurlow 
1554bff34e3Sthurlow int
1564bff34e3Sthurlow mb_done(struct mbdata *mbp)
1574bff34e3Sthurlow {
1584bff34e3Sthurlow 	if (mbp->mb_top) {
1594bff34e3Sthurlow 		m_freem(mbp->mb_top);
1604bff34e3Sthurlow 		mbp->mb_top = NULL;
1614bff34e3Sthurlow 	}
1624bff34e3Sthurlow 	return (0);
1634bff34e3Sthurlow }
1644bff34e3Sthurlow 
1654bff34e3Sthurlow int
1664bff34e3Sthurlow m_getm(struct mbuf *top, size_t len, struct mbuf **mpp)
1674bff34e3Sthurlow {
1684bff34e3Sthurlow 	struct mbuf *m, *mp;
169*7568150aSgwr 	int  error, ts;
1704bff34e3Sthurlow 
1714bff34e3Sthurlow 	for (mp = top; ; mp = mp->m_next) {
172*7568150aSgwr 		ts = M_TRAILINGSPACE(mp);
173*7568150aSgwr 		if (len <= ts)
174*7568150aSgwr 			goto out;
175*7568150aSgwr 		len -= ts;
1764bff34e3Sthurlow 		if (mp->m_next == NULL)
1774bff34e3Sthurlow 			break;
1784bff34e3Sthurlow 
1794bff34e3Sthurlow 	}
1804bff34e3Sthurlow 	if (len > 0) {
1814bff34e3Sthurlow 		if ((error = m_get(len, &m)) != 0)
1824bff34e3Sthurlow 			return (error);
1834bff34e3Sthurlow 		mp->m_next = m;
1844bff34e3Sthurlow 	}
185*7568150aSgwr out:
1864bff34e3Sthurlow 	*mpp = top;
1874bff34e3Sthurlow 	return (0);
1884bff34e3Sthurlow }
1894bff34e3Sthurlow 
1904bff34e3Sthurlow /*
1914bff34e3Sthurlow  * Routines to put data in a buffer
1924bff34e3Sthurlow  */
1934bff34e3Sthurlow #define	MB_PUT(t)	int error; t *p; \
1944bff34e3Sthurlow 		if ((error = mb_fit(mbp, sizeof (t), (char **)&p)) != 0) \
1954bff34e3Sthurlow 			return (error)
1964bff34e3Sthurlow 
1974bff34e3Sthurlow /*
1984bff34e3Sthurlow  * Check if object of size 'size' fit to the current position and
1994bff34e3Sthurlow  * allocate new mbuf if not. Advance pointers and increase length of mbuf(s).
2004bff34e3Sthurlow  * Return pointer to the object placeholder or NULL if any error occured.
2014bff34e3Sthurlow  */
2024bff34e3Sthurlow int
2034bff34e3Sthurlow mb_fit(struct mbdata *mbp, size_t size, char **pp)
2044bff34e3Sthurlow {
2054bff34e3Sthurlow 	struct mbuf *m, *mn;
2064bff34e3Sthurlow 	int error;
2074bff34e3Sthurlow 
2084bff34e3Sthurlow 	m = mbp->mb_cur;
2094bff34e3Sthurlow 	if (M_TRAILINGSPACE(m) < (int)size) {
2104bff34e3Sthurlow 		if ((error = m_get(size, &mn)) != 0)
2114bff34e3Sthurlow 			return (error);
2124bff34e3Sthurlow 		mbp->mb_pos = mtod(mn, char *);
2134bff34e3Sthurlow 		mbp->mb_cur = m->m_next = mn;
2144bff34e3Sthurlow 		m = mn;
2154bff34e3Sthurlow 	}
2164bff34e3Sthurlow 	m->m_len += size;
2174bff34e3Sthurlow 	*pp = mbp->mb_pos;
2184bff34e3Sthurlow 	mbp->mb_pos += size;
2194bff34e3Sthurlow 	mbp->mb_count += size;
2204bff34e3Sthurlow 	return (0);
2214bff34e3Sthurlow }
2224bff34e3Sthurlow 
2234bff34e3Sthurlow int
2244bff34e3Sthurlow mb_put_uint8(struct mbdata *mbp, uint8_t x)
2254bff34e3Sthurlow {
2264bff34e3Sthurlow 	MB_PUT(uint8_t);
2274bff34e3Sthurlow 	*p = x;
2284bff34e3Sthurlow 	return (0);
2294bff34e3Sthurlow }
2304bff34e3Sthurlow 
2314bff34e3Sthurlow int
2324bff34e3Sthurlow mb_put_uint16be(struct mbdata *mbp, uint16_t x)
2334bff34e3Sthurlow {
2344bff34e3Sthurlow 	MB_PUT(uint16_t);
2354bff34e3Sthurlow 	/* LINTED */
2364bff34e3Sthurlow 	setwbe(p, 0, x);
2374bff34e3Sthurlow 	return (0);
2384bff34e3Sthurlow }
2394bff34e3Sthurlow 
2404bff34e3Sthurlow int
2414bff34e3Sthurlow mb_put_uint16le(struct mbdata *mbp, uint16_t x)
2424bff34e3Sthurlow {
2434bff34e3Sthurlow 	MB_PUT(uint16_t);
2444bff34e3Sthurlow 	/* LINTED */
2454bff34e3Sthurlow 	setwle(p, 0, x);
2464bff34e3Sthurlow 	return (0);
2474bff34e3Sthurlow }
2484bff34e3Sthurlow 
2494bff34e3Sthurlow int
2504bff34e3Sthurlow mb_put_uint32be(struct mbdata *mbp, uint32_t x)
2514bff34e3Sthurlow {
2524bff34e3Sthurlow 	MB_PUT(uint32_t);
2534bff34e3Sthurlow 	/* LINTED */
2544bff34e3Sthurlow 	setdbe(p, 0, x);
2554bff34e3Sthurlow 	return (0);
2564bff34e3Sthurlow }
2574bff34e3Sthurlow 
2584bff34e3Sthurlow int
2594bff34e3Sthurlow mb_put_uint32le(struct mbdata *mbp, uint32_t x)
2604bff34e3Sthurlow {
2614bff34e3Sthurlow 	MB_PUT(uint32_t);
2624bff34e3Sthurlow 	/* LINTED */
2634bff34e3Sthurlow 	setdle(p, 0, x);
2644bff34e3Sthurlow 	return (0);
2654bff34e3Sthurlow }
2664bff34e3Sthurlow 
2674bff34e3Sthurlow int
2684bff34e3Sthurlow mb_put_uint64be(struct mbdata *mbp, uint64_t x)
2694bff34e3Sthurlow {
2704bff34e3Sthurlow 	MB_PUT(uint64_t);
2714bff34e3Sthurlow 	*p = htobeq(x);
2724bff34e3Sthurlow 	return (0);
2734bff34e3Sthurlow }
2744bff34e3Sthurlow 
2754bff34e3Sthurlow int
2764bff34e3Sthurlow mb_put_uint64le(struct mbdata *mbp, uint64_t x)
2774bff34e3Sthurlow {
2784bff34e3Sthurlow 	MB_PUT(uint64_t);
2794bff34e3Sthurlow 	*p = htoleq(x);
2804bff34e3Sthurlow 	return (0);
2814bff34e3Sthurlow }
2824bff34e3Sthurlow 
2834bff34e3Sthurlow int
2844bff34e3Sthurlow mb_put_mem(struct mbdata *mbp, const char *source, size_t size)
2854bff34e3Sthurlow {
2864bff34e3Sthurlow 	struct mbuf *m;
2874bff34e3Sthurlow 	char  *dst;
2884bff34e3Sthurlow 	size_t cplen;
2894bff34e3Sthurlow 	int error;
2904bff34e3Sthurlow 
2914bff34e3Sthurlow 	if (size == 0)
2924bff34e3Sthurlow 		return (0);
2934bff34e3Sthurlow 	m = mbp->mb_cur;
2944bff34e3Sthurlow 	if ((error = m_getm(m, size, &m)) != 0)
2954bff34e3Sthurlow 		return (error);
2964bff34e3Sthurlow 	while (size > 0) {
2974bff34e3Sthurlow 		cplen = M_TRAILINGSPACE(m);
2984bff34e3Sthurlow 		if (cplen == 0) {
2994bff34e3Sthurlow 			m = m->m_next;
3004bff34e3Sthurlow 			continue;
3014bff34e3Sthurlow 		}
3024bff34e3Sthurlow 		if (cplen > size)
3034bff34e3Sthurlow 			cplen = size;
3044bff34e3Sthurlow 		dst = mtod(m, char *) + m->m_len;
3054bff34e3Sthurlow 		if (source) {
3064bff34e3Sthurlow 			bcopy(source, dst, cplen);
3074bff34e3Sthurlow 			source += cplen;
3084bff34e3Sthurlow 		} else
3094bff34e3Sthurlow 			bzero(dst, cplen);
3104bff34e3Sthurlow 		size -= cplen;
3114bff34e3Sthurlow 		m->m_len += cplen;
3124bff34e3Sthurlow 		mbp->mb_count += cplen;
3134bff34e3Sthurlow 	}
3144bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
3154bff34e3Sthurlow 	mbp->mb_cur = m;
3164bff34e3Sthurlow 	return (0);
3174bff34e3Sthurlow }
3184bff34e3Sthurlow 
3194bff34e3Sthurlow int
3204bff34e3Sthurlow mb_put_mbuf(struct mbdata *mbp, struct mbuf *m)
3214bff34e3Sthurlow {
3224bff34e3Sthurlow 	mbp->mb_cur->m_next = m;
3234bff34e3Sthurlow 	while (m) {
3244bff34e3Sthurlow 		mbp->mb_count += m->m_len;
3254bff34e3Sthurlow 		if (m->m_next == NULL)
3264bff34e3Sthurlow 			break;
3274bff34e3Sthurlow 		m = m->m_next;
3284bff34e3Sthurlow 	}
3294bff34e3Sthurlow 	mbp->mb_pos = mtod(m, char *) + m->m_len;
3304bff34e3Sthurlow 	mbp->mb_cur = m;
3314bff34e3Sthurlow 	return (0);
3324bff34e3Sthurlow }
3334bff34e3Sthurlow 
3344bff34e3Sthurlow int
3354bff34e3Sthurlow mb_put_pstring(struct mbdata *mbp, const char *s)
3364bff34e3Sthurlow {
3374bff34e3Sthurlow 	int error, len = strlen(s);
3384bff34e3Sthurlow 
3394bff34e3Sthurlow 	if (len > 255) {
3404bff34e3Sthurlow 		len = 255;
3414bff34e3Sthurlow 	}
3424bff34e3Sthurlow 	if ((error = mb_put_uint8(mbp, len)) != 0)
3434bff34e3Sthurlow 		return (error);
3444bff34e3Sthurlow 	return (mb_put_mem(mbp, s, len));
3454bff34e3Sthurlow }
3464bff34e3Sthurlow 
3474bff34e3Sthurlow /*
3484bff34e3Sthurlow  * Routines for fetching data from an mbuf chain
3494bff34e3Sthurlow  */
3504bff34e3Sthurlow #define	mb_left(m, p)	(mtod(m, char *) + (m)->m_len - (p))
3514bff34e3Sthurlow 
3524bff34e3Sthurlow int
3534bff34e3Sthurlow mb_get_uint8(struct mbdata *mbp, uint8_t *x)
3544bff34e3Sthurlow {
3554bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 1));
3564bff34e3Sthurlow }
3574bff34e3Sthurlow 
3584bff34e3Sthurlow int
3594bff34e3Sthurlow mb_get_uint16(struct mbdata *mbp, uint16_t *x)
3604bff34e3Sthurlow {
3614bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 2));
3624bff34e3Sthurlow }
3634bff34e3Sthurlow 
3644bff34e3Sthurlow int
3654bff34e3Sthurlow mb_get_uint16le(struct mbdata *mbp, uint16_t *x)
3664bff34e3Sthurlow {
3674bff34e3Sthurlow 	uint16_t v;
3684bff34e3Sthurlow 	int error = mb_get_uint16(mbp, &v);
3694bff34e3Sthurlow 
3704bff34e3Sthurlow 	if (x != NULL)
3714bff34e3Sthurlow 		*x = letohs(v);
3724bff34e3Sthurlow 	return (error);
3734bff34e3Sthurlow }
3744bff34e3Sthurlow 
3754bff34e3Sthurlow int
3764bff34e3Sthurlow mb_get_uint16be(struct mbdata *mbp, uint16_t *x) {
3774bff34e3Sthurlow 	uint16_t v;
3784bff34e3Sthurlow 	int error = mb_get_uint16(mbp, &v);
3794bff34e3Sthurlow 
3804bff34e3Sthurlow 	if (x != NULL)
3814bff34e3Sthurlow 		*x = betohs(v);
3824bff34e3Sthurlow 	return (error);
3834bff34e3Sthurlow }
3844bff34e3Sthurlow 
3854bff34e3Sthurlow int
3864bff34e3Sthurlow mb_get_uint32(struct mbdata *mbp, uint32_t *x)
3874bff34e3Sthurlow {
3884bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 4));
3894bff34e3Sthurlow }
3904bff34e3Sthurlow 
3914bff34e3Sthurlow int
3924bff34e3Sthurlow mb_get_uint32be(struct mbdata *mbp, uint32_t *x)
3934bff34e3Sthurlow {
3944bff34e3Sthurlow 	uint32_t v;
3954bff34e3Sthurlow 	int error;
3964bff34e3Sthurlow 
3974bff34e3Sthurlow 	error = mb_get_uint32(mbp, &v);
3984bff34e3Sthurlow 	if (x != NULL)
3994bff34e3Sthurlow 		*x = betohl(v);
4004bff34e3Sthurlow 	return (error);
4014bff34e3Sthurlow }
4024bff34e3Sthurlow 
4034bff34e3Sthurlow int
4044bff34e3Sthurlow mb_get_uint32le(struct mbdata *mbp, uint32_t *x)
4054bff34e3Sthurlow {
4064bff34e3Sthurlow 	uint32_t v;
4074bff34e3Sthurlow 	int error;
4084bff34e3Sthurlow 
4094bff34e3Sthurlow 	error = mb_get_uint32(mbp, &v);
4104bff34e3Sthurlow 	if (x != NULL)
4114bff34e3Sthurlow 		*x = letohl(v);
4124bff34e3Sthurlow 	return (error);
4134bff34e3Sthurlow }
4144bff34e3Sthurlow 
4154bff34e3Sthurlow int
4164bff34e3Sthurlow mb_get_uint64(struct mbdata *mbp, uint64_t *x)
4174bff34e3Sthurlow {
4184bff34e3Sthurlow 	return (mb_get_mem(mbp, (char *)x, 8));
4194bff34e3Sthurlow }
4204bff34e3Sthurlow 
4214bff34e3Sthurlow int
4224bff34e3Sthurlow mb_get_uint64be(struct mbdata *mbp, uint64_t *x)
4234bff34e3Sthurlow {
4244bff34e3Sthurlow 	uint64_t v;
4254bff34e3Sthurlow 	int error;
4264bff34e3Sthurlow 
4274bff34e3Sthurlow 	error = mb_get_uint64(mbp, &v);
4284bff34e3Sthurlow 	if (x != NULL)
4294bff34e3Sthurlow 		*x = betohq(v);
4304bff34e3Sthurlow 	return (error);
4314bff34e3Sthurlow }
4324bff34e3Sthurlow 
4334bff34e3Sthurlow int
4344bff34e3Sthurlow mb_get_uint64le(struct mbdata *mbp, uint64_t *x)
4354bff34e3Sthurlow {
4364bff34e3Sthurlow 	uint64_t v;
4374bff34e3Sthurlow 	int error;
4384bff34e3Sthurlow 
4394bff34e3Sthurlow 	error = mb_get_uint64(mbp, &v);
4404bff34e3Sthurlow 	if (x != NULL)
4414bff34e3Sthurlow 		*x = letohq(v);
4424bff34e3Sthurlow 	return (error);
4434bff34e3Sthurlow }
4444bff34e3Sthurlow 
4454bff34e3Sthurlow int
4464bff34e3Sthurlow mb_get_mem(struct mbdata *mbp, char *target, size_t size)
4474bff34e3Sthurlow {
4484bff34e3Sthurlow 	struct mbuf *m = mbp->mb_cur;
4494bff34e3Sthurlow 	uint_t count;
4504bff34e3Sthurlow 
4514bff34e3Sthurlow 	while (size > 0) {
4524bff34e3Sthurlow 		if (m == NULL) {
4534bff34e3Sthurlow #ifdef DEBUG
4544bff34e3Sthurlow 			printf(
4554bff34e3Sthurlow 			    dgettext(TEXT_DOMAIN, "incomplete copy\n"));
4564bff34e3Sthurlow #endif
4574bff34e3Sthurlow #ifdef APPLE
4584bff34e3Sthurlow 			MBERROR("incomplete copy\n");
4594bff34e3Sthurlow #endif
4604bff34e3Sthurlow 			return (EBADRPC);
4614bff34e3Sthurlow 		}
4624bff34e3Sthurlow 		count = mb_left(m, mbp->mb_pos);
4634bff34e3Sthurlow 		if (count == 0) {
4644bff34e3Sthurlow 			mbp->mb_cur = m = m->m_next;
4654bff34e3Sthurlow 			if (m)
4664bff34e3Sthurlow 				mbp->mb_pos = mtod(m, char *);
4674bff34e3Sthurlow 			continue;
4684bff34e3Sthurlow 		}
4694bff34e3Sthurlow 		if (count > size)
4704bff34e3Sthurlow 			count = size;
4714bff34e3Sthurlow 		size -= count;
4724bff34e3Sthurlow 		if (target) {
4734bff34e3Sthurlow 			if (count == 1) {
4744bff34e3Sthurlow 				*target++ = *mbp->mb_pos;
4754bff34e3Sthurlow 			} else {
4764bff34e3Sthurlow 				bcopy(mbp->mb_pos, target, count);
4774bff34e3Sthurlow 				target += count;
4784bff34e3Sthurlow 			}
4794bff34e3Sthurlow 		}
4804bff34e3Sthurlow 		mbp->mb_pos += count;
4814bff34e3Sthurlow 	}
4824bff34e3Sthurlow 	return (0);
4834bff34e3Sthurlow }
484