1 /* $NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 2010, Oracle America, Inc. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials 15 * provided with the distribution. 16 * * Neither the name of the "Oracle America, Inc." nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #if defined(LIBC_SCCS) && !defined(lint) 35 static char *sccsid2 = "@(#)xdr.c 1.35 87/08/12"; 36 static char *sccsid = "@(#)xdr.c 2.1 88/07/29 4.0 RPCSRC"; 37 #endif 38 #include <sys/cdefs.h> 39 __FBSDID("$FreeBSD$"); 40 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/types.h> 56 #include <rpc/xdr.h> 57 #include "un-namespace.h" 58 59 typedef quad_t longlong_t; /* ANSI long long type */ 60 typedef u_quad_t u_longlong_t; /* ANSI unsigned long long type */ 61 62 /* 63 * constants specific to the xdr "protocol" 64 */ 65 #define XDR_FALSE ((long) 0) 66 #define XDR_TRUE ((long) 1) 67 #define LASTUNSIGNED ((u_int) 0-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, u_int32_t *u_int32_p) 229 { 230 u_long l; 231 232 switch (xdrs->x_op) { 233 234 case XDR_ENCODE: 235 l = (u_long) *u_int32_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 *u_int32_p = (u_int32_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 *u_int32_p) 258 { 259 u_long l; 260 261 switch (xdrs->x_op) { 262 263 case XDR_ENCODE: 264 l = (u_long) *u_int32_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 *u_int32_p = (u_int32_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, u_int16_t *u_int16_p) 371 { 372 u_long l; 373 374 switch (xdrs->x_op) { 375 376 case XDR_ENCODE: 377 l = (u_long) *u_int16_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 *u_int16_p = (u_int16_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 *u_int16_p) 399 { 400 u_long l; 401 402 switch (xdrs->x_op) { 403 404 case XDR_ENCODE: 405 l = (u_long) *u_int16_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 *u_int16_p = (u_int16_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 565 /* 566 * first deal with the length since xdr bytes are counted 567 */ 568 if (! xdr_u_int(xdrs, sizep)) { 569 return (FALSE); 570 } 571 nodesize = *sizep; 572 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { 573 return (FALSE); 574 } 575 576 /* 577 * now deal with the actual bytes 578 */ 579 switch (xdrs->x_op) { 580 581 case XDR_DECODE: 582 if (nodesize == 0) { 583 return (TRUE); 584 } 585 if (sp == NULL) { 586 *cpp = sp = mem_alloc(nodesize); 587 } 588 if (sp == NULL) { 589 warnx("xdr_bytes: out of memory"); 590 return (FALSE); 591 } 592 /* FALLTHROUGH */ 593 594 case XDR_ENCODE: 595 return (xdr_opaque(xdrs, sp, nodesize)); 596 597 case XDR_FREE: 598 if (sp != NULL) { 599 mem_free(sp, nodesize); 600 *cpp = NULL; 601 } 602 return (TRUE); 603 } 604 /* NOTREACHED */ 605 return (FALSE); 606 } 607 608 /* 609 * Implemented here due to commonality of the object. 610 */ 611 bool_t 612 xdr_netobj(XDR *xdrs, struct netobj *np) 613 { 614 615 return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); 616 } 617 618 /* 619 * XDR a descriminated union 620 * Support routine for discriminated unions. 621 * You create an array of xdrdiscrim structures, terminated with 622 * an entry with a null procedure pointer. The routine gets 623 * the discriminant value and then searches the array of xdrdiscrims 624 * looking for that value. It calls the procedure given in the xdrdiscrim 625 * to handle the discriminant. If there is no specific routine a default 626 * routine may be called. 627 * If there is no specific or default routine an error is returned. 628 */ 629 bool_t 630 xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, const struct xdr_discrim *choices, xdrproc_t dfault) 631 /* 632 * XDR *xdrs; 633 * enum_t *dscmp; // enum to decide which arm to work on 634 * char *unp; // the union itself 635 * const struct xdr_discrim *choices; // [value, xdr proc] for each arm 636 * xdrproc_t dfault; // default xdr routine 637 */ 638 { 639 enum_t dscm; 640 641 /* 642 * we deal with the discriminator; it's an enum 643 */ 644 if (! xdr_enum(xdrs, dscmp)) { 645 return (FALSE); 646 } 647 dscm = *dscmp; 648 649 /* 650 * search choices for a value that matches the discriminator. 651 * if we find one, execute the xdr routine for that value. 652 */ 653 for (; choices->proc != NULL_xdrproc_t; choices++) { 654 if (choices->value == dscm) 655 return ((*(choices->proc))(xdrs, unp)); 656 } 657 658 /* 659 * no match - execute the default xdr routine if there is one 660 */ 661 return ((dfault == NULL_xdrproc_t) ? FALSE : 662 (*dfault)(xdrs, unp)); 663 } 664 665 666 /* 667 * Non-portable xdr primitives. 668 * Care should be taken when moving these routines to new architectures. 669 */ 670 671 672 /* 673 * XDR null terminated ASCII strings 674 * xdr_string deals with "C strings" - arrays of bytes that are 675 * terminated by a NULL character. The parameter cpp references a 676 * pointer to storage; If the pointer is null, then the necessary 677 * storage is allocated. The last parameter is the max allowed length 678 * of the string as specified by a protocol. 679 */ 680 bool_t 681 xdr_string(XDR *xdrs, char **cpp, u_int maxsize) 682 { 683 char *sp = *cpp; /* sp is the actual string pointer */ 684 u_int size; 685 u_int nodesize; 686 687 /* 688 * first deal with the length since xdr strings are counted-strings 689 */ 690 switch (xdrs->x_op) { 691 case XDR_FREE: 692 if (sp == NULL) { 693 return(TRUE); /* already free */ 694 } 695 /* FALLTHROUGH */ 696 case XDR_ENCODE: 697 size = strlen(sp); 698 break; 699 case XDR_DECODE: 700 break; 701 } 702 if (! xdr_u_int(xdrs, &size)) { 703 return (FALSE); 704 } 705 if (size > maxsize) { 706 return (FALSE); 707 } 708 nodesize = size + 1; 709 710 /* 711 * now deal with the actual bytes 712 */ 713 switch (xdrs->x_op) { 714 715 case XDR_DECODE: 716 if (nodesize == 0) { 717 return (TRUE); 718 } 719 if (sp == NULL) 720 *cpp = sp = mem_alloc(nodesize); 721 if (sp == NULL) { 722 warnx("xdr_string: out of memory"); 723 return (FALSE); 724 } 725 sp[size] = 0; 726 /* FALLTHROUGH */ 727 728 case XDR_ENCODE: 729 return (xdr_opaque(xdrs, sp, size)); 730 731 case XDR_FREE: 732 mem_free(sp, nodesize); 733 *cpp = NULL; 734 return (TRUE); 735 } 736 /* NOTREACHED */ 737 return (FALSE); 738 } 739 740 /* 741 * Wrapper for xdr_string that can be called directly from 742 * routines like clnt_call 743 */ 744 bool_t 745 xdr_wrapstring(XDR *xdrs, char **cpp) 746 { 747 return xdr_string(xdrs, cpp, LASTUNSIGNED); 748 } 749 750 /* 751 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t() 752 * are in the "non-portable" section because they require that a `long long' 753 * be a 64-bit type. 754 * 755 * --thorpej@netbsd.org, November 30, 1999 756 */ 757 758 /* 759 * XDR 64-bit integers 760 */ 761 bool_t 762 xdr_int64_t(XDR *xdrs, int64_t *llp) 763 { 764 u_long ul[2]; 765 766 switch (xdrs->x_op) { 767 case XDR_ENCODE: 768 ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff; 769 ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff; 770 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 771 return (FALSE); 772 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 773 case XDR_DECODE: 774 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 775 return (FALSE); 776 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 777 return (FALSE); 778 *llp = (int64_t) 779 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 780 return (TRUE); 781 case XDR_FREE: 782 return (TRUE); 783 } 784 /* NOTREACHED */ 785 return (FALSE); 786 } 787 788 789 /* 790 * XDR unsigned 64-bit integers 791 */ 792 bool_t 793 xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp) 794 { 795 u_long ul[2]; 796 797 switch (xdrs->x_op) { 798 case XDR_ENCODE: 799 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; 800 ul[1] = (u_long)(*ullp) & 0xffffffff; 801 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 802 return (FALSE); 803 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 804 case XDR_DECODE: 805 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 806 return (FALSE); 807 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 808 return (FALSE); 809 *ullp = (u_int64_t) 810 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 811 return (TRUE); 812 case XDR_FREE: 813 return (TRUE); 814 } 815 /* NOTREACHED */ 816 return (FALSE); 817 } 818 819 /* 820 * XDR unsigned 64-bit integers 821 */ 822 bool_t 823 xdr_uint64_t(XDR *xdrs, uint64_t *ullp) 824 { 825 u_long ul[2]; 826 827 switch (xdrs->x_op) { 828 case XDR_ENCODE: 829 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff; 830 ul[1] = (u_long)(*ullp) & 0xffffffff; 831 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 832 return (FALSE); 833 return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 834 case XDR_DECODE: 835 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 836 return (FALSE); 837 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 838 return (FALSE); 839 *ullp = (u_int64_t) 840 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 841 return (TRUE); 842 case XDR_FREE: 843 return (TRUE); 844 } 845 /* NOTREACHED */ 846 return (FALSE); 847 } 848 849 850 /* 851 * XDR hypers 852 */ 853 bool_t 854 xdr_hyper(XDR *xdrs, longlong_t *llp) 855 { 856 857 /* 858 * Don't bother open-coding this; it's a fair amount of code. Just 859 * call xdr_int64_t(). 860 */ 861 return (xdr_int64_t(xdrs, (int64_t *)llp)); 862 } 863 864 865 /* 866 * XDR unsigned hypers 867 */ 868 bool_t 869 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp) 870 { 871 872 /* 873 * Don't bother open-coding this; it's a fair amount of code. Just 874 * call xdr_u_int64_t(). 875 */ 876 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 877 } 878 879 880 /* 881 * XDR longlong_t's 882 */ 883 bool_t 884 xdr_longlong_t(XDR *xdrs, longlong_t *llp) 885 { 886 887 /* 888 * Don't bother open-coding this; it's a fair amount of code. Just 889 * call xdr_int64_t(). 890 */ 891 return (xdr_int64_t(xdrs, (int64_t *)llp)); 892 } 893 894 895 /* 896 * XDR u_longlong_t's 897 */ 898 bool_t 899 xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp) 900 { 901 902 /* 903 * Don't bother open-coding this; it's a fair amount of code. Just 904 * call xdr_u_int64_t(). 905 */ 906 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 907 } 908