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