diff --git a/sys/xdr/xdr_mbuf.c b/sys/xdr/xdr_mbuf.c index 0ed807de903e..896e317f5526 100644 --- a/sys/xdr/xdr_mbuf.c +++ b/sys/xdr/xdr_mbuf.c @@ -1,302 +1,302 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2008 Isilon Inc http://www.isilon.com/ * Authors: Doug Rabson * Developed with Red Inc: Alfred Perlstein * * 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. * * 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. */ #include #include #include #include #include #include static void xdrmbuf_destroy(XDR *); static bool_t xdrmbuf_getlong(XDR *, long *); static bool_t xdrmbuf_putlong(XDR *, const long *); static bool_t xdrmbuf_getbytes(XDR *, char *, u_int); static bool_t xdrmbuf_putbytes(XDR *, const char *, u_int); /* XXX: w/64-bit pointers, u_int not enough! */ static u_int xdrmbuf_getpos(XDR *); static bool_t xdrmbuf_setpos(XDR *, u_int); static int32_t *xdrmbuf_inline(XDR *, u_int); static const struct xdr_ops xdrmbuf_ops = { - xdrmbuf_getlong, - xdrmbuf_putlong, - xdrmbuf_getbytes, - xdrmbuf_putbytes, - xdrmbuf_getpos, - xdrmbuf_setpos, - xdrmbuf_inline, - xdrmbuf_destroy + .x_getlong = xdrmbuf_getlong, + .x_putlong = xdrmbuf_putlong, + .x_getbytes = xdrmbuf_getbytes, + .x_putbytes = xdrmbuf_putbytes, + .x_getpostn = xdrmbuf_getpos, + .x_setpostn = xdrmbuf_setpos, + .x_inline = xdrmbuf_inline, + .x_destroy = xdrmbuf_destroy, }; /* * The procedure xdrmbuf_create initializes a stream descriptor for a * mbuf. */ void xdrmbuf_create(XDR *xdrs, struct mbuf *m, enum xdr_op op) { KASSERT(m != NULL, ("xdrmbuf_create with NULL mbuf chain")); xdrs->x_op = op; xdrs->x_ops = &xdrmbuf_ops; xdrs->x_base = (char *) m; if (op == XDR_ENCODE) { m = m_last(m); xdrs->x_private = m; xdrs->x_handy = m->m_len; } else { xdrs->x_private = m; xdrs->x_handy = 0; } } void xdrmbuf_append(XDR *xdrs, struct mbuf *madd) { struct mbuf *m; KASSERT(xdrs->x_ops == &xdrmbuf_ops && xdrs->x_op == XDR_ENCODE, ("xdrmbuf_append: invalid XDR stream")); if (m_length(madd, NULL) == 0) { m_freem(madd); return; } m = (struct mbuf *) xdrs->x_private; m->m_next = madd; m = m_last(madd); xdrs->x_private = m; xdrs->x_handy = m->m_len; } struct mbuf * xdrmbuf_getall(XDR *xdrs) { struct mbuf *m0, *m; KASSERT(xdrs->x_ops == &xdrmbuf_ops && xdrs->x_op == XDR_DECODE, ("xdrmbuf_append: invalid XDR stream")); m0 = (struct mbuf *) xdrs->x_base; m = (struct mbuf *) xdrs->x_private; if (m0 != m) { while (m0->m_next != m) m0 = m0->m_next; m0->m_next = NULL; xdrs->x_private = NULL; } else { xdrs->x_base = NULL; xdrs->x_private = NULL; } if (m) m_adj(m, xdrs->x_handy); else m = m_get(M_WAITOK, MT_DATA); return (m); } static void xdrmbuf_destroy(XDR *xdrs) { if (xdrs->x_op == XDR_DECODE && xdrs->x_base) { m_freem((struct mbuf *) xdrs->x_base); xdrs->x_base = NULL; xdrs->x_private = NULL; } } static bool_t xdrmbuf_getlong(XDR *xdrs, long *lp) { int32_t *p; int32_t t; p = xdrmbuf_inline(xdrs, sizeof(int32_t)); if (p) { t = *p; } else { xdrmbuf_getbytes(xdrs, (char *) &t, sizeof(int32_t)); } *lp = ntohl(t); return (TRUE); } static bool_t xdrmbuf_putlong(XDR *xdrs, const long *lp) { int32_t *p; int32_t t = htonl(*lp); p = xdrmbuf_inline(xdrs, sizeof(int32_t)); if (p) { *p = t; return (TRUE); } else { return (xdrmbuf_putbytes(xdrs, (char *) &t, sizeof(int32_t))); } } static bool_t xdrmbuf_getbytes(XDR *xdrs, char *addr, u_int len) { struct mbuf *m = (struct mbuf *) xdrs->x_private; size_t sz; while (len > 0) { /* * Make sure we haven't hit the end. */ if (!m) { return (FALSE); } /* * See how much we can get from this mbuf. */ sz = m->m_len - xdrs->x_handy; if (sz > len) sz = len; bcopy(mtod(m, const char *) + xdrs->x_handy, addr, sz); addr += sz; xdrs->x_handy += sz; len -= sz; if (xdrs->x_handy == m->m_len) { m = m->m_next; xdrs->x_private = (void *) m; xdrs->x_handy = 0; } } return (TRUE); } static bool_t xdrmbuf_putbytes(XDR *xdrs, const char *addr, u_int len) { struct mbuf *m = (struct mbuf *) xdrs->x_private; struct mbuf *n; size_t sz; while (len > 0) { sz = M_TRAILINGSPACE(m) + (m->m_len - xdrs->x_handy); if (sz > len) sz = len; bcopy(addr, mtod(m, char *) + xdrs->x_handy, sz); addr += sz; xdrs->x_handy += sz; if (xdrs->x_handy > m->m_len) m->m_len = xdrs->x_handy; len -= sz; if (xdrs->x_handy == m->m_len && M_TRAILINGSPACE(m) == 0) { if (!m->m_next) { if (m->m_flags & M_EXT) n = m_getcl(M_WAITOK, m->m_type, 0); else n = m_get(M_WAITOK, m->m_type); m->m_next = n; } m = m->m_next; xdrs->x_private = (void *) m; xdrs->x_handy = 0; } } return (TRUE); } static u_int xdrmbuf_getpos(XDR *xdrs) { struct mbuf *m0 = (struct mbuf *) xdrs->x_base; struct mbuf *m = (struct mbuf *) xdrs->x_private; u_int pos = 0; while (m0 && m0 != m) { pos += m0->m_len; m0 = m0->m_next; } KASSERT(m0, ("Corrupted mbuf chain")); return (pos + xdrs->x_handy); } static bool_t xdrmbuf_setpos(XDR *xdrs, u_int pos) { struct mbuf *m = (struct mbuf *) xdrs->x_base; while (m && pos > m->m_len) { pos -= m->m_len; m = m->m_next; } KASSERT(m, ("Corrupted mbuf chain")); xdrs->x_private = (void *) m; xdrs->x_handy = pos; return (TRUE); } static int32_t * xdrmbuf_inline(XDR *xdrs, u_int len) { struct mbuf *m = (struct mbuf *) xdrs->x_private; size_t available; char *p; if (!m) return (0); if (xdrs->x_op == XDR_ENCODE) { available = M_TRAILINGSPACE(m) + (m->m_len - xdrs->x_handy); } else { available = m->m_len - xdrs->x_handy; } if (available >= len) { p = mtod(m, char *) + xdrs->x_handy; if (((uintptr_t) p) & (sizeof(int32_t) - 1)) return (0); xdrs->x_handy += len; if (xdrs->x_handy > m->m_len) m->m_len = xdrs->x_handy; return ((int32_t *) p); } return (0); } diff --git a/sys/xdr/xdr_mem.c b/sys/xdr/xdr_mem.c index 1489aadf53a0..65a74836b7b3 100644 --- a/sys/xdr/xdr_mem.c +++ b/sys/xdr/xdr_mem.c @@ -1,267 +1,267 @@ /* $NetBSD: xdr_mem.c,v 1.15 2000/01/22 22:19:18 mycroft Exp $ */ /* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ #include /* * xdr_mem.h, XDR implementation using memory buffers. * * Copyright (C) 1984, Sun Microsystems, Inc. * * If you have some data to be interpreted as external data representation * or to be converted to external data representation in a memory buffer, * then this is the package for you. * */ #include #include #include #include #include static void xdrmem_destroy(XDR *); static bool_t xdrmem_getlong_aligned(XDR *, long *); static bool_t xdrmem_putlong_aligned(XDR *, const long *); static bool_t xdrmem_getlong_unaligned(XDR *, long *); static bool_t xdrmem_putlong_unaligned(XDR *, const long *); static bool_t xdrmem_getbytes(XDR *, char *, u_int); static bool_t xdrmem_putbytes(XDR *, const char *, u_int); /* XXX: w/64-bit pointers, u_int not enough! */ static u_int xdrmem_getpos(XDR *); static bool_t xdrmem_setpos(XDR *, u_int); static int32_t *xdrmem_inline_aligned(XDR *, u_int); static int32_t *xdrmem_inline_unaligned(XDR *, u_int); static bool_t xdrmem_control(XDR *xdrs, int request, void *info); static const struct xdr_ops xdrmem_ops_aligned = { - xdrmem_getlong_aligned, - xdrmem_putlong_aligned, - xdrmem_getbytes, - xdrmem_putbytes, - xdrmem_getpos, - xdrmem_setpos, - xdrmem_inline_aligned, - xdrmem_destroy, - xdrmem_control + .x_getlong = xdrmem_getlong_aligned, + .x_putlong = xdrmem_putlong_aligned, + .x_getbytes = xdrmem_getbytes, + .x_putbytes = xdrmem_putbytes, + .x_getpostn = xdrmem_getpos, + .x_setpostn = xdrmem_setpos, + .x_inline = xdrmem_inline_aligned, + .x_destroy = xdrmem_destroy, + .x_control = xdrmem_control, }; static const struct xdr_ops xdrmem_ops_unaligned = { - xdrmem_getlong_unaligned, - xdrmem_putlong_unaligned, - xdrmem_getbytes, - xdrmem_putbytes, - xdrmem_getpos, - xdrmem_setpos, - xdrmem_inline_unaligned, - xdrmem_destroy, - xdrmem_control + .x_getlong = xdrmem_getlong_unaligned, + .x_putlong = xdrmem_putlong_unaligned, + .x_getbytes = xdrmem_getbytes, + .x_putbytes = xdrmem_putbytes, + .x_getpostn = xdrmem_getpos, + .x_setpostn = xdrmem_setpos, + .x_inline = xdrmem_inline_unaligned, + .x_destroy = xdrmem_destroy, + .x_control = xdrmem_control }; /* * The procedure xdrmem_create initializes a stream descriptor for a * memory buffer. */ void xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op) { xdrs->x_op = op; xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1)) ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned; xdrs->x_private = xdrs->x_base = addr; xdrs->x_handy = size; } /*ARGSUSED*/ static void xdrmem_destroy(XDR *xdrs) { } static bool_t xdrmem_getlong_aligned(XDR *xdrs, long *lp) { if (xdrs->x_handy < sizeof(int32_t)) return (FALSE); xdrs->x_handy -= sizeof(int32_t); *lp = ntohl(*(uint32_t *)xdrs->x_private); xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); return (TRUE); } static bool_t xdrmem_putlong_aligned(XDR *xdrs, const long *lp) { if (xdrs->x_handy < sizeof(int32_t)) return (FALSE); xdrs->x_handy -= sizeof(int32_t); *(uint32_t *)xdrs->x_private = htonl((uint32_t)*lp); xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); return (TRUE); } static bool_t xdrmem_getlong_unaligned(XDR *xdrs, long *lp) { uint32_t l; if (xdrs->x_handy < sizeof(int32_t)) return (FALSE); xdrs->x_handy -= sizeof(int32_t); memmove(&l, xdrs->x_private, sizeof(int32_t)); *lp = ntohl(l); xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); return (TRUE); } static bool_t xdrmem_putlong_unaligned(XDR *xdrs, const long *lp) { uint32_t l; if (xdrs->x_handy < sizeof(int32_t)) return (FALSE); xdrs->x_handy -= sizeof(int32_t); l = htonl((uint32_t)*lp); memmove(xdrs->x_private, &l, sizeof(int32_t)); xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); return (TRUE); } static bool_t xdrmem_getbytes(XDR *xdrs, char *addr, u_int len) { if (xdrs->x_handy < len) return (FALSE); xdrs->x_handy -= len; memmove(addr, xdrs->x_private, len); xdrs->x_private = (char *)xdrs->x_private + len; return (TRUE); } static bool_t xdrmem_putbytes(XDR *xdrs, const char *addr, u_int len) { if (xdrs->x_handy < len) return (FALSE); xdrs->x_handy -= len; memmove(xdrs->x_private, addr, len); xdrs->x_private = (char *)xdrs->x_private + len; return (TRUE); } static u_int xdrmem_getpos(XDR *xdrs) { /* XXX w/64-bit pointers, u_int not enough! */ return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base); } static bool_t xdrmem_setpos(XDR *xdrs, u_int pos) { char *newaddr = xdrs->x_base + pos; char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy; if (newaddr > lastaddr) return (FALSE); xdrs->x_private = newaddr; xdrs->x_handy = (u_int)(lastaddr - newaddr); /* XXX sizeof(u_int) x_handy >= len) { xdrs->x_handy -= len; buf = (int32_t *)xdrs->x_private; xdrs->x_private = (char *)xdrs->x_private + len; } return (buf); } /* ARGSUSED */ static int32_t * xdrmem_inline_unaligned(XDR *xdrs, u_int len) { return (0); } static bool_t xdrmem_control(XDR *xdrs, int request, void *info) { xdr_bytesrec *xptr; int32_t *l; int len; switch (request) { case XDR_GET_BYTES_AVAIL: xptr = (xdr_bytesrec *)info; xptr->xc_is_last_record = TRUE; xptr->xc_num_avail = xdrs->x_handy; return (TRUE); case XDR_PEEK: /* * Return the next 4 byte unit in the XDR stream. */ if (xdrs->x_handy < sizeof (int32_t)) return (FALSE); l = (int32_t *)info; *l = (int32_t)ntohl((uint32_t) (*((int32_t *)(xdrs->x_private)))); return (TRUE); case XDR_SKIPBYTES: /* * Skip the next N bytes in the XDR stream. */ l = (int32_t *)info; len = RNDUP((int)(*l)); if (xdrs->x_handy < len) return (FALSE); xdrs->x_handy -= len; xdrs->x_private = (char *)xdrs->x_private + len; return (TRUE); } return (FALSE); }