xref: /freebsd/lib/libc/xdr/xdr.c (revision 7c1b51d6dc2e165ae7333373513b080f17cf79bd)
1 /*	$NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 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 #if defined(LIBC_SCCS) && !defined(lint)
35 static char *sccsid2 = "@(#)xdr.c 1.35 87/08/12";
36 static char *sccsid = "@(#)xdr.c	2.1 88/07/29 4.0 RPCSRC";
37 #endif
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40 
41 /*
42  * xdr.c, Generic XDR routines implementation.
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/rpc.h>
56 #include <rpc/rpc_com.h>
57 #include <rpc/types.h>
58 #include <rpc/xdr.h>
59 #include "un-namespace.h"
60 
61 typedef quad_t          longlong_t;     /* ANSI long long type */
62 typedef u_quad_t        u_longlong_t;   /* ANSI unsigned long long type */
63 
64 /*
65  * constants specific to the xdr "protocol"
66  */
67 #define XDR_FALSE	((long) 0)
68 #define XDR_TRUE	((long) 1)
69 
70 /*
71  * for unit alignment
72  */
73 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
74 
75 /*
76  * Free a data structure using XDR
77  * Not a filter, but a convenient utility nonetheless
78  */
79 void
80 xdr_free(xdrproc_t proc, void *objp)
81 {
82 	XDR x;
83 
84 	x.x_op = XDR_FREE;
85 	(*proc)(&x, objp);
86 }
87 
88 /*
89  * XDR nothing
90  */
91 bool_t
92 xdr_void(void)
93 {
94 
95 	return (TRUE);
96 }
97 
98 
99 /*
100  * XDR integers
101  */
102 bool_t
103 xdr_int(XDR *xdrs, int *ip)
104 {
105 	long l;
106 
107 	switch (xdrs->x_op) {
108 
109 	case XDR_ENCODE:
110 		l = (long) *ip;
111 		return (XDR_PUTLONG(xdrs, &l));
112 
113 	case XDR_DECODE:
114 		if (!XDR_GETLONG(xdrs, &l)) {
115 			return (FALSE);
116 		}
117 		*ip = (int) l;
118 		return (TRUE);
119 
120 	case XDR_FREE:
121 		return (TRUE);
122 	}
123 	/* NOTREACHED */
124 	return (FALSE);
125 }
126 
127 /*
128  * XDR unsigned integers
129  */
130 bool_t
131 xdr_u_int(XDR *xdrs, u_int *up)
132 {
133 	u_long l;
134 
135 	switch (xdrs->x_op) {
136 
137 	case XDR_ENCODE:
138 		l = (u_long) *up;
139 		return (XDR_PUTLONG(xdrs, (long *)&l));
140 
141 	case XDR_DECODE:
142 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
143 			return (FALSE);
144 		}
145 		*up = (u_int) l;
146 		return (TRUE);
147 
148 	case XDR_FREE:
149 		return (TRUE);
150 	}
151 	/* NOTREACHED */
152 	return (FALSE);
153 }
154 
155 
156 /*
157  * XDR long integers
158  * same as xdr_u_long - open coded to save a proc call!
159  */
160 bool_t
161 xdr_long(XDR *xdrs, long *lp)
162 {
163 	switch (xdrs->x_op) {
164 	case XDR_ENCODE:
165 		return (XDR_PUTLONG(xdrs, lp));
166 	case XDR_DECODE:
167 		return (XDR_GETLONG(xdrs, lp));
168 	case XDR_FREE:
169 		return (TRUE);
170 	}
171 	/* NOTREACHED */
172 	return (FALSE);
173 }
174 
175 /*
176  * XDR unsigned long integers
177  * same as xdr_long - open coded to save a proc call!
178  */
179 bool_t
180 xdr_u_long(XDR *xdrs, u_long *ulp)
181 {
182 	switch (xdrs->x_op) {
183 	case XDR_ENCODE:
184 		return (XDR_PUTLONG(xdrs, (long *)ulp));
185 	case XDR_DECODE:
186 		return (XDR_GETLONG(xdrs, (long *)ulp));
187 	case XDR_FREE:
188 		return (TRUE);
189 	}
190 	/* NOTREACHED */
191 	return (FALSE);
192 }
193 
194 
195 /*
196  * XDR 32-bit integers
197  * same as xdr_u_int32_t - open coded to save a proc call!
198  */
199 bool_t
200 xdr_int32_t(XDR *xdrs, int32_t *int32_p)
201 {
202 	long l;
203 
204 	switch (xdrs->x_op) {
205 
206 	case XDR_ENCODE:
207 		l = (long) *int32_p;
208 		return (XDR_PUTLONG(xdrs, &l));
209 
210 	case XDR_DECODE:
211 		if (!XDR_GETLONG(xdrs, &l)) {
212 			return (FALSE);
213 		}
214 		*int32_p = (int32_t) l;
215 		return (TRUE);
216 
217 	case XDR_FREE:
218 		return (TRUE);
219 	}
220 	/* NOTREACHED */
221 	return (FALSE);
222 }
223 
224 /*
225  * XDR unsigned 32-bit integers
226  * same as xdr_int32_t - open coded to save a proc call!
227  */
228 bool_t
229 xdr_u_int32_t(XDR *xdrs, u_int32_t *u_int32_p)
230 {
231 	u_long l;
232 
233 	switch (xdrs->x_op) {
234 
235 	case XDR_ENCODE:
236 		l = (u_long) *u_int32_p;
237 		return (XDR_PUTLONG(xdrs, (long *)&l));
238 
239 	case XDR_DECODE:
240 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
241 			return (FALSE);
242 		}
243 		*u_int32_p = (u_int32_t) l;
244 		return (TRUE);
245 
246 	case XDR_FREE:
247 		return (TRUE);
248 	}
249 	/* NOTREACHED */
250 	return (FALSE);
251 }
252 
253 /*
254  * XDR unsigned 32-bit integers
255  * same as xdr_int32_t - open coded to save a proc call!
256  */
257 bool_t
258 xdr_uint32_t(XDR *xdrs, uint32_t *u_int32_p)
259 {
260 	u_long l;
261 
262 	switch (xdrs->x_op) {
263 
264 	case XDR_ENCODE:
265 		l = (u_long) *u_int32_p;
266 		return (XDR_PUTLONG(xdrs, (long *)&l));
267 
268 	case XDR_DECODE:
269 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
270 			return (FALSE);
271 		}
272 		*u_int32_p = (u_int32_t) l;
273 		return (TRUE);
274 
275 	case XDR_FREE:
276 		return (TRUE);
277 	}
278 	/* NOTREACHED */
279 	return (FALSE);
280 }
281 
282 /*
283  * XDR short integers
284  */
285 bool_t
286 xdr_short(XDR *xdrs, short *sp)
287 {
288 	long l;
289 
290 	switch (xdrs->x_op) {
291 
292 	case XDR_ENCODE:
293 		l = (long) *sp;
294 		return (XDR_PUTLONG(xdrs, &l));
295 
296 	case XDR_DECODE:
297 		if (!XDR_GETLONG(xdrs, &l)) {
298 			return (FALSE);
299 		}
300 		*sp = (short) l;
301 		return (TRUE);
302 
303 	case XDR_FREE:
304 		return (TRUE);
305 	}
306 	/* NOTREACHED */
307 	return (FALSE);
308 }
309 
310 /*
311  * XDR unsigned short integers
312  */
313 bool_t
314 xdr_u_short(XDR *xdrs, u_short *usp)
315 {
316 	u_long l;
317 
318 	switch (xdrs->x_op) {
319 
320 	case XDR_ENCODE:
321 		l = (u_long) *usp;
322 		return (XDR_PUTLONG(xdrs, (long *)&l));
323 
324 	case XDR_DECODE:
325 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
326 			return (FALSE);
327 		}
328 		*usp = (u_short) l;
329 		return (TRUE);
330 
331 	case XDR_FREE:
332 		return (TRUE);
333 	}
334 	/* NOTREACHED */
335 	return (FALSE);
336 }
337 
338 
339 /*
340  * XDR 16-bit integers
341  */
342 bool_t
343 xdr_int16_t(XDR *xdrs, int16_t *int16_p)
344 {
345 	long l;
346 
347 	switch (xdrs->x_op) {
348 
349 	case XDR_ENCODE:
350 		l = (long) *int16_p;
351 		return (XDR_PUTLONG(xdrs, &l));
352 
353 	case XDR_DECODE:
354 		if (!XDR_GETLONG(xdrs, &l)) {
355 			return (FALSE);
356 		}
357 		*int16_p = (int16_t) l;
358 		return (TRUE);
359 
360 	case XDR_FREE:
361 		return (TRUE);
362 	}
363 	/* NOTREACHED */
364 	return (FALSE);
365 }
366 
367 /*
368  * XDR unsigned 16-bit integers
369  */
370 bool_t
371 xdr_u_int16_t(XDR *xdrs, u_int16_t *u_int16_p)
372 {
373 	u_long l;
374 
375 	switch (xdrs->x_op) {
376 
377 	case XDR_ENCODE:
378 		l = (u_long) *u_int16_p;
379 		return (XDR_PUTLONG(xdrs, (long *)&l));
380 
381 	case XDR_DECODE:
382 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
383 			return (FALSE);
384 		}
385 		*u_int16_p = (u_int16_t) l;
386 		return (TRUE);
387 
388 	case XDR_FREE:
389 		return (TRUE);
390 	}
391 	/* NOTREACHED */
392 	return (FALSE);
393 }
394 
395 /*
396  * XDR unsigned 16-bit integers
397  */
398 bool_t
399 xdr_uint16_t(XDR *xdrs, uint16_t *u_int16_p)
400 {
401 	u_long l;
402 
403 	switch (xdrs->x_op) {
404 
405 	case XDR_ENCODE:
406 		l = (u_long) *u_int16_p;
407 		return (XDR_PUTLONG(xdrs, (long *)&l));
408 
409 	case XDR_DECODE:
410 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
411 			return (FALSE);
412 		}
413 		*u_int16_p = (u_int16_t) l;
414 		return (TRUE);
415 
416 	case XDR_FREE:
417 		return (TRUE);
418 	}
419 	/* NOTREACHED */
420 	return (FALSE);
421 }
422 
423 
424 /*
425  * XDR a char
426  */
427 bool_t
428 xdr_char(XDR *xdrs, char *cp)
429 {
430 	int i;
431 
432 	i = (*cp);
433 	if (!xdr_int(xdrs, &i)) {
434 		return (FALSE);
435 	}
436 	*cp = i;
437 	return (TRUE);
438 }
439 
440 /*
441  * XDR an unsigned char
442  */
443 bool_t
444 xdr_u_char(XDR *xdrs, u_char *cp)
445 {
446 	u_int u;
447 
448 	u = (*cp);
449 	if (!xdr_u_int(xdrs, &u)) {
450 		return (FALSE);
451 	}
452 	*cp = u;
453 	return (TRUE);
454 }
455 
456 /*
457  * XDR booleans
458  */
459 bool_t
460 xdr_bool(XDR *xdrs, bool_t *bp)
461 {
462 	long lb;
463 
464 	switch (xdrs->x_op) {
465 
466 	case XDR_ENCODE:
467 		lb = *bp ? XDR_TRUE : XDR_FALSE;
468 		return (XDR_PUTLONG(xdrs, &lb));
469 
470 	case XDR_DECODE:
471 		if (!XDR_GETLONG(xdrs, &lb)) {
472 			return (FALSE);
473 		}
474 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
475 		return (TRUE);
476 
477 	case XDR_FREE:
478 		return (TRUE);
479 	}
480 	/* NOTREACHED */
481 	return (FALSE);
482 }
483 
484 /*
485  * XDR enumerations
486  */
487 bool_t
488 xdr_enum(XDR *xdrs, enum_t *ep)
489 {
490 	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
491 
492 	/*
493 	 * enums are treated as ints
494 	 */
495 	/* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
496 		return (xdr_long(xdrs, (long *)(void *)ep));
497 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
498 		return (xdr_int(xdrs, (int *)(void *)ep));
499 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
500 		return (xdr_short(xdrs, (short *)(void *)ep));
501 	} else {
502 		return (FALSE);
503 	}
504 }
505 
506 /*
507  * XDR opaque data
508  * Allows the specification of a fixed size sequence of opaque bytes.
509  * cp points to the opaque object and cnt gives the byte length.
510  */
511 bool_t
512 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
513 {
514 	u_int rndup;
515 	static int crud[BYTES_PER_XDR_UNIT];
516 
517 	/*
518 	 * if no data we are done
519 	 */
520 	if (cnt == 0)
521 		return (TRUE);
522 
523 	/*
524 	 * round byte count to full xdr units
525 	 */
526 	rndup = cnt % BYTES_PER_XDR_UNIT;
527 	if (rndup > 0)
528 		rndup = BYTES_PER_XDR_UNIT - rndup;
529 
530 	if (xdrs->x_op == XDR_DECODE) {
531 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
532 			return (FALSE);
533 		}
534 		if (rndup == 0)
535 			return (TRUE);
536 		return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
537 	}
538 
539 	if (xdrs->x_op == XDR_ENCODE) {
540 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
541 			return (FALSE);
542 		}
543 		if (rndup == 0)
544 			return (TRUE);
545 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
546 	}
547 
548 	if (xdrs->x_op == XDR_FREE) {
549 		return (TRUE);
550 	}
551 
552 	return (FALSE);
553 }
554 
555 /*
556  * XDR counted bytes
557  * *cpp is a pointer to the bytes, *sizep is the count.
558  * If *cpp is NULL maxsize bytes are allocated
559  */
560 bool_t
561 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
562 {
563 	char *sp = *cpp;  /* sp is the actual string pointer */
564 	u_int nodesize;
565 	bool_t ret, allocated = FALSE;
566 
567 	/*
568 	 * first deal with the length since xdr bytes are counted
569 	 */
570 	if (! xdr_u_int(xdrs, sizep)) {
571 		return (FALSE);
572 	}
573 	nodesize = *sizep;
574 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
575 		return (FALSE);
576 	}
577 
578 	/*
579 	 * now deal with the actual bytes
580 	 */
581 	switch (xdrs->x_op) {
582 
583 	case XDR_DECODE:
584 		if (nodesize == 0) {
585 			return (TRUE);
586 		}
587 		if (sp == NULL) {
588 			*cpp = sp = mem_alloc(nodesize);
589 			allocated = TRUE;
590 		}
591 		if (sp == NULL) {
592 			warnx("xdr_bytes: out of memory");
593 			return (FALSE);
594 		}
595 		/* FALLTHROUGH */
596 
597 	case XDR_ENCODE:
598 		ret = xdr_opaque(xdrs, sp, nodesize);
599 		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
600 			if (allocated == TRUE) {
601 				free(sp);
602 				*cpp = NULL;
603 			}
604 		}
605 		return (ret);
606 
607 	case XDR_FREE:
608 		if (sp != NULL) {
609 			mem_free(sp, nodesize);
610 			*cpp = NULL;
611 		}
612 		return (TRUE);
613 	}
614 	/* NOTREACHED */
615 	return (FALSE);
616 }
617 
618 /*
619  * Implemented here due to commonality of the object.
620  */
621 bool_t
622 xdr_netobj(XDR *xdrs, struct netobj *np)
623 {
624 
625 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
626 }
627 
628 /*
629  * XDR a descriminated union
630  * Support routine for discriminated unions.
631  * You create an array of xdrdiscrim structures, terminated with
632  * an entry with a null procedure pointer.  The routine gets
633  * the discriminant value and then searches the array of xdrdiscrims
634  * looking for that value.  It calls the procedure given in the xdrdiscrim
635  * to handle the discriminant.  If there is no specific routine a default
636  * routine may be called.
637  * If there is no specific or default routine an error is returned.
638  */
639 bool_t
640 xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, const struct xdr_discrim *choices, xdrproc_t dfault)
641 /*
642  *	XDR *xdrs;
643  *	enum_t *dscmp;		// enum to decide which arm to work on
644  *	char *unp;		// the union itself
645  *	const struct xdr_discrim *choices;	// [value, xdr proc] for each arm
646  *	xdrproc_t dfault;	// default xdr routine
647  */
648 {
649 	enum_t dscm;
650 
651 	/*
652 	 * we deal with the discriminator;  it's an enum
653 	 */
654 	if (! xdr_enum(xdrs, dscmp)) {
655 		return (FALSE);
656 	}
657 	dscm = *dscmp;
658 
659 	/*
660 	 * search choices for a value that matches the discriminator.
661 	 * if we find one, execute the xdr routine for that value.
662 	 */
663 	for (; choices->proc != NULL_xdrproc_t; choices++) {
664 		if (choices->value == dscm)
665 			return ((*(choices->proc))(xdrs, unp));
666 	}
667 
668 	/*
669 	 * no match - execute the default xdr routine if there is one
670 	 */
671 	return ((dfault == NULL_xdrproc_t) ? FALSE :
672 	    (*dfault)(xdrs, unp));
673 }
674 
675 
676 /*
677  * Non-portable xdr primitives.
678  * Care should be taken when moving these routines to new architectures.
679  */
680 
681 
682 /*
683  * XDR null terminated ASCII strings
684  * xdr_string deals with "C strings" - arrays of bytes that are
685  * terminated by a NULL character.  The parameter cpp references a
686  * pointer to storage; If the pointer is null, then the necessary
687  * storage is allocated.  The last parameter is the max allowed length
688  * of the string as specified by a protocol.
689  */
690 bool_t
691 xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
692 {
693 	char *sp = *cpp;  /* sp is the actual string pointer */
694 	u_int size;
695 	u_int nodesize;
696 	bool_t ret, allocated = FALSE;
697 
698 	/*
699 	 * first deal with the length since xdr strings are counted-strings
700 	 */
701 	switch (xdrs->x_op) {
702 	case XDR_FREE:
703 		if (sp == NULL) {
704 			return(TRUE);	/* already free */
705 		}
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