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 #include <sys/param.h> 78 #include <sys/mbuf.h> 79 80 int nfsm_chain_new_mbuf(struct nfsm_chain *, size_t); 81 int nfsm_chain_add_opaque_f(struct nfsm_chain *, const u_char *, size_t); 82 int nfsm_chain_add_opaque_nopad_f(struct nfsm_chain *, const u_char *, size_t); 83 84 int nfsm_chain_advance(struct nfsm_chain *, size_t); 85 size_t nfsm_chain_offset(struct nfsm_chain *); 86 int nfsm_chain_get_opaque_pointer_f(struct nfsm_chain *, uint32_t, u_char **); 87 int nfsm_chain_get_opaque_f(struct nfsm_chain *, size_t, u_char *); 88 int nfsm_chain_get_uio(struct nfsm_chain *, size_t, uio_t); 89 90 #if CONFIG_NFS_SERVER 91 void nfsm_adj(mbuf_t, int, int); 92 int nfsm_mbuf_get_list(size_t, mbuf_t *, int *); 93 94 int nfsm_chain_add_fattr(struct nfsrv_descript *, struct nfsm_chain *, struct vnode_attr *); 95 int nfsm_chain_add_wcc_data_f(struct nfsrv_descript *, struct nfsm_chain *, int, 96 struct vnode_attr *, int, struct vnode_attr *); 97 int nfsm_chain_get_path_namei(struct nfsm_chain *, uint32_t, struct nameidata *); 98 int nfsm_chain_get_sattr(struct nfsrv_descript *, struct nfsm_chain *, struct vnode_attr *); 99 int nfsm_chain_trim_data(struct nfsm_chain *, int, int *); 100 #endif /* CONFIG_NFS_SERVER */ 101 102 /* check name length */ 103 #define nfsm_name_len_check(E, ND, LEN) \ 104 do { \ 105 if (E) break; \ 106 if (((ND)->nd_vers == NFS_VER2) && ((LEN) > NFS_MAXNAMLEN)) \ 107 (E) = NFSERR_NAMETOL; \ 108 if ((LEN) <= 0) \ 109 error = EBADRPC; \ 110 } while (0) 111 112 #define nfsm_assert(E, COND, ERR) \ 113 do { \ 114 if (E) break; \ 115 if (!(COND)) \ 116 (E) = (ERR); \ 117 } while (0) 118 119 /* Initialize a vnode_attr to retrieve attributes for the NFS server. */ 120 #define nfsm_srv_vattr_init(VAP, VERS) \ 121 do { \ 122 VATTR_INIT(VAP); \ 123 VATTR_WANTED((VAP), va_type); \ 124 VATTR_WANTED((VAP), va_mode); \ 125 VATTR_WANTED((VAP), va_nlink); \ 126 VATTR_WANTED((VAP), va_uid); \ 127 VATTR_WANTED((VAP), va_gid); \ 128 VATTR_WANTED((VAP), va_data_size); \ 129 VATTR_WANTED((VAP), va_data_alloc); \ 130 VATTR_WANTED((VAP), va_rdev); \ 131 VATTR_WANTED((VAP), va_fsid); \ 132 VATTR_WANTED((VAP), va_fileid); \ 133 VATTR_WANTED((VAP), va_access_time); \ 134 VATTR_WANTED((VAP), va_modify_time); \ 135 VATTR_WANTED((VAP), va_change_time); \ 136 if ((VERS) == NFS_VER2) \ 137 VATTR_WANTED((VAP), va_iosize); \ 138 if ((VERS) == NFS_VER3) \ 139 VATTR_WANTED((VAP), va_filerev); \ 140 } while (0) 141 142 /* Initialize a vnode_attr to retrieve pre-operation attributes for the NFS server. */ 143 #define nfsm_srv_pre_vattr_init(VAP) \ 144 do { \ 145 VATTR_INIT(VAP); \ 146 VATTR_WANTED((VAP), va_data_size); \ 147 VATTR_WANTED((VAP), va_modify_time); \ 148 VATTR_WANTED((VAP), va_change_time); \ 149 } while (0) 150 151 /* round up to a multiple of 4 */ 152 #define nfsm_rndup(a) (((a)+3)&(~0x3)) 153 154 #define nfsm_pad(a) (nfsm_rndup(a) - (a)) 155 156 /* 157 * control flow macros: 158 * go to the appropriate label on condition 159 */ 160 #define nfsmout_if(E) do { if (E) goto nfsmout; } while (0) 161 #define nfsmerr_if(E) do { if (E) goto nfsmerr; } while (0) 162 163 /* 164 * For NFS v2 errors and EBADRPC, the reply contains only the error. 165 * This macro is used to skip any reply building code and go straight 166 * to nfsmout instead. 167 */ 168 #define nfsmout_on_status(ND, E) \ 169 do { \ 170 if (((ND)->nd_repstat == EBADRPC) || \ 171 ((ND)->nd_repstat && ((ND)->nd_vers == NFS_VER2))) { \ 172 (E) = 0; \ 173 goto nfsmout; \ 174 } \ 175 } while (0) 176 177 /* initialize an mbuf chain */ 178 #define nfsm_chain_null(NMC) \ 179 do { \ 180 (NMC)->nmc_mhead = (NMC)->nmc_mcur = NULL; \ 181 (NMC)->nmc_ptr = NULL; \ 182 } while (0) 183 184 /* cleanup an mbuf chain */ 185 #define nfsm_chain_cleanup(NMC) \ 186 do { \ 187 if (!(NMC)->nmc_mhead) break; \ 188 mbuf_freem((NMC)->nmc_mhead); \ 189 nfsm_chain_null(NMC); \ 190 } while (0) 191 192 /* get an mbuf given a size hint */ 193 #define nfsm_mbuf_get(E, MBP, SIZEHINT) \ 194 do { \ 195 *(MBP) = NULL; \ 196 if ((size_t)(SIZEHINT) >= nfs_mbuf_minclsize) \ 197 (E) = mbuf_mclget(MBUF_WAITOK, MBUF_TYPE_DATA, (MBP)); \ 198 else \ 199 (E) = mbuf_get(MBUF_WAITOK, MBUF_TYPE_DATA, (MBP)); \ 200 } while (0) 201 202 /* 203 * get an mbuf with size of M16KCLBYTES given a size hint 204 * According to mbuf_getcluster() documentation, clusters greater than 4096 bytes might 205 * not be available in all configurations; the caller must additionally check for ENOTSUP. 206 * */ 207 #define nfsm_mbuf_getcluster(E, MBP, SIZEHINT) \ 208 do { \ 209 *(MBP) = NULL; \ 210 if ((size_t)(SIZEHINT) > MBIGCLBYTES) { \ 211 (E) = mbuf_getcluster(MBUF_WAITOK, MBUF_TYPE_DATA, M16KCLBYTES, (MBP)); \ 212 if ((E) == 0) { \ 213 break; \ 214 } \ 215 } \ 216 if ((size_t)(SIZEHINT) > MCLBYTES) { \ 217 (E) = mbuf_getcluster(MBUF_WAITOK, MBUF_TYPE_DATA, MBIGCLBYTES, (MBP)); \ 218 if ((E) == 0) { \ 219 break; \ 220 } \ 221 } \ 222 nfsm_mbuf_get(E, MBP, SIZEHINT); \ 223 } while (0) 224 225 226 /* 227 * macros for building NFS mbuf chains 228 */ 229 230 /* prepare an mbuf chain for building starting with the given mbuf */ 231 #define nfsm_chain_init(NMC, MB) \ 232 do { \ 233 (NMC)->nmc_mhead = (MB); \ 234 (NMC)->nmc_mcur = (NMC)->nmc_mhead; \ 235 (NMC)->nmc_ptr = mtod((NMC)->nmc_mcur, caddr_t); \ 236 (NMC)->nmc_left = mbuf_trailingspace((NMC)->nmc_mcur); \ 237 (NMC)->nmc_flags = 0; \ 238 } while (0) 239 240 /* prepare an mbuf chain for building starting with a newly allocated mbuf */ 241 #define nfsm_chain_build_alloc_init(E, NMC, SIZEHINT) \ 242 do { \ 243 mbuf_t ncbimb; \ 244 nfsm_mbuf_get((E), &ncbimb, (SIZEHINT)); \ 245 if (E) break; \ 246 nfsm_chain_init((NMC), ncbimb); \ 247 } while (0) 248 249 /* done building an mbuf chain */ 250 #define nfsm_chain_build_done(E, NMC) \ 251 do { \ 252 if ((E) || !(NMC)->nmc_mcur) break; \ 253 /* cap off current mbuf */ \ 254 mbuf_setlen((NMC)->nmc_mcur, \ 255 (NMC)->nmc_ptr - (caddr_t)mtod((NMC)->nmc_mcur, caddr_t)); \ 256 } while (0) 257 258 /* make sure there's room for size bytes in current mbuf */ 259 #define nfsm_chain_check_size(E, NMC, SIZE) \ 260 do { \ 261 if (E) break; \ 262 if ((NMC)->nmc_left < (SIZE)) { \ 263 (E) = nfsm_chain_new_mbuf((NMC), (SIZE)); \ 264 if (!(E) && ((NMC)->nmc_left < (SIZE))) \ 265 (E) = ENOMEM; \ 266 } \ 267 } while (0) 268 269 /* add a 32bit value to an mbuf chain extending if necessary */ 270 #define nfsm_chain_add_32(E, NMC, VAL) \ 271 do { \ 272 nfsm_chain_check_size((E), (NMC), NFSX_UNSIGNED); \ 273 if (E) break; \ 274 *((uint32_t*)(NMC)->nmc_ptr) = txdr_unsigned(VAL); \ 275 (NMC)->nmc_ptr += NFSX_UNSIGNED; \ 276 (NMC)->nmc_left -= NFSX_UNSIGNED; \ 277 } while (0) 278 279 /* add a 64bit value to an mbuf chain */ 280 #define nfsm_chain_add_64(E, NMC, VAL) \ 281 do { \ 282 uint64_t __tmp64; \ 283 nfsm_chain_check_size((E), (NMC), 2 * NFSX_UNSIGNED); \ 284 if (E) break; \ 285 __tmp64 = (VAL); \ 286 txdr_hyper(&__tmp64, (NMC)->nmc_ptr); \ 287 (NMC)->nmc_ptr += 2 * NFSX_UNSIGNED; \ 288 (NMC)->nmc_left -= 2 * NFSX_UNSIGNED; \ 289 } while (0) 290 291 /* zero the last 4 bytes for a range of opaque */ 292 /* data to make sure any pad bytes will be zero. */ 293 #define nfsm_chain_zero_opaque_pad(BUF, LEN) \ 294 do { \ 295 if ((LEN) > 0) \ 296 *(((uint32_t*)(BUF))+((nfsm_rndup(LEN)>>2)-1)) = 0; \ 297 } while (0) 298 299 /* add buffer of opaque data to an mbuf chain */ 300 #define nfsm_chain_add_opaque(E, NMC, BUF, LEN) \ 301 do { \ 302 size_t rndlen = nfsm_rndup(LEN); \ 303 if (E) break; \ 304 if ((NMC)->nmc_left < rndlen) { \ 305 (E) = nfsm_chain_add_opaque_f((NMC), (const u_char*)(BUF), (LEN)); \ 306 break; \ 307 } \ 308 nfsm_chain_zero_opaque_pad((NMC)->nmc_ptr, (LEN)); \ 309 bcopy((BUF), (NMC)->nmc_ptr, (LEN)); \ 310 (NMC)->nmc_ptr += rndlen; \ 311 (NMC)->nmc_left -= rndlen; \ 312 } while (0) 313 314 /* add buffer of opaque data to an mbuf chain without padding */ 315 #define nfsm_chain_add_opaque_nopad(E, NMC, BUF, LEN) \ 316 do { \ 317 if (E) break; \ 318 if ((NMC)->nmc_left < (uint32_t) (LEN)) { \ 319 (E) = nfsm_chain_add_opaque_nopad_f((NMC), (const u_char*)(BUF), (LEN)); \ 320 break; \ 321 } \ 322 bcopy((BUF), (NMC)->nmc_ptr, (LEN)); \ 323 (NMC)->nmc_ptr += (LEN); \ 324 (NMC)->nmc_left -= (LEN); \ 325 } while (0) 326 327 /* finish an mbuf in a chain to allow subsequent insertion */ 328 #define nfsm_chain_finish_mbuf(E, NMC) \ 329 do { \ 330 if (E) break; \ 331 mbuf_setlen((NMC)->nmc_mcur, \ 332 (NMC)->nmc_ptr - mtod((NMC)->nmc_mcur, caddr_t)); \ 333 (NMC)->nmc_left = 0; \ 334 } while (0) 335 336 /* add a file handle to an mbuf chain */ 337 #define nfsm_chain_add_fh(E, NMC, VERS, FHP, FHLEN) \ 338 do { \ 339 if (E) break; \ 340 if ((VERS) != NFS_VER2) \ 341 nfsm_chain_add_32((E), (NMC), (FHLEN)); \ 342 nfsm_chain_add_opaque((E), (NMC), (FHP), (FHLEN)); \ 343 } while (0) 344 345 /* add a string to an mbuf chain */ 346 #define nfsm_chain_add_string(E, NMC, STR, LEN) \ 347 do { \ 348 nfsm_chain_add_32((E), (NMC), (LEN)); \ 349 nfsm_chain_add_opaque((E), (NMC), (STR), (LEN)); \ 350 } while (0) 351 352 /* add an NFSv2 time to an mbuf chain */ 353 #define nfsm_chain_add_v2time(E, NMC, TVP) \ 354 do { \ 355 if (TVP) { \ 356 nfsm_chain_add_32((E), (NMC), (TVP)->tv_sec); \ 357 nfsm_chain_add_32((E), (NMC), ((TVP)->tv_nsec != -1) ? \ 358 ((uint32_t)(TVP)->tv_nsec / 1000) : 0xffffffff); \ 359 } else { \ 360 /* no time... use -1 */ \ 361 nfsm_chain_add_32((E), (NMC), -1); \ 362 nfsm_chain_add_32((E), (NMC), -1); \ 363 } \ 364 } while (0) 365 366 /* add an NFSv3 time to an mbuf chain */ 367 #define nfsm_chain_add_v3time(E, NMC, TVP) \ 368 do { \ 369 nfsm_chain_add_32((E), (NMC), (TVP)->tv_sec); \ 370 nfsm_chain_add_32((E), (NMC), (TVP)->tv_nsec); \ 371 } while (0) 372 373 /* add an NFS v2 or v3 time to an mbuf chain */ 374 #define nfsm_chain_add_time(E, NMC, VERS, TVP) \ 375 do { \ 376 if ((VERS) == NFS_VER2) { \ 377 nfsm_chain_add_v2time((E), (NMC), (TVP)); \ 378 } else { \ 379 nfsm_chain_add_v3time((E), (NMC), (TVP)); \ 380 } \ 381 } while (0) 382 383 /* add an NFSv3 postop file handle to an mbuf chain */ 384 #define nfsm_chain_add_postop_fh(E, NMC, FHP, FHLEN) \ 385 do { \ 386 nfsm_chain_add_32((E), (NMC), TRUE); \ 387 nfsm_chain_add_fh((E), (NMC), NFS_VER3, (FHP), (FHLEN)); \ 388 } while (0) 389 390 /* add NFSv3 postop attributes to an mbuf chain */ 391 #define nfsm_chain_add_postop_attr(E, ND, NMC, ATTRERR, VAP) \ 392 do { \ 393 if (E) break; \ 394 if (ATTRERR) { \ 395 nfsm_chain_add_32((E), (NMC), FALSE); \ 396 break; \ 397 } \ 398 nfsm_chain_add_32((E), (NMC), TRUE); \ 399 if (E) break; \ 400 (E) = nfsm_chain_add_fattr((ND), (NMC), (VAP)); \ 401 } while (0) 402 403 /* add NFSv3 WCC data to an mbuf chain */ 404 #define nfsm_chain_add_wcc_data(E, ND, NMC, PREERR, PREVAP, POSTERR, POSTVAP) \ 405 do { \ 406 if (E) break; \ 407 (E) = nfsm_chain_add_wcc_data_f((ND), (NMC), \ 408 (PREERR), (PREVAP), (POSTERR), (POSTVAP)); \ 409 } while (0) 410 411 /* 412 * macros for dissecting NFS mbuf chains 413 */ 414 415 /* prepare an mbuf chain for dissection starting with the given mbuf */ 416 #define nfsm_chain_dissect_init(E, NMC, H) \ 417 do { \ 418 if (!(H)) { \ 419 (E) = EINVAL; \ 420 break; \ 421 } \ 422 (NMC)->nmc_mcur = (NMC)->nmc_mhead = (H); \ 423 (NMC)->nmc_ptr = mtod(H, caddr_t); \ 424 (NMC)->nmc_left = mbuf_len(H); \ 425 } while (0) 426 427 /* skip a number of bytes in an mbuf chain */ 428 #define nfsm_chain_adv(E, NMC, LEN) \ 429 do { \ 430 if (E) break; \ 431 if ((NMC)->nmc_left >= (uint32_t)(LEN)) { \ 432 (NMC)->nmc_left -= (LEN); \ 433 (NMC)->nmc_ptr += (LEN); \ 434 } else { \ 435 (E) = nfsm_chain_advance((NMC), (LEN)); \ 436 } \ 437 } while (0) 438 439 /* get a 32bit value from an mbuf chain */ 440 #define nfsm_chain_get_32(E, NMC, LVAL) \ 441 do { \ 442 uint32_t __tmp32, *__tmpptr; \ 443 (LVAL) = 0; \ 444 if (E) break; \ 445 if ((NMC)->nmc_left >= NFSX_UNSIGNED) { \ 446 __tmpptr = (uint32_t*)(NMC)->nmc_ptr; \ 447 (NMC)->nmc_left -= NFSX_UNSIGNED; \ 448 (NMC)->nmc_ptr += NFSX_UNSIGNED; \ 449 } else { \ 450 __tmpptr = &__tmp32; \ 451 (E) = nfsm_chain_get_opaque_f((NMC), NFSX_UNSIGNED, (u_char*)__tmpptr); \ 452 if (E) break; \ 453 } \ 454 (LVAL) = fxdr_unsigned(uint32_t, *__tmpptr); \ 455 } while (0) 456 457 /* get a 64bit value from an mbuf chain */ 458 #define nfsm_chain_get_64(E, NMC, LVAL) \ 459 do { \ 460 uint64_t __tmp64, *__tmpptr; \ 461 (LVAL) = 0; \ 462 if (E) break; \ 463 if ((NMC)->nmc_left >= 2 * NFSX_UNSIGNED) { \ 464 __tmpptr = (uint64_t*)(NMC)->nmc_ptr; \ 465 (NMC)->nmc_left -= 2 * NFSX_UNSIGNED; \ 466 (NMC)->nmc_ptr += 2 * NFSX_UNSIGNED; \ 467 } else { \ 468 __tmpptr = &__tmp64; \ 469 (E) = nfsm_chain_get_opaque_f((NMC), 2 * NFSX_UNSIGNED, (u_char*)__tmpptr); \ 470 if (E) break; \ 471 } \ 472 fxdr_hyper(__tmpptr, &(LVAL)); \ 473 } while (0) 474 475 /* get a pointer to the next consecutive bytes in an mbuf chain */ 476 #define nfsm_chain_get_opaque_pointer(E, NMC, LEN, PTR) \ 477 do { \ 478 uint32_t rndlen; \ 479 if (E) break; \ 480 rndlen = nfsm_rndup(LEN); \ 481 if (rndlen < (LEN)) { \ 482 (E) = EBADRPC; \ 483 break; \ 484 } \ 485 if ((NMC)->nmc_left >= rndlen) { \ 486 (PTR) = (void*)(NMC)->nmc_ptr; \ 487 (NMC)->nmc_left -= rndlen; \ 488 (NMC)->nmc_ptr += rndlen; \ 489 } else { \ 490 (E) = nfsm_chain_get_opaque_pointer_f((NMC), (LEN), (u_char**)&(PTR)); \ 491 } \ 492 } while (0) 493 494 /* copy the next consecutive bytes of opaque data from an mbuf chain */ 495 #define nfsm_chain_get_opaque(E, NMC, LEN, PTR) \ 496 do { \ 497 size_t rndlen; \ 498 if (E) break; \ 499 rndlen = nfsm_rndup(LEN); \ 500 if (rndlen < (LEN)) { \ 501 (E) = EBADRPC; \ 502 break; \ 503 } \ 504 if ((NMC)->nmc_left >= rndlen) { \ 505 u_char *__tmpptr = (u_char*)(NMC)->nmc_ptr; \ 506 (NMC)->nmc_left -= rndlen; \ 507 (NMC)->nmc_ptr += rndlen; \ 508 bcopy(__tmpptr, (PTR), (LEN)); \ 509 } else { \ 510 (E) = nfsm_chain_get_opaque_f((NMC), (LEN), (u_char*)(PTR)); \ 511 } \ 512 } while (0) 513 514 /* get the size of and a pointer to a file handle in an mbuf chain */ 515 #define nfsm_chain_get_fh_ptr(E, NMC, VERS, FHP, FHSIZE) \ 516 do { \ 517 if ((VERS) != NFS_VER2) { \ 518 nfsm_chain_get_32((E), (NMC), (FHSIZE)); \ 519 if (E) break; \ 520 if ((FHSIZE) > NFSV3_MAX_FH_SIZE) \ 521 (E) = NFSERR_BADHANDLE; \ 522 } else \ 523 (FHSIZE) = NFSX_V2FH;\ 524 if ((E) == 0) \ 525 nfsm_chain_get_opaque_pointer((E), (NMC), (FHSIZE), (FHP));\ 526 } while (0) 527 528 /* get the size of and data for a file handle in an mbuf chain */ 529 #define nfsm_chain_get_fh(E, NMC, VERS, FHP) \ 530 do { \ 531 if ((VERS) != NFS_VER2) { \ 532 nfsm_chain_get_32((E), (NMC), (FHP)->fh_len); \ 533 if ((FHP)->fh_len > sizeof((FHP)->fh_data)) \ 534 (E) = EBADRPC; \ 535 } else \ 536 (FHP)->fh_len = NFSX_V2FH;\ 537 if ((E) == 0) \ 538 nfsm_chain_get_opaque((E), (NMC), (uint32_t)(FHP)->fh_len, (FHP)->fh_data);\ 539 else \ 540 (FHP)->fh_len = 0;\ 541 } while (0) 542 543 /* get an NFS v2 or v3 time from an mbuf chain */ 544 #define nfsm_chain_get_time(E, NMC, VERS, TSEC, TNSEC) \ 545 do { \ 546 nfsm_chain_get_32((E), (NMC), (TSEC)); \ 547 nfsm_chain_get_32((E), (NMC), (TNSEC)); \ 548 if ((E) || ((VERS) != NFS_VER2)) break; \ 549 if ((uint32_t)(TNSEC) == 0xffffffff) \ 550 (TNSEC) = 0; \ 551 else \ 552 (TNSEC) *= 1000; \ 553 } while (0) 554 555 #endif /* __APPLE_API_PRIVATE */ 556 #endif /* _NFS_NFSM_SUBS_H_ */ 557