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