summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbp <bp@FreeBSD.org>2001-02-24 15:44:30 +0000
committerbp <bp@FreeBSD.org>2001-02-24 15:44:30 +0000
commit1bdf6a6d1487f16229bd23e00ffc0ff9fdcaff8f (patch)
treef826bac67a557e7ac83634b923aa31999a7043e8
parentf39a190a3fbeec164c525428c49351465d4a9477 (diff)
downloadFreeBSD-src-1bdf6a6d1487f16229bd23e00ffc0ff9fdcaff8f.zip
FreeBSD-src-1bdf6a6d1487f16229bd23e00ffc0ff9fdcaff8f.tar.gz
Introduce API for sequential reads/writes (build/dissect) of mbuf chains.
Reviewed by: Ian Dowse <iedowse@maths.tcd.ie>, Bosko Milekic <bmilekic@technokratis.com>, Julian Elischer <julian@elischer.org> and arch@/net@ Obtained from: smbfs
-rw-r--r--sys/conf/NOTES3
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/options1
-rw-r--r--sys/i386/conf/NOTES3
-rw-r--r--sys/kern/subr_mchain.c549
-rw-r--r--sys/modules/Makefile2
-rw-r--r--sys/modules/libmchain/Makefile8
-rw-r--r--sys/sys/mchain.h155
8 files changed, 721 insertions, 1 deletions
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index a613a71..1b3dc79 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -413,6 +413,9 @@ options NETATALKDEBUG #Appletalk debugging
#options NS #Xerox NS protocols
#options NSIP #XNS over IP
+# mchain library. It can be either loaded as KLD or compiled into kernel
+options LIBMCHAIN
+
# netgraph(4). Enable the base netgraph code with the NETGRAPH option.
# Individual node types can be enabled with the corresponding option
# listed below; however, this is not strictly necessary as netgraph
diff --git a/sys/conf/files b/sys/conf/files
index d1b80bc..93b652a 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -697,6 +697,7 @@ kern/subr_diskslice.c standard
kern/subr_eventhandler.c standard
kern/subr_kobj.c standard
kern/subr_log.c standard
+kern/subr_mchain.c optional libmchain
kern/subr_module.c standard
kern/subr_prf.c standard
kern/subr_prof.c standard
diff --git a/sys/conf/options b/sys/conf/options
index 86198f6..5df2902 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -262,6 +262,7 @@ IPSTEALTH
IPX opt_ipx.h
IPXIP opt_ipx.h
IPTUNNEL opt_ipx.h
+LIBMCHAIN
NCP opt_ncp.h
NETATALK opt_atalk.h
PPP_BSDCOMP opt_ppp.h
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index a613a71..1b3dc79 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -413,6 +413,9 @@ options NETATALKDEBUG #Appletalk debugging
#options NS #Xerox NS protocols
#options NSIP #XNS over IP
+# mchain library. It can be either loaded as KLD or compiled into kernel
+options LIBMCHAIN
+
# netgraph(4). Enable the base netgraph code with the NETGRAPH option.
# Individual node types can be enabled with the corresponding option
# listed below; however, this is not strictly necessary as netgraph
diff --git a/sys/kern/subr_mchain.c b/sys/kern/subr_mchain.c
new file mode 100644
index 0000000..3f13c80
--- /dev/null
+++ b/sys/kern/subr_mchain.c
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2000, 2001 Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/mbuf.h>
+#include <sys/module.h>
+#include <sys/uio.h>
+
+#include <sys/mchain.h>
+
+MODULE_VERSION(libmchain, 1);
+
+#define MBERROR(format, args...) printf("%s(%d): "format, __FUNCTION__ , \
+ __LINE__ ,## args)
+
+#define MBPANIC(format, args...) printf("%s(%d): "format, __FUNCTION__ , \
+ __LINE__ ,## args)
+
+/*
+ * Various helper functions
+ */
+int
+m_fixhdr(struct mbuf *m0)
+{
+ struct mbuf *m = m0;
+ int len = 0;
+
+ while (m) {
+ len += m->m_len;
+ m = m->m_next;
+ }
+ m0->m_pkthdr.len = len;
+ return len;
+}
+
+int
+mb_init(struct mbchain *mbp)
+{
+ struct mbuf *m;
+
+ m = m_gethdr(M_TRYWAIT, MT_DATA);
+ if (m == NULL)
+ return ENOBUFS;
+ m->m_pkthdr.rcvif = NULL;
+ m->m_len = 0;
+ mb_initm(mbp, m);
+ return 0;
+}
+
+void
+mb_initm(struct mbchain *mbp, struct mbuf *m)
+{
+ bzero(mbp, sizeof(*mbp));
+ mbp->mb_top = mbp->mb_cur = m;
+ mbp->mb_mleft = M_TRAILINGSPACE(m);
+}
+
+void
+mb_done(struct mbchain *mbp)
+{
+ if (mbp->mb_top) {
+ m_freem(mbp->mb_top);
+ mbp->mb_top = NULL;
+ }
+}
+
+struct mbuf *
+mb_detach(struct mbchain *mbp)
+{
+ struct mbuf *m;
+
+ m = mbp->mb_top;
+ mbp->mb_top = NULL;
+ return m;
+}
+
+int
+mb_fixhdr(struct mbchain *mbp)
+{
+ return mbp->mb_top->m_pkthdr.len = m_fixhdr(mbp->mb_top);
+}
+
+/*
+ * Check if object of size 'size' fit to the current position and
+ * allocate new mbuf if not. Advance pointers and increase length of mbuf(s).
+ * Return pointer to the object placeholder or NULL if any error occured.
+ * Note: size should be <= MLEN
+ */
+caddr_t
+mb_reserve(struct mbchain *mbp, int size)
+{
+ struct mbuf *m, *mn;
+ caddr_t bpos;
+
+ if (size > MLEN)
+ panic("mb_reserve: size = %d\n", size);
+ m = mbp->mb_cur;
+ if (mbp->mb_mleft < size) {
+ mn = m_get(M_TRYWAIT, MT_DATA);
+ if (mn == NULL)
+ return NULL;
+ mbp->mb_cur = m->m_next = mn;
+ m = mn;
+ m->m_len = 0;
+ mbp->mb_mleft = M_TRAILINGSPACE(m);
+ }
+ mbp->mb_mleft -= size;
+ mbp->mb_count += size;
+ bpos = mtod(m, caddr_t) + m->m_len;
+ m->m_len += size;
+ return bpos;
+}
+
+int
+mb_put_uint8(struct mbchain *mbp, u_int8_t x)
+{
+ return mb_put_mem(mbp, (caddr_t)&x, sizeof(x), MB_MSYSTEM);
+}
+
+int
+mb_put_uint16be(struct mbchain *mbp, u_int16_t x)
+{
+ x = htobes(x);
+ return mb_put_mem(mbp, (caddr_t)&x, sizeof(x), MB_MSYSTEM);
+}
+
+int
+mb_put_uint16le(struct mbchain *mbp, u_int16_t x)
+{
+ x = htoles(x);
+ return mb_put_mem(mbp, (caddr_t)&x, sizeof(x), MB_MSYSTEM);
+}
+
+int
+mb_put_uint32be(struct mbchain *mbp, u_int32_t x)
+{
+ x = htobel(x);
+ return mb_put_mem(mbp, (caddr_t)&x, sizeof(x), MB_MSYSTEM);
+}
+
+int
+mb_put_uint32le(struct mbchain *mbp, u_int32_t x)
+{
+ x = htolel(x);
+ return mb_put_mem(mbp, (caddr_t)&x, sizeof(x), MB_MSYSTEM);
+}
+
+int
+mb_put_int64be(struct mbchain *mbp, int64_t x)
+{
+ x = htobeq(x);
+ return mb_put_mem(mbp, (caddr_t)&x, sizeof(x), MB_MSYSTEM);
+}
+
+int
+mb_put_int64le(struct mbchain *mbp, int64_t x)
+{
+ x = htoleq(x);
+ return mb_put_mem(mbp, (caddr_t)&x, sizeof(x), MB_MSYSTEM);
+}
+
+int
+mb_put_mem(struct mbchain *mbp, c_caddr_t source, int size, int type)
+{
+ struct mbuf *m;
+ caddr_t dst;
+ c_caddr_t src;
+ int cplen, error, mleft, count;
+
+ m = mbp->mb_cur;
+ mleft = mbp->mb_mleft;
+
+ while (size > 0) {
+ if (mleft == 0) {
+ if (m->m_next == NULL) {
+ m = m_getm(m, size, M_TRYWAIT, MT_DATA);
+ if (m == NULL)
+ return ENOBUFS;
+ }
+ m = m->m_next;
+ mleft = M_TRAILINGSPACE(m);
+ continue;
+ }
+ cplen = mleft > size ? size : mleft;
+ dst = mtod(m, caddr_t) + m->m_len;
+ switch (type) {
+ case MB_MCUSTOM:
+ error = mbp->mb_copy(mbp, source, dst, cplen);
+ if (error)
+ return error;
+ break;
+ case MB_MINLINE:
+ for (src = source, count = cplen; count; count--)
+ *dst++ = *src++;
+ break;
+ case MB_MSYSTEM:
+ bcopy(source, dst, cplen);
+ break;
+ case MB_MUSER:
+ error = copyin(source, dst, cplen);
+ if (error)
+ return error;
+ break;
+ case MB_MZERO:
+ bzero(dst, cplen);
+ break;
+ }
+ size -= cplen;
+ source += cplen;
+ m->m_len += cplen;
+ mleft -= cplen;
+ mbp->mb_count += cplen;
+ }
+ mbp->mb_cur = m;
+ mbp->mb_mleft = mleft;
+ return 0;
+}
+
+int
+mb_put_mbuf(struct mbchain *mbp, struct mbuf *m)
+{
+ mbp->mb_cur->m_next = m;
+ while (m) {
+ mbp->mb_count += m->m_len;
+ if (m->m_next == NULL)
+ break;
+ m = m->m_next;
+ }
+ mbp->mb_mleft = M_TRAILINGSPACE(m);
+ mbp->mb_cur = m;
+ return 0;
+}
+
+/*
+ * copies a uio scatter/gather list to an mbuf chain.
+ * NOTE: can ony handle iovcnt == 1
+ */
+int
+mb_put_uio(struct mbchain *mbp, struct uio *uiop, int size)
+{
+ long left;
+ int mtype, error;
+
+#ifdef DIAGNOSTIC
+ if (uiop->uio_iovcnt != 1)
+ MBPANIC("iovcnt != 1");
+#endif
+ mtype = (uiop->uio_segflg == UIO_SYSSPACE) ? MB_MSYSTEM : MB_MUSER;
+
+ while (size > 0) {
+ left = uiop->uio_iov->iov_len;
+ if (left > size)
+ left = size;
+ error = mb_put_mem(mbp, uiop->uio_iov->iov_base, left, mtype);
+ if (error)
+ return error;
+ uiop->uio_offset += left;
+ uiop->uio_resid -= left;
+ uiop->uio_iov->iov_base += left;
+ uiop->uio_iov->iov_len -= left;
+ size -= left;
+ }
+ return 0;
+}
+
+/*
+ * Routines for fetching data from an mbuf chain
+ */
+int
+md_init(struct mdchain *mdp)
+{
+ struct mbuf *m;
+
+ m = m_gethdr(M_TRYWAIT, MT_DATA);
+ if (m == NULL)
+ return ENOBUFS;
+ m->m_pkthdr.rcvif = NULL;
+ m->m_len = 0;
+ md_initm(mdp, m);
+ return 0;
+}
+
+void
+md_initm(struct mdchain *mdp, struct mbuf *m)
+{
+ bzero(mdp, sizeof(*mdp));
+ mdp->md_top = mdp->md_cur = m;
+ mdp->md_pos = mtod(m, u_char*);
+}
+
+void
+md_done(struct mdchain *mdp)
+{
+ if (mdp->md_top) {
+ m_freem(mdp->md_top);
+ mdp->md_top = NULL;
+ }
+}
+
+/*
+ * Append a separate mbuf chain. It is caller responsibility to prevent
+ * multiple calls to fetch/record routines.
+ */
+void
+md_append_record(struct mdchain *mdp, struct mbuf *top)
+{
+ struct mbuf *m;
+
+ if (mdp->md_top == NULL) {
+ md_initm(mdp, top);
+ return;
+ }
+ m = mdp->md_top;
+ while (m->m_nextpkt)
+ m = m->m_nextpkt;
+ m->m_nextpkt = top;
+ top->m_nextpkt = NULL;
+ return;
+}
+
+/*
+ * Put next record in place of existing
+ */
+int
+md_next_record(struct mdchain *mdp)
+{
+ struct mbuf *m;
+
+ if (mdp->md_top == NULL)
+ return ENOENT;
+ m = mdp->md_top->m_nextpkt;
+ md_done(mdp);
+ if (m == NULL)
+ return ENOENT;
+ md_initm(mdp, m);
+ return 0;
+}
+
+int
+md_get_uint8(struct mdchain *mdp, u_int8_t *x)
+{
+ return md_get_mem(mdp, x, 1, MB_MINLINE);
+}
+
+int
+md_get_uint16(struct mdchain *mdp, u_int16_t *x)
+{
+ return md_get_mem(mdp, (caddr_t)x, 2, MB_MINLINE);
+}
+
+int
+md_get_uint16le(struct mdchain *mdp, u_int16_t *x)
+{
+ u_int16_t v;
+ int error = md_get_uint16(mdp, &v);
+
+ *x = letohs(v);
+ return error;
+}
+
+int
+md_get_uint16be(struct mdchain *mdp, u_int16_t *x) {
+ u_int16_t v;
+ int error = md_get_uint16(mdp, &v);
+
+ *x = betohs(v);
+ return error;
+}
+
+int
+md_get_uint32(struct mdchain *mdp, u_int32_t *x)
+{
+ return md_get_mem(mdp, (caddr_t)x, 4, MB_MINLINE);
+}
+
+int
+md_get_uint32be(struct mdchain *mdp, u_int32_t *x)
+{
+ u_int32_t v;
+ int error;
+
+ error = md_get_uint32(mdp, &v);
+ *x = betohl(v);
+ return error;
+}
+
+int
+md_get_uint32le(struct mdchain *mdp, u_int32_t *x)
+{
+ u_int32_t v;
+ int error;
+
+ error = md_get_uint32(mdp, &v);
+ *x = letohl(v);
+ return error;
+}
+
+int
+md_get_int64(struct mdchain *mdp, int64_t *x)
+{
+ return md_get_mem(mdp, (caddr_t)x, 8, MB_MINLINE);
+}
+
+int
+md_get_int64be(struct mdchain *mdp, int64_t *x)
+{
+ int64_t v;
+ int error;
+
+ error = md_get_int64(mdp, &v);
+ *x = betohq(v);
+ return error;
+}
+
+int
+md_get_int64le(struct mdchain *mdp, int64_t *x)
+{
+ int64_t v;
+ int error;
+
+ error = md_get_int64(mdp, &v);
+ *x = letohq(v);
+ return error;
+}
+
+int
+md_get_mem(struct mdchain *mdp, caddr_t target, int size, int type)
+{
+ struct mbuf *m = mdp->md_cur;
+ int error;
+ u_int count;
+ u_char *s;
+
+ while (size > 0) {
+ if (m == NULL) {
+ MBERROR("incomplete copy\n");
+ return EBADRPC;
+ }
+ s = mdp->md_pos;
+ count = mtod(m, u_char*) + m->m_len - s;
+ if (count == 0) {
+ mdp->md_cur = m = m->m_next;
+ if (m)
+ s = mdp->md_pos = mtod(m, caddr_t);
+ continue;
+ }
+ if (count > size)
+ count = size;
+ size -= count;
+ mdp->md_pos += count;
+ if (target == NULL)
+ continue;
+ switch (type) {
+ case MB_MUSER:
+ error = copyout(s, target, count);
+ if (error)
+ return error;
+ break;
+ case MB_MSYSTEM:
+ bcopy(s, target, count);
+ break;
+ case MB_MINLINE:
+ while (count--)
+ *target++ = *s++;
+ continue;
+ }
+ target += count;
+ }
+ return 0;
+}
+
+int
+md_get_mbuf(struct mdchain *mdp, int size, struct mbuf **ret)
+{
+ struct mbuf *m = mdp->md_cur, *rm;
+
+ rm = m_copym(m, mdp->md_pos - mtod(m, u_char*), size, M_TRYWAIT);
+ if (rm == NULL)
+ return EBADRPC;
+ md_get_mem(mdp, NULL, size, MB_MZERO);
+ *ret = rm;
+ return 0;
+}
+
+int
+md_get_uio(struct mdchain *mdp, struct uio *uiop, int size)
+{
+ char *uiocp;
+ long left;
+ int mtype, error;
+
+ mtype = (uiop->uio_segflg == UIO_SYSSPACE) ? MB_MSYSTEM : MB_MUSER;
+ while (size > 0) {
+ if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
+ return EFBIG;
+ left = uiop->uio_iov->iov_len;
+ uiocp = uiop->uio_iov->iov_base;
+ if (left > size)
+ left = size;
+ error = md_get_mem(mdp, uiocp, left, mtype);
+ if (error)
+ return error;
+ uiop->uio_offset += left;
+ uiop->uio_resid -= left;
+ if (uiop->uio_iov->iov_len <= size) {
+ uiop->uio_iovcnt--;
+ uiop->uio_iov++;
+ } else {
+ uiop->uio_iov->iov_base += left;
+ uiop->uio_iov->iov_len -= left;
+ }
+ size -= left;
+ }
+ return 0;
+}
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 50cdc43..fd7f58f 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -9,7 +9,7 @@ _random= random
SUBDIR= 3dfx accf_data accf_http agp aha amr an aue \
cam ccd cd9660 coda cue dc de ed fdesc fxp if_disc if_ef \
if_ppp if_sl if_tap if_tun ip6fw ipfilter ipfw ispfw joy kue \
- linux lnc md mfs mii mlx msdos ncp netgraph nfs ntfs nullfs \
+ libmchain linux lnc md mfs mii mlx msdos ncp netgraph nfs ntfs nullfs \
nwfs pcn portal procfs ${_random} \
rl rp sf sis sk sn sound sppp ste sym syscons sysvipc ti tl twe tx \
udbp ugen uhid ukbd ulpt umapfs umass umodem ums union urio usb \
diff --git a/sys/modules/libmchain/Makefile b/sys/modules/libmchain/Makefile
new file mode 100644
index 0000000..39cfeb0
--- /dev/null
+++ b/sys/modules/libmchain/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../kern
+
+KMOD= libmchain
+SRCS= subr_mchain.c
+
+.include <bsd.kmod.mk>
diff --git a/sys/sys/mchain.h b/sys/sys/mchain.h
new file mode 100644
index 0000000..e79fbfb
--- /dev/null
+++ b/sys/sys/mchain.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2000, 2001 Boris Popov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Boris Popov.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _SYS_MCHAIN_H_
+#define _SYS_MCHAIN_H_
+
+#include <machine/endian.h>
+
+/*
+ * This macros probably belongs to the endian.h
+ */
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+
+#define htoles(x) ((u_int16_t)(x))
+#define letohs(x) ((u_int16_t)(x))
+#define htolel(x) ((u_int32_t)(x))
+#define letohl(x) ((u_int32_t)(x))
+#define htoleq(x) ((int64_t)(x))
+#define letohq(x) ((int64_t)(x))
+
+#define htobes(x) (htons(x))
+#define betohs(x) (ntohs(x))
+#define htobel(x) (htonl(x))
+#define betohl(x) (ntohl(x))
+
+static __inline int64_t
+htobeq(int64_t x)
+{
+ return (int64_t)htonl((u_int32_t)(x >> 32)) |
+ (int64_t)htonl((u_int32_t)(x & 0xffffffff)) << 32;
+}
+
+static __inline int64_t
+betohq(int64_t x)
+{
+ return (int64_t)ntohl((u_int32_t)(x >> 32)) |
+ (int64_t)ntohl((u_int32_t)(x & 0xffffffff)) << 32;
+}
+
+#else /* (BYTE_ORDER == LITTLE_ENDIAN) */
+
+#error "Macros for Big-Endians are incomplete"
+
+/*
+#define htoles(x) ((u_int16_t)(x))
+#define letohs(x) ((u_int16_t)(x))
+#define htolel(x) ((u_int32_t)(x))
+#define letohl(x) ((u_int32_t)(x))
+*/
+#endif /* (BYTE_ORDER == LITTLE_ENDIAN) */
+
+
+#ifdef _KERNEL
+
+/*
+ * Type of copy for mb_{put|get}_mem()
+ */
+#define MB_MSYSTEM 0 /* use bcopy() */
+#define MB_MUSER 1 /* use copyin()/copyout() */
+#define MB_MINLINE 2 /* use an inline copy loop */
+#define MB_MZERO 3 /* bzero(), mb_put_mem only */
+#define MB_MCUSTOM 4 /* use an user defined function */
+
+struct mbuf;
+struct mbchain;
+
+typedef int mb_copy_t(struct mbchain *mbp, c_caddr_t src, caddr_t dst, int len);
+
+struct mbchain {
+ struct mbuf * mb_top; /* head of mbufs chain */
+ struct mbuf * mb_cur; /* current mbuf */
+ int mb_mleft; /* free space in the current mbuf */
+ int mb_count; /* total number of bytes */
+ mb_copy_t * mb_copy; /* user defined copy function */
+ void * mb_udata; /* user data */
+};
+
+struct mdchain {
+ struct mbuf * md_top; /* head of mbufs chain */
+ struct mbuf * md_cur; /* current mbuf */
+ u_char * md_pos; /* offset in the current mbuf */
+};
+
+int m_fixhdr(struct mbuf *m);
+
+int mb_init(struct mbchain *mbp);
+void mb_initm(struct mbchain *mbp, struct mbuf *m);
+void mb_done(struct mbchain *mbp);
+struct mbuf *mb_detach(struct mbchain *mbp);
+int mb_fixhdr(struct mbchain *mbp);
+caddr_t mb_reserve(struct mbchain *mbp, int size);
+
+int mb_put_uint8(struct mbchain *mbp, u_int8_t x);
+int mb_put_uint16be(struct mbchain *mbp, u_int16_t x);
+int mb_put_uint16le(struct mbchain *mbp, u_int16_t x);
+int mb_put_uint32be(struct mbchain *mbp, u_int32_t x);
+int mb_put_uint32le(struct mbchain *mbp, u_int32_t x);
+int mb_put_int64be(struct mbchain *mbp, int64_t x);
+int mb_put_int64le(struct mbchain *mbp, int64_t x);
+int mb_put_mem(struct mbchain *mbp, c_caddr_t source, int size, int type);
+int mb_put_mbuf(struct mbchain *mbp, struct mbuf *m);
+int mb_put_uio(struct mbchain *mbp, struct uio *uiop, int size);
+
+int md_init(struct mdchain *mdp);
+void md_initm(struct mdchain *mbp, struct mbuf *m);
+void md_done(struct mdchain *mdp);
+void md_append_record(struct mdchain *mdp, struct mbuf *top);
+int md_next_record(struct mdchain *mdp);
+int md_get_uint8(struct mdchain *mdp, u_int8_t *x);
+int md_get_uint16(struct mdchain *mdp, u_int16_t *x);
+int md_get_uint16le(struct mdchain *mdp, u_int16_t *x);
+int md_get_uint16be(struct mdchain *mdp, u_int16_t *x);
+int md_get_uint32(struct mdchain *mdp, u_int32_t *x);
+int md_get_uint32be(struct mdchain *mdp, u_int32_t *x);
+int md_get_uint32le(struct mdchain *mdp, u_int32_t *x);
+int md_get_int64(struct mdchain *mdp, int64_t *x);
+int md_get_int64be(struct mdchain *mdp, int64_t *x);
+int md_get_int64le(struct mdchain *mdp, int64_t *x);
+int md_get_mem(struct mdchain *mdp, caddr_t target, int size, int type);
+int md_get_mbuf(struct mdchain *mdp, int size, struct mbuf **m);
+int md_get_uio(struct mdchain *mdp, struct uio *uiop, int size);
+
+#endif /* ifdef _KERNEL */
+
+#endif /* !_SYS_MCHAIN_H_ */
OpenPOWER on IntegriCloud