17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*61961e0fSrobinson */ 22*61961e0fSrobinson 23*61961e0fSrobinson /* 24*61961e0fSrobinson * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 257c478bd9Sstevel@tonic-gate * Use is subject to license terms. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 317c478bd9Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of 327c478bd9Sstevel@tonic-gate * California. 337c478bd9Sstevel@tonic-gate */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* 387c478bd9Sstevel@tonic-gate * xdr.c, Generic XDR routines implementation. 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * These are the "generic" xdr routines used to serialize and de-serialize 417c478bd9Sstevel@tonic-gate * most common data items. See xdr.h for more info on the interface to 427c478bd9Sstevel@tonic-gate * xdr. 437c478bd9Sstevel@tonic-gate */ 44*61961e0fSrobinson #include <stdlib.h> 457c478bd9Sstevel@tonic-gate #include <sys/types.h> 467c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h> 477c478bd9Sstevel@tonic-gate #include <syslog.h> 487c478bd9Sstevel@tonic-gate #include <stdio.h> 497c478bd9Sstevel@tonic-gate #include <stdlib.h> 507c478bd9Sstevel@tonic-gate #include <string.h> 517c478bd9Sstevel@tonic-gate #include <limits.h> 527c478bd9Sstevel@tonic-gate #include <rpc/types.h> 537c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 547c478bd9Sstevel@tonic-gate #include <inttypes.h> 557c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 56*61961e0fSrobinson #include <assert.h> 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate #pragma weak xdr_int64_t = xdr_hyper 597c478bd9Sstevel@tonic-gate #pragma weak xdr_uint64_t = xdr_u_hyper 607c478bd9Sstevel@tonic-gate #pragma weak xdr_int32_t = xdr_int 617c478bd9Sstevel@tonic-gate #pragma weak xdr_uint32_t = xdr_u_int 627c478bd9Sstevel@tonic-gate #pragma weak xdr_int16_t = xdr_short 637c478bd9Sstevel@tonic-gate #pragma weak xdr_uint16_t = xdr_u_short 647c478bd9Sstevel@tonic-gate #pragma weak xdr_int8_t = xdr_char 657c478bd9Sstevel@tonic-gate #pragma weak xdr_uint8_t = xdr_u_char 667c478bd9Sstevel@tonic-gate 67*61961e0fSrobinson /* 68*61961e0fSrobinson * The following routine was part of a workaround for an rpcgen 69*61961e0fSrobinson * that was fixed, this routine should be removed sometime. 70*61961e0fSrobinson */ 71*61961e0fSrobinson #pragma weak xdr_ulonglong_t = xdr_u_longlong_t 72*61961e0fSrobinson 737c478bd9Sstevel@tonic-gate /* 747c478bd9Sstevel@tonic-gate * constants specific to the xdr "protocol" 757c478bd9Sstevel@tonic-gate */ 767c478bd9Sstevel@tonic-gate #define XDR_FALSE ((uint_t)0) 777c478bd9Sstevel@tonic-gate #define XDR_TRUE ((uint_t)1) 787c478bd9Sstevel@tonic-gate #define LASTUNSIGNED ((uint_t)0-1) 797c478bd9Sstevel@tonic-gate 807c478bd9Sstevel@tonic-gate /* fragment size to use when doing an xdr_string() */ 817c478bd9Sstevel@tonic-gate #define FRAGMENT 65536 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate /* 847c478bd9Sstevel@tonic-gate * for unit alignment 857c478bd9Sstevel@tonic-gate */ 867c478bd9Sstevel@tonic-gate static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0 }; 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* 897c478bd9Sstevel@tonic-gate * Free a data structure using XDR 907c478bd9Sstevel@tonic-gate * Not a filter, but a convenient utility nonetheless 917c478bd9Sstevel@tonic-gate */ 927c478bd9Sstevel@tonic-gate void 937c478bd9Sstevel@tonic-gate xdr_free(xdrproc_t proc, char *objp) 947c478bd9Sstevel@tonic-gate { 957c478bd9Sstevel@tonic-gate XDR x; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate x.x_op = XDR_FREE; 987c478bd9Sstevel@tonic-gate (*proc)(&x, objp); 997c478bd9Sstevel@tonic-gate } 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate /* 1027c478bd9Sstevel@tonic-gate * XDR nothing 1037c478bd9Sstevel@tonic-gate */ 1047c478bd9Sstevel@tonic-gate bool_t 105*61961e0fSrobinson xdr_void(void) 1067c478bd9Sstevel@tonic-gate { 1077c478bd9Sstevel@tonic-gate return (TRUE); 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate /* 1117c478bd9Sstevel@tonic-gate * xdr_time_t sends time_t value over the wire. 1127c478bd9Sstevel@tonic-gate * Due to RPC Protocol limitation, it can only send 1137c478bd9Sstevel@tonic-gate * up to 32-bit integer quantity over the wire. 1147c478bd9Sstevel@tonic-gate * 1157c478bd9Sstevel@tonic-gate */ 1167c478bd9Sstevel@tonic-gate bool_t 1177c478bd9Sstevel@tonic-gate xdr_time_t(XDR *xdrs, time_t *tp) 1187c478bd9Sstevel@tonic-gate { 1197c478bd9Sstevel@tonic-gate int32_t i; 1207c478bd9Sstevel@tonic-gate 1217c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 1227c478bd9Sstevel@tonic-gate case XDR_ENCODE: 1237c478bd9Sstevel@tonic-gate /* 1247c478bd9Sstevel@tonic-gate * Check for the time overflow, when encoding it. 1257c478bd9Sstevel@tonic-gate * Don't want to send OTW the time value too large to 1267c478bd9Sstevel@tonic-gate * handle by the protocol. 1277c478bd9Sstevel@tonic-gate */ 1287c478bd9Sstevel@tonic-gate #if defined(_LP64) 1297c478bd9Sstevel@tonic-gate if (*tp > INT32_MAX) 1307c478bd9Sstevel@tonic-gate *tp = INT32_MAX; 1317c478bd9Sstevel@tonic-gate else if (*tp < INT32_MIN) 1327c478bd9Sstevel@tonic-gate *tp = INT32_MIN; 1337c478bd9Sstevel@tonic-gate #endif 1347c478bd9Sstevel@tonic-gate i = (int32_t)*tp; 135*61961e0fSrobinson return (XDR_PUTINT32(xdrs, &i)); 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate case XDR_DECODE: 138*61961e0fSrobinson if (!XDR_GETINT32(xdrs, &i)) 1397c478bd9Sstevel@tonic-gate return (FALSE); 1407c478bd9Sstevel@tonic-gate *tp = (time_t)i; 1417c478bd9Sstevel@tonic-gate return (TRUE); 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate case XDR_FREE: 1447c478bd9Sstevel@tonic-gate return (TRUE); 1457c478bd9Sstevel@tonic-gate } 1467c478bd9Sstevel@tonic-gate return (FALSE); 1477c478bd9Sstevel@tonic-gate } 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate /* 1507c478bd9Sstevel@tonic-gate * XDR integers 1517c478bd9Sstevel@tonic-gate */ 1527c478bd9Sstevel@tonic-gate bool_t 1537c478bd9Sstevel@tonic-gate xdr_int(XDR *xdrs, int *ip) 1547c478bd9Sstevel@tonic-gate { 155*61961e0fSrobinson switch (xdrs->x_op) { 156*61961e0fSrobinson case XDR_ENCODE: 1577c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, ip)); 158*61961e0fSrobinson case XDR_DECODE: 1597c478bd9Sstevel@tonic-gate return (XDR_GETINT32(xdrs, ip)); 160*61961e0fSrobinson case XDR_FREE: 1617c478bd9Sstevel@tonic-gate return (TRUE); 162*61961e0fSrobinson } 1637c478bd9Sstevel@tonic-gate return (FALSE); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /* 1677c478bd9Sstevel@tonic-gate * XDR unsigned integers 1687c478bd9Sstevel@tonic-gate */ 1697c478bd9Sstevel@tonic-gate bool_t 1707c478bd9Sstevel@tonic-gate xdr_u_int(XDR *xdrs, uint_t *up) 1717c478bd9Sstevel@tonic-gate { 172*61961e0fSrobinson switch (xdrs->x_op) { 173*61961e0fSrobinson case XDR_ENCODE: 1747c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, (int *)up)); 175*61961e0fSrobinson case XDR_DECODE: 1767c478bd9Sstevel@tonic-gate return (XDR_GETINT32(xdrs, (int *)up)); 177*61961e0fSrobinson case XDR_FREE: 1787c478bd9Sstevel@tonic-gate return (TRUE); 179*61961e0fSrobinson } 1807c478bd9Sstevel@tonic-gate return (FALSE); 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate /* 1847c478bd9Sstevel@tonic-gate * The definition of xdr_long()/xdr_u_long() is kept for backward 1857c478bd9Sstevel@tonic-gate * compatibitlity. 1867c478bd9Sstevel@tonic-gate * XDR long integers, same as xdr_u_long 1877c478bd9Sstevel@tonic-gate */ 1887c478bd9Sstevel@tonic-gate bool_t 1897c478bd9Sstevel@tonic-gate xdr_long(XDR *xdrs, long *lp) 1907c478bd9Sstevel@tonic-gate { 1917c478bd9Sstevel@tonic-gate int32_t i; 1927c478bd9Sstevel@tonic-gate 193*61961e0fSrobinson switch (xdrs->x_op) { 194*61961e0fSrobinson case XDR_ENCODE: 1957c478bd9Sstevel@tonic-gate #if defined(_LP64) 196*61961e0fSrobinson if ((*lp > INT32_MAX) || (*lp < INT32_MIN)) 1977c478bd9Sstevel@tonic-gate return (FALSE); 1987c478bd9Sstevel@tonic-gate #endif 1997c478bd9Sstevel@tonic-gate i = (int32_t)*lp; 200*61961e0fSrobinson return (XDR_PUTINT32(xdrs, &i)); 201*61961e0fSrobinson case XDR_DECODE: 202*61961e0fSrobinson if (!XDR_GETINT32(xdrs, &i)) 203*61961e0fSrobinson return (FALSE); 2047c478bd9Sstevel@tonic-gate *lp = (long)i; 205*61961e0fSrobinson return (TRUE); 206*61961e0fSrobinson case XDR_FREE: 207*61961e0fSrobinson return (TRUE); 208*61961e0fSrobinson } 209*61961e0fSrobinson return (FALSE); 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate /* 2137c478bd9Sstevel@tonic-gate * XDR unsigned long integers 2147c478bd9Sstevel@tonic-gate * same as xdr_long 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate bool_t 2177c478bd9Sstevel@tonic-gate xdr_u_long(XDR *xdrs, ulong_t *ulp) 2187c478bd9Sstevel@tonic-gate { 2197c478bd9Sstevel@tonic-gate uint32_t ui; 2207c478bd9Sstevel@tonic-gate 221*61961e0fSrobinson switch (xdrs->x_op) { 222*61961e0fSrobinson case XDR_ENCODE: 2237c478bd9Sstevel@tonic-gate #if defined(_LP64) 224*61961e0fSrobinson if (*ulp > UINT32_MAX) 2257c478bd9Sstevel@tonic-gate return (FALSE); 2267c478bd9Sstevel@tonic-gate #endif 2277c478bd9Sstevel@tonic-gate ui = (uint32_t)*ulp; 228*61961e0fSrobinson return (XDR_PUTINT32(xdrs, (int32_t *)&ui)); 229*61961e0fSrobinson case XDR_DECODE: 230*61961e0fSrobinson if (!XDR_GETINT32(xdrs, (int32_t *)&ui)) 231*61961e0fSrobinson return (FALSE); 2327c478bd9Sstevel@tonic-gate *ulp = (ulong_t)ui; 233*61961e0fSrobinson return (TRUE); 234*61961e0fSrobinson case XDR_FREE: 235*61961e0fSrobinson return (TRUE); 236*61961e0fSrobinson } 237*61961e0fSrobinson return (FALSE); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate /* 2417c478bd9Sstevel@tonic-gate * XDR short integers 2427c478bd9Sstevel@tonic-gate */ 2437c478bd9Sstevel@tonic-gate bool_t 2447c478bd9Sstevel@tonic-gate xdr_short(XDR *xdrs, short *sp) 2457c478bd9Sstevel@tonic-gate { 2467c478bd9Sstevel@tonic-gate int32_t l; 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 2497c478bd9Sstevel@tonic-gate case XDR_ENCODE: 2507c478bd9Sstevel@tonic-gate l = (int32_t)*sp; 251*61961e0fSrobinson return (XDR_PUTINT32(xdrs, &l)); 2527c478bd9Sstevel@tonic-gate case XDR_DECODE: 253*61961e0fSrobinson if (!XDR_GETINT32(xdrs, &l)) 2547c478bd9Sstevel@tonic-gate return (FALSE); 2557c478bd9Sstevel@tonic-gate *sp = (short)l; 2567c478bd9Sstevel@tonic-gate return (TRUE); 2577c478bd9Sstevel@tonic-gate case XDR_FREE: 2587c478bd9Sstevel@tonic-gate return (TRUE); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate return (FALSE); 2617c478bd9Sstevel@tonic-gate } 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate /* 2647c478bd9Sstevel@tonic-gate * XDR unsigned short integers 2657c478bd9Sstevel@tonic-gate */ 2667c478bd9Sstevel@tonic-gate bool_t 2677c478bd9Sstevel@tonic-gate xdr_u_short(XDR *xdrs, ushort_t *usp) 2687c478bd9Sstevel@tonic-gate { 2697c478bd9Sstevel@tonic-gate uint_t i; 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 2727c478bd9Sstevel@tonic-gate case XDR_ENCODE: 2737c478bd9Sstevel@tonic-gate i = (uint_t)*usp; 274*61961e0fSrobinson return (XDR_PUTINT32(xdrs, (int *)&i)); 2757c478bd9Sstevel@tonic-gate case XDR_DECODE: 276*61961e0fSrobinson if (!XDR_GETINT32(xdrs, (int *)&i)) 2777c478bd9Sstevel@tonic-gate return (FALSE); 2787c478bd9Sstevel@tonic-gate *usp = (ushort_t)i; 2797c478bd9Sstevel@tonic-gate return (TRUE); 2807c478bd9Sstevel@tonic-gate case XDR_FREE: 2817c478bd9Sstevel@tonic-gate return (TRUE); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate return (FALSE); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate /* 2887c478bd9Sstevel@tonic-gate * XDR a char 2897c478bd9Sstevel@tonic-gate */ 2907c478bd9Sstevel@tonic-gate bool_t 2917c478bd9Sstevel@tonic-gate xdr_char(XDR *xdrs, char *cp) 2927c478bd9Sstevel@tonic-gate { 2937c478bd9Sstevel@tonic-gate int i; 2947c478bd9Sstevel@tonic-gate 295*61961e0fSrobinson switch (xdrs->x_op) { 296*61961e0fSrobinson case XDR_ENCODE: 2977c478bd9Sstevel@tonic-gate i = (*cp); 298*61961e0fSrobinson return (XDR_PUTINT32(xdrs, &i)); 299*61961e0fSrobinson case XDR_DECODE: 300*61961e0fSrobinson if (!XDR_GETINT32(xdrs, &i)) 301*61961e0fSrobinson return (FALSE); 3027c478bd9Sstevel@tonic-gate *cp = (char)i; 303*61961e0fSrobinson return (TRUE); 304*61961e0fSrobinson case XDR_FREE: 305*61961e0fSrobinson return (TRUE); 306*61961e0fSrobinson } 307*61961e0fSrobinson return (FALSE); 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * XDR an unsigned char 3127c478bd9Sstevel@tonic-gate */ 3137c478bd9Sstevel@tonic-gate bool_t 3147c478bd9Sstevel@tonic-gate xdr_u_char(XDR *xdrs, uchar_t *cp) 3157c478bd9Sstevel@tonic-gate { 3167c478bd9Sstevel@tonic-gate int i; 3177c478bd9Sstevel@tonic-gate 318*61961e0fSrobinson switch (xdrs->x_op) { 319*61961e0fSrobinson case XDR_ENCODE: 3207c478bd9Sstevel@tonic-gate i = (*cp); 321*61961e0fSrobinson return (XDR_PUTINT32(xdrs, &i)); 322*61961e0fSrobinson case XDR_DECODE: 323*61961e0fSrobinson if (!XDR_GETINT32(xdrs, &i)) 324*61961e0fSrobinson return (FALSE); 3257c478bd9Sstevel@tonic-gate *cp = (uchar_t)i; 326*61961e0fSrobinson return (TRUE); 327*61961e0fSrobinson case XDR_FREE: 328*61961e0fSrobinson return (TRUE); 329*61961e0fSrobinson } 330*61961e0fSrobinson return (FALSE); 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate /* 3347c478bd9Sstevel@tonic-gate * XDR booleans 3357c478bd9Sstevel@tonic-gate */ 3367c478bd9Sstevel@tonic-gate bool_t 3377c478bd9Sstevel@tonic-gate xdr_bool(XDR *xdrs, bool_t *bp) 3387c478bd9Sstevel@tonic-gate { 3397c478bd9Sstevel@tonic-gate int i; 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 3427c478bd9Sstevel@tonic-gate case XDR_ENCODE: 3437c478bd9Sstevel@tonic-gate i = *bp ? XDR_TRUE : XDR_FALSE; 344*61961e0fSrobinson return (XDR_PUTINT32(xdrs, &i)); 3457c478bd9Sstevel@tonic-gate case XDR_DECODE: 346*61961e0fSrobinson if (!XDR_GETINT32(xdrs, &i)) 3477c478bd9Sstevel@tonic-gate return (FALSE); 3487c478bd9Sstevel@tonic-gate *bp = (i == XDR_FALSE) ? FALSE : TRUE; 3497c478bd9Sstevel@tonic-gate return (TRUE); 3507c478bd9Sstevel@tonic-gate case XDR_FREE: 3517c478bd9Sstevel@tonic-gate return (TRUE); 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate return (FALSE); 3547c478bd9Sstevel@tonic-gate } 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate /* 3577c478bd9Sstevel@tonic-gate * XDR enumerations 3587c478bd9Sstevel@tonic-gate */ 3597c478bd9Sstevel@tonic-gate bool_t 3607c478bd9Sstevel@tonic-gate xdr_enum(XDR *xdrs, enum_t *ep) 3617c478bd9Sstevel@tonic-gate { 3627c478bd9Sstevel@tonic-gate enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate /* 3657c478bd9Sstevel@tonic-gate * enums are treated as ints 3667c478bd9Sstevel@tonic-gate */ 367*61961e0fSrobinson /* CONSTCOND */ 368*61961e0fSrobinson assert(sizeof (enum sizecheck) == sizeof (int32_t)); 369*61961e0fSrobinson return (xdr_int(xdrs, (int *)ep)); 3707c478bd9Sstevel@tonic-gate } 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate /* 3737c478bd9Sstevel@tonic-gate * XDR opaque data 3747c478bd9Sstevel@tonic-gate * Allows the specification of a fixed size sequence of opaque bytes. 3757c478bd9Sstevel@tonic-gate * cp points to the opaque object and cnt gives the byte length. 3767c478bd9Sstevel@tonic-gate */ 3777c478bd9Sstevel@tonic-gate bool_t 378*61961e0fSrobinson xdr_opaque(XDR *xdrs, caddr_t cp, const uint_t cnt) 3797c478bd9Sstevel@tonic-gate { 380*61961e0fSrobinson uint_t rndup; 3817c478bd9Sstevel@tonic-gate char crud[BYTES_PER_XDR_UNIT]; 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate /* 3847c478bd9Sstevel@tonic-gate * if no data we are done 3857c478bd9Sstevel@tonic-gate */ 386*61961e0fSrobinson if (cnt == 0) 3877c478bd9Sstevel@tonic-gate return (TRUE); 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /* 3907c478bd9Sstevel@tonic-gate * round byte count to full xdr units 3917c478bd9Sstevel@tonic-gate */ 3927c478bd9Sstevel@tonic-gate rndup = cnt % BYTES_PER_XDR_UNIT; 3937c478bd9Sstevel@tonic-gate if ((int)rndup > 0) 3947c478bd9Sstevel@tonic-gate rndup = BYTES_PER_XDR_UNIT - rndup; 3957c478bd9Sstevel@tonic-gate 396*61961e0fSrobinson switch (xdrs->x_op) { 397*61961e0fSrobinson case XDR_DECODE: 398*61961e0fSrobinson if (!XDR_GETBYTES(xdrs, cp, cnt)) 3997c478bd9Sstevel@tonic-gate return (FALSE); 400*61961e0fSrobinson if (rndup == 0) 4017c478bd9Sstevel@tonic-gate return (TRUE); 402*61961e0fSrobinson return (XDR_GETBYTES(xdrs, crud, rndup)); 403*61961e0fSrobinson case XDR_ENCODE: 404*61961e0fSrobinson if (!XDR_PUTBYTES(xdrs, cp, cnt)) 4057c478bd9Sstevel@tonic-gate return (FALSE); 406*61961e0fSrobinson if (rndup == 0) 4077c478bd9Sstevel@tonic-gate return (TRUE); 408*61961e0fSrobinson return (XDR_PUTBYTES(xdrs, (caddr_t)&xdr_zero[0], rndup)); 409*61961e0fSrobinson case XDR_FREE: 4107c478bd9Sstevel@tonic-gate return (TRUE); 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate return (FALSE); 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate /* 4167c478bd9Sstevel@tonic-gate * XDR counted bytes 4177c478bd9Sstevel@tonic-gate * *cpp is a pointer to the bytes, *sizep is the count. 4187c478bd9Sstevel@tonic-gate * If *cpp is NULL maxsize bytes are allocated 4197c478bd9Sstevel@tonic-gate */ 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate static const char xdr_err[] = "xdr_%s: out of memory"; 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate bool_t 424*61961e0fSrobinson xdr_bytes(XDR *xdrs, char **cpp, uint_t *sizep, const uint_t maxsize) 4257c478bd9Sstevel@tonic-gate { 426*61961e0fSrobinson char *sp = *cpp; /* sp is the actual string pointer */ 427*61961e0fSrobinson uint_t nodesize; 4287c478bd9Sstevel@tonic-gate 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * first deal with the length since xdr bytes are counted 4317c478bd9Sstevel@tonic-gate * We decided not to use MACRO XDR_U_INT here, because the 4327c478bd9Sstevel@tonic-gate * advantages here will be miniscule compared to xdr_bytes. 4337c478bd9Sstevel@tonic-gate * This saved us 100 bytes in the library size. 4347c478bd9Sstevel@tonic-gate */ 435*61961e0fSrobinson if (!xdr_u_int(xdrs, sizep)) 4367c478bd9Sstevel@tonic-gate return (FALSE); 4377c478bd9Sstevel@tonic-gate nodesize = *sizep; 438*61961e0fSrobinson if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) 4397c478bd9Sstevel@tonic-gate return (FALSE); 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate /* 4427c478bd9Sstevel@tonic-gate * now deal with the actual bytes 4437c478bd9Sstevel@tonic-gate */ 4447c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 4457c478bd9Sstevel@tonic-gate case XDR_DECODE: 446*61961e0fSrobinson if (nodesize == 0) 4477c478bd9Sstevel@tonic-gate return (TRUE); 448*61961e0fSrobinson if (sp == NULL) 449*61961e0fSrobinson *cpp = sp = malloc(nodesize); 4507c478bd9Sstevel@tonic-gate if (sp == NULL) { 4517c478bd9Sstevel@tonic-gate (void) syslog(LOG_ERR, xdr_err, (const char *)"bytes"); 4527c478bd9Sstevel@tonic-gate return (FALSE); 4537c478bd9Sstevel@tonic-gate } 4547c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 4557c478bd9Sstevel@tonic-gate case XDR_ENCODE: 456*61961e0fSrobinson return (xdr_opaque(xdrs, sp, nodesize)); 4577c478bd9Sstevel@tonic-gate case XDR_FREE: 4587c478bd9Sstevel@tonic-gate if (sp != NULL) { 459*61961e0fSrobinson free(sp); 4607c478bd9Sstevel@tonic-gate *cpp = NULL; 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate return (TRUE); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate return (FALSE); 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate /* 4687c478bd9Sstevel@tonic-gate * Implemented here due to commonality of the object. 4697c478bd9Sstevel@tonic-gate */ 4707c478bd9Sstevel@tonic-gate bool_t 4717c478bd9Sstevel@tonic-gate xdr_netobj(XDR *xdrs, struct netobj *np) 4727c478bd9Sstevel@tonic-gate { 473*61961e0fSrobinson return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate /* 4777c478bd9Sstevel@tonic-gate * XDR a descriminated union 4787c478bd9Sstevel@tonic-gate * Support routine for discriminated unions. 4797c478bd9Sstevel@tonic-gate * You create an array of xdrdiscrim structures, terminated with 4807c478bd9Sstevel@tonic-gate * an entry with a null procedure pointer. The routine gets 4817c478bd9Sstevel@tonic-gate * the discriminant value and then searches the array of xdrdiscrims 4827c478bd9Sstevel@tonic-gate * looking for that value. It calls the procedure given in the xdrdiscrim 4837c478bd9Sstevel@tonic-gate * to handle the discriminant. If there is no specific routine a default 4847c478bd9Sstevel@tonic-gate * routine may be called. 4857c478bd9Sstevel@tonic-gate * If there is no specific or default routine an error is returned. 4867c478bd9Sstevel@tonic-gate */ 4877c478bd9Sstevel@tonic-gate bool_t 4887c478bd9Sstevel@tonic-gate xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, 489*61961e0fSrobinson const struct xdr_discrim *choices, const xdrproc_t dfault) 4907c478bd9Sstevel@tonic-gate { 491*61961e0fSrobinson enum_t dscm; 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate /* 4947c478bd9Sstevel@tonic-gate * we deal with the discriminator; it's an enum 4957c478bd9Sstevel@tonic-gate */ 496*61961e0fSrobinson if (!xdr_enum(xdrs, dscmp)) 4977c478bd9Sstevel@tonic-gate return (FALSE); 4987c478bd9Sstevel@tonic-gate dscm = *dscmp; 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate /* 5017c478bd9Sstevel@tonic-gate * search choices for a value that matches the discriminator. 5027c478bd9Sstevel@tonic-gate * if we find one, execute the xdr routine for that value. 5037c478bd9Sstevel@tonic-gate */ 5047c478bd9Sstevel@tonic-gate for (; choices->proc != NULL_xdrproc_t; choices++) { 505*61961e0fSrobinson if (choices->value == dscm) 506*61961e0fSrobinson return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate /* 5107c478bd9Sstevel@tonic-gate * no match - execute the default xdr routine if there is one 5117c478bd9Sstevel@tonic-gate */ 512*61961e0fSrobinson return ((dfault == NULL_xdrproc_t) ? FALSE : 513*61961e0fSrobinson (*dfault)(xdrs, unp, LASTUNSIGNED)); 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate /* 5187c478bd9Sstevel@tonic-gate * Non-portable xdr primitives. 5197c478bd9Sstevel@tonic-gate * Care should be taken when moving these routines to new architectures. 5207c478bd9Sstevel@tonic-gate */ 5217c478bd9Sstevel@tonic-gate 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate /* 5247c478bd9Sstevel@tonic-gate * XDR null terminated ASCII strings 5257c478bd9Sstevel@tonic-gate * xdr_string deals with "C strings" - arrays of bytes that are 5267c478bd9Sstevel@tonic-gate * terminated by a NULL character. The parameter cpp references a 5277c478bd9Sstevel@tonic-gate * pointer to storage; If the pointer is null, then the necessary 5287c478bd9Sstevel@tonic-gate * storage is allocated. The last parameter is the max allowed length 5297c478bd9Sstevel@tonic-gate * of the string as specified by a protocol. 5307c478bd9Sstevel@tonic-gate */ 5317c478bd9Sstevel@tonic-gate bool_t 532*61961e0fSrobinson xdr_string(XDR *xdrs, char **cpp, const uint_t maxsize) 5337c478bd9Sstevel@tonic-gate { 534*61961e0fSrobinson char *newsp, *sp = *cpp; /* sp is the actual string pointer */ 5357c478bd9Sstevel@tonic-gate uint_t size, block; 5367c478bd9Sstevel@tonic-gate uint64_t bytesread; 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate /* 5397c478bd9Sstevel@tonic-gate * first deal with the length since xdr strings are counted-strings 5407c478bd9Sstevel@tonic-gate */ 5417c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 5427c478bd9Sstevel@tonic-gate case XDR_FREE: 543*61961e0fSrobinson if (sp == NULL) 5447c478bd9Sstevel@tonic-gate return (TRUE); /* already free */ 5457c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 5467c478bd9Sstevel@tonic-gate case XDR_ENCODE: 5477c478bd9Sstevel@tonic-gate size = (sp != NULL) ? (uint_t)strlen(sp) : 0; 5487c478bd9Sstevel@tonic-gate break; 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate /* 5517c478bd9Sstevel@tonic-gate * We decided not to use MACRO XDR_U_INT here, because the 5527c478bd9Sstevel@tonic-gate * advantages here will be miniscule compared to xdr_string. 5537c478bd9Sstevel@tonic-gate * This saved us 100 bytes in the library size. 5547c478bd9Sstevel@tonic-gate */ 555*61961e0fSrobinson if (!xdr_u_int(xdrs, &size)) 5567c478bd9Sstevel@tonic-gate return (FALSE); 557*61961e0fSrobinson if (size > maxsize) 5587c478bd9Sstevel@tonic-gate return (FALSE); 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate /* 5617c478bd9Sstevel@tonic-gate * now deal with the actual bytes 5627c478bd9Sstevel@tonic-gate */ 5637c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 5647c478bd9Sstevel@tonic-gate case XDR_DECODE: 5657c478bd9Sstevel@tonic-gate /* if buffer is already given, call xdr_opaque() directly */ 5667c478bd9Sstevel@tonic-gate if (sp != NULL) { 567*61961e0fSrobinson if (!xdr_opaque(xdrs, sp, size)) 568*61961e0fSrobinson return (FALSE); 5697c478bd9Sstevel@tonic-gate sp[size] = 0; 570*61961e0fSrobinson return (TRUE); 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate 5737c478bd9Sstevel@tonic-gate /* 5747c478bd9Sstevel@tonic-gate * We have to allocate a buffer of size 'size'. To avoid 5757c478bd9Sstevel@tonic-gate * malloc()ing one huge chunk, we'll read the bytes in max 5767c478bd9Sstevel@tonic-gate * FRAGMENT size blocks and keep realloc()ing. 'block' is 5777c478bd9Sstevel@tonic-gate * the number of bytes to read in each xdr_opaque() and 5787c478bd9Sstevel@tonic-gate * 'bytesread' is what we have already read. sp is NULL 5797c478bd9Sstevel@tonic-gate * when we are in the loop for the first time. 5807c478bd9Sstevel@tonic-gate */ 5817c478bd9Sstevel@tonic-gate bytesread = 0; 5827c478bd9Sstevel@tonic-gate do { 5837c478bd9Sstevel@tonic-gate block = MIN(size - bytesread, FRAGMENT); 5847c478bd9Sstevel@tonic-gate /* 5857c478bd9Sstevel@tonic-gate * allocate enough for 'bytesread + block' bytes and 5867c478bd9Sstevel@tonic-gate * one extra for the terminating NULL. 5877c478bd9Sstevel@tonic-gate */ 5887c478bd9Sstevel@tonic-gate newsp = realloc(sp, bytesread + block + 1); 5897c478bd9Sstevel@tonic-gate if (newsp == NULL) { 5907c478bd9Sstevel@tonic-gate if (sp != NULL) 5917c478bd9Sstevel@tonic-gate free(sp); 5927c478bd9Sstevel@tonic-gate return (FALSE); 5937c478bd9Sstevel@tonic-gate } 5947c478bd9Sstevel@tonic-gate sp = newsp; 5957c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, &sp[bytesread], block)) { 5967c478bd9Sstevel@tonic-gate free(sp); 5977c478bd9Sstevel@tonic-gate return (FALSE); 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate bytesread += block; 6007c478bd9Sstevel@tonic-gate } while (bytesread < size); 6017c478bd9Sstevel@tonic-gate 6027c478bd9Sstevel@tonic-gate sp[bytesread] = 0; /* terminate the string with a NULL */ 6037c478bd9Sstevel@tonic-gate *cpp = sp; 6047c478bd9Sstevel@tonic-gate return (TRUE); 6057c478bd9Sstevel@tonic-gate case XDR_ENCODE: 606*61961e0fSrobinson return (xdr_opaque(xdrs, sp, size)); 6077c478bd9Sstevel@tonic-gate case XDR_FREE: 6087c478bd9Sstevel@tonic-gate free(sp); 6097c478bd9Sstevel@tonic-gate *cpp = NULL; 6107c478bd9Sstevel@tonic-gate return (TRUE); 6117c478bd9Sstevel@tonic-gate } 6127c478bd9Sstevel@tonic-gate return (FALSE); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate bool_t 6167c478bd9Sstevel@tonic-gate xdr_hyper(XDR *xdrs, longlong_t *hp) 6177c478bd9Sstevel@tonic-gate { 6187c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 6197c478bd9Sstevel@tonic-gate #if defined(_LONG_LONG_HTOL) 620*61961e0fSrobinson if (XDR_PUTINT32(xdrs, (int *)hp) == TRUE) 621*61961e0fSrobinson /* LINTED pointer cast */ 622*61961e0fSrobinson return (XDR_PUTINT32(xdrs, (int *)((char *)hp + 623*61961e0fSrobinson BYTES_PER_XDR_UNIT))); 6247c478bd9Sstevel@tonic-gate #else 625*61961e0fSrobinson /* LINTED pointer cast */ 6267c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, (int *)((char *)hp + 627*61961e0fSrobinson BYTES_PER_XDR_UNIT)) == TRUE) 628*61961e0fSrobinson return (XDR_PUTINT32(xdrs, (int32_t *)hp)); 6297c478bd9Sstevel@tonic-gate #endif 6307c478bd9Sstevel@tonic-gate return (FALSE); 631*61961e0fSrobinson } 6327c478bd9Sstevel@tonic-gate 633*61961e0fSrobinson if (xdrs->x_op == XDR_DECODE) { 6347c478bd9Sstevel@tonic-gate #if defined(_LONG_LONG_HTOL) 6357c478bd9Sstevel@tonic-gate if (XDR_GETINT32(xdrs, (int *)hp) == FALSE || 636*61961e0fSrobinson /* LINTED pointer cast */ 6377c478bd9Sstevel@tonic-gate (XDR_GETINT32(xdrs, (int *)((char *)hp + 638*61961e0fSrobinson BYTES_PER_XDR_UNIT)) == FALSE)) 6397c478bd9Sstevel@tonic-gate return (FALSE); 6407c478bd9Sstevel@tonic-gate #else 641*61961e0fSrobinson /* LINTED pointer cast */ 6427c478bd9Sstevel@tonic-gate if ((XDR_GETINT32(xdrs, (int *)((char *)hp + 6437c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT)) == FALSE) || 644*61961e0fSrobinson (XDR_GETINT32(xdrs, (int *)hp) == FALSE)) 6457c478bd9Sstevel@tonic-gate return (FALSE); 6467c478bd9Sstevel@tonic-gate #endif 6477c478bd9Sstevel@tonic-gate return (TRUE); 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate return (TRUE); 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate 6527c478bd9Sstevel@tonic-gate bool_t 6537c478bd9Sstevel@tonic-gate xdr_u_hyper(XDR *xdrs, u_longlong_t *hp) 6547c478bd9Sstevel@tonic-gate { 655*61961e0fSrobinson return (xdr_hyper(xdrs, (longlong_t *)hp)); 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate bool_t 6597c478bd9Sstevel@tonic-gate xdr_longlong_t(XDR *xdrs, longlong_t *hp) 6607c478bd9Sstevel@tonic-gate { 661*61961e0fSrobinson return (xdr_hyper(xdrs, hp)); 6627c478bd9Sstevel@tonic-gate } 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate bool_t 6657c478bd9Sstevel@tonic-gate xdr_u_longlong_t(XDR *xdrs, u_longlong_t *hp) 6667c478bd9Sstevel@tonic-gate { 667*61961e0fSrobinson return (xdr_hyper(xdrs, (longlong_t *)hp)); 6687c478bd9Sstevel@tonic-gate } 6697c478bd9Sstevel@tonic-gate 6707c478bd9Sstevel@tonic-gate /* 6717c478bd9Sstevel@tonic-gate * Wrapper for xdr_string that can be called directly from 6727c478bd9Sstevel@tonic-gate * routines like clnt_call 6737c478bd9Sstevel@tonic-gate */ 6747c478bd9Sstevel@tonic-gate bool_t 6757c478bd9Sstevel@tonic-gate xdr_wrapstring(XDR *xdrs, char **cpp) 6767c478bd9Sstevel@tonic-gate { 677*61961e0fSrobinson return (xdr_string(xdrs, cpp, LASTUNSIGNED)); 6787c478bd9Sstevel@tonic-gate } 679