Index: head/sys/xdr/xdr.c =================================================================== --- head/sys/xdr/xdr.c (revision 365223) +++ head/sys/xdr/xdr.c (revision 365224) @@ -1,856 +1,832 @@ /* $NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos 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 */ #if defined(LIBC_SCCS) && !defined(lint) static char *sccsid2 = "@(#)xdr.c 1.35 87/08/12"; static char *sccsid = "@(#)xdr.c 2.1 88/07/29 4.0 RPCSRC"; #endif #include __FBSDID("$FreeBSD$"); /* * xdr.c, Generic XDR routines implementation. * * Copyright (C) 1986, Sun Microsystems, Inc. * * These are the "generic" xdr routines used to serialize and de-serialize * most common data items. See xdr.h for more info on the interface to * xdr. */ #include #include #include #include #include #include #include #include #include typedef quad_t longlong_t; /* ANSI long long type */ typedef u_quad_t u_longlong_t; /* ANSI unsigned long long type */ /* * constants specific to the xdr "protocol" */ #define XDR_FALSE ((long) 0) #define XDR_TRUE ((long) 1) MALLOC_DEFINE(M_RPC, "rpc", "Remote Procedure Call"); /* * for unit alignment */ static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; /* * Free a data structure using XDR * Not a filter, but a convenient utility nonetheless */ void xdr_free(xdrproc_t proc, void *objp) { XDR x; - + x.x_op = XDR_FREE; (*proc)(&x, objp); } /* * XDR nothing */ bool_t xdr_void(void) { return (TRUE); } - /* * XDR integers */ bool_t xdr_int(XDR *xdrs, int *ip) { long l; switch (xdrs->x_op) { - case XDR_ENCODE: l = (long) *ip; return (XDR_PUTLONG(xdrs, &l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, &l)) { return (FALSE); } *ip = (int) l; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } /* * XDR unsigned integers */ bool_t xdr_u_int(XDR *xdrs, u_int *up) { u_long l; switch (xdrs->x_op) { - case XDR_ENCODE: l = (u_long) *up; return (XDR_PUTLONG(xdrs, (long *)&l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, (long *)&l)) { return (FALSE); } *up = (u_int) l; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } - /* * XDR long integers * same as xdr_u_long - open coded to save a proc call! */ bool_t xdr_long(XDR *xdrs, long *lp) { switch (xdrs->x_op) { case XDR_ENCODE: return (XDR_PUTLONG(xdrs, lp)); case XDR_DECODE: return (XDR_GETLONG(xdrs, lp)); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } /* * XDR unsigned long integers * same as xdr_long - open coded to save a proc call! */ bool_t xdr_u_long(XDR *xdrs, u_long *ulp) { switch (xdrs->x_op) { case XDR_ENCODE: return (XDR_PUTLONG(xdrs, (long *)ulp)); case XDR_DECODE: return (XDR_GETLONG(xdrs, (long *)ulp)); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } - /* * XDR 32-bit integers * same as xdr_uint32_t - open coded to save a proc call! */ bool_t xdr_int32_t(XDR *xdrs, int32_t *int32_p) { long l; switch (xdrs->x_op) { - case XDR_ENCODE: l = (long) *int32_p; return (XDR_PUTLONG(xdrs, &l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, &l)) { return (FALSE); } *int32_p = (int32_t) l; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } /* * XDR unsigned 32-bit integers * same as xdr_int32_t - open coded to save a proc call! */ bool_t xdr_uint32_t(XDR *xdrs, uint32_t *uint32_p) { u_long l; switch (xdrs->x_op) { - case XDR_ENCODE: l = (u_long) *uint32_p; return (XDR_PUTLONG(xdrs, (long *)&l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, (long *)&l)) { return (FALSE); } *uint32_p = (uint32_t) l; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } - /* * XDR short integers */ bool_t xdr_short(XDR *xdrs, short *sp) { long l; switch (xdrs->x_op) { - case XDR_ENCODE: l = (long) *sp; return (XDR_PUTLONG(xdrs, &l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, &l)) { return (FALSE); } *sp = (short) l; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } /* * XDR unsigned short integers */ bool_t xdr_u_short(XDR *xdrs, u_short *usp) { u_long l; switch (xdrs->x_op) { - case XDR_ENCODE: l = (u_long) *usp; return (XDR_PUTLONG(xdrs, (long *)&l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, (long *)&l)) { return (FALSE); } *usp = (u_short) l; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } - /* * XDR 16-bit integers */ bool_t xdr_int16_t(XDR *xdrs, int16_t *int16_p) { long l; switch (xdrs->x_op) { - case XDR_ENCODE: l = (long) *int16_p; return (XDR_PUTLONG(xdrs, &l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, &l)) { return (FALSE); } *int16_p = (int16_t) l; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } /* * XDR unsigned 16-bit integers */ bool_t xdr_uint16_t(XDR *xdrs, uint16_t *uint16_p) { u_long l; switch (xdrs->x_op) { - case XDR_ENCODE: l = (u_long) *uint16_p; return (XDR_PUTLONG(xdrs, (long *)&l)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, (long *)&l)) { return (FALSE); } *uint16_p = (uint16_t) l; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } - /* * XDR a char */ bool_t xdr_char(XDR *xdrs, char *cp) { int i; i = (*cp); if (!xdr_int(xdrs, &i)) { return (FALSE); } *cp = i; return (TRUE); } /* * XDR an unsigned char */ bool_t xdr_u_char(XDR *xdrs, u_char *cp) { u_int u; u = (*cp); if (!xdr_u_int(xdrs, &u)) { return (FALSE); } *cp = u; return (TRUE); } /* * XDR booleans */ bool_t xdr_bool(XDR *xdrs, bool_t *bp) { long lb; switch (xdrs->x_op) { - case XDR_ENCODE: lb = *bp ? XDR_TRUE : XDR_FALSE; return (XDR_PUTLONG(xdrs, &lb)); case XDR_DECODE: if (!XDR_GETLONG(xdrs, &lb)) { return (FALSE); } *bp = (lb == XDR_FALSE) ? FALSE : TRUE; return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } /* * XDR enumerations */ bool_t xdr_enum(XDR *xdrs, enum_t *ep) { enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ /* * enums are treated as ints */ /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) { return (xdr_long(xdrs, (long *)(void *)ep)); } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) { return (xdr_int(xdrs, (int *)(void *)ep)); } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) { return (xdr_short(xdrs, (short *)(void *)ep)); } else { return (FALSE); } } /* * XDR opaque data * Allows the specification of a fixed size sequence of opaque bytes. * cp points to the opaque object and cnt gives the byte length. */ bool_t xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt) { u_int rndup; static int crud[BYTES_PER_XDR_UNIT]; /* * if no data we are done */ if (cnt == 0) return (TRUE); /* * round byte count to full xdr units */ rndup = cnt % BYTES_PER_XDR_UNIT; if (rndup > 0) rndup = BYTES_PER_XDR_UNIT - rndup; if (xdrs->x_op == XDR_DECODE) { if (!XDR_GETBYTES(xdrs, cp, cnt)) { return (FALSE); } if (rndup == 0) return (TRUE); return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup)); } if (xdrs->x_op == XDR_ENCODE) { if (!XDR_PUTBYTES(xdrs, cp, cnt)) { return (FALSE); } if (rndup == 0) return (TRUE); return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); } if (xdrs->x_op == XDR_FREE) { return (TRUE); } return (FALSE); } /* * XDR counted bytes * *cpp is a pointer to the bytes, *sizep is the count. * If *cpp is NULL maxsize bytes are allocated */ bool_t xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) { char *sp = *cpp; /* sp is the actual string pointer */ u_int nodesize; bool_t ret, allocated = FALSE; /* * first deal with the length since xdr bytes are counted */ if (! xdr_u_int(xdrs, sizep)) { return (FALSE); } nodesize = *sizep; if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { return (FALSE); } /* * now deal with the actual bytes */ switch (xdrs->x_op) { - case XDR_DECODE: if (nodesize == 0) { return (TRUE); } if (sp == NULL) { *cpp = sp = mem_alloc(nodesize); allocated = TRUE; } if (sp == NULL) { printf("xdr_bytes: out of memory"); return (FALSE); } /* FALLTHROUGH */ case XDR_ENCODE: ret = xdr_opaque(xdrs, sp, nodesize); if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) { if (allocated == TRUE) { mem_free(sp, nodesize); *cpp = NULL; } } return (ret); case XDR_FREE: if (sp != NULL) { mem_free(sp, nodesize); *cpp = NULL; } return (TRUE); } /* NOTREACHED */ return (FALSE); } /* * Implemented here due to commonality of the object. */ bool_t xdr_netobj(XDR *xdrs, struct netobj *np) { return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); } /* * XDR a descriminated union * Support routine for discriminated unions. * You create an array of xdrdiscrim structures, terminated with * an entry with a null procedure pointer. The routine gets * the discriminant value and then searches the array of xdrdiscrims * looking for that value. It calls the procedure given in the xdrdiscrim * to handle the discriminant. If there is no specific routine a default * routine may be called. * If there is no specific or default routine an error is returned. */ bool_t xdr_union(XDR *xdrs, enum_t *dscmp, /* enum to decide which arm to work on */ char *unp, /* the union itself */ const struct xdr_discrim *choices, /* [value, xdr proc] for each arm */ xdrproc_t dfault) /* default xdr routine */ { enum_t dscm; /* * we deal with the discriminator; it's an enum */ if (! xdr_enum(xdrs, dscmp)) { return (FALSE); } dscm = *dscmp; /* * search choices for a value that matches the discriminator. * if we find one, execute the xdr routine for that value. */ for (; choices->proc != NULL_xdrproc_t; choices++) { if (choices->value == dscm) return ((*(choices->proc))(xdrs, unp)); } /* * no match - execute the default xdr routine if there is one */ return ((dfault == NULL_xdrproc_t) ? FALSE : (*dfault)(xdrs, unp)); } - /* * Non-portable xdr primitives. * Care should be taken when moving these routines to new architectures. */ - /* * XDR null terminated ASCII strings * xdr_string deals with "C strings" - arrays of bytes that are * terminated by a NULL character. The parameter cpp references a * pointer to storage; If the pointer is null, then the necessary * storage is allocated. The last parameter is the max allowed length * of the string as specified by a protocol. */ bool_t xdr_string(XDR *xdrs, char **cpp, u_int maxsize) { char *sp = *cpp; /* sp is the actual string pointer */ u_int size; u_int nodesize; bool_t ret, allocated = FALSE; /* * first deal with the length since xdr strings are counted-strings */ switch (xdrs->x_op) { case XDR_FREE: if (sp == NULL) { return(TRUE); /* already free */ } /* FALLTHROUGH */ case XDR_ENCODE: size = strlen(sp); break; case XDR_DECODE: break; } if (! xdr_u_int(xdrs, &size)) { return (FALSE); } if (size > maxsize) { return (FALSE); } nodesize = size + 1; /* * now deal with the actual bytes */ switch (xdrs->x_op) { - case XDR_DECODE: if (nodesize == 0) { return (TRUE); } if (sp == NULL) { *cpp = sp = mem_alloc(nodesize); allocated = TRUE; } if (sp == NULL) { printf("xdr_string: out of memory"); return (FALSE); } sp[size] = 0; /* FALLTHROUGH */ case XDR_ENCODE: ret = xdr_opaque(xdrs, sp, size); if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) { if (allocated == TRUE) { mem_free(sp, nodesize); *cpp = NULL; } } return (ret); case XDR_FREE: mem_free(sp, nodesize); *cpp = NULL; return (TRUE); } /* NOTREACHED */ return (FALSE); } /* * Wrapper for xdr_string that can be called directly from * routines like clnt_call */ bool_t xdr_wrapstring(XDR *xdrs, char **cpp) { return xdr_string(xdrs, cpp, RPC_MAXDATASIZE); } /* * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t() * are in the "non-portable" section because they require that a `long long' * be a 64-bit type. * * --thorpej@netbsd.org, November 30, 1999 */ /* * XDR 64-bit integers */ bool_t xdr_int64_t(XDR *xdrs, int64_t *llp) { u_long ul[2]; switch (xdrs->x_op) { case XDR_ENCODE: ul[0] = (u_long)((uint64_t)*llp >> 32) & 0xffffffff; ul[1] = (u_long)((uint64_t)*llp) & 0xffffffff; if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) return (FALSE); return (XDR_PUTLONG(xdrs, (long *)&ul[1])); case XDR_DECODE: if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) return (FALSE); if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) return (FALSE); *llp = (int64_t) (((uint64_t)ul[0] << 32) | ((uint64_t)ul[1])); return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } - /* * XDR unsigned 64-bit integers */ bool_t xdr_uint64_t(XDR *xdrs, uint64_t *ullp) { u_long ul[2]; switch (xdrs->x_op) { case XDR_ENCODE: ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; ul[1] = (u_long)(*ullp) & 0xffffffff; if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) return (FALSE); return (XDR_PUTLONG(xdrs, (long *)&ul[1])); case XDR_DECODE: if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) return (FALSE); if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) return (FALSE); *ullp = (uint64_t) (((uint64_t)ul[0] << 32) | ((uint64_t)ul[1])); return (TRUE); case XDR_FREE: return (TRUE); } /* NOTREACHED */ return (FALSE); } - /* * XDR hypers */ bool_t xdr_hyper(XDR *xdrs, longlong_t *llp) { /* * Don't bother open-coding this; it's a fair amount of code. Just * call xdr_int64_t(). */ return (xdr_int64_t(xdrs, (int64_t *)llp)); } - /* * XDR unsigned hypers */ bool_t xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp) { /* * Don't bother open-coding this; it's a fair amount of code. Just * call xdr_uint64_t(). */ return (xdr_uint64_t(xdrs, (uint64_t *)ullp)); } - /* * XDR longlong_t's */ bool_t xdr_longlong_t(XDR *xdrs, longlong_t *llp) { /* * Don't bother open-coding this; it's a fair amount of code. Just * call xdr_int64_t(). */ return (xdr_int64_t(xdrs, (int64_t *)llp)); } - /* * XDR u_longlong_t's */ bool_t xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp) { /* * Don't bother open-coding this; it's a fair amount of code. Just * call xdr_uint64_t(). */ return (xdr_uint64_t(xdrs, (uint64_t *)ullp)); } /* * Kernel module glue */ static int xdr_modevent(module_t mod, int type, void *data) { return (0); } static moduledata_t xdr_mod = { "xdr", xdr_modevent, NULL, }; DECLARE_MODULE(xdr, xdr_mod, SI_SUB_VFS, SI_ORDER_ANY); MODULE_VERSION(xdr, 1); Index: head/sys/xdr/xdr_array.c =================================================================== --- head/sys/xdr/xdr_array.c (revision 365223) +++ head/sys/xdr/xdr_array.c (revision 365224) @@ -1,155 +1,155 @@ /* $NetBSD: xdr_array.c,v 1.12 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 */ #if defined(LIBC_SCCS) && !defined(lint) static char *sccsid2 = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC"; #endif #include __FBSDID("$FreeBSD$"); /* * xdr_array.c, Generic XDR routines implementation. * * Copyright (C) 1984, Sun Microsystems, Inc. * * These are the "non-trivial" xdr primitives used to serialize and de-serialize * arrays. See xdr.h for more info on the interface to xdr. */ #include #include #include #include #include #include /* * XDR an array of arbitrary elements * *addrp is a pointer to the array, *sizep is the number of elements. * If addrp is NULL (*sizep * elsize) bytes are allocated. * elsize is the size (in bytes) of each element, and elproc is the * xdr procedure to call to handle each element of the array. */ bool_t xdr_array(XDR *xdrs, caddr_t *addrp, /* array pointer */ u_int *sizep, /* number of elements */ u_int maxsize, /* max numberof elements */ u_int elsize, /* size in bytes of each element */ xdrproc_t elproc) /* xdr routine to handle each element */ { u_int i; caddr_t target = *addrp; u_int c; /* the actual element count */ bool_t stat = TRUE; u_int nodesize; /* like strings, arrays are really counted arrays */ if (!xdr_u_int(xdrs, sizep)) { return (FALSE); } c = *sizep; if ((c > maxsize || UINT_MAX/elsize < c) && (xdrs->x_op != XDR_FREE)) { return (FALSE); } nodesize = c * elsize; /* * if we are deserializing, we may need to allocate an array. * We also save time by checking for a null array if we are freeing. */ if (target == NULL) switch (xdrs->x_op) { case XDR_DECODE: if (c == 0) return (TRUE); *addrp = target = mem_alloc(nodesize); if (target == NULL) { printf("xdr_array: out of memory"); return (FALSE); } memset(target, 0, nodesize); break; case XDR_FREE: return (TRUE); case XDR_ENCODE: break; } - + /* * now we xdr each element of array */ for (i = 0; (i < c) && stat; i++) { stat = (*elproc)(xdrs, target); target += elsize; } /* * the array may need freeing */ if (xdrs->x_op == XDR_FREE) { mem_free(*addrp, nodesize); *addrp = NULL; } return (stat); } /* * xdr_vector(): * * XDR a fixed length array. Unlike variable-length arrays, * the storage of fixed length arrays is static and unfreeable. * > basep: base of the array * > size: size of the array * > elemsize: size of each element * > xdr_elem: routine to XDR each element */ bool_t xdr_vector(XDR *xdrs, char *basep, u_int nelem, u_int elemsize, xdrproc_t xdr_elem) { u_int i; char *elptr; elptr = basep; for (i = 0; i < nelem; i++) { if (!(*xdr_elem)(xdrs, elptr)) { return(FALSE); } elptr += elemsize; } return(TRUE); } Index: head/sys/xdr/xdr_mbuf.c =================================================================== --- head/sys/xdr/xdr_mbuf.c (revision 365223) +++ head/sys/xdr/xdr_mbuf.c (revision 365224) @@ -1,307 +1,307 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * 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 __FBSDID("$FreeBSD$"); #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 }; /* * 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(xdrs, lp) 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); } Index: head/sys/xdr/xdr_mem.c =================================================================== --- head/sys/xdr/xdr_mem.c (revision 365223) +++ head/sys/xdr/xdr_mem.c (revision 365224) @@ -1,275 +1,273 @@ /* $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 */ #if defined(LIBC_SCCS) && !defined(lint) static char *sccsid2 = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; static char *sccsid = "@(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC"; #endif #include __FBSDID("$FreeBSD$"); /* * 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 }; 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 }; /* * 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(*(u_int32_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); *(u_int32_t *)xdrs->x_private = htonl((u_int32_t)*lp); xdrs->x_private = (char *)xdrs->x_private + sizeof(int32_t); return (TRUE); } static bool_t xdrmem_getlong_unaligned(XDR *xdrs, long *lp) { u_int32_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) { u_int32_t l; if (xdrs->x_handy < sizeof(int32_t)) return (FALSE); xdrs->x_handy -= sizeof(int32_t); l = htonl((u_int32_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); } Index: head/sys/xdr/xdr_reference.c =================================================================== --- head/sys/xdr/xdr_reference.c (revision 365223) +++ head/sys/xdr/xdr_reference.c (revision 365224) @@ -1,135 +1,134 @@ /* $NetBSD: xdr_reference.c,v 1.13 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 */ #if defined(LIBC_SCCS) && !defined(lint) static char *sccsid2 = "@(#)xdr_reference.c 1.11 87/08/11 SMI"; static char *sccsid = "@(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC"; #endif #include __FBSDID("$FreeBSD$"); /* * xdr_reference.c, Generic XDR routines implementation. * * Copyright (C) 1987, Sun Microsystems, Inc. * * These are the "non-trivial" xdr primitives used to serialize and de-serialize * "pointers". See xdr.h for more info on the interface to xdr. */ #include #include #include #include #include /* * XDR an indirect pointer * xdr_reference is for recursively translating a structure that is * referenced by a pointer inside the structure that is currently being * translated. pp references a pointer to storage. If *pp is null * the necessary storage is allocated. * size is the sizeof the referneced structure. * proc is the routine to handle the referenced structure. */ bool_t xdr_reference(XDR *xdrs, caddr_t *pp, /* the pointer to work on */ u_int size, /* size of the object pointed to */ xdrproc_t proc) /* xdr routine to handle the object */ { caddr_t loc = *pp; bool_t stat; if (loc == NULL) switch (xdrs->x_op) { case XDR_FREE: return (TRUE); case XDR_DECODE: *pp = loc = (caddr_t) mem_alloc(size); if (loc == NULL) { printf("xdr_reference: out of memory"); return (FALSE); } memset(loc, 0, size); break; case XDR_ENCODE: break; } stat = (*proc)(xdrs, loc); if (xdrs->x_op == XDR_FREE) { mem_free(loc, size); *pp = NULL; } return (stat); } - /* * xdr_pointer(): * * XDR a pointer to a possibly recursive data structure. This * differs with xdr_reference in that it can serialize/deserialiaze * trees correctly. * * What's sent is actually a union: * * union object_pointer switch (boolean b) { * case TRUE: object_data data; * case FALSE: void nothing; * } * * > objpp: Pointer to the pointer to the object. * > obj_size: size of the object. * > xdr_obj: routine to XDR an object. * */ bool_t xdr_pointer(XDR *xdrs, char **objpp, u_int obj_size, xdrproc_t xdr_obj) { bool_t more_data; more_data = (*objpp != NULL); if (! xdr_bool(xdrs,&more_data)) { return (FALSE); } if (! more_data) { *objpp = NULL; return (TRUE); } return (xdr_reference(xdrs,objpp,obj_size,xdr_obj)); }