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