xdr.c revision 273188
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)
35static char *sccsid2 = "@(#)xdr.c 1.35 87/08/12";
36static char *sccsid = "@(#)xdr.c	2.1 88/07/29 4.0 RPCSRC";
37#endif
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD: releng/10.1/lib/libc/xdr/xdr.c 273188 2014-10-16 22:00:24Z hrs $");
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/types.h>
56#include <rpc/xdr.h>
57#include "un-namespace.h"
58
59typedef quad_t          longlong_t;     /* ANSI long long type */
60typedef 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 */
72static 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 */
78void
79xdr_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 */
92bool_t
93xdr_void(void)
94{
95
96	return (TRUE);
97}
98
99
100/*
101 * XDR integers
102 */
103bool_t
104xdr_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 */
133bool_t
134xdr_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 */
165bool_t
166xdr_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 */
186bool_t
187xdr_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 */
208bool_t
209xdr_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 */
239bool_t
240xdr_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 */
270bool_t
271xdr_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 */
300bool_t
301xdr_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 */
330bool_t
331xdr_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 */
361bool_t
362xdr_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 */
391bool_t
392xdr_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 */
421bool_t
422xdr_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 */
452bool_t
453xdr_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 */
470bool_t
471xdr_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 */
488bool_t
489xdr_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 */
518bool_t
519xdr_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 */
544bool_t
545xdr_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 */
596bool_t
597xdr_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 */
652bool_t
653xdr_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 */
672bool_t
673xdr_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 */
721bool_t
722xdr_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 */
788bool_t
789xdr_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 */
807bool_t
808xdr_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 */
840bool_t
841xdr_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 */
872bool_t
873xdr_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 */
905bool_t
906xdr_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 */
922bool_t
923xdr_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 */
939bool_t
940xdr_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 */
956bool_t
957xdr_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