1 /* 2 * Copyright (c) 2000-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ 29 /* 30 * Copyright (c) 1989, 1993 31 * The Regents of the University of California. All rights reserved. 32 * 33 * This code is derived from software contributed to Berkeley by 34 * Rick Macklem at The University of Guelph. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. All advertising materials mentioning features or use of this software 45 * must display the following acknowledgement: 46 * This product includes software developed by the University of 47 * California, Berkeley and its contributors. 48 * 4. Neither the name of the University nor the names of its contributors 49 * may be used to endorse or promote products derived from this software 50 * without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * SUCH DAMAGE. 63 * 64 * @(#)nfsm_subs.h 8.2 (Berkeley) 3/30/95 65 * FreeBSD-Id: nfsm_subs.h,v 1.13 1997/07/16 09:06:30 dfr Exp $ 66 */ 67 68 69 #ifndef _NFS_NFSM_SUBS_H_ 70 #define _NFS_NFSM_SUBS_H_ 71 72 #include <sys/appleapiopts.h> 73 74 #ifdef __APPLE_API_PRIVATE 75 76 #include <nfs/nfs_conf.h> 77 78 int nfsm_chain_new_mbuf(struct nfsm_chain *, size_t); 79 int nfsm_chain_add_opaque_f(struct nfsm_chain *, const u_char *, size_t); 80 int nfsm_chain_add_opaque_nopad_f(struct nfsm_chain *, const u_char *, size_t); 81 82 int nfsm_chain_advance(struct nfsm_chain *, size_t); 83 size_t nfsm_chain_offset(struct nfsm_chain *); 84 int nfsm_chain_get_opaque_pointer_f(struct nfsm_chain *, uint32_t, u_char **); 85 int nfsm_chain_get_opaque_f(struct nfsm_chain *, size_t, u_char *); 86 int nfsm_chain_get_uio(struct nfsm_chain *, size_t, uio_t); 87 88 #if CONFIG_NFS_SERVER 89 void nfsm_adj(mbuf_t, int, int); 90 int nfsm_mbuf_get_list(size_t, mbuf_t *, int *); 91 92 int nfsm_chain_add_fattr(struct nfsrv_descript *, struct nfsm_chain *, struct vnode_attr *); 93 int nfsm_chain_add_wcc_data_f(struct nfsrv_descript *, struct nfsm_chain *, int, 94 struct vnode_attr *, int, struct vnode_attr *); 95 int nfsm_chain_get_path_namei(struct nfsm_chain *, uint32_t, struct nameidata *); 96 int nfsm_chain_get_sattr(struct nfsrv_descript *, struct nfsm_chain *, struct vnode_attr *); 97 int nfsm_chain_trim_data(struct nfsm_chain *, int, int *); 98 #endif /* CONFIG_NFS_SERVER */ 99 100 /* check name length */ 101 #define nfsm_name_len_check(E, ND, LEN) \ 102 do { \ 103 if (E) break; \ 104 if (((ND)->nd_vers == NFS_VER2) && ((LEN) > NFS_MAXNAMLEN)) \ 105 (E) = NFSERR_NAMETOL; \ 106 if ((LEN) <= 0) \ 107 error = EBADRPC; \ 108 } while (0) 109 110 #define nfsm_assert(E, COND, ERR) \ 111 do { \ 112 if (E) break; \ 113 if (!(COND)) \ 114 (E) = (ERR); \ 115 } while (0) 116 117 /* Initialize a vnode_attr to retrieve attributes for the NFS server. */ 118 #define nfsm_srv_vattr_init(VAP, VERS) \ 119 do { \ 120 VATTR_INIT(VAP); \ 121 VATTR_WANTED((VAP), va_type); \ 122 VATTR_WANTED((VAP), va_mode); \ 123 VATTR_WANTED((VAP), va_nlink); \ 124 VATTR_WANTED((VAP), va_uid); \ 125 VATTR_WANTED((VAP), va_gid); \ 126 VATTR_WANTED((VAP), va_data_size); \ 127 VATTR_WANTED((VAP), va_data_alloc); \ 128 VATTR_WANTED((VAP), va_rdev); \ 129 VATTR_WANTED((VAP), va_fsid); \ 130 VATTR_WANTED((VAP), va_fileid); \ 131 VATTR_WANTED((VAP), va_access_time); \ 132 VATTR_WANTED((VAP), va_modify_time); \ 133 VATTR_WANTED((VAP), va_change_time); \ 134 if ((VERS) == NFS_VER2) \ 135 VATTR_WANTED((VAP), va_iosize); \ 136 if ((VERS) == NFS_VER3) \ 137 VATTR_WANTED((VAP), va_filerev); \ 138 } while (0) 139 140 /* Initialize a vnode_attr to retrieve pre-operation attributes for the NFS server. */ 141 #define nfsm_srv_pre_vattr_init(VAP) \ 142 do { \ 143 VATTR_INIT(VAP); \ 144 VATTR_WANTED((VAP), va_data_size); \ 145 VATTR_WANTED((VAP), va_modify_time); \ 146 VATTR_WANTED((VAP), va_change_time); \ 147 } while (0) 148 149 /* round up to a multiple of 4 */ 150 #define nfsm_rndup(a) (((a)+3)&(~0x3)) 151 152 #define nfsm_pad(a) (nfsm_rndup(a) - (a)) 153 154 /* 155 * control flow macros: 156 * go to the appropriate label on condition 157 */ 158 #define nfsmout_if(E) do { if (E) goto nfsmout; } while (0) 159 #define nfsmerr_if(E) do { if (E) goto nfsmerr; } while (0) 160 161 /* 162 * For NFS v2 errors and EBADRPC, the reply contains only the error. 163 * This macro is used to skip any reply building code and go straight 164 * to nfsmout instead. 165 */ 166 #define nfsmout_on_status(ND, E) \ 167 do { \ 168 if (((ND)->nd_repstat == EBADRPC) || \ 169 ((ND)->nd_repstat && ((ND)->nd_vers == NFS_VER2))) { \ 170 (E) = 0; \ 171 goto nfsmout; \ 172 } \ 173 } while (0) 174 175 /* initialize an mbuf chain */ 176 #define nfsm_chain_null(NMC) \ 177 do { \ 178 (NMC)->nmc_mhead = (NMC)->nmc_mcur = NULL; \ 179 (NMC)->nmc_ptr = NULL; \ 180 } while (0) 181 182 /* cleanup an mbuf chain */ 183 #define nfsm_chain_cleanup(NMC) \ 184 do { \ 185 if (!(NMC)->nmc_mhead) break; \ 186 mbuf_freem((NMC)->nmc_mhead); \ 187 nfsm_chain_null(NMC); \ 188 } while (0) 189 190 /* get an mbuf given a size hint */ 191 #define nfsm_mbuf_get(E, MBP, SIZEHINT) \ 192 do { \ 193 *(MBP) = NULL; \ 194 if ((size_t)(SIZEHINT) >= nfs_mbuf_minclsize) \ 195 (E) = mbuf_mclget(MBUF_WAITOK, MBUF_TYPE_DATA, (MBP)); \ 196 else \ 197 (E) = mbuf_get(MBUF_WAITOK, MBUF_TYPE_DATA, (MBP)); \ 198 } while (0) 199 200 /* 201 * get an mbuf with size of M16KCLBYTES given a size hint 202 * According to mbuf_getcluster() documentation, clusters greater than 4096 bytes might 203 * not be available in all configurations; the caller must additionally check for ENOTSUP. 204 * */ 205 #define nfsm_mbuf_getcluster(E, MBP, SIZEHINT) \ 206 do { \ 207 *(MBP) = NULL; \ 208 if ((size_t)(SIZEHINT) > MBIGCLBYTES) { \ 209 (E) = mbuf_getcluster(MBUF_WAITOK, MBUF_TYPE_DATA, M16KCLBYTES, (MBP)); \ 210 if ((E) == 0) { \ 211 break; \ 212 } \ 213 } \ 214 if ((size_t)(SIZEHINT) > MCLBYTES) { \ 215 (E) = mbuf_getcluster(MBUF_WAITOK, MBUF_TYPE_DATA, MBIGCLBYTES, (MBP)); \ 216 if ((E) == 0) { \ 217 break; \ 218 } \ 219 } \ 220 nfsm_mbuf_get(E, MBP, SIZEHINT); \ 221 } while (0) 222 223 224 /* 225 * macros for building NFS mbuf chains 226 */ 227 228 /* prepare an mbuf chain for building starting with the given mbuf */ 229 #define nfsm_chain_init(NMC, MB) \ 230 do { \ 231 (NMC)->nmc_mhead = (MB); \ 232 (NMC)->nmc_mcur = (NMC)->nmc_mhead; \ 233 (NMC)->nmc_ptr = mbuf_data((NMC)->nmc_mcur); \ 234 (NMC)->nmc_left = mbuf_trailingspace((NMC)->nmc_mcur); \ 235 (NMC)->nmc_flags = 0; \ 236 } while (0) 237 238 /* prepare an mbuf chain for building starting with a newly allocated mbuf */ 239 #define nfsm_chain_build_alloc_init(E, NMC, SIZEHINT) \ 240 do { \ 241 mbuf_t ncbimb; \ 242 nfsm_mbuf_get((E), &ncbimb, (SIZEHINT)); \ 243 if (E) break; \ 244 nfsm_chain_init((NMC), ncbimb); \ 245 } while (0) 246 247 /* done building an mbuf chain */ 248 #define nfsm_chain_build_done(E, NMC) \ 249 do { \ 250 if ((E) || !(NMC)->nmc_mcur) break; \ 251 /* cap off current mbuf */ \ 252 mbuf_setlen((NMC)->nmc_mcur, \ 253 (NMC)->nmc_ptr - (caddr_t)mbuf_data((NMC)->nmc_mcur)); \ 254 } while (0) 255 256 /* make sure there's room for size bytes in current mbuf */ 257 #define nfsm_chain_check_size(E, NMC, SIZE) \ 258 do { \ 259 if (E) break; \ 260 if ((NMC)->nmc_left < (SIZE)) { \ 261 (E) = nfsm_chain_new_mbuf((NMC), (SIZE)); \ 262 if (!(E) && ((NMC)->nmc_left < (SIZE))) \ 263 (E) = ENOMEM; \ 264 } \ 265 } while (0) 266 267 /* add a 32bit value to an mbuf chain extending if necessary */ 268 #define nfsm_chain_add_32(E, NMC, VAL) \ 269 do { \ 270 nfsm_chain_check_size((E), (NMC), NFSX_UNSIGNED); \ 271 if (E) break; \ 272 *((uint32_t*)(NMC)->nmc_ptr) = txdr_unsigned(VAL); \ 273 (NMC)->nmc_ptr += NFSX_UNSIGNED; \ 274 (NMC)->nmc_left -= NFSX_UNSIGNED; \ 275 } while (0) 276 277 /* add a 64bit value to an mbuf chain */ 278 #define nfsm_chain_add_64(E, NMC, VAL) \ 279 do { \ 280 uint64_t __tmp64; \ 281 nfsm_chain_check_size((E), (NMC), 2 * NFSX_UNSIGNED); \ 282 if (E) break; \ 283 __tmp64 = (VAL); \ 284 txdr_hyper(&__tmp64, (NMC)->nmc_ptr); \ 285 (NMC)->nmc_ptr += 2 * NFSX_UNSIGNED; \ 286 (NMC)->nmc_left -= 2 * NFSX_UNSIGNED; \ 287 } while (0) 288 289 /* zero the last 4 bytes for a range of opaque */ 290 /* data to make sure any pad bytes will be zero. */ 291 #define nfsm_chain_zero_opaque_pad(BUF, LEN) \ 292 do { \ 293 if ((LEN) > 0) \ 294 *(((uint32_t*)(BUF))+((nfsm_rndup(LEN)>>2)-1)) = 0; \ 295 } while (0) 296 297 /* add buffer of opaque data to an mbuf chain */ 298 #define nfsm_chain_add_opaque(E, NMC, BUF, LEN) \ 299 do { \ 300 size_t rndlen = nfsm_rndup(LEN); \ 301 if (E) break; \ 302 if ((NMC)->nmc_left < rndlen) { \ 303 (E) = nfsm_chain_add_opaque_f((NMC), (const u_char*)(BUF), (LEN)); \ 304 break; \ 305 } \ 306 nfsm_chain_zero_opaque_pad((NMC)->nmc_ptr, (LEN)); \ 307 bcopy((BUF), (NMC)->nmc_ptr, (LEN)); \ 308 (NMC)->nmc_ptr += rndlen; \ 309 (NMC)->nmc_left -= rndlen; \ 310 } while (0) 311 312 /* add buffer of opaque data to an mbuf chain without padding */ 313 #define nfsm_chain_add_opaque_nopad(E, NMC, BUF, LEN) \ 314 do { \ 315 if (E) break; \ 316 if ((NMC)->nmc_left < (uint32_t) (LEN)) { \ 317 (E) = nfsm_chain_add_opaque_nopad_f((NMC), (const u_char*)(BUF), (LEN)); \ 318 break; \ 319 } \ 320 bcopy((BUF), (NMC)->nmc_ptr, (LEN)); \ 321 (NMC)->nmc_ptr += (LEN); \ 322 (NMC)->nmc_left -= (LEN); \ 323 } while (0) 324 325 /* finish an mbuf in a chain to allow subsequent insertion */ 326 #define nfsm_chain_finish_mbuf(E, NMC) \ 327 do { \ 328 if (E) break; \ 329 mbuf_setlen((NMC)->nmc_mcur, \ 330 (NMC)->nmc_ptr - (caddr_t)mbuf_data((NMC)->nmc_mcur)); \ 331 (NMC)->nmc_left = 0; \ 332 } while (0) 333 334 /* add a file handle to an mbuf chain */ 335 #define nfsm_chain_add_fh(E, NMC, VERS, FHP, FHLEN) \ 336 do { \ 337 if (E) break; \ 338 if ((VERS) != NFS_VER2) \ 339 nfsm_chain_add_32((E), (NMC), (FHLEN)); \ 340 nfsm_chain_add_opaque((E), (NMC), (FHP), (FHLEN)); \ 341 } while (0) 342 343 /* add a string to an mbuf chain */ 344 #define nfsm_chain_add_string(E, NMC, STR, LEN) \ 345 do { \ 346 nfsm_chain_add_32((E), (NMC), (LEN)); \ 347 nfsm_chain_add_opaque((E), (NMC), (STR), (LEN)); \ 348 } while (0) 349 350 /* add an NFSv2 time to an mbuf chain */ 351 #define nfsm_chain_add_v2time(E, NMC, TVP) \ 352 do { \ 353 if (TVP) { \ 354 nfsm_chain_add_32((E), (NMC), (TVP)->tv_sec); \ 355 nfsm_chain_add_32((E), (NMC), ((TVP)->tv_nsec != -1) ? \ 356 ((uint32_t)(TVP)->tv_nsec / 1000) : 0xffffffff); \ 357 } else { \ 358 /* no time... use -1 */ \ 359 nfsm_chain_add_32((E), (NMC), -1); \ 360 nfsm_chain_add_32((E), (NMC), -1); \ 361 } \ 362 } while (0) 363 364 /* add an NFSv3 time to an mbuf chain */ 365 #define nfsm_chain_add_v3time(E, NMC, TVP) \ 366 do { \ 367 nfsm_chain_add_32((E), (NMC), (TVP)->tv_sec); \ 368 nfsm_chain_add_32((E), (NMC), (TVP)->tv_nsec); \ 369 } while (0) 370 371 /* add an NFS v2 or v3 time to an mbuf chain */ 372 #define nfsm_chain_add_time(E, NMC, VERS, TVP) \ 373 do { \ 374 if ((VERS) == NFS_VER2) { \ 375 nfsm_chain_add_v2time((E), (NMC), (TVP)); \ 376 } else { \ 377 nfsm_chain_add_v3time((E), (NMC), (TVP)); \ 378 } \ 379 } while (0) 380 381 /* add an NFSv3 postop file handle to an mbuf chain */ 382 #define nfsm_chain_add_postop_fh(E, NMC, FHP, FHLEN) \ 383 do { \ 384 nfsm_chain_add_32((E), (NMC), TRUE); \ 385 nfsm_chain_add_fh((E), (NMC), NFS_VER3, (FHP), (FHLEN)); \ 386 } while (0) 387 388 /* add NFSv3 postop attributes to an mbuf chain */ 389 #define nfsm_chain_add_postop_attr(E, ND, NMC, ATTRERR, VAP) \ 390 do { \ 391 if (E) break; \ 392 if (ATTRERR) { \ 393 nfsm_chain_add_32((E), (NMC), FALSE); \ 394 break; \ 395 } \ 396 nfsm_chain_add_32((E), (NMC), TRUE); \ 397 if (E) break; \ 398 (E) = nfsm_chain_add_fattr((ND), (NMC), (VAP)); \ 399 } while (0) 400 401 /* add NFSv3 WCC data to an mbuf chain */ 402 #define nfsm_chain_add_wcc_data(E, ND, NMC, PREERR, PREVAP, POSTERR, POSTVAP) \ 403 do { \ 404 if (E) break; \ 405 (E) = nfsm_chain_add_wcc_data_f((ND), (NMC), \ 406 (PREERR), (PREVAP), (POSTERR), (POSTVAP)); \ 407 } while (0) 408 409 /* 410 * macros for dissecting NFS mbuf chains 411 */ 412 413 /* prepare an mbuf chain for dissection starting with the given mbuf */ 414 #define nfsm_chain_dissect_init(E, NMC, H) \ 415 do { \ 416 if (!(H)) { \ 417 (E) = EINVAL; \ 418 break; \ 419 } \ 420 (NMC)->nmc_mcur = (NMC)->nmc_mhead = (H); \ 421 (NMC)->nmc_ptr = mbuf_data(H); \ 422 (NMC)->nmc_left = mbuf_len(H); \ 423 } while (0) 424 425 /* skip a number of bytes in an mbuf chain */ 426 #define nfsm_chain_adv(E, NMC, LEN) \ 427 do { \ 428 if (E) break; \ 429 if ((NMC)->nmc_left >= (uint32_t)(LEN)) { \ 430 (NMC)->nmc_left -= (LEN); \ 431 (NMC)->nmc_ptr += (LEN); \ 432 } else { \ 433 (E) = nfsm_chain_advance((NMC), (LEN)); \ 434 } \ 435 } while (0) 436 437 /* get a 32bit value from an mbuf chain */ 438 #define nfsm_chain_get_32(E, NMC, LVAL) \ 439 do { \ 440 uint32_t __tmp32, *__tmpptr; \ 441 (LVAL) = 0; \ 442 if (E) break; \ 443 if ((NMC)->nmc_left >= NFSX_UNSIGNED) { \ 444 __tmpptr = (uint32_t*)(NMC)->nmc_ptr; \ 445 (NMC)->nmc_left -= NFSX_UNSIGNED; \ 446 (NMC)->nmc_ptr += NFSX_UNSIGNED; \ 447 } else { \ 448 __tmpptr = &__tmp32; \ 449 (E) = nfsm_chain_get_opaque_f((NMC), NFSX_UNSIGNED, (u_char*)__tmpptr); \ 450 if (E) break; \ 451 } \ 452 (LVAL) = fxdr_unsigned(uint32_t, *__tmpptr); \ 453 } while (0) 454 455 /* get a 64bit value from an mbuf chain */ 456 #define nfsm_chain_get_64(E, NMC, LVAL) \ 457 do { \ 458 uint64_t __tmp64, *__tmpptr; \ 459 (LVAL) = 0; \ 460 if (E) break; \ 461 if ((NMC)->nmc_left >= 2 * NFSX_UNSIGNED) { \ 462 __tmpptr = (uint64_t*)(NMC)->nmc_ptr; \ 463 (NMC)->nmc_left -= 2 * NFSX_UNSIGNED; \ 464 (NMC)->nmc_ptr += 2 * NFSX_UNSIGNED; \ 465 } else { \ 466 __tmpptr = &__tmp64; \ 467 (E) = nfsm_chain_get_opaque_f((NMC), 2 * NFSX_UNSIGNED, (u_char*)__tmpptr); \ 468 if (E) break; \ 469 } \ 470 fxdr_hyper(__tmpptr, &(LVAL)); \ 471 } while (0) 472 473 /* get a pointer to the next consecutive bytes in an mbuf chain */ 474 #define nfsm_chain_get_opaque_pointer(E, NMC, LEN, PTR) \ 475 do { \ 476 uint32_t rndlen; \ 477 if (E) break; \ 478 rndlen = nfsm_rndup(LEN); \ 479 if (rndlen < (LEN)) { \ 480 (E) = EBADRPC; \ 481 break; \ 482 } \ 483 if ((NMC)->nmc_left >= rndlen) { \ 484 (PTR) = (void*)(NMC)->nmc_ptr; \ 485 (NMC)->nmc_left -= rndlen; \ 486 (NMC)->nmc_ptr += rndlen; \ 487 } else { \ 488 (E) = nfsm_chain_get_opaque_pointer_f((NMC), (LEN), (u_char**)&(PTR)); \ 489 } \ 490 } while (0) 491 492 /* copy the next consecutive bytes of opaque data from an mbuf chain */ 493 #define nfsm_chain_get_opaque(E, NMC, LEN, PTR) \ 494 do { \ 495 size_t rndlen; \ 496 if (E) break; \ 497 rndlen = nfsm_rndup(LEN); \ 498 if (rndlen < (LEN)) { \ 499 (E) = EBADRPC; \ 500 break; \ 501 } \ 502 if ((NMC)->nmc_left >= rndlen) { \ 503 u_char *__tmpptr = (u_char*)(NMC)->nmc_ptr; \ 504 (NMC)->nmc_left -= rndlen; \ 505 (NMC)->nmc_ptr += rndlen; \ 506 bcopy(__tmpptr, (PTR), (LEN)); \ 507 } else { \ 508 (E) = nfsm_chain_get_opaque_f((NMC), (LEN), (u_char*)(PTR)); \ 509 } \ 510 } while (0) 511 512 /* get the size of and a pointer to a file handle in an mbuf chain */ 513 #define nfsm_chain_get_fh_ptr(E, NMC, VERS, FHP, FHSIZE) \ 514 do { \ 515 if ((VERS) != NFS_VER2) { \ 516 nfsm_chain_get_32((E), (NMC), (FHSIZE)); \ 517 if (E) break; \ 518 if ((FHSIZE) > NFSV3_MAX_FH_SIZE) \ 519 (E) = NFSERR_BADHANDLE; \ 520 } else \ 521 (FHSIZE) = NFSX_V2FH;\ 522 if ((E) == 0) \ 523 nfsm_chain_get_opaque_pointer((E), (NMC), (FHSIZE), (FHP));\ 524 } while (0) 525 526 /* get the size of and data for a file handle in an mbuf chain */ 527 #define nfsm_chain_get_fh(E, NMC, VERS, FHP) \ 528 do { \ 529 if ((VERS) != NFS_VER2) { \ 530 nfsm_chain_get_32((E), (NMC), (FHP)->fh_len); \ 531 if ((FHP)->fh_len > sizeof((FHP)->fh_data)) \ 532 (E) = EBADRPC; \ 533 } else \ 534 (FHP)->fh_len = NFSX_V2FH;\ 535 if ((E) == 0) \ 536 nfsm_chain_get_opaque((E), (NMC), (uint32_t)(FHP)->fh_len, (FHP)->fh_data);\ 537 else \ 538 (FHP)->fh_len = 0;\ 539 } while (0) 540 541 /* get an NFS v2 or v3 time from an mbuf chain */ 542 #define nfsm_chain_get_time(E, NMC, VERS, TSEC, TNSEC) \ 543 do { \ 544 nfsm_chain_get_32((E), (NMC), (TSEC)); \ 545 nfsm_chain_get_32((E), (NMC), (TNSEC)); \ 546 if ((E) || ((VERS) != NFS_VER2)) break; \ 547 if ((uint32_t)(TNSEC) == 0xffffffff) \ 548 (TNSEC) = 0; \ 549 else \ 550 (TNSEC) *= 1000; \ 551 } while (0) 552 553 #endif /* __APPLE_API_PRIVATE */ 554 #endif /* _NFS_NFSM_SUBS_H_ */ 555