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 * @(#)xdr.c 1.35 87/08/12 36 * @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC 37 * $FreeBSD: head/lib/libc/xdr/xdr.c 326025 2017-11-20 19:49:47Z pfg $ 38 */ 39 40 /* 41 * xdr.c, Generic XDR routines implementation. 42 * 43 * These are the "generic" xdr routines used to serialize and de-serialize 44 * most common data items. See xdr.h for more info on the interface to 45 * xdr. 46 */ 47 48 #include "namespace.h" 49 #include <err.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 54 #include <rpc/rpc.h> 55 #include <rpc/rpc_com.h> 56 #include <rpc/types.h> 57 #include <rpc/xdr.h> 58 #include "un-namespace.h" 59 60 typedef quad_t longlong_t; /* ANSI long long type */ 61 typedef u_quad_t u_longlong_t; /* ANSI unsigned long long type */ 62 63 /* 64 * constants specific to the xdr "protocol" 65 */ 66 #define XDR_FALSE ((long) 0) 67 #define XDR_TRUE ((long) 1) 68 69 /* 70 * for unit alignment 71 */ 72 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; 73 74 /* 75 * Free a data structure using XDR 76 * Not a filter, but a convenient utility nonetheless 77 */ 78 void 79 xdr_free(xdrproc_t proc, void *objp) 80 { 81 XDR x; 82 83 x.x_op = XDR_FREE; 84 (*proc)(&x, objp); 85 } 86 87 /* 88 * XDR nothing 89 */ 90 bool_t 91 xdr_void(void) 92 { 93 94 return (TRUE); 95 } 96 97 98 /* 99 * XDR integers 100 */ 101 bool_t 102 xdr_int(XDR *xdrs, int *ip) 103 { 104 long l; 105 106 switch (xdrs->x_op) { 107 108 case XDR_ENCODE: 109 l = (long) *ip; 110 return (XDR_PUTLONG(xdrs, &l)); 111 112 case XDR_DECODE: 113 if (!XDR_GETLONG(xdrs, &l)) { 114 return (FALSE); 115 } 116 *ip = (int) l; 117 return (TRUE); 118 119 case XDR_FREE: 120 return (TRUE); 121 } 122 /* NOTREACHED */ 123 return (FALSE); 124 } 125 126 /* 127 * XDR unsigned integers 128 */ 129 bool_t 130 xdr_u_int(XDR *xdrs, u_int *up) 131 { 132 u_long l; 133 134 switch (xdrs->x_op) { 135 136 case XDR_ENCODE: 137 l = (u_long) *up; 138 return (XDR_PUTLONG(xdrs, (long *)&l)); 139 140 case XDR_DECODE: 141 if (!XDR_GETLONG(xdrs, (long *)&l)) { 142 return (FALSE); 143 } 144 *up = (u_int) l; 145 return (TRUE); 146 147 case XDR_FREE: 148 return (TRUE); 149 } 150 /* NOTREACHED */ 151 return (FALSE); 152 } 153 154 155 /* 156 * XDR long integers 157 * same as xdr_u_long - open coded to save a proc call! 158 */ 159 bool_t 160 xdr_long(XDR *xdrs, long *lp) 161 { 162 switch (xdrs->x_op) { 163 case XDR_ENCODE: 164 return (XDR_PUTLONG(xdrs, lp)); 165 case XDR_DECODE: 166 return (XDR_GETLONG(xdrs, lp)); 167 case XDR_FREE: 168 return (TRUE); 169 } 170 /* NOTREACHED */ 171 return (FALSE); 172 } 173 174 /* 175 * XDR unsigned long integers 176 * same as xdr_long - open coded to save a proc call! 177 */ 178 bool_t 179 xdr_u_long(XDR *xdrs, u_long *ulp) 180 { 181 switch (xdrs->x_op) { 182 case XDR_ENCODE: 183 return (XDR_PUTLONG(xdrs, (long *)ulp)); 184 case XDR_DECODE: 185 return (XDR_GETLONG(xdrs, (long *)ulp)); 186 case XDR_FREE: 187 return (TRUE); 188 } 189 /* NOTREACHED */ 190 return (FALSE); 191 } 192 193 194 /* 195 * XDR 32-bit integers 196 * same as xdr_u_int32_t - open coded to save a proc call! 197 */ 198 bool_t 199 xdr_int32_t(XDR *xdrs, int32_t *int32_p) 200 { 201 long l; 202 203 switch (xdrs->x_op) { 204 205 case XDR_ENCODE: 206 l = (long) *int32_p; 207 return (XDR_PUTLONG(xdrs, &l)); 208 209 case XDR_DECODE: 210 if (!XDR_GETLONG(xdrs, &l)) { 211 return (FALSE); 212 } 213 *int32_p = (int32_t) l; 214 return (TRUE); 215 216 case XDR_FREE: 217 return (TRUE); 218 } 219 /* NOTREACHED */ 220 return (FALSE); 221 } 222 223 /* 224 * XDR unsigned 32-bit integers 225 * same as xdr_int32_t - open coded to save a proc call! 226 */ 227 bool_t 228 xdr_u_int32_t(XDR *xdrs, uint32_t *uint32_p) 229 { 230 u_long l; 231 232 switch (xdrs->x_op) { 233 234 case XDR_ENCODE: 235 l = (u_long) *uint32_p; 236 return (XDR_PUTLONG(xdrs, (long *)&l)); 237 238 case XDR_DECODE: 239 if (!XDR_GETLONG(xdrs, (long *)&l)) { 240 return (FALSE); 241 } 242 *uint32_p = (uint32_t) l; 243 return (TRUE); 244 245 case XDR_FREE: 246 return (TRUE); 247 } 248 /* NOTREACHED */ 249 return (FALSE); 250 } 251 252 /* 253 * XDR unsigned 32-bit integers 254 * same as xdr_int32_t - open coded to save a proc call! 255 */ 256 bool_t 257 xdr_uint32_t(XDR *xdrs, uint32_t *uint32_p) 258 { 259 u_long l; 260 261 switch (xdrs->x_op) { 262 263 case XDR_ENCODE: 264 l = (u_long) *uint32_p; 265 return (XDR_PUTLONG(xdrs, (long *)&l)); 266 267 case XDR_DECODE: 268 if (!XDR_GETLONG(xdrs, (long *)&l)) { 269 return (FALSE); 270 } 271 *uint32_p = (uint32_t) l; 272 return (TRUE); 273 274 case XDR_FREE: 275 return (TRUE); 276 } 277 /* NOTREACHED */ 278 return (FALSE); 279 } 280 281 /* 282 * XDR short integers 283 */ 284 bool_t 285 xdr_short(XDR *xdrs, short *sp) 286 { 287 long l; 288 289 switch (xdrs->x_op) { 290 291 case XDR_ENCODE: 292 l = (long) *sp; 293 return (XDR_PUTLONG(xdrs, &l)); 294 295 case XDR_DECODE: 296 if (!XDR_GETLONG(xdrs, &l)) { 297 return (FALSE); 298 } 299 *sp = (short) l; 300 return (TRUE); 301 302 case XDR_FREE: 303 return (TRUE); 304 } 305 /* NOTREACHED */ 306 return (FALSE); 307 } 308 309 /* 310 * XDR unsigned short integers 311 */ 312 bool_t 313 xdr_u_short(XDR *xdrs, u_short *usp) 314 { 315 u_long l; 316 317 switch (xdrs->x_op) { 318 319 case XDR_ENCODE: 320 l = (u_long) *usp; 321 return (XDR_PUTLONG(xdrs, (long *)&l)); 322 323 case XDR_DECODE: 324 if (!XDR_GETLONG(xdrs, (long *)&l)) { 325 return (FALSE); 326 } 327 *usp = (u_short) l; 328 return (TRUE); 329 330 case XDR_FREE: 331 return (TRUE); 332 } 333 /* NOTREACHED */ 334 return (FALSE); 335 } 336 337 338 /* 339 * XDR 16-bit integers 340 */ 341 bool_t 342 xdr_int16_t(XDR *xdrs, int16_t *int16_p) 343 { 344 long l; 345 346 switch (xdrs->x_op) { 347 348 case XDR_ENCODE: 349 l = (long) *int16_p; 350 return (XDR_PUTLONG(xdrs, &l)); 351 352 case XDR_DECODE: 353 if (!XDR_GETLONG(xdrs, &l)) { 354 return (FALSE); 355 } 356 *int16_p = (int16_t) l; 357 return (TRUE); 358 359 case XDR_FREE: 360 return (TRUE); 361 } 362 /* NOTREACHED */ 363 return (FALSE); 364 } 365 366 /* 367 * XDR unsigned 16-bit integers 368 */ 369 bool_t 370 xdr_u_int16_t(XDR *xdrs, uint16_t *uint16_p) 371 { 372 u_long l; 373 374 switch (xdrs->x_op) { 375 376 case XDR_ENCODE: 377 l = (u_long) *uint16_p; 378 return (XDR_PUTLONG(xdrs, (long *)&l)); 379 380 case XDR_DECODE: 381 if (!XDR_GETLONG(xdrs, (long *)&l)) { 382 return (FALSE); 383 } 384 *uint16_p = (uint16_t) l; 385 return (TRUE); 386 387 case XDR_FREE: 388 return (TRUE); 389 } 390 /* NOTREACHED */ 391 return (FALSE); 392 } 393 394 /* 395 * XDR unsigned 16-bit integers 396 */ 397 bool_t 398 xdr_uint16_t(XDR *xdrs, uint16_t *uint16_p) 399 { 400 u_long l; 401 402 switch (xdrs->x_op) { 403 404 case XDR_ENCODE: 405 l = (u_long) *uint16_p; 406 return (XDR_PUTLONG(xdrs, (long *)&l)); 407 408 case XDR_DECODE: 409 if (!XDR_GETLONG(xdrs, (long *)&l)) { 410 return (FALSE); 411 } 412 *uint16_p = (uint16_t) l; 413 return (TRUE); 414 415 case XDR_FREE: 416 return (TRUE); 417 } 418 /* NOTREACHED */ 419 return (FALSE); 420 } 421 422 423 /* 424 * XDR a char 425 */ 426 bool_t 427 xdr_char(XDR *xdrs, char *cp) 428 { 429 int i; 430 431 i = (*cp); 432 if (!xdr_int(xdrs, &i)) { 433 return (FALSE); 434 } 435 *cp = i; 436 return (TRUE); 437 } 438 439 /* 440 * XDR an unsigned char 441 */ 442 bool_t 443 xdr_u_char(XDR *xdrs, u_char *cp) 444 { 445 u_int u; 446 447 u = (*cp); 448 if (!xdr_u_int(xdrs, &u)) { 449 return (FALSE); 450 } 451 *cp = u; 452 return (TRUE); 453 } 454 455 /* 456 * XDR booleans 457 */ 458 bool_t 459 xdr_bool(XDR *xdrs, bool_t *bp) 460 { 461 long lb; 462 463 switch (xdrs->x_op) { 464 465 case XDR_ENCODE: 466 lb = *bp ? XDR_TRUE : XDR_FALSE; 467 return (XDR_PUTLONG(xdrs, &lb)); 468 469 case XDR_DECODE: 470 if (!XDR_GETLONG(xdrs, &lb)) { 471 return (FALSE); 472 } 473 *bp = (lb == XDR_FALSE) ? FALSE : TRUE; 474 return (TRUE); 475 476 case XDR_FREE: 477 return (TRUE); 478 } 479 /* NOTREACHED */ 480 return (FALSE); 481 } 482 483 /* 484 * XDR enumerations 485 */ 486 bool_t 487 xdr_enum(XDR *xdrs, enum_t *ep) 488 { 489 enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ 490 491 /* 492 * enums are treated as ints 493 */ 494 /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) { 495 return (xdr_long(xdrs, (long *)(void *)ep)); 496 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) { 497 return (xdr_int(xdrs, (int *)(void *)ep)); 498 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) { 499 return (xdr_short(xdrs, (short *)(void *)ep)); 500 } else { 501 return (FALSE); 502 } 503 } 504 505 /* 506 * XDR opaque data 507 * Allows the specification of a fixed size sequence of opaque bytes. 508 * cp points to the opaque object and cnt gives the byte length. 509 */ 510 bool_t 511 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt) 512 { 513 u_int rndup; 514 static int crud[BYTES_PER_XDR_UNIT]; 515 516 /* 517 * if no data we are done 518 */ 519 if (cnt == 0) 520 return (TRUE); 521 522 /* 523 * round byte count to full xdr units 524 */ 525 rndup = cnt % BYTES_PER_XDR_UNIT; 526 if (rndup > 0) 527 rndup = BYTES_PER_XDR_UNIT - rndup; 528 529 if (xdrs->x_op == XDR_DECODE) { 530 if (!XDR_GETBYTES(xdrs, cp, cnt)) { 531 return (FALSE); 532 } 533 if (rndup == 0) 534 return (TRUE); 535 return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup)); 536 } 537 538 if (xdrs->x_op == XDR_ENCODE) { 539 if (!XDR_PUTBYTES(xdrs, cp, cnt)) { 540 return (FALSE); 541 } 542 if (rndup == 0) 543 return (TRUE); 544 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); 545 } 546 547 if (xdrs->x_op == XDR_FREE) { 548 return (TRUE); 549 } 550 551 return (FALSE); 552 } 553 554 /* 555 * XDR counted bytes 556 * *cpp is a pointer to the bytes, *sizep is the count. 557 * If *cpp is NULL maxsize bytes are allocated 558 */ 559 bool_t 560 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) 561 { 562 char *sp = *cpp; /* sp is the actual string pointer */ 563 u_int nodesize; 564 bool_t ret, allocated = FALSE; 565 566 /* 567 * first deal with the length since xdr bytes are counted 568 */ 569 if (! xdr_u_int(xdrs, sizep)) { 570 return (FALSE); 571 } 572 nodesize = *sizep; 573 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { 574 return (FALSE); 575 } 576 577 /* 578 * now deal with the actual bytes 579 */ 580 switch (xdrs->x_op) { 581 582 case XDR_DECODE: 583 if (nodesize == 0) { 584 return (TRUE); 585 } 586 if (sp == NULL) { 587 *cpp = sp = mem_alloc(nodesize); 588 allocated = TRUE; 589 } 590 if (sp == NULL) { 591 warnx("xdr_bytes: out of memory"); 592 return (FALSE); 593 } 594 /* FALLTHROUGH */ 595 596 case XDR_ENCODE: 597 ret = xdr_opaque(xdrs, sp, nodesize); 598 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) { 599 if (allocated == TRUE) { 600 free(sp); 601 *cpp = NULL; 602 } 603 } 604 return (ret); 605 606 case XDR_FREE: 607 if (sp != NULL) { 608 mem_free(sp, nodesize); 609 *cpp = NULL; 610 } 611 return (TRUE); 612 } 613 /* NOTREACHED */ 614 return (FALSE); 615 } 616 617 /* 618 * Implemented here due to commonality of the object. 619 */ 620 bool_t 621 xdr_netobj(XDR *xdrs, struct netobj *np) 622 { 623 return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); 624 } 625 626 /* 627 * XDR a descriminated union 628 * Support routine for discriminated unions. 629 * You create an array of xdrdiscrim structures, terminated with 630 * an entry with a null procedure pointer. The routine gets 631 * the discriminant value and then searches the array of xdrdiscrims 632 * looking for that value. It calls the procedure given in the xdrdiscrim 633 * to handle the discriminant. If there is no specific routine a default 634 * routine may be called. 635 * If there is no specific or default routine an error is returned. 636 * 637 * Parameters: 638 * dscmp: enum to decide which ar to work on 639 * unp: the union itself 640 * choices: [value, xdr proc] for each arm 641 * dfault: default xdr routine 642 */ 643 bool_t 644 xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, 645 const struct xdr_discrim *choices, xdrproc_t dfault) 646 { 647 enum_t dscm; 648 649 /* 650 * we deal with the discriminator; it's an enum 651 */ 652 if (! xdr_enum(xdrs, dscmp)) { 653 return (FALSE); 654 } 655 dscm = *dscmp; 656 657 /* 658 * search choices for a value that matches the discriminator. 659 * if we find one, execute the xdr routine for that value. 660 */ 661 for (; choices->proc != NULL_xdrproc_t; choices++) { 662 if (choices->value == dscm) 663 return ((*(choices->proc))(xdrs, unp)); 664 } 665 666 /* 667 * no match - execute the default xdr routine if there is one 668 */ 669 return ((dfault == NULL_xdrproc_t) ? FALSE : 670 (*dfault)(xdrs, unp)); 671 } 672 673 674 /* 675 * Non-portable xdr primitives. 676 * Care should be taken when moving these routines to new architectures. 677 */ 678 679 680 /* 681 * XDR null terminated ASCII strings 682 * xdr_string deals with "C strings" - arrays of bytes that are 683 * terminated by a NULL character. The parameter cpp references a 684 * pointer to storage; If the pointer is null, then the necessary 685 * storage is allocated. The last parameter is the max allowed length 686 * of the string as specified by a protocol. 687 */ 688 bool_t 689 xdr_string(XDR *xdrs, char **cpp, u_int maxsize) 690 { 691 char *sp = *cpp; /* sp is the actual string pointer */ 692 u_int size; 693 u_int nodesize; 694 bool_t ret, allocated = FALSE; 695 696 /* 697 * first deal with the length since xdr strings are counted-strings 698 */ 699 switch (xdrs->x_op) { 700 case XDR_FREE: 701 if (sp == NULL) { 702 return(TRUE); /* already free */ 703 } 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, RPC_MAXDATASIZE); 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)((uint64_t)*llp >> 32) & 0xffffffff; 787 ul[1] = (u_long)((uint64_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 (((uint64_t)ul[0] << 32) | ((uint64_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, uint64_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 = (uint64_t) 828 (((uint64_t)ul[0] << 32) | ((uint64_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 = (uint64_t) 858 (((uint64_t)ul[0] << 32) | ((uint64_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, (uint64_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, (uint64_t *)ullp)); 925 } 926