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