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