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