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