1 /* $NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $ */ 2 3 /*- 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * Copyright (c) 2010, Oracle America, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are 10 * met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * * Redistributions in binary form must reproduce the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer in the documentation and/or other materials 17 * provided with the distribution. 18 * * Neither the name of the "Oracle America, Inc." nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 29 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /* 37 * xdr.c, Generic XDR routines implementation. 38 * 39 * These are the "generic" xdr routines used to serialize and de-serialize 40 * most common data items. See xdr.h for more info on the interface to 41 * xdr. 42 */ 43 44 #include "namespace.h" 45 #include <err.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 50 #include <rpc/rpc.h> 51 #include <rpc/rpc_com.h> 52 #include <rpc/types.h> 53 #include <rpc/xdr.h> 54 #include "un-namespace.h" 55 56 typedef quad_t longlong_t; /* ANSI long long type */ 57 typedef u_quad_t u_longlong_t; /* ANSI unsigned long long type */ 58 59 /* 60 * constants specific to the xdr "protocol" 61 */ 62 #define XDR_FALSE ((long) 0) 63 #define XDR_TRUE ((long) 1) 64 65 /* 66 * for unit alignment 67 */ 68 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; 69 70 /* 71 * Free a data structure using XDR 72 * Not a filter, but a convenient utility nonetheless 73 */ 74 void 75 xdr_free(xdrproc_t proc, void *objp) 76 { 77 XDR x; 78 79 x.x_op = XDR_FREE; 80 (*proc)(&x, objp); 81 } 82 83 /* 84 * XDR nothing 85 */ 86 bool_t 87 xdr_void(XDR *xdrs __unused, void *ptr __unused) 88 { 89 return (TRUE); 90 } 91 92 /* 93 * XDR integers 94 */ 95 bool_t 96 xdr_int(XDR *xdrs, int *ip) 97 { 98 long l; 99 100 switch (xdrs->x_op) { 101 102 case XDR_ENCODE: 103 l = (long) *ip; 104 return (XDR_PUTLONG(xdrs, &l)); 105 106 case XDR_DECODE: 107 if (!XDR_GETLONG(xdrs, &l)) { 108 return (FALSE); 109 } 110 *ip = (int) l; 111 return (TRUE); 112 113 case XDR_FREE: 114 return (TRUE); 115 } 116 /* NOTREACHED */ 117 return (FALSE); 118 } 119 120 /* 121 * XDR unsigned integers 122 */ 123 bool_t 124 xdr_u_int(XDR *xdrs, u_int *up) 125 { 126 u_long l; 127 128 switch (xdrs->x_op) { 129 130 case XDR_ENCODE: 131 l = (u_long) *up; 132 return (XDR_PUTLONG(xdrs, (long *)&l)); 133 134 case XDR_DECODE: 135 if (!XDR_GETLONG(xdrs, (long *)&l)) { 136 return (FALSE); 137 } 138 *up = (u_int) l; 139 return (TRUE); 140 141 case XDR_FREE: 142 return (TRUE); 143 } 144 /* NOTREACHED */ 145 return (FALSE); 146 } 147 148 149 /* 150 * XDR long integers 151 * same as xdr_u_long - open coded to save a proc call! 152 */ 153 bool_t 154 xdr_long(XDR *xdrs, long *lp) 155 { 156 switch (xdrs->x_op) { 157 case XDR_ENCODE: 158 return (XDR_PUTLONG(xdrs, lp)); 159 case XDR_DECODE: 160 return (XDR_GETLONG(xdrs, lp)); 161 case XDR_FREE: 162 return (TRUE); 163 } 164 /* NOTREACHED */ 165 return (FALSE); 166 } 167 168 /* 169 * XDR unsigned long integers 170 * same as xdr_long - open coded to save a proc call! 171 */ 172 bool_t 173 xdr_u_long(XDR *xdrs, u_long *ulp) 174 { 175 switch (xdrs->x_op) { 176 case XDR_ENCODE: 177 return (XDR_PUTLONG(xdrs, (long *)ulp)); 178 case XDR_DECODE: 179 return (XDR_GETLONG(xdrs, (long *)ulp)); 180 case XDR_FREE: 181 return (TRUE); 182 } 183 /* NOTREACHED */ 184 return (FALSE); 185 } 186 187 188 /* 189 * XDR 32-bit integers 190 * same as xdr_u_int32_t - open coded to save a proc call! 191 */ 192 bool_t 193 xdr_int32_t(XDR *xdrs, int32_t *int32_p) 194 { 195 long l; 196 197 switch (xdrs->x_op) { 198 199 case XDR_ENCODE: 200 l = (long) *int32_p; 201 return (XDR_PUTLONG(xdrs, &l)); 202 203 case XDR_DECODE: 204 if (!XDR_GETLONG(xdrs, &l)) { 205 return (FALSE); 206 } 207 *int32_p = (int32_t) l; 208 return (TRUE); 209 210 case XDR_FREE: 211 return (TRUE); 212 } 213 /* NOTREACHED */ 214 return (FALSE); 215 } 216 217 /* 218 * XDR unsigned 32-bit integers 219 * same as xdr_int32_t - open coded to save a proc call! 220 */ 221 bool_t 222 xdr_u_int32_t(XDR *xdrs, u_int32_t *u_int32_p) 223 { 224 u_long l; 225 226 switch (xdrs->x_op) { 227 228 case XDR_ENCODE: 229 l = (u_long) *u_int32_p; 230 return (XDR_PUTLONG(xdrs, (long *)&l)); 231 232 case XDR_DECODE: 233 if (!XDR_GETLONG(xdrs, (long *)&l)) { 234 return (FALSE); 235 } 236 *u_int32_p = (u_int32_t) l; 237 return (TRUE); 238 239 case XDR_FREE: 240 return (TRUE); 241 } 242 /* NOTREACHED */ 243 return (FALSE); 244 } 245 246 /* 247 * XDR unsigned 32-bit integers 248 * same as xdr_int32_t - open coded to save a proc call! 249 */ 250 bool_t 251 xdr_uint32_t(XDR *xdrs, uint32_t *u_int32_p) 252 { 253 u_long l; 254 255 switch (xdrs->x_op) { 256 257 case XDR_ENCODE: 258 l = (u_long) *u_int32_p; 259 return (XDR_PUTLONG(xdrs, (long *)&l)); 260 261 case XDR_DECODE: 262 if (!XDR_GETLONG(xdrs, (long *)&l)) { 263 return (FALSE); 264 } 265 *u_int32_p = (u_int32_t) l; 266 return (TRUE); 267 268 case XDR_FREE: 269 return (TRUE); 270 } 271 /* NOTREACHED */ 272 return (FALSE); 273 } 274 275 /* 276 * XDR short integers 277 */ 278 bool_t 279 xdr_short(XDR *xdrs, short *sp) 280 { 281 long l; 282 283 switch (xdrs->x_op) { 284 285 case XDR_ENCODE: 286 l = (long) *sp; 287 return (XDR_PUTLONG(xdrs, &l)); 288 289 case XDR_DECODE: 290 if (!XDR_GETLONG(xdrs, &l)) { 291 return (FALSE); 292 } 293 *sp = (short) l; 294 return (TRUE); 295 296 case XDR_FREE: 297 return (TRUE); 298 } 299 /* NOTREACHED */ 300 return (FALSE); 301 } 302 303 /* 304 * XDR unsigned short integers 305 */ 306 bool_t 307 xdr_u_short(XDR *xdrs, u_short *usp) 308 { 309 u_long l; 310 311 switch (xdrs->x_op) { 312 313 case XDR_ENCODE: 314 l = (u_long) *usp; 315 return (XDR_PUTLONG(xdrs, (long *)&l)); 316 317 case XDR_DECODE: 318 if (!XDR_GETLONG(xdrs, (long *)&l)) { 319 return (FALSE); 320 } 321 *usp = (u_short) l; 322 return (TRUE); 323 324 case XDR_FREE: 325 return (TRUE); 326 } 327 /* NOTREACHED */ 328 return (FALSE); 329 } 330 331 332 /* 333 * XDR 16-bit integers 334 */ 335 bool_t 336 xdr_int16_t(XDR *xdrs, int16_t *int16_p) 337 { 338 long l; 339 340 switch (xdrs->x_op) { 341 342 case XDR_ENCODE: 343 l = (long) *int16_p; 344 return (XDR_PUTLONG(xdrs, &l)); 345 346 case XDR_DECODE: 347 if (!XDR_GETLONG(xdrs, &l)) { 348 return (FALSE); 349 } 350 *int16_p = (int16_t) l; 351 return (TRUE); 352 353 case XDR_FREE: 354 return (TRUE); 355 } 356 /* NOTREACHED */ 357 return (FALSE); 358 } 359 360 /* 361 * XDR unsigned 16-bit integers 362 */ 363 bool_t 364 xdr_u_int16_t(XDR *xdrs, u_int16_t *u_int16_p) 365 { 366 u_long l; 367 368 switch (xdrs->x_op) { 369 370 case XDR_ENCODE: 371 l = (u_long) *u_int16_p; 372 return (XDR_PUTLONG(xdrs, (long *)&l)); 373 374 case XDR_DECODE: 375 if (!XDR_GETLONG(xdrs, (long *)&l)) { 376 return (FALSE); 377 } 378 *u_int16_p = (u_int16_t) l; 379 return (TRUE); 380 381 case XDR_FREE: 382 return (TRUE); 383 } 384 /* NOTREACHED */ 385 return (FALSE); 386 } 387 388 /* 389 * XDR unsigned 16-bit integers 390 */ 391 bool_t 392 xdr_uint16_t(XDR *xdrs, uint16_t *u_int16_p) 393 { 394 u_long l; 395 396 switch (xdrs->x_op) { 397 398 case XDR_ENCODE: 399 l = (u_long) *u_int16_p; 400 return (XDR_PUTLONG(xdrs, (long *)&l)); 401 402 case XDR_DECODE: 403 if (!XDR_GETLONG(xdrs, (long *)&l)) { 404 return (FALSE); 405 } 406 *u_int16_p = (u_int16_t) l; 407 return (TRUE); 408 409 case XDR_FREE: 410 return (TRUE); 411 } 412 /* NOTREACHED */ 413 return (FALSE); 414 } 415 416 417 /* 418 * XDR a char 419 */ 420 bool_t 421 xdr_char(XDR *xdrs, char *cp) 422 { 423 u_int i; 424 425 i = *((unsigned char *)cp); 426 if (!xdr_u_int(xdrs, &i)) { 427 return (FALSE); 428 } 429 *((unsigned char *)cp) = i; 430 return (TRUE); 431 } 432 433 /* 434 * XDR an unsigned char 435 */ 436 bool_t 437 xdr_u_char(XDR *xdrs, u_char *cp) 438 { 439 u_int u; 440 441 u = (*cp); 442 if (!xdr_u_int(xdrs, &u)) { 443 return (FALSE); 444 } 445 *cp = u; 446 return (TRUE); 447 } 448 449 /* 450 * XDR booleans 451 */ 452 bool_t 453 xdr_bool(XDR *xdrs, bool_t *bp) 454 { 455 long lb; 456 457 switch (xdrs->x_op) { 458 459 case XDR_ENCODE: 460 lb = *bp ? XDR_TRUE : XDR_FALSE; 461 return (XDR_PUTLONG(xdrs, &lb)); 462 463 case XDR_DECODE: 464 if (!XDR_GETLONG(xdrs, &lb)) { 465 return (FALSE); 466 } 467 *bp = (lb == XDR_FALSE) ? FALSE : TRUE; 468 return (TRUE); 469 470 case XDR_FREE: 471 return (TRUE); 472 } 473 /* NOTREACHED */ 474 return (FALSE); 475 } 476 477 /* 478 * XDR enumerations 479 */ 480 bool_t 481 xdr_enum(XDR *xdrs, enum_t *ep) 482 { 483 enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ 484 485 /* 486 * enums are treated as ints 487 */ 488 /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) { 489 return (xdr_long(xdrs, (long *)(void *)ep)); 490 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) { 491 return (xdr_int(xdrs, (int *)(void *)ep)); 492 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) { 493 return (xdr_short(xdrs, (short *)(void *)ep)); 494 } else { 495 return (FALSE); 496 } 497 } 498 499 /* 500 * XDR opaque data 501 * Allows the specification of a fixed size sequence of opaque bytes. 502 * cp points to the opaque object and cnt gives the byte length. 503 */ 504 bool_t 505 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt) 506 { 507 u_int rndup; 508 static int crud[BYTES_PER_XDR_UNIT]; 509 510 /* 511 * if no data we are done 512 */ 513 if (cnt == 0) 514 return (TRUE); 515 516 /* 517 * round byte count to full xdr units 518 */ 519 rndup = cnt % BYTES_PER_XDR_UNIT; 520 if (rndup > 0) 521 rndup = BYTES_PER_XDR_UNIT - rndup; 522 523 if (xdrs->x_op == XDR_DECODE) { 524 if (!XDR_GETBYTES(xdrs, cp, cnt)) { 525 return (FALSE); 526 } 527 if (rndup == 0) 528 return (TRUE); 529 return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup)); 530 } 531 532 if (xdrs->x_op == XDR_ENCODE) { 533 if (!XDR_PUTBYTES(xdrs, cp, cnt)) { 534 return (FALSE); 535 } 536 if (rndup == 0) 537 return (TRUE); 538 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); 539 } 540 541 if (xdrs->x_op == XDR_FREE) { 542 return (TRUE); 543 } 544 545 return (FALSE); 546 } 547 548 /* 549 * XDR counted bytes 550 * *cpp is a pointer to the bytes, *sizep is the count. 551 * If *cpp is NULL maxsize bytes are allocated 552 */ 553 bool_t 554 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) 555 { 556 char *sp = *cpp; /* sp is the actual string pointer */ 557 u_int nodesize; 558 bool_t ret, allocated = FALSE; 559 560 /* 561 * first deal with the length since xdr bytes are counted 562 */ 563 if (! xdr_u_int(xdrs, sizep)) { 564 return (FALSE); 565 } 566 nodesize = *sizep; 567 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { 568 return (FALSE); 569 } 570 571 /* 572 * now deal with the actual bytes 573 */ 574 switch (xdrs->x_op) { 575 576 case XDR_DECODE: 577 if (nodesize == 0) { 578 return (TRUE); 579 } 580 if (sp == NULL) { 581 *cpp = sp = mem_alloc(nodesize); 582 allocated = TRUE; 583 } 584 if (sp == NULL) { 585 warnx("xdr_bytes: out of memory"); 586 return (FALSE); 587 } 588 /* FALLTHROUGH */ 589 590 case XDR_ENCODE: 591 ret = xdr_opaque(xdrs, sp, nodesize); 592 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) { 593 if (allocated == TRUE) { 594 free(sp); 595 *cpp = NULL; 596 } 597 } 598 return (ret); 599 600 case XDR_FREE: 601 if (sp != NULL) { 602 mem_free(sp, nodesize); 603 *cpp = NULL; 604 } 605 return (TRUE); 606 } 607 /* NOTREACHED */ 608 return (FALSE); 609 } 610 611 /* 612 * Implemented here due to commonality of the object. 613 */ 614 bool_t 615 xdr_netobj(XDR *xdrs, struct netobj *np) 616 { 617 618 return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); 619 } 620 621 /* 622 * XDR a discriminated union 623 * Support routine for discriminated unions. 624 * You create an array of xdrdiscrim structures, terminated with 625 * an entry with a null procedure pointer. The routine gets 626 * the discriminant value and then searches the array of xdrdiscrims 627 * looking for that value. It calls the procedure given in the xdrdiscrim 628 * to handle the discriminant. If there is no specific routine a default 629 * routine may be called. 630 * If there is no specific or default routine an error is returned. 631 */ 632 bool_t 633 xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, const struct xdr_discrim *choices, xdrproc_t dfault) 634 /* 635 * XDR *xdrs; 636 * enum_t *dscmp; // enum to decide which arm to work on 637 * char *unp; // the union itself 638 * const struct xdr_discrim *choices; // [value, xdr proc] for each arm 639 * xdrproc_t dfault; // default xdr routine 640 */ 641 { 642 enum_t dscm; 643 644 /* 645 * we deal with the discriminator; it's an enum 646 */ 647 if (! xdr_enum(xdrs, dscmp)) { 648 return (FALSE); 649 } 650 dscm = *dscmp; 651 652 /* 653 * search choices for a value that matches the discriminator. 654 * if we find one, execute the xdr routine for that value. 655 */ 656 for (; choices->proc != NULL_xdrproc_t; choices++) { 657 if (choices->value == dscm) 658 return ((*(choices->proc))(xdrs, unp)); 659 } 660 661 /* 662 * no match - execute the default xdr routine if there is one 663 */ 664 return ((dfault == NULL_xdrproc_t) ? FALSE : 665 (*dfault)(xdrs, unp)); 666 } 667 668 669 /* 670 * Non-portable xdr primitives. 671 * Care should be taken when moving these routines to new architectures. 672 */ 673 674 675 /* 676 * XDR null terminated ASCII strings 677 * xdr_string deals with "C strings" - arrays of bytes that are 678 * terminated by a NULL character. The parameter cpp references a 679 * pointer to storage; If the pointer is null, then the necessary 680 * storage is allocated. The last parameter is the max allowed length 681 * of the string as specified by a protocol. 682 */ 683 bool_t 684 xdr_string(XDR *xdrs, char **cpp, u_int maxsize) 685 { 686 char *sp = *cpp; /* sp is the actual string pointer */ 687 u_int size; 688 u_int nodesize; 689 bool_t ret, allocated = FALSE; 690 691 /* 692 * first deal with the length since xdr strings are counted-strings 693 */ 694 switch (xdrs->x_op) { 695 case XDR_FREE: 696 if (sp == NULL) { 697 return(TRUE); /* already free */ 698 } 699 /* 700 * XXX: buggy software may call this without a third 701 * argument via xdr_free(). Ignore maxsize since it may 702 * be invalid. Otherwise, if it's very small, we might 703 * fail to free the string. 704 */ 705 maxsize = RPC_MAXDATASIZE; 706 /* FALLTHROUGH */ 707 case XDR_ENCODE: 708 size = strlen(sp); 709 break; 710 case XDR_DECODE: 711 break; 712 } 713 if (! xdr_u_int(xdrs, &size)) { 714 return (FALSE); 715 } 716 if (size > maxsize) { 717 return (FALSE); 718 } 719 nodesize = size + 1; 720 721 /* 722 * now deal with the actual bytes 723 */ 724 switch (xdrs->x_op) { 725 726 case XDR_DECODE: 727 if (nodesize == 0) { 728 return (TRUE); 729 } 730 if (sp == NULL) { 731 *cpp = sp = mem_alloc(nodesize); 732 allocated = TRUE; 733 } 734 if (sp == NULL) { 735 warnx("xdr_string: out of memory"); 736 return (FALSE); 737 } 738 sp[size] = 0; 739 /* FALLTHROUGH */ 740 741 case XDR_ENCODE: 742 ret = xdr_opaque(xdrs, sp, size); 743 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) { 744 if (allocated == TRUE) { 745 free(sp); 746 *cpp = NULL; 747 } 748 } 749 return (ret); 750 751 case XDR_FREE: 752 mem_free(sp, nodesize); 753 *cpp = NULL; 754 return (TRUE); 755 } 756 /* NOTREACHED */ 757 return (FALSE); 758 } 759 760 /* 761 * Wrapper for xdr_string that can be called directly from 762 * routines like clnt_call 763 */ 764 bool_t 765 xdr_wrapstring(XDR *xdrs, char **cpp) 766 { 767 return xdr_string(xdrs, cpp, RPC_MAXDATASIZE); 768 } 769 770 /* 771 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t() 772 * are in the "non-portable" section because they require that a `long long' 773 * be a 64-bit type. 774 * 775 * --thorpej@netbsd.org, November 30, 1999 776 */ 777 778 /* 779 * XDR 64-bit integers 780 */ 781 bool_t 782 xdr_int64_t(XDR *xdrs, int64_t *llp) 783 { 784 u_long ul[2]; 785 786 switch (xdrs->x_op) { 787 case XDR_ENCODE: 788 ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff; 789 ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff; 790 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 791 return (FALSE); 792 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 793 case XDR_DECODE: 794 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 795 return (FALSE); 796 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 797 return (FALSE); 798 *llp = (int64_t) 799 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 800 return (TRUE); 801 case XDR_FREE: 802 return (TRUE); 803 } 804 /* NOTREACHED */ 805 return (FALSE); 806 } 807 808 809 /* 810 * XDR unsigned 64-bit integers 811 */ 812 bool_t 813 xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp) 814 { 815 u_long ul[2]; 816 817 switch (xdrs->x_op) { 818 case XDR_ENCODE: 819 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; 820 ul[1] = (u_long)(*ullp) & 0xffffffff; 821 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 822 return (FALSE); 823 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 824 case XDR_DECODE: 825 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 826 return (FALSE); 827 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 828 return (FALSE); 829 *ullp = (u_int64_t) 830 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 831 return (TRUE); 832 case XDR_FREE: 833 return (TRUE); 834 } 835 /* NOTREACHED */ 836 return (FALSE); 837 } 838 839 /* 840 * XDR unsigned 64-bit integers 841 */ 842 bool_t 843 xdr_uint64_t(XDR *xdrs, uint64_t *ullp) 844 { 845 u_long ul[2]; 846 847 switch (xdrs->x_op) { 848 case XDR_ENCODE: 849 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; 850 ul[1] = (u_long)(*ullp) & 0xffffffff; 851 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 852 return (FALSE); 853 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 854 case XDR_DECODE: 855 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 856 return (FALSE); 857 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 858 return (FALSE); 859 *ullp = (u_int64_t) 860 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 861 return (TRUE); 862 case XDR_FREE: 863 return (TRUE); 864 } 865 /* NOTREACHED */ 866 return (FALSE); 867 } 868 869 870 /* 871 * XDR hypers 872 */ 873 bool_t 874 xdr_hyper(XDR *xdrs, longlong_t *llp) 875 { 876 877 /* 878 * Don't bother open-coding this; it's a fair amount of code. Just 879 * call xdr_int64_t(). 880 */ 881 return (xdr_int64_t(xdrs, (int64_t *)llp)); 882 } 883 884 885 /* 886 * XDR unsigned hypers 887 */ 888 bool_t 889 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp) 890 { 891 892 /* 893 * Don't bother open-coding this; it's a fair amount of code. Just 894 * call xdr_u_int64_t(). 895 */ 896 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 897 } 898 899 900 /* 901 * XDR longlong_t's 902 */ 903 bool_t 904 xdr_longlong_t(XDR *xdrs, longlong_t *llp) 905 { 906 907 /* 908 * Don't bother open-coding this; it's a fair amount of code. Just 909 * call xdr_int64_t(). 910 */ 911 return (xdr_int64_t(xdrs, (int64_t *)llp)); 912 } 913 914 915 /* 916 * XDR u_longlong_t's 917 */ 918 bool_t 919 xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp) 920 { 921 922 /* 923 * Don't bother open-coding this; it's a fair amount of code. Just 924 * call xdr_u_int64_t(). 925 */ 926 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 927 } 928