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 /* FALLTHROUGH */ 700 case XDR_ENCODE: 701 size = strlen(sp); 702 break; 703 case XDR_DECODE: 704 break; 705 } 706 if (! xdr_u_int(xdrs, &size)) { 707 return (FALSE); 708 } 709 if (size > maxsize) { 710 return (FALSE); 711 } 712 nodesize = size + 1; 713 714 /* 715 * now deal with the actual bytes 716 */ 717 switch (xdrs->x_op) { 718 719 case XDR_DECODE: 720 if (nodesize == 0) { 721 return (TRUE); 722 } 723 if (sp == NULL) { 724 *cpp = sp = mem_alloc(nodesize); 725 allocated = TRUE; 726 } 727 if (sp == NULL) { 728 warnx("xdr_string: out of memory"); 729 return (FALSE); 730 } 731 sp[size] = 0; 732 /* FALLTHROUGH */ 733 734 case XDR_ENCODE: 735 ret = xdr_opaque(xdrs, sp, size); 736 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) { 737 if (allocated == TRUE) { 738 free(sp); 739 *cpp = NULL; 740 } 741 } 742 return (ret); 743 744 case XDR_FREE: 745 mem_free(sp, nodesize); 746 *cpp = NULL; 747 return (TRUE); 748 } 749 /* NOTREACHED */ 750 return (FALSE); 751 } 752 753 /* 754 * Wrapper for xdr_string that can be called directly from 755 * routines like clnt_call 756 */ 757 bool_t 758 xdr_wrapstring(XDR *xdrs, char **cpp) 759 { 760 return xdr_string(xdrs, cpp, RPC_MAXDATASIZE); 761 } 762 763 /* 764 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t() 765 * are in the "non-portable" section because they require that a `long long' 766 * be a 64-bit type. 767 * 768 * --thorpej@netbsd.org, November 30, 1999 769 */ 770 771 /* 772 * XDR 64-bit integers 773 */ 774 bool_t 775 xdr_int64_t(XDR *xdrs, int64_t *llp) 776 { 777 u_long ul[2]; 778 779 switch (xdrs->x_op) { 780 case XDR_ENCODE: 781 ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff; 782 ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff; 783 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 784 return (FALSE); 785 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 786 case XDR_DECODE: 787 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 788 return (FALSE); 789 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 790 return (FALSE); 791 *llp = (int64_t) 792 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 793 return (TRUE); 794 case XDR_FREE: 795 return (TRUE); 796 } 797 /* NOTREACHED */ 798 return (FALSE); 799 } 800 801 802 /* 803 * XDR unsigned 64-bit integers 804 */ 805 bool_t 806 xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp) 807 { 808 u_long ul[2]; 809 810 switch (xdrs->x_op) { 811 case XDR_ENCODE: 812 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; 813 ul[1] = (u_long)(*ullp) & 0xffffffff; 814 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 815 return (FALSE); 816 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 817 case XDR_DECODE: 818 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 819 return (FALSE); 820 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 821 return (FALSE); 822 *ullp = (u_int64_t) 823 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 824 return (TRUE); 825 case XDR_FREE: 826 return (TRUE); 827 } 828 /* NOTREACHED */ 829 return (FALSE); 830 } 831 832 /* 833 * XDR unsigned 64-bit integers 834 */ 835 bool_t 836 xdr_uint64_t(XDR *xdrs, uint64_t *ullp) 837 { 838 u_long ul[2]; 839 840 switch (xdrs->x_op) { 841 case XDR_ENCODE: 842 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; 843 ul[1] = (u_long)(*ullp) & 0xffffffff; 844 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 845 return (FALSE); 846 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 847 case XDR_DECODE: 848 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 849 return (FALSE); 850 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 851 return (FALSE); 852 *ullp = (u_int64_t) 853 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 854 return (TRUE); 855 case XDR_FREE: 856 return (TRUE); 857 } 858 /* NOTREACHED */ 859 return (FALSE); 860 } 861 862 863 /* 864 * XDR hypers 865 */ 866 bool_t 867 xdr_hyper(XDR *xdrs, longlong_t *llp) 868 { 869 870 /* 871 * Don't bother open-coding this; it's a fair amount of code. Just 872 * call xdr_int64_t(). 873 */ 874 return (xdr_int64_t(xdrs, (int64_t *)llp)); 875 } 876 877 878 /* 879 * XDR unsigned hypers 880 */ 881 bool_t 882 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp) 883 { 884 885 /* 886 * Don't bother open-coding this; it's a fair amount of code. Just 887 * call xdr_u_int64_t(). 888 */ 889 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 890 } 891 892 893 /* 894 * XDR longlong_t's 895 */ 896 bool_t 897 xdr_longlong_t(XDR *xdrs, longlong_t *llp) 898 { 899 900 /* 901 * Don't bother open-coding this; it's a fair amount of code. Just 902 * call xdr_int64_t(). 903 */ 904 return (xdr_int64_t(xdrs, (int64_t *)llp)); 905 } 906 907 908 /* 909 * XDR u_longlong_t's 910 */ 911 bool_t 912 xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp) 913 { 914 915 /* 916 * Don't bother open-coding this; it's a fair amount of code. Just 917 * call xdr_u_int64_t(). 918 */ 919 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 920 } 921