xref: /freebsd/lib/libc/xdr/xdr.c (revision 39beb93c)
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  * XDR unsigned 32-bit integers
268  * same as xdr_int32_t - open coded to save a proc call!
269  */
270 bool_t
271 xdr_uint32_t(xdrs, u_int32_p)
272 	XDR *xdrs;
273 	uint32_t *u_int32_p;
274 {
275 	u_long l;
276 
277 	switch (xdrs->x_op) {
278 
279 	case XDR_ENCODE:
280 		l = (u_long) *u_int32_p;
281 		return (XDR_PUTLONG(xdrs, (long *)&l));
282 
283 	case XDR_DECODE:
284 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
285 			return (FALSE);
286 		}
287 		*u_int32_p = (u_int32_t) l;
288 		return (TRUE);
289 
290 	case XDR_FREE:
291 		return (TRUE);
292 	}
293 	/* NOTREACHED */
294 	return (FALSE);
295 }
296 
297 /*
298  * XDR short integers
299  */
300 bool_t
301 xdr_short(xdrs, sp)
302 	XDR *xdrs;
303 	short *sp;
304 {
305 	long l;
306 
307 	switch (xdrs->x_op) {
308 
309 	case XDR_ENCODE:
310 		l = (long) *sp;
311 		return (XDR_PUTLONG(xdrs, &l));
312 
313 	case XDR_DECODE:
314 		if (!XDR_GETLONG(xdrs, &l)) {
315 			return (FALSE);
316 		}
317 		*sp = (short) l;
318 		return (TRUE);
319 
320 	case XDR_FREE:
321 		return (TRUE);
322 	}
323 	/* NOTREACHED */
324 	return (FALSE);
325 }
326 
327 /*
328  * XDR unsigned short integers
329  */
330 bool_t
331 xdr_u_short(xdrs, usp)
332 	XDR *xdrs;
333 	u_short *usp;
334 {
335 	u_long l;
336 
337 	switch (xdrs->x_op) {
338 
339 	case XDR_ENCODE:
340 		l = (u_long) *usp;
341 		return (XDR_PUTLONG(xdrs, (long *)&l));
342 
343 	case XDR_DECODE:
344 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
345 			return (FALSE);
346 		}
347 		*usp = (u_short) l;
348 		return (TRUE);
349 
350 	case XDR_FREE:
351 		return (TRUE);
352 	}
353 	/* NOTREACHED */
354 	return (FALSE);
355 }
356 
357 
358 /*
359  * XDR 16-bit integers
360  */
361 bool_t
362 xdr_int16_t(xdrs, int16_p)
363 	XDR *xdrs;
364 	int16_t *int16_p;
365 {
366 	long l;
367 
368 	switch (xdrs->x_op) {
369 
370 	case XDR_ENCODE:
371 		l = (long) *int16_p;
372 		return (XDR_PUTLONG(xdrs, &l));
373 
374 	case XDR_DECODE:
375 		if (!XDR_GETLONG(xdrs, &l)) {
376 			return (FALSE);
377 		}
378 		*int16_p = (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_u_int16_t(xdrs, u_int16_p)
393 	XDR *xdrs;
394 	u_int16_t *u_int16_p;
395 {
396 	u_long l;
397 
398 	switch (xdrs->x_op) {
399 
400 	case XDR_ENCODE:
401 		l = (u_long) *u_int16_p;
402 		return (XDR_PUTLONG(xdrs, (long *)&l));
403 
404 	case XDR_DECODE:
405 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
406 			return (FALSE);
407 		}
408 		*u_int16_p = (u_int16_t) l;
409 		return (TRUE);
410 
411 	case XDR_FREE:
412 		return (TRUE);
413 	}
414 	/* NOTREACHED */
415 	return (FALSE);
416 }
417 
418 /*
419  * XDR unsigned 16-bit integers
420  */
421 bool_t
422 xdr_uint16_t(xdrs, u_int16_p)
423 	XDR *xdrs;
424 	uint16_t *u_int16_p;
425 {
426 	u_long l;
427 
428 	switch (xdrs->x_op) {
429 
430 	case XDR_ENCODE:
431 		l = (u_long) *u_int16_p;
432 		return (XDR_PUTLONG(xdrs, (long *)&l));
433 
434 	case XDR_DECODE:
435 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
436 			return (FALSE);
437 		}
438 		*u_int16_p = (u_int16_t) l;
439 		return (TRUE);
440 
441 	case XDR_FREE:
442 		return (TRUE);
443 	}
444 	/* NOTREACHED */
445 	return (FALSE);
446 }
447 
448 
449 /*
450  * XDR a char
451  */
452 bool_t
453 xdr_char(xdrs, cp)
454 	XDR *xdrs;
455 	char *cp;
456 {
457 	int i;
458 
459 	i = (*cp);
460 	if (!xdr_int(xdrs, &i)) {
461 		return (FALSE);
462 	}
463 	*cp = i;
464 	return (TRUE);
465 }
466 
467 /*
468  * XDR an unsigned char
469  */
470 bool_t
471 xdr_u_char(xdrs, cp)
472 	XDR *xdrs;
473 	u_char *cp;
474 {
475 	u_int u;
476 
477 	u = (*cp);
478 	if (!xdr_u_int(xdrs, &u)) {
479 		return (FALSE);
480 	}
481 	*cp = u;
482 	return (TRUE);
483 }
484 
485 /*
486  * XDR booleans
487  */
488 bool_t
489 xdr_bool(xdrs, bp)
490 	XDR *xdrs;
491 	bool_t *bp;
492 {
493 	long lb;
494 
495 	switch (xdrs->x_op) {
496 
497 	case XDR_ENCODE:
498 		lb = *bp ? XDR_TRUE : XDR_FALSE;
499 		return (XDR_PUTLONG(xdrs, &lb));
500 
501 	case XDR_DECODE:
502 		if (!XDR_GETLONG(xdrs, &lb)) {
503 			return (FALSE);
504 		}
505 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
506 		return (TRUE);
507 
508 	case XDR_FREE:
509 		return (TRUE);
510 	}
511 	/* NOTREACHED */
512 	return (FALSE);
513 }
514 
515 /*
516  * XDR enumerations
517  */
518 bool_t
519 xdr_enum(xdrs, ep)
520 	XDR *xdrs;
521 	enum_t *ep;
522 {
523 	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
524 
525 	/*
526 	 * enums are treated as ints
527 	 */
528 	/* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
529 		return (xdr_long(xdrs, (long *)(void *)ep));
530 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
531 		return (xdr_int(xdrs, (int *)(void *)ep));
532 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
533 		return (xdr_short(xdrs, (short *)(void *)ep));
534 	} else {
535 		return (FALSE);
536 	}
537 }
538 
539 /*
540  * XDR opaque data
541  * Allows the specification of a fixed size sequence of opaque bytes.
542  * cp points to the opaque object and cnt gives the byte length.
543  */
544 bool_t
545 xdr_opaque(xdrs, cp, cnt)
546 	XDR *xdrs;
547 	caddr_t cp;
548 	u_int cnt;
549 {
550 	u_int rndup;
551 	static int crud[BYTES_PER_XDR_UNIT];
552 
553 	/*
554 	 * if no data we are done
555 	 */
556 	if (cnt == 0)
557 		return (TRUE);
558 
559 	/*
560 	 * round byte count to full xdr units
561 	 */
562 	rndup = cnt % BYTES_PER_XDR_UNIT;
563 	if (rndup > 0)
564 		rndup = BYTES_PER_XDR_UNIT - rndup;
565 
566 	if (xdrs->x_op == XDR_DECODE) {
567 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
568 			return (FALSE);
569 		}
570 		if (rndup == 0)
571 			return (TRUE);
572 		return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
573 	}
574 
575 	if (xdrs->x_op == XDR_ENCODE) {
576 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
577 			return (FALSE);
578 		}
579 		if (rndup == 0)
580 			return (TRUE);
581 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
582 	}
583 
584 	if (xdrs->x_op == XDR_FREE) {
585 		return (TRUE);
586 	}
587 
588 	return (FALSE);
589 }
590 
591 /*
592  * XDR counted bytes
593  * *cpp is a pointer to the bytes, *sizep is the count.
594  * If *cpp is NULL maxsize bytes are allocated
595  */
596 bool_t
597 xdr_bytes(xdrs, cpp, sizep, maxsize)
598 	XDR *xdrs;
599 	char **cpp;
600 	u_int *sizep;
601 	u_int maxsize;
602 {
603 	char *sp = *cpp;  /* sp is the actual string pointer */
604 	u_int nodesize;
605 
606 	/*
607 	 * first deal with the length since xdr bytes are counted
608 	 */
609 	if (! xdr_u_int(xdrs, sizep)) {
610 		return (FALSE);
611 	}
612 	nodesize = *sizep;
613 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
614 		return (FALSE);
615 	}
616 
617 	/*
618 	 * now deal with the actual bytes
619 	 */
620 	switch (xdrs->x_op) {
621 
622 	case XDR_DECODE:
623 		if (nodesize == 0) {
624 			return (TRUE);
625 		}
626 		if (sp == NULL) {
627 			*cpp = sp = mem_alloc(nodesize);
628 		}
629 		if (sp == NULL) {
630 			warnx("xdr_bytes: out of memory");
631 			return (FALSE);
632 		}
633 		/* FALLTHROUGH */
634 
635 	case XDR_ENCODE:
636 		return (xdr_opaque(xdrs, sp, nodesize));
637 
638 	case XDR_FREE:
639 		if (sp != NULL) {
640 			mem_free(sp, nodesize);
641 			*cpp = NULL;
642 		}
643 		return (TRUE);
644 	}
645 	/* NOTREACHED */
646 	return (FALSE);
647 }
648 
649 /*
650  * Implemented here due to commonality of the object.
651  */
652 bool_t
653 xdr_netobj(xdrs, np)
654 	XDR *xdrs;
655 	struct netobj *np;
656 {
657 
658 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
659 }
660 
661 /*
662  * XDR a descriminated union
663  * Support routine for discriminated unions.
664  * You create an array of xdrdiscrim structures, terminated with
665  * an entry with a null procedure pointer.  The routine gets
666  * the discriminant value and then searches the array of xdrdiscrims
667  * looking for that value.  It calls the procedure given in the xdrdiscrim
668  * to handle the discriminant.  If there is no specific routine a default
669  * routine may be called.
670  * If there is no specific or default routine an error is returned.
671  */
672 bool_t
673 xdr_union(xdrs, dscmp, unp, choices, dfault)
674 	XDR *xdrs;
675 	enum_t *dscmp;		/* enum to decide which arm to work on */
676 	char *unp;		/* the union itself */
677 	const struct xdr_discrim *choices;	/* [value, xdr proc] for each arm */
678 	xdrproc_t dfault;	/* default xdr routine */
679 {
680 	enum_t dscm;
681 
682 	/*
683 	 * we deal with the discriminator;  it's an enum
684 	 */
685 	if (! xdr_enum(xdrs, dscmp)) {
686 		return (FALSE);
687 	}
688 	dscm = *dscmp;
689 
690 	/*
691 	 * search choices for a value that matches the discriminator.
692 	 * if we find one, execute the xdr routine for that value.
693 	 */
694 	for (; choices->proc != NULL_xdrproc_t; choices++) {
695 		if (choices->value == dscm)
696 			return ((*(choices->proc))(xdrs, unp));
697 	}
698 
699 	/*
700 	 * no match - execute the default xdr routine if there is one
701 	 */
702 	return ((dfault == NULL_xdrproc_t) ? FALSE :
703 	    (*dfault)(xdrs, unp));
704 }
705 
706 
707 /*
708  * Non-portable xdr primitives.
709  * Care should be taken when moving these routines to new architectures.
710  */
711 
712 
713 /*
714  * XDR null terminated ASCII strings
715  * xdr_string deals with "C strings" - arrays of bytes that are
716  * terminated by a NULL character.  The parameter cpp references a
717  * pointer to storage; If the pointer is null, then the necessary
718  * storage is allocated.  The last parameter is the max allowed length
719  * of the string as specified by a protocol.
720  */
721 bool_t
722 xdr_string(xdrs, cpp, maxsize)
723 	XDR *xdrs;
724 	char **cpp;
725 	u_int maxsize;
726 {
727 	char *sp = *cpp;  /* sp is the actual string pointer */
728 	u_int size;
729 	u_int nodesize;
730 
731 	/*
732 	 * first deal with the length since xdr strings are counted-strings
733 	 */
734 	switch (xdrs->x_op) {
735 	case XDR_FREE:
736 		if (sp == NULL) {
737 			return(TRUE);	/* already free */
738 		}
739 		/* FALLTHROUGH */
740 	case XDR_ENCODE:
741 		size = strlen(sp);
742 		break;
743 	case XDR_DECODE:
744 		break;
745 	}
746 	if (! xdr_u_int(xdrs, &size)) {
747 		return (FALSE);
748 	}
749 	if (size > maxsize) {
750 		return (FALSE);
751 	}
752 	nodesize = size + 1;
753 
754 	/*
755 	 * now deal with the actual bytes
756 	 */
757 	switch (xdrs->x_op) {
758 
759 	case XDR_DECODE:
760 		if (nodesize == 0) {
761 			return (TRUE);
762 		}
763 		if (sp == NULL)
764 			*cpp = sp = mem_alloc(nodesize);
765 		if (sp == NULL) {
766 			warnx("xdr_string: out of memory");
767 			return (FALSE);
768 		}
769 		sp[size] = 0;
770 		/* FALLTHROUGH */
771 
772 	case XDR_ENCODE:
773 		return (xdr_opaque(xdrs, sp, size));
774 
775 	case XDR_FREE:
776 		mem_free(sp, nodesize);
777 		*cpp = NULL;
778 		return (TRUE);
779 	}
780 	/* NOTREACHED */
781 	return (FALSE);
782 }
783 
784 /*
785  * Wrapper for xdr_string that can be called directly from
786  * routines like clnt_call
787  */
788 bool_t
789 xdr_wrapstring(xdrs, cpp)
790 	XDR *xdrs;
791 	char **cpp;
792 {
793 	return xdr_string(xdrs, cpp, LASTUNSIGNED);
794 }
795 
796 /*
797  * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
798  * are in the "non-portable" section because they require that a `long long'
799  * be a 64-bit type.
800  *
801  *	--thorpej@netbsd.org, November 30, 1999
802  */
803 
804 /*
805  * XDR 64-bit integers
806  */
807 bool_t
808 xdr_int64_t(xdrs, llp)
809 	XDR *xdrs;
810 	int64_t *llp;
811 {
812 	u_long ul[2];
813 
814 	switch (xdrs->x_op) {
815 	case XDR_ENCODE:
816 		ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff;
817 		ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff;
818 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
819 			return (FALSE);
820 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
821 	case XDR_DECODE:
822 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
823 			return (FALSE);
824 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
825 			return (FALSE);
826 		*llp = (int64_t)
827 		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
828 		return (TRUE);
829 	case XDR_FREE:
830 		return (TRUE);
831 	}
832 	/* NOTREACHED */
833 	return (FALSE);
834 }
835 
836 
837 /*
838  * XDR unsigned 64-bit integers
839  */
840 bool_t
841 xdr_u_int64_t(xdrs, ullp)
842 	XDR *xdrs;
843 	u_int64_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  * XDR unsigned 64-bit integers
871  */
872 bool_t
873 xdr_uint64_t(xdrs, ullp)
874 	XDR *xdrs;
875 	uint64_t *ullp;
876 {
877 	u_long ul[2];
878 
879 	switch (xdrs->x_op) {
880 	case XDR_ENCODE:
881 		ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
882 		ul[1] = (u_long)(*ullp) & 0xffffffff;
883 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
884 			return (FALSE);
885 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
886 	case XDR_DECODE:
887 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
888 			return (FALSE);
889 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
890 			return (FALSE);
891 		*ullp = (u_int64_t)
892 		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
893 		return (TRUE);
894 	case XDR_FREE:
895 		return (TRUE);
896 	}
897 	/* NOTREACHED */
898 	return (FALSE);
899 }
900 
901 
902 /*
903  * XDR hypers
904  */
905 bool_t
906 xdr_hyper(xdrs, llp)
907 	XDR *xdrs;
908 	longlong_t *llp;
909 {
910 
911 	/*
912 	 * Don't bother open-coding this; it's a fair amount of code.  Just
913 	 * call xdr_int64_t().
914 	 */
915 	return (xdr_int64_t(xdrs, (int64_t *)llp));
916 }
917 
918 
919 /*
920  * XDR unsigned hypers
921  */
922 bool_t
923 xdr_u_hyper(xdrs, ullp)
924 	XDR *xdrs;
925 	u_longlong_t *ullp;
926 {
927 
928 	/*
929 	 * Don't bother open-coding this; it's a fair amount of code.  Just
930 	 * call xdr_u_int64_t().
931 	 */
932 	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
933 }
934 
935 
936 /*
937  * XDR longlong_t's
938  */
939 bool_t
940 xdr_longlong_t(xdrs, llp)
941 	XDR *xdrs;
942 	longlong_t *llp;
943 {
944 
945 	/*
946 	 * Don't bother open-coding this; it's a fair amount of code.  Just
947 	 * call xdr_int64_t().
948 	 */
949 	return (xdr_int64_t(xdrs, (int64_t *)llp));
950 }
951 
952 
953 /*
954  * XDR u_longlong_t's
955  */
956 bool_t
957 xdr_u_longlong_t(xdrs, ullp)
958 	XDR *xdrs;
959 	u_longlong_t *ullp;
960 {
961 
962 	/*
963 	 * Don't bother open-coding this; it's a fair amount of code.  Just
964 	 * call xdr_u_int64_t().
965 	 */
966 	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
967 }
968