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