1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 23*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 24*7c478bd9Sstevel@tonic-gate */ 25*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 27*7c478bd9Sstevel@tonic-gate /* 28*7c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 29*7c478bd9Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of 30*7c478bd9Sstevel@tonic-gate * California. 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate /* 36*7c478bd9Sstevel@tonic-gate * xdr.c, Generic XDR routines implementation. 37*7c478bd9Sstevel@tonic-gate * 38*7c478bd9Sstevel@tonic-gate * These are the "generic" xdr routines used to serialize and de-serialize 39*7c478bd9Sstevel@tonic-gate * most common data items. See xdr.h for more info on the interface to 40*7c478bd9Sstevel@tonic-gate * xdr. 41*7c478bd9Sstevel@tonic-gate */ 42*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 43*7c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h> 44*7c478bd9Sstevel@tonic-gate #include <rpc/trace.h> 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 47*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 48*7c478bd9Sstevel@tonic-gate #include <sys/systm.h> 49*7c478bd9Sstevel@tonic-gate #else 50*7c478bd9Sstevel@tonic-gate #include <syslog.h> 51*7c478bd9Sstevel@tonic-gate #include <stdio.h> 52*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 53*7c478bd9Sstevel@tonic-gate #include <string.h> 54*7c478bd9Sstevel@tonic-gate #endif 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate #include <limits.h> 57*7c478bd9Sstevel@tonic-gate #include <rpc/types.h> 58*7c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 59*7c478bd9Sstevel@tonic-gate #include <inttypes.h> 60*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int64_t = xdr_hyper 63*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint64_t = xdr_u_hyper 64*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int32_t = xdr_int 65*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint32_t = xdr_u_int 66*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int16_t = xdr_short 67*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint16_t = xdr_u_short 68*7c478bd9Sstevel@tonic-gate #pragma weak xdr_int8_t = xdr_char 69*7c478bd9Sstevel@tonic-gate #pragma weak xdr_uint8_t = xdr_u_char 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate /* 72*7c478bd9Sstevel@tonic-gate * constants specific to the xdr "protocol" 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate #define XDR_FALSE ((uint_t)0) 75*7c478bd9Sstevel@tonic-gate #define XDR_TRUE ((uint_t)1) 76*7c478bd9Sstevel@tonic-gate #define LASTUNSIGNED ((uint_t)0-1) 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate /* fragment size to use when doing an xdr_string() */ 79*7c478bd9Sstevel@tonic-gate #define FRAGMENT 65536 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate /* 82*7c478bd9Sstevel@tonic-gate * for unit alignment 83*7c478bd9Sstevel@tonic-gate */ 84*7c478bd9Sstevel@tonic-gate static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0 }; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate #ifndef KERNEL 87*7c478bd9Sstevel@tonic-gate /* 88*7c478bd9Sstevel@tonic-gate * Free a data structure using XDR 89*7c478bd9Sstevel@tonic-gate * Not a filter, but a convenient utility nonetheless 90*7c478bd9Sstevel@tonic-gate */ 91*7c478bd9Sstevel@tonic-gate void 92*7c478bd9Sstevel@tonic-gate xdr_free(xdrproc_t proc, char *objp) 93*7c478bd9Sstevel@tonic-gate { 94*7c478bd9Sstevel@tonic-gate XDR x; 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_free, 0); 97*7c478bd9Sstevel@tonic-gate x.x_op = XDR_FREE; 98*7c478bd9Sstevel@tonic-gate (*proc)(&x, objp); 99*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_free, 1); 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate #endif 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /* 104*7c478bd9Sstevel@tonic-gate * XDR nothing 105*7c478bd9Sstevel@tonic-gate */ 106*7c478bd9Sstevel@tonic-gate bool_t 107*7c478bd9Sstevel@tonic-gate xdr_void() 108*7c478bd9Sstevel@tonic-gate { 109*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_void, 0); 110*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_void, 1); 111*7c478bd9Sstevel@tonic-gate return (TRUE); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate /* 115*7c478bd9Sstevel@tonic-gate * xdr_time_t sends time_t value over the wire. 116*7c478bd9Sstevel@tonic-gate * Due to RPC Protocol limitation, it can only send 117*7c478bd9Sstevel@tonic-gate * up to 32-bit integer quantity over the wire. 118*7c478bd9Sstevel@tonic-gate * 119*7c478bd9Sstevel@tonic-gate */ 120*7c478bd9Sstevel@tonic-gate bool_t 121*7c478bd9Sstevel@tonic-gate xdr_time_t(XDR *xdrs, time_t *tp) 122*7c478bd9Sstevel@tonic-gate { 123*7c478bd9Sstevel@tonic-gate bool_t dummy; 124*7c478bd9Sstevel@tonic-gate int32_t i; 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_time_t, 0); 127*7c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 128*7c478bd9Sstevel@tonic-gate case XDR_ENCODE: 129*7c478bd9Sstevel@tonic-gate /* 130*7c478bd9Sstevel@tonic-gate * Check for the time overflow, when encoding it. 131*7c478bd9Sstevel@tonic-gate * Don't want to send OTW the time value too large to 132*7c478bd9Sstevel@tonic-gate * handle by the protocol. 133*7c478bd9Sstevel@tonic-gate */ 134*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 135*7c478bd9Sstevel@tonic-gate if (*tp > INT32_MAX) 136*7c478bd9Sstevel@tonic-gate *tp = INT32_MAX; 137*7c478bd9Sstevel@tonic-gate else if (*tp < INT32_MIN) 138*7c478bd9Sstevel@tonic-gate *tp = INT32_MIN; 139*7c478bd9Sstevel@tonic-gate #endif 140*7c478bd9Sstevel@tonic-gate i = (int32_t)*tp; 141*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTINT32(xdrs, &i); 142*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_time_t, 1); 143*7c478bd9Sstevel@tonic-gate return (dummy); 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate case XDR_DECODE: 146*7c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, &i)) { 147*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_time_t, 1); 148*7c478bd9Sstevel@tonic-gate return (FALSE); 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate *tp = (time_t)i; 151*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_time_t, 1); 152*7c478bd9Sstevel@tonic-gate return (TRUE); 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate case XDR_FREE: 155*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_time_t, 1); 156*7c478bd9Sstevel@tonic-gate return (TRUE); 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_time_t, 1); 159*7c478bd9Sstevel@tonic-gate return (FALSE); 160*7c478bd9Sstevel@tonic-gate } 161*7c478bd9Sstevel@tonic-gate 162*7c478bd9Sstevel@tonic-gate /* 163*7c478bd9Sstevel@tonic-gate * XDR integers 164*7c478bd9Sstevel@tonic-gate */ 165*7c478bd9Sstevel@tonic-gate bool_t 166*7c478bd9Sstevel@tonic-gate xdr_int(XDR *xdrs, int *ip) 167*7c478bd9Sstevel@tonic-gate { 168*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_int, 0); 169*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) 170*7c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, ip)); 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) 173*7c478bd9Sstevel@tonic-gate return (XDR_GETINT32(xdrs, ip)); 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 176*7c478bd9Sstevel@tonic-gate return (TRUE); 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_int, 1); 179*7c478bd9Sstevel@tonic-gate return (FALSE); 180*7c478bd9Sstevel@tonic-gate } 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate /* 183*7c478bd9Sstevel@tonic-gate * XDR unsigned integers 184*7c478bd9Sstevel@tonic-gate */ 185*7c478bd9Sstevel@tonic-gate bool_t 186*7c478bd9Sstevel@tonic-gate xdr_u_int(XDR *xdrs, uint_t *up) 187*7c478bd9Sstevel@tonic-gate { 188*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_int, 0); 189*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) 190*7c478bd9Sstevel@tonic-gate return (XDR_PUTINT32(xdrs, (int *)up)); 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) 193*7c478bd9Sstevel@tonic-gate return (XDR_GETINT32(xdrs, (int *)up)); 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 196*7c478bd9Sstevel@tonic-gate return (TRUE); 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_int, 1); 199*7c478bd9Sstevel@tonic-gate return (FALSE); 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate #ifndef KERNEL 203*7c478bd9Sstevel@tonic-gate static const char xdrlong_err[] = 204*7c478bd9Sstevel@tonic-gate "xdr_%s: value too large to be stored in data type"; 205*7c478bd9Sstevel@tonic-gate #endif 206*7c478bd9Sstevel@tonic-gate 207*7c478bd9Sstevel@tonic-gate /* 208*7c478bd9Sstevel@tonic-gate * The definition of xdr_long()/xdr_u_long() is kept for backward 209*7c478bd9Sstevel@tonic-gate * compatibitlity. 210*7c478bd9Sstevel@tonic-gate * XDR long integers, same as xdr_u_long 211*7c478bd9Sstevel@tonic-gate */ 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate bool_t 214*7c478bd9Sstevel@tonic-gate xdr_long(XDR *xdrs, long *lp) 215*7c478bd9Sstevel@tonic-gate { 216*7c478bd9Sstevel@tonic-gate bool_t dummy; 217*7c478bd9Sstevel@tonic-gate int32_t i; 218*7c478bd9Sstevel@tonic-gate 219*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_long, 0); 220*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 221*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 222*7c478bd9Sstevel@tonic-gate if ((*lp > INT32_MAX) || (*lp < INT32_MIN)) { 223*7c478bd9Sstevel@tonic-gate return (FALSE); 224*7c478bd9Sstevel@tonic-gate } 225*7c478bd9Sstevel@tonic-gate #endif 226*7c478bd9Sstevel@tonic-gate i = (int32_t)*lp; 227*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTINT32(xdrs, &i); 228*7c478bd9Sstevel@tonic-gate } else if (xdrs->x_op == XDR_DECODE) { 229*7c478bd9Sstevel@tonic-gate dummy = XDR_GETINT32(xdrs, &i); 230*7c478bd9Sstevel@tonic-gate *lp = (long)i; 231*7c478bd9Sstevel@tonic-gate } else if (xdrs->x_op == XDR_FREE) 232*7c478bd9Sstevel@tonic-gate dummy = TRUE; 233*7c478bd9Sstevel@tonic-gate else 234*7c478bd9Sstevel@tonic-gate dummy = FALSE; 235*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_long, 1); 236*7c478bd9Sstevel@tonic-gate return (dummy); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* 240*7c478bd9Sstevel@tonic-gate * XDR unsigned long integers 241*7c478bd9Sstevel@tonic-gate * same as xdr_long 242*7c478bd9Sstevel@tonic-gate */ 243*7c478bd9Sstevel@tonic-gate bool_t 244*7c478bd9Sstevel@tonic-gate xdr_u_long(XDR *xdrs, ulong_t *ulp) 245*7c478bd9Sstevel@tonic-gate { 246*7c478bd9Sstevel@tonic-gate bool_t dummy; 247*7c478bd9Sstevel@tonic-gate uint32_t ui; 248*7c478bd9Sstevel@tonic-gate 249*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_long, 0); 250*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 251*7c478bd9Sstevel@tonic-gate #if defined(_LP64) 252*7c478bd9Sstevel@tonic-gate if (*ulp > UINT32_MAX) { 253*7c478bd9Sstevel@tonic-gate return (FALSE); 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate #endif 256*7c478bd9Sstevel@tonic-gate ui = (uint32_t)*ulp; 257*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTINT32(xdrs, (int32_t *)&ui); 258*7c478bd9Sstevel@tonic-gate } else if (xdrs->x_op == XDR_DECODE) { 259*7c478bd9Sstevel@tonic-gate dummy = XDR_GETINT32(xdrs, (int32_t *)&ui); 260*7c478bd9Sstevel@tonic-gate *ulp = (ulong_t)ui; 261*7c478bd9Sstevel@tonic-gate } else if (xdrs->x_op == XDR_FREE) 262*7c478bd9Sstevel@tonic-gate dummy = TRUE; 263*7c478bd9Sstevel@tonic-gate else 264*7c478bd9Sstevel@tonic-gate dummy = FALSE; 265*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_long, 1); 266*7c478bd9Sstevel@tonic-gate return (dummy); 267*7c478bd9Sstevel@tonic-gate } 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate /* 270*7c478bd9Sstevel@tonic-gate * XDR short integers 271*7c478bd9Sstevel@tonic-gate */ 272*7c478bd9Sstevel@tonic-gate bool_t 273*7c478bd9Sstevel@tonic-gate xdr_short(XDR *xdrs, short *sp) 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate int32_t l; 276*7c478bd9Sstevel@tonic-gate bool_t dummy; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_short, 0); 279*7c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate case XDR_ENCODE: 282*7c478bd9Sstevel@tonic-gate l = (int32_t)*sp; 283*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTINT32(xdrs, &l); 284*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_short, 1); 285*7c478bd9Sstevel@tonic-gate return (dummy); 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate case XDR_DECODE: 288*7c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, &l)) { 289*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_short, 1); 290*7c478bd9Sstevel@tonic-gate return (FALSE); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate *sp = (short)l; 293*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_short, 1); 294*7c478bd9Sstevel@tonic-gate return (TRUE); 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate case XDR_FREE: 297*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_short, 1); 298*7c478bd9Sstevel@tonic-gate return (TRUE); 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_short, 1); 301*7c478bd9Sstevel@tonic-gate return (FALSE); 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate /* 305*7c478bd9Sstevel@tonic-gate * XDR unsigned short integers 306*7c478bd9Sstevel@tonic-gate */ 307*7c478bd9Sstevel@tonic-gate bool_t 308*7c478bd9Sstevel@tonic-gate xdr_u_short(XDR *xdrs, ushort_t *usp) 309*7c478bd9Sstevel@tonic-gate { 310*7c478bd9Sstevel@tonic-gate uint_t i; 311*7c478bd9Sstevel@tonic-gate bool_t dummy; 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_short, 0); 315*7c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 316*7c478bd9Sstevel@tonic-gate 317*7c478bd9Sstevel@tonic-gate case XDR_ENCODE: 318*7c478bd9Sstevel@tonic-gate i = (uint_t)*usp; 319*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTINT32(xdrs, (int *)&i); 320*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_short, 1); 321*7c478bd9Sstevel@tonic-gate return (dummy); 322*7c478bd9Sstevel@tonic-gate 323*7c478bd9Sstevel@tonic-gate case XDR_DECODE: 324*7c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, (int *)&i)) { 325*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 326*7c478bd9Sstevel@tonic-gate printf("xdr_u_short: decode FAILED\n"); 327*7c478bd9Sstevel@tonic-gate #endif 328*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_short, 1); 329*7c478bd9Sstevel@tonic-gate return (FALSE); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate *usp = (ushort_t)i; 332*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_short, 1); 333*7c478bd9Sstevel@tonic-gate return (TRUE); 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate case XDR_FREE: 336*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_short, 1); 337*7c478bd9Sstevel@tonic-gate return (TRUE); 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 340*7c478bd9Sstevel@tonic-gate printf("xdr_u_short: bad op FAILED\n"); 341*7c478bd9Sstevel@tonic-gate #endif 342*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_short, 1); 343*7c478bd9Sstevel@tonic-gate return (FALSE); 344*7c478bd9Sstevel@tonic-gate } 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate 347*7c478bd9Sstevel@tonic-gate /* 348*7c478bd9Sstevel@tonic-gate * XDR a char 349*7c478bd9Sstevel@tonic-gate */ 350*7c478bd9Sstevel@tonic-gate bool_t 351*7c478bd9Sstevel@tonic-gate xdr_char(XDR *xdrs, char *cp) 352*7c478bd9Sstevel@tonic-gate { 353*7c478bd9Sstevel@tonic-gate int i; 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_char, 0); 356*7c478bd9Sstevel@tonic-gate 357*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) 358*7c478bd9Sstevel@tonic-gate i = (*cp); 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate if (! xdr_int(xdrs, &i)) { 361*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_char, 1); 362*7c478bd9Sstevel@tonic-gate return (FALSE); 363*7c478bd9Sstevel@tonic-gate } 364*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) 365*7c478bd9Sstevel@tonic-gate *cp = (char)i; 366*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_char, 1); 367*7c478bd9Sstevel@tonic-gate return (TRUE); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate #ifndef KERNEL 371*7c478bd9Sstevel@tonic-gate /* 372*7c478bd9Sstevel@tonic-gate * XDR an unsigned char 373*7c478bd9Sstevel@tonic-gate */ 374*7c478bd9Sstevel@tonic-gate bool_t 375*7c478bd9Sstevel@tonic-gate xdr_u_char(XDR *xdrs, uchar_t *cp) 376*7c478bd9Sstevel@tonic-gate { 377*7c478bd9Sstevel@tonic-gate int i; 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_char, 0); 380*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) 381*7c478bd9Sstevel@tonic-gate i = (*cp); 382*7c478bd9Sstevel@tonic-gate if (! xdr_int(xdrs, &i)) { 383*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_char, 1); 384*7c478bd9Sstevel@tonic-gate return (FALSE); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) 387*7c478bd9Sstevel@tonic-gate *cp = (uchar_t)i; 388*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_char, 1); 389*7c478bd9Sstevel@tonic-gate return (TRUE); 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate #endif /* !KERNEL */ 392*7c478bd9Sstevel@tonic-gate 393*7c478bd9Sstevel@tonic-gate /* 394*7c478bd9Sstevel@tonic-gate * XDR booleans 395*7c478bd9Sstevel@tonic-gate */ 396*7c478bd9Sstevel@tonic-gate bool_t 397*7c478bd9Sstevel@tonic-gate xdr_bool(XDR *xdrs, bool_t *bp) 398*7c478bd9Sstevel@tonic-gate { 399*7c478bd9Sstevel@tonic-gate int i; 400*7c478bd9Sstevel@tonic-gate bool_t dummy; 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bool, 0); 403*7c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate case XDR_ENCODE: 406*7c478bd9Sstevel@tonic-gate i = *bp ? XDR_TRUE : XDR_FALSE; 407*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTINT32(xdrs, &i); 408*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bool, 1); 409*7c478bd9Sstevel@tonic-gate return (dummy); 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate case XDR_DECODE: 412*7c478bd9Sstevel@tonic-gate if (!XDR_GETINT32(xdrs, &i)) { 413*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 414*7c478bd9Sstevel@tonic-gate printf("xdr_bool: decode FAILED\n"); 415*7c478bd9Sstevel@tonic-gate #endif 416*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bool, 1); 417*7c478bd9Sstevel@tonic-gate return (FALSE); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate *bp = (i == XDR_FALSE) ? FALSE : TRUE; 420*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bool, 1); 421*7c478bd9Sstevel@tonic-gate return (TRUE); 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate case XDR_FREE: 424*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bool, 1); 425*7c478bd9Sstevel@tonic-gate return (TRUE); 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 428*7c478bd9Sstevel@tonic-gate printf("xdr_bool: bad op FAILED\n"); 429*7c478bd9Sstevel@tonic-gate #endif 430*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bool, 1); 431*7c478bd9Sstevel@tonic-gate return (FALSE); 432*7c478bd9Sstevel@tonic-gate } 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate /* 435*7c478bd9Sstevel@tonic-gate * XDR enumerations 436*7c478bd9Sstevel@tonic-gate */ 437*7c478bd9Sstevel@tonic-gate bool_t 438*7c478bd9Sstevel@tonic-gate xdr_enum(XDR *xdrs, enum_t *ep) 439*7c478bd9Sstevel@tonic-gate { 440*7c478bd9Sstevel@tonic-gate bool_t dummy; 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate #ifndef lint 443*7c478bd9Sstevel@tonic-gate enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate /* 446*7c478bd9Sstevel@tonic-gate * enums are treated as ints 447*7c478bd9Sstevel@tonic-gate */ 448*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_enum, 0); 449*7c478bd9Sstevel@tonic-gate if (sizeof (enum sizecheck) == sizeof (int32_t)) { 450*7c478bd9Sstevel@tonic-gate dummy = xdr_int(xdrs, (int *)ep); 451*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_enum, 1); 452*7c478bd9Sstevel@tonic-gate return (dummy); 453*7c478bd9Sstevel@tonic-gate } else if (sizeof (enum sizecheck) == sizeof (short)) { 454*7c478bd9Sstevel@tonic-gate dummy = xdr_short(xdrs, (short *)ep); 455*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_enum, 1); 456*7c478bd9Sstevel@tonic-gate return (dummy); 457*7c478bd9Sstevel@tonic-gate } else if (sizeof (enum sizecheck) == sizeof (char)) { 458*7c478bd9Sstevel@tonic-gate dummy = xdr_char(xdrs, (char *)ep); 459*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_enum, 1); 460*7c478bd9Sstevel@tonic-gate return (dummy); 461*7c478bd9Sstevel@tonic-gate } else { 462*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_enum, 1); 463*7c478bd9Sstevel@tonic-gate return (FALSE); 464*7c478bd9Sstevel@tonic-gate } 465*7c478bd9Sstevel@tonic-gate #else 466*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_enum, 0); 467*7c478bd9Sstevel@tonic-gate (void) (xdr_char(xdrs, (char *)ep)); 468*7c478bd9Sstevel@tonic-gate (void) (xdr_short(xdrs, (short *)ep)); 469*7c478bd9Sstevel@tonic-gate dummy = xdr_int(xdrs, (int32_t *)ep); 470*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_enum, 1); 471*7c478bd9Sstevel@tonic-gate return (dummy); 472*7c478bd9Sstevel@tonic-gate #endif 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate /* 476*7c478bd9Sstevel@tonic-gate * XDR opaque data 477*7c478bd9Sstevel@tonic-gate * Allows the specification of a fixed size sequence of opaque bytes. 478*7c478bd9Sstevel@tonic-gate * cp points to the opaque object and cnt gives the byte length. 479*7c478bd9Sstevel@tonic-gate */ 480*7c478bd9Sstevel@tonic-gate bool_t 481*7c478bd9Sstevel@tonic-gate xdr_opaque(XDR *xdrs, caddr_t cp, uint_t cnt) 482*7c478bd9Sstevel@tonic-gate { 483*7c478bd9Sstevel@tonic-gate bool_t dummy; 484*7c478bd9Sstevel@tonic-gate register uint_t rndup; 485*7c478bd9Sstevel@tonic-gate char crud[BYTES_PER_XDR_UNIT]; 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate /* 488*7c478bd9Sstevel@tonic-gate * if no data we are done 489*7c478bd9Sstevel@tonic-gate */ 490*7c478bd9Sstevel@tonic-gate trace2(TR_xdr_opaque, 0, cnt); 491*7c478bd9Sstevel@tonic-gate if (cnt == 0) { 492*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 493*7c478bd9Sstevel@tonic-gate return (TRUE); 494*7c478bd9Sstevel@tonic-gate } 495*7c478bd9Sstevel@tonic-gate 496*7c478bd9Sstevel@tonic-gate /* 497*7c478bd9Sstevel@tonic-gate * round byte count to full xdr units 498*7c478bd9Sstevel@tonic-gate */ 499*7c478bd9Sstevel@tonic-gate rndup = cnt % BYTES_PER_XDR_UNIT; 500*7c478bd9Sstevel@tonic-gate if ((int)rndup > 0) 501*7c478bd9Sstevel@tonic-gate rndup = BYTES_PER_XDR_UNIT - rndup; 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_DECODE) { 504*7c478bd9Sstevel@tonic-gate if (!XDR_GETBYTES(xdrs, cp, cnt)) { 505*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 506*7c478bd9Sstevel@tonic-gate printf("xdr_opaque: decode FAILED\n"); 507*7c478bd9Sstevel@tonic-gate #endif 508*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 509*7c478bd9Sstevel@tonic-gate return (FALSE); 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate if (rndup == 0) { 512*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 513*7c478bd9Sstevel@tonic-gate return (TRUE); 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate dummy = XDR_GETBYTES(xdrs, crud, rndup); 516*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 517*7c478bd9Sstevel@tonic-gate return (dummy); 518*7c478bd9Sstevel@tonic-gate } 519*7c478bd9Sstevel@tonic-gate 520*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate if (!XDR_PUTBYTES(xdrs, cp, cnt)) { 523*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 524*7c478bd9Sstevel@tonic-gate printf("xdr_opaque: encode FAILED\n"); 525*7c478bd9Sstevel@tonic-gate #endif 526*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 527*7c478bd9Sstevel@tonic-gate return (FALSE); 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate if (rndup == 0) { 530*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 531*7c478bd9Sstevel@tonic-gate return (TRUE); 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTBYTES(xdrs, (caddr_t)&xdr_zero[0], rndup); 534*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 535*7c478bd9Sstevel@tonic-gate return (dummy); 536*7c478bd9Sstevel@tonic-gate } 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) { 539*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 540*7c478bd9Sstevel@tonic-gate return (TRUE); 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate 543*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 544*7c478bd9Sstevel@tonic-gate printf("xdr_opaque: bad op FAILED\n"); 545*7c478bd9Sstevel@tonic-gate #endif 546*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_opaque, 1); 547*7c478bd9Sstevel@tonic-gate return (FALSE); 548*7c478bd9Sstevel@tonic-gate } 549*7c478bd9Sstevel@tonic-gate 550*7c478bd9Sstevel@tonic-gate /* 551*7c478bd9Sstevel@tonic-gate * XDR counted bytes 552*7c478bd9Sstevel@tonic-gate * *cpp is a pointer to the bytes, *sizep is the count. 553*7c478bd9Sstevel@tonic-gate * If *cpp is NULL maxsize bytes are allocated 554*7c478bd9Sstevel@tonic-gate */ 555*7c478bd9Sstevel@tonic-gate 556*7c478bd9Sstevel@tonic-gate #ifndef KERNEL 557*7c478bd9Sstevel@tonic-gate static const char xdr_err[] = "xdr_%s: out of memory"; 558*7c478bd9Sstevel@tonic-gate #endif 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate bool_t 561*7c478bd9Sstevel@tonic-gate xdr_bytes(XDR *xdrs, char **cpp, uint_t *sizep, uint_t maxsize) 562*7c478bd9Sstevel@tonic-gate { 563*7c478bd9Sstevel@tonic-gate bool_t dummy; 564*7c478bd9Sstevel@tonic-gate register char *sp = *cpp; /* sp is the actual string pointer */ 565*7c478bd9Sstevel@tonic-gate register uint_t nodesize; 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate /* 568*7c478bd9Sstevel@tonic-gate * first deal with the length since xdr bytes are counted 569*7c478bd9Sstevel@tonic-gate * We decided not to use MACRO XDR_U_INT here, because the 570*7c478bd9Sstevel@tonic-gate * advantages here will be miniscule compared to xdr_bytes. 571*7c478bd9Sstevel@tonic-gate * This saved us 100 bytes in the library size. 572*7c478bd9Sstevel@tonic-gate */ 573*7c478bd9Sstevel@tonic-gate trace2(TR_xdr_bytes, 0, maxsize); 574*7c478bd9Sstevel@tonic-gate if (! xdr_u_int(xdrs, sizep)) { 575*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 576*7c478bd9Sstevel@tonic-gate printf("xdr_bytes: size FAILED\n"); 577*7c478bd9Sstevel@tonic-gate #endif 578*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bytes, 1); 579*7c478bd9Sstevel@tonic-gate return (FALSE); 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate nodesize = *sizep; 582*7c478bd9Sstevel@tonic-gate if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { 583*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 584*7c478bd9Sstevel@tonic-gate printf("xdr_bytes: bad size FAILED\n"); 585*7c478bd9Sstevel@tonic-gate #endif 586*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bytes, 1); 587*7c478bd9Sstevel@tonic-gate return (FALSE); 588*7c478bd9Sstevel@tonic-gate } 589*7c478bd9Sstevel@tonic-gate 590*7c478bd9Sstevel@tonic-gate /* 591*7c478bd9Sstevel@tonic-gate * now deal with the actual bytes 592*7c478bd9Sstevel@tonic-gate */ 593*7c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 594*7c478bd9Sstevel@tonic-gate 595*7c478bd9Sstevel@tonic-gate case XDR_DECODE: 596*7c478bd9Sstevel@tonic-gate if (nodesize == 0) { 597*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bytes, 1); 598*7c478bd9Sstevel@tonic-gate return (TRUE); 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate if (sp == NULL) { 601*7c478bd9Sstevel@tonic-gate *cpp = sp = (char *)mem_alloc(nodesize); 602*7c478bd9Sstevel@tonic-gate } 603*7c478bd9Sstevel@tonic-gate #ifndef KERNEL 604*7c478bd9Sstevel@tonic-gate if (sp == NULL) { 605*7c478bd9Sstevel@tonic-gate (void) syslog(LOG_ERR, xdr_err, (const char *)"bytes"); 606*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bytes, 1); 607*7c478bd9Sstevel@tonic-gate return (FALSE); 608*7c478bd9Sstevel@tonic-gate } 609*7c478bd9Sstevel@tonic-gate #endif 610*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate case XDR_ENCODE: 613*7c478bd9Sstevel@tonic-gate dummy = xdr_opaque(xdrs, sp, nodesize); 614*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bytes, 1); 615*7c478bd9Sstevel@tonic-gate return (dummy); 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate case XDR_FREE: 618*7c478bd9Sstevel@tonic-gate if (sp != NULL) { 619*7c478bd9Sstevel@tonic-gate mem_free(sp, nodesize); 620*7c478bd9Sstevel@tonic-gate *cpp = NULL; 621*7c478bd9Sstevel@tonic-gate } 622*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bytes, 1); 623*7c478bd9Sstevel@tonic-gate return (TRUE); 624*7c478bd9Sstevel@tonic-gate } 625*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 626*7c478bd9Sstevel@tonic-gate printf("xdr_bytes: bad op FAILED\n"); 627*7c478bd9Sstevel@tonic-gate #endif 628*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_bytes, 1); 629*7c478bd9Sstevel@tonic-gate return (FALSE); 630*7c478bd9Sstevel@tonic-gate } 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate /* 633*7c478bd9Sstevel@tonic-gate * Implemented here due to commonality of the object. 634*7c478bd9Sstevel@tonic-gate */ 635*7c478bd9Sstevel@tonic-gate bool_t 636*7c478bd9Sstevel@tonic-gate xdr_netobj(XDR *xdrs, struct netobj *np) 637*7c478bd9Sstevel@tonic-gate { 638*7c478bd9Sstevel@tonic-gate bool_t dummy; 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_netobj, 0); 641*7c478bd9Sstevel@tonic-gate dummy = xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ); 642*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_netobj, 1); 643*7c478bd9Sstevel@tonic-gate return (dummy); 644*7c478bd9Sstevel@tonic-gate } 645*7c478bd9Sstevel@tonic-gate 646*7c478bd9Sstevel@tonic-gate /* 647*7c478bd9Sstevel@tonic-gate * XDR a descriminated union 648*7c478bd9Sstevel@tonic-gate * Support routine for discriminated unions. 649*7c478bd9Sstevel@tonic-gate * You create an array of xdrdiscrim structures, terminated with 650*7c478bd9Sstevel@tonic-gate * an entry with a null procedure pointer. The routine gets 651*7c478bd9Sstevel@tonic-gate * the discriminant value and then searches the array of xdrdiscrims 652*7c478bd9Sstevel@tonic-gate * looking for that value. It calls the procedure given in the xdrdiscrim 653*7c478bd9Sstevel@tonic-gate * to handle the discriminant. If there is no specific routine a default 654*7c478bd9Sstevel@tonic-gate * routine may be called. 655*7c478bd9Sstevel@tonic-gate * If there is no specific or default routine an error is returned. 656*7c478bd9Sstevel@tonic-gate */ 657*7c478bd9Sstevel@tonic-gate bool_t 658*7c478bd9Sstevel@tonic-gate xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, 659*7c478bd9Sstevel@tonic-gate const struct xdr_discrim *choices, xdrproc_t dfault) 660*7c478bd9Sstevel@tonic-gate { 661*7c478bd9Sstevel@tonic-gate register enum_t dscm; 662*7c478bd9Sstevel@tonic-gate bool_t dummy; 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate /* 665*7c478bd9Sstevel@tonic-gate * we deal with the discriminator; it's an enum 666*7c478bd9Sstevel@tonic-gate */ 667*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_union, 0); 668*7c478bd9Sstevel@tonic-gate if (! xdr_enum(xdrs, dscmp)) { 669*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 670*7c478bd9Sstevel@tonic-gate printf("xdr_enum: dscmp FAILED\n"); 671*7c478bd9Sstevel@tonic-gate #endif 672*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_union, 1); 673*7c478bd9Sstevel@tonic-gate return (FALSE); 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate dscm = *dscmp; 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate /* 678*7c478bd9Sstevel@tonic-gate * search choices for a value that matches the discriminator. 679*7c478bd9Sstevel@tonic-gate * if we find one, execute the xdr routine for that value. 680*7c478bd9Sstevel@tonic-gate */ 681*7c478bd9Sstevel@tonic-gate for (; choices->proc != NULL_xdrproc_t; choices++) { 682*7c478bd9Sstevel@tonic-gate if (choices->value == dscm) { 683*7c478bd9Sstevel@tonic-gate dummy = (*(choices->proc))(xdrs, unp, LASTUNSIGNED); 684*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_union, 1); 685*7c478bd9Sstevel@tonic-gate return (dummy); 686*7c478bd9Sstevel@tonic-gate } 687*7c478bd9Sstevel@tonic-gate } 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate /* 690*7c478bd9Sstevel@tonic-gate * no match - execute the default xdr routine if there is one 691*7c478bd9Sstevel@tonic-gate */ 692*7c478bd9Sstevel@tonic-gate dummy = (dfault == NULL_xdrproc_t) ? FALSE : 693*7c478bd9Sstevel@tonic-gate (*dfault)(xdrs, unp, LASTUNSIGNED); 694*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_union, 1); 695*7c478bd9Sstevel@tonic-gate return (dummy); 696*7c478bd9Sstevel@tonic-gate } 697*7c478bd9Sstevel@tonic-gate 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate /* 700*7c478bd9Sstevel@tonic-gate * Non-portable xdr primitives. 701*7c478bd9Sstevel@tonic-gate * Care should be taken when moving these routines to new architectures. 702*7c478bd9Sstevel@tonic-gate */ 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate /* 706*7c478bd9Sstevel@tonic-gate * XDR null terminated ASCII strings 707*7c478bd9Sstevel@tonic-gate * xdr_string deals with "C strings" - arrays of bytes that are 708*7c478bd9Sstevel@tonic-gate * terminated by a NULL character. The parameter cpp references a 709*7c478bd9Sstevel@tonic-gate * pointer to storage; If the pointer is null, then the necessary 710*7c478bd9Sstevel@tonic-gate * storage is allocated. The last parameter is the max allowed length 711*7c478bd9Sstevel@tonic-gate * of the string as specified by a protocol. 712*7c478bd9Sstevel@tonic-gate */ 713*7c478bd9Sstevel@tonic-gate bool_t 714*7c478bd9Sstevel@tonic-gate xdr_string(XDR *xdrs, char **cpp, uint_t maxsize) 715*7c478bd9Sstevel@tonic-gate { 716*7c478bd9Sstevel@tonic-gate bool_t dummy; 717*7c478bd9Sstevel@tonic-gate register char *newsp, *sp = *cpp; /* sp is the actual string pointer */ 718*7c478bd9Sstevel@tonic-gate uint_t size, block; 719*7c478bd9Sstevel@tonic-gate uint64_t bytesread; 720*7c478bd9Sstevel@tonic-gate 721*7c478bd9Sstevel@tonic-gate /* 722*7c478bd9Sstevel@tonic-gate * first deal with the length since xdr strings are counted-strings 723*7c478bd9Sstevel@tonic-gate */ 724*7c478bd9Sstevel@tonic-gate trace2(TR_xdr_string, 0, maxsize); 725*7c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 726*7c478bd9Sstevel@tonic-gate case XDR_FREE: 727*7c478bd9Sstevel@tonic-gate if (sp == NULL) { 728*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 729*7c478bd9Sstevel@tonic-gate return (TRUE); /* already free */ 730*7c478bd9Sstevel@tonic-gate } 731*7c478bd9Sstevel@tonic-gate /*FALLTHROUGH*/ 732*7c478bd9Sstevel@tonic-gate case XDR_ENCODE: 733*7c478bd9Sstevel@tonic-gate size = (sp != NULL) ? (uint_t)strlen(sp) : 0; 734*7c478bd9Sstevel@tonic-gate break; 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate /* 737*7c478bd9Sstevel@tonic-gate * We decided not to use MACRO XDR_U_INT here, because the 738*7c478bd9Sstevel@tonic-gate * advantages here will be miniscule compared to xdr_string. 739*7c478bd9Sstevel@tonic-gate * This saved us 100 bytes in the library size. 740*7c478bd9Sstevel@tonic-gate */ 741*7c478bd9Sstevel@tonic-gate if (! xdr_u_int(xdrs, &size)) { 742*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 743*7c478bd9Sstevel@tonic-gate return (FALSE); 744*7c478bd9Sstevel@tonic-gate } 745*7c478bd9Sstevel@tonic-gate if (size > maxsize) { 746*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 747*7c478bd9Sstevel@tonic-gate return (FALSE); 748*7c478bd9Sstevel@tonic-gate } 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate /* 751*7c478bd9Sstevel@tonic-gate * now deal with the actual bytes 752*7c478bd9Sstevel@tonic-gate */ 753*7c478bd9Sstevel@tonic-gate switch (xdrs->x_op) { 754*7c478bd9Sstevel@tonic-gate 755*7c478bd9Sstevel@tonic-gate case XDR_DECODE: 756*7c478bd9Sstevel@tonic-gate /* if buffer is already given, call xdr_opaque() directly */ 757*7c478bd9Sstevel@tonic-gate if (sp != NULL) { 758*7c478bd9Sstevel@tonic-gate dummy = xdr_opaque(xdrs, sp, size); 759*7c478bd9Sstevel@tonic-gate sp[size] = 0; 760*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 761*7c478bd9Sstevel@tonic-gate return (dummy); 762*7c478bd9Sstevel@tonic-gate } 763*7c478bd9Sstevel@tonic-gate 764*7c478bd9Sstevel@tonic-gate /* 765*7c478bd9Sstevel@tonic-gate * We have to allocate a buffer of size 'size'. To avoid 766*7c478bd9Sstevel@tonic-gate * malloc()ing one huge chunk, we'll read the bytes in max 767*7c478bd9Sstevel@tonic-gate * FRAGMENT size blocks and keep realloc()ing. 'block' is 768*7c478bd9Sstevel@tonic-gate * the number of bytes to read in each xdr_opaque() and 769*7c478bd9Sstevel@tonic-gate * 'bytesread' is what we have already read. sp is NULL 770*7c478bd9Sstevel@tonic-gate * when we are in the loop for the first time. 771*7c478bd9Sstevel@tonic-gate */ 772*7c478bd9Sstevel@tonic-gate bytesread = 0; 773*7c478bd9Sstevel@tonic-gate do { 774*7c478bd9Sstevel@tonic-gate block = MIN(size - bytesread, FRAGMENT); 775*7c478bd9Sstevel@tonic-gate /* 776*7c478bd9Sstevel@tonic-gate * allocate enough for 'bytesread + block' bytes and 777*7c478bd9Sstevel@tonic-gate * one extra for the terminating NULL. 778*7c478bd9Sstevel@tonic-gate */ 779*7c478bd9Sstevel@tonic-gate newsp = realloc(sp, bytesread + block + 1); 780*7c478bd9Sstevel@tonic-gate if (newsp == NULL) { 781*7c478bd9Sstevel@tonic-gate if (sp != NULL) 782*7c478bd9Sstevel@tonic-gate free(sp); 783*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 784*7c478bd9Sstevel@tonic-gate return (FALSE); 785*7c478bd9Sstevel@tonic-gate } 786*7c478bd9Sstevel@tonic-gate sp = newsp; 787*7c478bd9Sstevel@tonic-gate if (!xdr_opaque(xdrs, &sp[bytesread], block)) { 788*7c478bd9Sstevel@tonic-gate free(sp); 789*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 790*7c478bd9Sstevel@tonic-gate return (FALSE); 791*7c478bd9Sstevel@tonic-gate } 792*7c478bd9Sstevel@tonic-gate bytesread += block; 793*7c478bd9Sstevel@tonic-gate } while (bytesread < size); 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate sp[bytesread] = 0; /* terminate the string with a NULL */ 796*7c478bd9Sstevel@tonic-gate *cpp = sp; 797*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 798*7c478bd9Sstevel@tonic-gate return (TRUE); 799*7c478bd9Sstevel@tonic-gate case XDR_ENCODE: 800*7c478bd9Sstevel@tonic-gate dummy = xdr_opaque(xdrs, sp, size); 801*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 802*7c478bd9Sstevel@tonic-gate return (dummy); 803*7c478bd9Sstevel@tonic-gate case XDR_FREE: 804*7c478bd9Sstevel@tonic-gate free(sp); 805*7c478bd9Sstevel@tonic-gate *cpp = NULL; 806*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 807*7c478bd9Sstevel@tonic-gate return (TRUE); 808*7c478bd9Sstevel@tonic-gate } 809*7c478bd9Sstevel@tonic-gate #ifdef KERNEL 810*7c478bd9Sstevel@tonic-gate printf("xdr_string: bad op FAILED\n"); 811*7c478bd9Sstevel@tonic-gate #endif 812*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_string, 1); 813*7c478bd9Sstevel@tonic-gate return (FALSE); 814*7c478bd9Sstevel@tonic-gate } 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate bool_t 817*7c478bd9Sstevel@tonic-gate xdr_hyper(XDR *xdrs, longlong_t *hp) 818*7c478bd9Sstevel@tonic-gate { 819*7c478bd9Sstevel@tonic-gate bool_t dummy; 820*7c478bd9Sstevel@tonic-gate 821*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_hyper, 0); 822*7c478bd9Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 823*7c478bd9Sstevel@tonic-gate #if defined(_LONG_LONG_HTOL) 824*7c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, (int *)hp) == TRUE) { 825*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTINT32(xdrs, (int *)((char *)hp + 826*7c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT)); 827*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_hyper, 1); 828*7c478bd9Sstevel@tonic-gate return (dummy); 829*7c478bd9Sstevel@tonic-gate } 830*7c478bd9Sstevel@tonic-gate 831*7c478bd9Sstevel@tonic-gate #else 832*7c478bd9Sstevel@tonic-gate if (XDR_PUTINT32(xdrs, (int *)((char *)hp + 833*7c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT)) == TRUE) { 834*7c478bd9Sstevel@tonic-gate dummy = XDR_PUTINT32(xdrs, (int32_t *)hp); 835*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_hyper, 1); 836*7c478bd9Sstevel@tonic-gate return (dummy); 837*7c478bd9Sstevel@tonic-gate } 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate #endif 840*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_hyper, 1); 841*7c478bd9Sstevel@tonic-gate return (FALSE); 842*7c478bd9Sstevel@tonic-gate 843*7c478bd9Sstevel@tonic-gate } else if (xdrs->x_op == XDR_DECODE) { 844*7c478bd9Sstevel@tonic-gate #if defined(_LONG_LONG_HTOL) 845*7c478bd9Sstevel@tonic-gate if (XDR_GETINT32(xdrs, (int *)hp) == FALSE || 846*7c478bd9Sstevel@tonic-gate (XDR_GETINT32(xdrs, (int *)((char *)hp + 847*7c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT)) == FALSE)) { 848*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_hyper, 1); 849*7c478bd9Sstevel@tonic-gate return (FALSE); 850*7c478bd9Sstevel@tonic-gate } 851*7c478bd9Sstevel@tonic-gate #else 852*7c478bd9Sstevel@tonic-gate if ((XDR_GETINT32(xdrs, (int *)((char *)hp + 853*7c478bd9Sstevel@tonic-gate BYTES_PER_XDR_UNIT)) == FALSE) || 854*7c478bd9Sstevel@tonic-gate (XDR_GETINT32(xdrs, (int *)hp) == FALSE)) { 855*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_hyper, 1); 856*7c478bd9Sstevel@tonic-gate return (FALSE); 857*7c478bd9Sstevel@tonic-gate } 858*7c478bd9Sstevel@tonic-gate #endif 859*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_hyper, 1); 860*7c478bd9Sstevel@tonic-gate return (TRUE); 861*7c478bd9Sstevel@tonic-gate } 862*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_hyper, 1); 863*7c478bd9Sstevel@tonic-gate return (TRUE); 864*7c478bd9Sstevel@tonic-gate } 865*7c478bd9Sstevel@tonic-gate 866*7c478bd9Sstevel@tonic-gate bool_t 867*7c478bd9Sstevel@tonic-gate xdr_u_hyper(XDR *xdrs, u_longlong_t *hp) 868*7c478bd9Sstevel@tonic-gate { 869*7c478bd9Sstevel@tonic-gate bool_t dummy; 870*7c478bd9Sstevel@tonic-gate 871*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_hyper, 0); 872*7c478bd9Sstevel@tonic-gate dummy = xdr_hyper(xdrs, (longlong_t *)hp); 873*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_hyper, 1); 874*7c478bd9Sstevel@tonic-gate return (dummy); 875*7c478bd9Sstevel@tonic-gate } 876*7c478bd9Sstevel@tonic-gate 877*7c478bd9Sstevel@tonic-gate bool_t 878*7c478bd9Sstevel@tonic-gate xdr_longlong_t(XDR *xdrs, longlong_t *hp) 879*7c478bd9Sstevel@tonic-gate { 880*7c478bd9Sstevel@tonic-gate bool_t dummy; 881*7c478bd9Sstevel@tonic-gate 882*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_longlong_t, 0); 883*7c478bd9Sstevel@tonic-gate dummy = xdr_hyper(xdrs, hp); 884*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_longlong_t, 1); 885*7c478bd9Sstevel@tonic-gate return (dummy); 886*7c478bd9Sstevel@tonic-gate } 887*7c478bd9Sstevel@tonic-gate 888*7c478bd9Sstevel@tonic-gate bool_t 889*7c478bd9Sstevel@tonic-gate xdr_u_longlong_t(XDR *xdrs, u_longlong_t *hp) 890*7c478bd9Sstevel@tonic-gate { 891*7c478bd9Sstevel@tonic-gate bool_t dummy; 892*7c478bd9Sstevel@tonic-gate 893*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_longlong_t, 0); 894*7c478bd9Sstevel@tonic-gate dummy = xdr_hyper(xdrs, (longlong_t *)hp); 895*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_longlong_t, 1); 896*7c478bd9Sstevel@tonic-gate return (dummy); 897*7c478bd9Sstevel@tonic-gate } 898*7c478bd9Sstevel@tonic-gate /* 899*7c478bd9Sstevel@tonic-gate * The following routine is part of a workaround for bug 900*7c478bd9Sstevel@tonic-gate * #1128007. When it is fixed, this routine should be 901*7c478bd9Sstevel@tonic-gate * removed. 902*7c478bd9Sstevel@tonic-gate */ 903*7c478bd9Sstevel@tonic-gate bool_t 904*7c478bd9Sstevel@tonic-gate xdr_ulonglong_t(XDR *xdrs, u_longlong_t *hp) 905*7c478bd9Sstevel@tonic-gate { 906*7c478bd9Sstevel@tonic-gate bool_t dummy; 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_longlong_t, 0); 909*7c478bd9Sstevel@tonic-gate dummy = xdr_hyper(xdrs, (longlong_t *)hp); 910*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_u_longlong_t, 1); 911*7c478bd9Sstevel@tonic-gate return (dummy); 912*7c478bd9Sstevel@tonic-gate } 913*7c478bd9Sstevel@tonic-gate 914*7c478bd9Sstevel@tonic-gate #ifndef KERNEL 915*7c478bd9Sstevel@tonic-gate /* 916*7c478bd9Sstevel@tonic-gate * Wrapper for xdr_string that can be called directly from 917*7c478bd9Sstevel@tonic-gate * routines like clnt_call 918*7c478bd9Sstevel@tonic-gate */ 919*7c478bd9Sstevel@tonic-gate bool_t 920*7c478bd9Sstevel@tonic-gate xdr_wrapstring(XDR *xdrs, char **cpp) 921*7c478bd9Sstevel@tonic-gate { 922*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_wrapstring, 0); 923*7c478bd9Sstevel@tonic-gate if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { 924*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_wrapstring, 1); 925*7c478bd9Sstevel@tonic-gate return (TRUE); 926*7c478bd9Sstevel@tonic-gate } 927*7c478bd9Sstevel@tonic-gate trace1(TR_xdr_wrapstring, 1); 928*7c478bd9Sstevel@tonic-gate return (FALSE); 929*7c478bd9Sstevel@tonic-gate } 930*7c478bd9Sstevel@tonic-gate #endif /* !KERNEL */ 931