1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 /* 27 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 28 * Copyright 2017 RackTop Systems. 29 */ 30 31 #include <rpc/types.h> 32 #include <rpc/xdr.h> 33 #include <sys/types.h> 34 35 /* ARGSUSED */ 36 static bool_t 37 x_putint32_t(XDR *xdrs, int32_t *ip) 38 { 39 xdrs->x_handy += BYTES_PER_XDR_UNIT; 40 return (TRUE); 41 } 42 43 /* ARGSUSED */ 44 static bool_t 45 x_putbytes(XDR *xdrs, char *bp, int len) 46 { 47 xdrs->x_handy += len; 48 return (TRUE); 49 } 50 51 static uint_t 52 x_getpostn(XDR *xdrs) 53 { 54 return (xdrs->x_handy); 55 } 56 57 /* ARGSUSED */ 58 static bool_t 59 x_setpostn(XDR *xdrs, uint_t pos) 60 { 61 /* This is not allowed */ 62 return (FALSE); 63 } 64 65 static rpc_inline_t * 66 x_inline(XDR *xdrs, int len) 67 { 68 if (len == 0) { 69 return (NULL); 70 } 71 if (xdrs->x_op != XDR_ENCODE) { 72 return (NULL); 73 } 74 if (len < (uintptr_t)xdrs->x_base) { 75 /* x_private was already allocated */ 76 xdrs->x_handy += len; 77 return ((rpc_inline_t *)xdrs->x_private); 78 } else { 79 /* Free the earlier space and allocate new area */ 80 if (xdrs->x_private) 81 mem_free(xdrs->x_private, (uintptr_t)xdrs->x_base); 82 if ((xdrs->x_private = (caddr_t)mem_alloc(len)) == NULL) { 83 xdrs->x_base = 0; 84 return (NULL); 85 } 86 xdrs->x_base = (caddr_t)(uintptr_t)len; 87 xdrs->x_handy += len; 88 return ((rpc_inline_t *)xdrs->x_private); 89 } 90 } 91 92 static int 93 harmless() 94 { 95 /* Always return FALSE/NULL, as the case may be */ 96 return (0); 97 } 98 99 static void 100 x_destroy(XDR *xdrs) 101 { 102 xdrs->x_handy = 0; 103 if (xdrs->x_private) { 104 mem_free(xdrs->x_private, (uintptr_t)xdrs->x_base); 105 xdrs->x_private = NULL; 106 } 107 xdrs->x_base = 0; 108 } 109 110 unsigned int 111 xdr_sizeof(xdrproc_t func, void *data) 112 { 113 XDR x; 114 struct xdr_ops ops; 115 bool_t stat; 116 /* to stop ANSI-C compiler from complaining */ 117 typedef bool_t (* dummyfunc1)(XDR *, caddr_t, int); 118 typedef bool_t (* dummyfunc2)(XDR *, int, void *); 119 #if defined(_LP64) || defined(_KERNEL) 120 typedef bool_t (* dummyfunc3)(XDR *, int32_t *); 121 #endif 122 123 ops.x_putbytes = x_putbytes; 124 ops.x_inline = x_inline; 125 ops.x_getpostn = x_getpostn; 126 ops.x_setpostn = x_setpostn; 127 ops.x_destroy = x_destroy; 128 129 #if defined(_LP64) || defined(_KERNEL) 130 ops.x_getint32 = (dummyfunc3)harmless; 131 ops.x_putint32 = x_putint32_t; 132 #endif 133 134 /* the other harmless ones */ 135 ops.x_getbytes = (dummyfunc1)harmless; 136 ops.x_control = (dummyfunc2)harmless; 137 138 x.x_op = XDR_ENCODE; 139 x.x_ops = &ops; 140 x.x_handy = 0; 141 x.x_private = (caddr_t)NULL; 142 x.x_base = NULL; 143 144 stat = func(&x, data); 145 if (x.x_private) 146 mem_free(x.x_private, (uintptr_t)x.x_base); 147 return (stat == TRUE ? (unsigned int)x.x_handy: 0); 148 } 149