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