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 117 ops.x_putbytes = x_putbytes; 118 ops.x_inline = x_inline; 119 ops.x_getpostn = x_getpostn; 120 ops.x_setpostn = x_setpostn; 121 ops.x_destroy = x_destroy; 122 123 #if defined(_LP64) || defined(_KERNEL) 124 ops.x_getint32 = (void *)harmless; 125 ops.x_putint32 = x_putint32_t; 126 #endif 127 128 /* the other harmless ones */ 129 ops.x_getbytes = (void *)harmless; 130 ops.x_control = (void *)harmless; 131 132 x.x_op = XDR_ENCODE; 133 x.x_ops = &ops; 134 x.x_handy = 0; 135 x.x_private = (caddr_t)NULL; 136 x.x_base = NULL; 137 138 stat = func(&x, data); 139 if (x.x_private) 140 mem_free(x.x_private, (uintptr_t)x.x_base); 141 return (stat == TRUE ? (unsigned int)x.x_handy: 0); 142 }