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