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