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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/salib.h> 30 #include <rpc/types.h> 31 #include <rpc/xdr.h> 32 #include <rpc/rpc.h> 33 #include <rpcsvc/nfs4_prot.h> 34 #include "nfs_inet.h" 35 36 #define dprintf if (boothowto & RB_DEBUG) printf 37 38 /* 39 * XDR routines for NFSv4 ops. 40 */ 41 static bool_t 42 xdr_b_utf8string(XDR *xdrs, utf8string *objp) 43 { 44 return (xdr_bytes(xdrs, (char **)&objp->utf8string_val, 45 (uint_t *)&objp->utf8string_len, NFS4_MAX_UTF8STRING)); 46 } 47 48 static bool_t 49 xdr_nfs_bfh4(XDR *xdrs, struct nfs_bfh4 *objp) 50 { 51 char *data = (char *)&objp->data; 52 return (xdr_bytes(xdrs, (char **)&data, (uint_t *)&objp->len, 53 NFS4_FHSIZE)); 54 } 55 56 static bool_t 57 xdr_b_putfh4_args(XDR *xdrs, putfh4arg_t *objp) 58 { 59 if (!xdr_u_int(xdrs, (uint_t *)&objp->pf_opnum)) 60 return (FALSE); 61 return (xdr_nfs_bfh4(xdrs, (struct nfs_bfh4 *)&objp->pf_filehandle)); 62 } 63 64 /* 65 * Common xdr routines for compound. Let the specific op routines handle 66 * op specific portions of the compound. 67 */ 68 static bool_t 69 xdr_b_compound_args(XDR *xdrs, b_compound_t *objp) 70 { 71 if (!xdr_b_utf8string(xdrs, &objp->ca_tag)) { 72 return (FALSE); 73 } 74 if (!xdr_u_int(xdrs, &objp->ca_minorversion)) 75 return (FALSE); 76 if (!xdr_u_int(xdrs, &objp->ca_argarray_len)) 77 return (FALSE); 78 if (objp->ca_isputrootfh) 79 return (xdr_u_int(xdrs, &objp->ca_opputfh.pf_opnum)); 80 return (xdr_b_putfh4_args(xdrs, &objp->ca_opputfh)); 81 } 82 83 static bool_t 84 xdr_b_compound_res(XDR *xdrs, b_compound_t *objp) 85 { 86 if (!xdr_enum(xdrs, (enum_t *)&objp->cr_status)) 87 return (FALSE); 88 if (!xdr_b_utf8string(xdrs, &objp->cr_tag)) 89 return (FALSE); 90 if (!xdr_u_int(xdrs, &objp->cr_resarray_len)) 91 return (FALSE); 92 if (!xdr_u_int(xdrs, &objp->cr_opputfh)) 93 return (FALSE); 94 return (xdr_enum(xdrs, (enum_t *)&objp->cr_putfh_status)); 95 } 96 97 static bool_t 98 xdr_b_bitmap4(XDR *xdrs, b_bitmap4_t *objp) 99 { 100 char *arp = (char *)&objp->b_bitmap_val; 101 return (xdr_array(xdrs, (char **)&arp, 102 (uint_t *)&objp->b_bitmap_len, ~0, 103 sizeof (uint_t), (xdrproc_t)xdr_u_int)); 104 } 105 106 static bool_t 107 xdr_b_stateid4(XDR *xdrs, stateid4 *objp) 108 { 109 if (!xdr_u_int(xdrs, (uint_t *)&objp->seqid)) 110 return (FALSE); 111 return (xdr_opaque(xdrs, objp->other, 12)); 112 } 113 114 bool_t 115 xdr_getattr4_args(XDR *xdrs, getattr4arg_t *objp) 116 { 117 if (!xdr_b_compound_args(xdrs, (b_compound_t *)&objp->ga_arg)) 118 return (FALSE); 119 if (!xdr_u_int(xdrs, (uint_t *)&objp->ga_opgetattr)) 120 return (FALSE); 121 return (xdr_b_bitmap4(xdrs, (b_bitmap4_t *)&objp->ga_attr_req)); 122 } 123 124 static bool_t 125 xdr_b_getattr_res_common(XDR *xdrs, getattrres_cmn_t *objp) 126 { 127 if (!xdr_u_int(xdrs, (uint_t *)&objp->gc_opgetattr)) 128 return (FALSE); 129 if (!xdr_enum(xdrs, (enum_t *)&objp->gc_attr_status)) 130 return (FALSE); 131 132 /* 133 * If the getattr suceeded, proceed and begin to decode the attributes. 134 */ 135 if (objp->gc_attr_status == NFS4_OK) { 136 char attrvals[sizeof (b_fattr4_t)]; 137 char *ap = attrvals; 138 139 if (!xdr_b_bitmap4(xdrs, (b_bitmap4_t *)&objp->gc_retattr)) 140 return (FALSE); 141 142 bzero(&attrvals, sizeof (attrvals)); 143 if (!xdr_bytes(xdrs, (char **)&ap, 144 (uint_t *)&objp->gc_attrlist_len, 145 sizeof (b_fattr4_t))) 146 return (FALSE); 147 #ifdef DEBUG 148 printf("xdr_b_getattr_res_common: attrlist_len = %d\n", 149 objp->gc_attrlist_len); 150 #endif 151 /* 152 * Go through the bitmap and see if the server 153 * sent us anything. 154 */ 155 if (objp->gc_attrlist_len > 0) { 156 XDR mxdrs; 157 b_fattr4_t *fattrp = &objp->gc_attrs; 158 attr4_bitmap1_t bitmap1; 159 attr4_bitmap2_t bitmap2; 160 #ifdef DEBUG 161 int i; 162 163 printf("dumping contents of attr buffer\n"); 164 for (i = 0; i < objp->gc_attrlist_len; i++) { 165 printf("[%d] = 0x%x\n", i, ap[i]); 166 } 167 #endif 168 bitmap1.word = objp->gc_retattr.b_bitmap_val[0]; 169 bitmap2.word = objp->gc_retattr.b_bitmap_val[1]; 170 171 #ifdef DEBUG 172 printf("xdr_b_getattr_res_common: bitmap1 = %d " 173 " bitmap2 = %d\n", 174 bitmap1.word, bitmap2.word); 175 #endif 176 xdrmem_create(&mxdrs, ap, objp->gc_attrlist_len, 177 XDR_DECODE); 178 179 /* 180 * Start with the first bitmap 181 */ 182 if (bitmap1.word > 0) { 183 if (bitmap1.bm_supported_attrs) { 184 if (!xdr_b_bitmap4(&mxdrs, 185 (b_bitmap4_t *)&fattrp->b_supported_attrs)) 186 return (FALSE); 187 } 188 189 if (bitmap1.bm_fattr4_type) { 190 if (!xdr_enum(&mxdrs, 191 (enum_t *)&fattrp->b_fattr4_type)) { 192 return (FALSE); 193 } 194 } 195 if (bitmap1.bm_fattr4_size) { 196 if (!xdr_u_longlong_t(&mxdrs, 197 (u_longlong_t *)&fattrp->b_fattr4_size)) 198 return (FALSE); 199 } 200 201 if (bitmap1.bm_fattr4_fsid) { 202 if (!xdr_u_longlong_t(&mxdrs, 203 (u_longlong_t *)&fattrp->b_fattr4_fsid.major)) 204 return (FALSE); 205 206 if (!xdr_u_longlong_t(&mxdrs, 207 (u_longlong_t *)&fattrp->b_fattr4_fsid.minor)) 208 return (FALSE); 209 } 210 if (bitmap1.bm_fattr4_filehandle) { 211 if (!xdr_nfs_bfh4(&mxdrs, 212 (struct nfs_bfh4 *)&fattrp->b_fattr4_filehandle)) 213 return (FALSE); 214 } 215 if (bitmap1.bm_fattr4_fileid) { 216 if (!xdr_u_longlong_t(&mxdrs, 217 (u_longlong_t *)&fattrp->b_fattr4_fileid)) 218 return (FALSE); 219 } 220 } 221 222 /* 223 * Now the second bitmap 224 */ 225 if (bitmap2.word > 0) { 226 if (bitmap2.bm_fattr4_mode) { 227 if (!xdr_u_int(&mxdrs, 228 (uint_t *)&objp->gc_attrs.b_fattr4_mode)) 229 return (FALSE); 230 } 231 232 if (bitmap2.bm_fattr4_time_access) { 233 if (!xdr_longlong_t(&mxdrs, 234 (longlong_t *)&objp->gc_attrs.b_fattr4_time_access.seconds)) 235 return (FALSE); 236 if (!xdr_u_int(&mxdrs, 237 (uint_t *)&objp->gc_attrs.b_fattr4_time_access.nseconds)) 238 return (FALSE); 239 } 240 241 if (bitmap2.bm_fattr4_time_metadata) { 242 if (!xdr_longlong_t(&mxdrs, 243 (longlong_t *)&objp->gc_attrs.b_fattr4_time_metadata.seconds)) 244 return (FALSE); 245 if (!xdr_u_int(&mxdrs, 246 (uint_t *)&objp->gc_attrs.b_fattr4_time_metadata.nseconds)) 247 return (FALSE); 248 } 249 250 if (bitmap2.bm_fattr4_time_modify) { 251 if (!xdr_longlong_t(&mxdrs, 252 (longlong_t *)&objp->gc_attrs.b_fattr4_time_modify.seconds)) 253 return (FALSE); 254 if (!xdr_u_int(&mxdrs, 255 (uint_t *)&objp->gc_attrs.b_fattr4_time_modify.nseconds)) 256 return (FALSE); 257 } 258 } 259 } 260 } 261 return (TRUE); 262 } 263 264 bool_t 265 xdr_getattr4_res(XDR *xdrs, getattr4res_t *objp) 266 { 267 if (!xdr_b_compound_res(xdrs, (b_compound_t *)&objp->gr_res)) 268 return (FALSE); 269 return (xdr_b_getattr_res_common(xdrs, 270 (getattrres_cmn_t *)&objp->gr_cmn)); 271 } 272 273 bool_t 274 xdr_lookup4_args(XDR *xdrs, lookup4arg_t *objp) 275 { 276 if (!xdr_b_compound_args(xdrs, (b_compound_t *)&objp->la_arg)) 277 return (FALSE); 278 if (!xdr_u_int(xdrs, (uint_t *)&objp->la_oplookup)) 279 return (FALSE); 280 if (!xdr_b_utf8string(xdrs, (utf8string *)&objp->la_pathname)) 281 return (FALSE); 282 if (!xdr_u_int(xdrs, (uint_t *)&objp->la_opgetattr)) 283 return (FALSE); 284 return (xdr_b_bitmap4(xdrs, (b_bitmap4_t *)&objp->la_attr_req)); 285 } 286 287 bool_t 288 xdr_lookup4_res(XDR *xdrs, lookup4res_t *objp) 289 { 290 if (!xdr_b_compound_res(xdrs, (b_compound_t *)&objp->lr_res)) 291 return (FALSE); 292 if (!xdr_u_int(xdrs, (uint_t *)&objp->lr_oplookup)) 293 return (FALSE); 294 if (!xdr_enum(xdrs, (enum_t *)&objp->lr_lookup_status)) 295 return (FALSE); 296 if (objp->lr_lookup_status == NFS4_OK) { 297 return (xdr_b_getattr_res_common(xdrs, 298 (getattrres_cmn_t *)&objp->lr_gcmn)); 299 } 300 return (TRUE); 301 } 302 303 bool_t 304 xdr_lookupp4_args(XDR *xdrs, lookupp4arg_t *objp) 305 { 306 if (!xdr_b_compound_args(xdrs, (b_compound_t *)&objp->la_arg)) 307 return (FALSE); 308 if (!xdr_u_int(xdrs, (uint_t *)&objp->la_oplookupp)) 309 return (FALSE); 310 if (!xdr_u_int(xdrs, (uint_t *)&objp->la_opgetattr)) 311 return (FALSE); 312 return (xdr_b_bitmap4(xdrs, (b_bitmap4_t *)&objp->la_attr_req)); 313 } 314 315 bool_t 316 xdr_read4_args(XDR *xdrs, read4arg_t *objp) 317 { 318 if (!xdr_b_compound_args(xdrs, (b_compound_t *)&objp->r_arg)) 319 return (FALSE); 320 if (!xdr_u_int(xdrs, (uint_t *)&objp->r_opread)) 321 return (FALSE); 322 if (!xdr_b_stateid4(xdrs, (stateid4 *)&objp->r_stateid)) 323 return (FALSE); 324 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->r_offset)) 325 return (FALSE); 326 return (xdr_u_int(xdrs, (uint_t *)&objp->r_count)); 327 } 328 329 bool_t 330 xdr_read4_res(XDR *xdrs, read4res_t *objp) 331 { 332 if (!xdr_b_compound_res(xdrs, (b_compound_t *)&objp->r_res)) 333 return (FALSE); 334 if (!xdr_u_int(xdrs, (uint_t *)&objp->r_opread)) 335 return (FALSE); 336 if (!xdr_enum(xdrs, (enum_t *)&objp->r_status)) 337 return (FALSE); 338 if (objp->r_status == NFS4_OK) { 339 if (!xdr_bool(xdrs, (bool_t *)&objp->r_eof)) 340 return (FALSE); 341 return (xdr_bytes(xdrs, (char **)&objp->r_data_val, 342 (uint_t *)&objp->r_data_len, ~0)); 343 } 344 return (TRUE); 345 } 346 347 bool_t 348 xdr_readdir4_args(XDR *xdrs, readdir4arg_t *objp) 349 { 350 if (!xdr_b_compound_args(xdrs, (b_compound_t *)&objp->rd_arg)) 351 return (FALSE); 352 if (!xdr_u_int(xdrs, (uint_t *)&objp->rd_opreaddir)) 353 return (FALSE); 354 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->rd_cookie)) 355 return (FALSE); 356 if (!xdr_opaque(xdrs, objp->rd_cookieverf, NFS4_VERIFIER_SIZE)) 357 return (FALSE); 358 if (!xdr_u_int(xdrs, (uint_t *)&objp->rd_dircount)) 359 return (FALSE); 360 if (!xdr_u_int(xdrs, (uint_t *)&objp->rd_maxcount)) 361 return (FALSE); 362 return (xdr_b_bitmap4(xdrs, (b_bitmap4_t *)&objp->rd_attr_req)); 363 } 364 365 static bool_t 366 xdr_b_entry4(XDR *xdrs, b_entry4_t *objp) 367 { 368 uint_t attrlen; 369 char attrvals[sizeof (b_fattr4_t)]; 370 char *ap = attrvals; 371 XDR mxdrs; 372 373 if (!xdr_u_longlong_t(xdrs, (u_longlong_t *)&objp->b_cookie)) 374 return (FALSE); 375 if (!xdr_b_utf8string(xdrs, &objp->b_name)) 376 return (FALSE); 377 378 bzero(&attrvals, sizeof (attrvals)); 379 if (!xdr_bytes(xdrs, (char **)&ap, (uint_t *)&attrlen, 380 sizeof (b_fattr4_t))) 381 return (FALSE); 382 383 /* 384 * We are *only* interested in the fileid, so just extract that. 385 */ 386 if (attrlen < sizeof (uint64_t)) 387 return (FALSE); 388 389 xdrmem_create(&mxdrs, ap, attrlen, XDR_DECODE); 390 391 if (!xdr_u_longlong_t(&mxdrs, (u_longlong_t *)&objp->b_fileid)) 392 return (FALSE); 393 return (xdr_pointer(xdrs, (char **)&objp->b_nextentry, 394 sizeof (b_entry4_t), (xdrproc_t)xdr_b_entry4)); 395 } 396 397 bool_t 398 xdr_readdir4_res(XDR *xdrs, readdir4res_t *objp) 399 { 400 if (!xdr_b_compound_res(xdrs, (b_compound_t *)&objp->rd_res)) 401 return (FALSE); 402 if (!xdr_u_int(xdrs, (uint_t *)&objp->rd_opreaddir)) 403 return (FALSE); 404 if (!xdr_enum(xdrs, (enum_t *)&objp->rd_status)) 405 return (FALSE); 406 if (objp->rd_status == NFS4_OK) { 407 if (!xdr_opaque(xdrs, objp->rd_cookieverf, NFS4_VERIFIER_SIZE)) 408 return (FALSE); 409 if (!xdr_pointer(xdrs, (char **)&objp->rd_entries, 410 sizeof (b_entry4_t), (xdrproc_t)xdr_b_entry4)) 411 return (FALSE); 412 return (xdr_bool(xdrs, &objp->rd_eof)); 413 } 414 return (TRUE); 415 } 416 417 bool_t 418 xdr_readlink4_args(XDR *xdrs, readlink4arg_t *objp) 419 { 420 if (!xdr_b_compound_args(xdrs, (b_compound_t *)&objp->rl_arg)) 421 return (FALSE); 422 return (xdr_u_int(xdrs, (uint_t *)&objp->rl_opreadlink)); 423 } 424 425 bool_t 426 xdr_readlink4_res(XDR *xdrs, readlink4res_t *objp) 427 { 428 if (!xdr_b_compound_res(xdrs, (b_compound_t *)&objp->rl_res)) 429 return (FALSE); 430 if (!xdr_u_int(xdrs, (uint_t *)&objp->rl_opreadlink)) 431 return (FALSE); 432 if (!xdr_enum(xdrs, (enum_t *)&objp->rl_status)) 433 return (FALSE); 434 if (objp->rl_status == NFS4_OK) 435 return (xdr_b_utf8string(xdrs, (utf8string *)&objp->rl_link)); 436 return (TRUE); 437 } 438