xdr.c revision 319615
1132451Sroberto/*	$NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $	*/
2132451Sroberto
3280849Scy/*-
4280849Scy * Copyright (c) 2010, Oracle America, Inc.
5280849Scy *
6280849Scy * Redistribution and use in source and binary forms, with or without
7280849Scy * modification, are permitted provided that the following conditions are
8280849Scy * met:
9280849Scy *
10280849Scy *     * Redistributions of source code must retain the above copyright
11280849Scy *       notice, this list of conditions and the following disclaimer.
12280849Scy *     * Redistributions in binary form must reproduce the above
13280849Scy *       copyright notice, this list of conditions and the following
14280849Scy *       disclaimer in the documentation and/or other materials
15280849Scy *       provided with the distribution.
16280849Scy *     * Neither the name of the "Oracle America, Inc." nor the names of its
17280849Scy *       contributors may be used to endorse or promote products derived
18280849Scy *       from this software without specific prior written permission.
19280849Scy *
20280849Scy *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21280849Scy *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22280849Scy *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23280849Scy *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24280849Scy *   COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25280849Scy *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26280849Scy *   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27132451Sroberto *   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28132451Sroberto *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29132451Sroberto *   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30132451Sroberto *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31132451Sroberto *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32132451Sroberto */
33132451Sroberto
34132451Sroberto#if defined(LIBC_SCCS) && !defined(lint)
35132451Srobertostatic char *sccsid2 = "@(#)xdr.c 1.35 87/08/12";
36132451Srobertostatic char *sccsid = "@(#)xdr.c	2.1 88/07/29 4.0 RPCSRC";
37132451Sroberto#endif
38132451Sroberto#include <sys/cdefs.h>
39132451Sroberto__FBSDID("$FreeBSD: stable/10/lib/libc/xdr/xdr.c 319615 2017-06-06 07:22:26Z delphij $");
40132451Sroberto
41132451Sroberto/*
42132451Sroberto * xdr.c, Generic XDR routines implementation.
43132451Sroberto *
44132451Sroberto * These are the "generic" xdr routines used to serialize and de-serialize
45132451Sroberto * most common data items.  See xdr.h for more info on the interface to
46132451Sroberto * xdr.
47132451Sroberto */
48132451Sroberto
49280849Scy#include "namespace.h"
50280849Scy#include <err.h>
51280849Scy#include <stdio.h>
52280849Scy#include <stdlib.h>
53280849Scy#include <string.h>
54280849Scy
55280849Scy#include <rpc/rpc.h>
56280849Scy#include <rpc/rpc_com.h>
57280849Scy#include <rpc/types.h>
58280849Scy#include <rpc/xdr.h>
59280849Scy#include "un-namespace.h"
60280849Scy
61280849Scytypedef quad_t          longlong_t;     /* ANSI long long type */
62280849Scytypedef u_quad_t        u_longlong_t;   /* ANSI unsigned long long type */
63280849Scy
64280849Scy/*
65280849Scy * constants specific to the xdr "protocol"
66280849Scy */
67280849Scy#define XDR_FALSE	((long) 0)
68280849Scy#define XDR_TRUE	((long) 1)
69280849Scy
70280849Scy/*
71280849Scy * for unit alignment
72280849Scy */
73280849Scystatic const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
74280849Scy
75280849Scy/*
76280849Scy * Free a data structure using XDR
77 * Not a filter, but a convenient utility nonetheless
78 */
79void
80xdr_free(proc, objp)
81	xdrproc_t proc;
82	void *objp;
83{
84	XDR x;
85
86	x.x_op = XDR_FREE;
87	(*proc)(&x, objp);
88}
89
90/*
91 * XDR nothing
92 */
93bool_t
94xdr_void(void)
95{
96
97	return (TRUE);
98}
99
100
101/*
102 * XDR integers
103 */
104bool_t
105xdr_int(xdrs, ip)
106	XDR *xdrs;
107	int *ip;
108{
109	long l;
110
111	switch (xdrs->x_op) {
112
113	case XDR_ENCODE:
114		l = (long) *ip;
115		return (XDR_PUTLONG(xdrs, &l));
116
117	case XDR_DECODE:
118		if (!XDR_GETLONG(xdrs, &l)) {
119			return (FALSE);
120		}
121		*ip = (int) l;
122		return (TRUE);
123
124	case XDR_FREE:
125		return (TRUE);
126	}
127	/* NOTREACHED */
128	return (FALSE);
129}
130
131/*
132 * XDR unsigned integers
133 */
134bool_t
135xdr_u_int(xdrs, up)
136	XDR *xdrs;
137	u_int *up;
138{
139	u_long l;
140
141	switch (xdrs->x_op) {
142
143	case XDR_ENCODE:
144		l = (u_long) *up;
145		return (XDR_PUTLONG(xdrs, (long *)&l));
146
147	case XDR_DECODE:
148		if (!XDR_GETLONG(xdrs, (long *)&l)) {
149			return (FALSE);
150		}
151		*up = (u_int) l;
152		return (TRUE);
153
154	case XDR_FREE:
155		return (TRUE);
156	}
157	/* NOTREACHED */
158	return (FALSE);
159}
160
161
162/*
163 * XDR long integers
164 * same as xdr_u_long - open coded to save a proc call!
165 */
166bool_t
167xdr_long(xdrs, lp)
168	XDR *xdrs;
169	long *lp;
170{
171	switch (xdrs->x_op) {
172	case XDR_ENCODE:
173		return (XDR_PUTLONG(xdrs, lp));
174	case XDR_DECODE:
175		return (XDR_GETLONG(xdrs, lp));
176	case XDR_FREE:
177		return (TRUE);
178	}
179	/* NOTREACHED */
180	return (FALSE);
181}
182
183/*
184 * XDR unsigned long integers
185 * same as xdr_long - open coded to save a proc call!
186 */
187bool_t
188xdr_u_long(xdrs, ulp)
189	XDR *xdrs;
190	u_long *ulp;
191{
192	switch (xdrs->x_op) {
193	case XDR_ENCODE:
194		return (XDR_PUTLONG(xdrs, (long *)ulp));
195	case XDR_DECODE:
196		return (XDR_GETLONG(xdrs, (long *)ulp));
197	case XDR_FREE:
198		return (TRUE);
199	}
200	/* NOTREACHED */
201	return (FALSE);
202}
203
204
205/*
206 * XDR 32-bit integers
207 * same as xdr_u_int32_t - open coded to save a proc call!
208 */
209bool_t
210xdr_int32_t(xdrs, int32_p)
211	XDR *xdrs;
212	int32_t *int32_p;
213{
214	long l;
215
216	switch (xdrs->x_op) {
217
218	case XDR_ENCODE:
219		l = (long) *int32_p;
220		return (XDR_PUTLONG(xdrs, &l));
221
222	case XDR_DECODE:
223		if (!XDR_GETLONG(xdrs, &l)) {
224			return (FALSE);
225		}
226		*int32_p = (int32_t) l;
227		return (TRUE);
228
229	case XDR_FREE:
230		return (TRUE);
231	}
232	/* NOTREACHED */
233	return (FALSE);
234}
235
236/*
237 * XDR unsigned 32-bit integers
238 * same as xdr_int32_t - open coded to save a proc call!
239 */
240bool_t
241xdr_u_int32_t(xdrs, u_int32_p)
242	XDR *xdrs;
243	u_int32_t *u_int32_p;
244{
245	u_long l;
246
247	switch (xdrs->x_op) {
248
249	case XDR_ENCODE:
250		l = (u_long) *u_int32_p;
251		return (XDR_PUTLONG(xdrs, (long *)&l));
252
253	case XDR_DECODE:
254		if (!XDR_GETLONG(xdrs, (long *)&l)) {
255			return (FALSE);
256		}
257		*u_int32_p = (u_int32_t) l;
258		return (TRUE);
259
260	case XDR_FREE:
261		return (TRUE);
262	}
263	/* NOTREACHED */
264	return (FALSE);
265}
266
267/*
268 * XDR unsigned 32-bit integers
269 * same as xdr_int32_t - open coded to save a proc call!
270 */
271bool_t
272xdr_uint32_t(xdrs, u_int32_p)
273	XDR *xdrs;
274	uint32_t *u_int32_p;
275{
276	u_long l;
277
278	switch (xdrs->x_op) {
279
280	case XDR_ENCODE:
281		l = (u_long) *u_int32_p;
282		return (XDR_PUTLONG(xdrs, (long *)&l));
283
284	case XDR_DECODE:
285		if (!XDR_GETLONG(xdrs, (long *)&l)) {
286			return (FALSE);
287		}
288		*u_int32_p = (u_int32_t) l;
289		return (TRUE);
290
291	case XDR_FREE:
292		return (TRUE);
293	}
294	/* NOTREACHED */
295	return (FALSE);
296}
297
298/*
299 * XDR short integers
300 */
301bool_t
302xdr_short(xdrs, sp)
303	XDR *xdrs;
304	short *sp;
305{
306	long l;
307
308	switch (xdrs->x_op) {
309
310	case XDR_ENCODE:
311		l = (long) *sp;
312		return (XDR_PUTLONG(xdrs, &l));
313
314	case XDR_DECODE:
315		if (!XDR_GETLONG(xdrs, &l)) {
316			return (FALSE);
317		}
318		*sp = (short) l;
319		return (TRUE);
320
321	case XDR_FREE:
322		return (TRUE);
323	}
324	/* NOTREACHED */
325	return (FALSE);
326}
327
328/*
329 * XDR unsigned short integers
330 */
331bool_t
332xdr_u_short(xdrs, usp)
333	XDR *xdrs;
334	u_short *usp;
335{
336	u_long l;
337
338	switch (xdrs->x_op) {
339
340	case XDR_ENCODE:
341		l = (u_long) *usp;
342		return (XDR_PUTLONG(xdrs, (long *)&l));
343
344	case XDR_DECODE:
345		if (!XDR_GETLONG(xdrs, (long *)&l)) {
346			return (FALSE);
347		}
348		*usp = (u_short) l;
349		return (TRUE);
350
351	case XDR_FREE:
352		return (TRUE);
353	}
354	/* NOTREACHED */
355	return (FALSE);
356}
357
358
359/*
360 * XDR 16-bit integers
361 */
362bool_t
363xdr_int16_t(xdrs, int16_p)
364	XDR *xdrs;
365	int16_t *int16_p;
366{
367	long l;
368
369	switch (xdrs->x_op) {
370
371	case XDR_ENCODE:
372		l = (long) *int16_p;
373		return (XDR_PUTLONG(xdrs, &l));
374
375	case XDR_DECODE:
376		if (!XDR_GETLONG(xdrs, &l)) {
377			return (FALSE);
378		}
379		*int16_p = (int16_t) l;
380		return (TRUE);
381
382	case XDR_FREE:
383		return (TRUE);
384	}
385	/* NOTREACHED */
386	return (FALSE);
387}
388
389/*
390 * XDR unsigned 16-bit integers
391 */
392bool_t
393xdr_u_int16_t(xdrs, u_int16_p)
394	XDR *xdrs;
395	u_int16_t *u_int16_p;
396{
397	u_long l;
398
399	switch (xdrs->x_op) {
400
401	case XDR_ENCODE:
402		l = (u_long) *u_int16_p;
403		return (XDR_PUTLONG(xdrs, (long *)&l));
404
405	case XDR_DECODE:
406		if (!XDR_GETLONG(xdrs, (long *)&l)) {
407			return (FALSE);
408		}
409		*u_int16_p = (u_int16_t) l;
410		return (TRUE);
411
412	case XDR_FREE:
413		return (TRUE);
414	}
415	/* NOTREACHED */
416	return (FALSE);
417}
418
419/*
420 * XDR unsigned 16-bit integers
421 */
422bool_t
423xdr_uint16_t(xdrs, u_int16_p)
424	XDR *xdrs;
425	uint16_t *u_int16_p;
426{
427	u_long l;
428
429	switch (xdrs->x_op) {
430
431	case XDR_ENCODE:
432		l = (u_long) *u_int16_p;
433		return (XDR_PUTLONG(xdrs, (long *)&l));
434
435	case XDR_DECODE:
436		if (!XDR_GETLONG(xdrs, (long *)&l)) {
437			return (FALSE);
438		}
439		*u_int16_p = (u_int16_t) l;
440		return (TRUE);
441
442	case XDR_FREE:
443		return (TRUE);
444	}
445	/* NOTREACHED */
446	return (FALSE);
447}
448
449
450/*
451 * XDR a char
452 */
453bool_t
454xdr_char(xdrs, cp)
455	XDR *xdrs;
456	char *cp;
457{
458	int i;
459
460	i = (*cp);
461	if (!xdr_int(xdrs, &i)) {
462		return (FALSE);
463	}
464	*cp = i;
465	return (TRUE);
466}
467
468/*
469 * XDR an unsigned char
470 */
471bool_t
472xdr_u_char(xdrs, cp)
473	XDR *xdrs;
474	u_char *cp;
475{
476	u_int u;
477
478	u = (*cp);
479	if (!xdr_u_int(xdrs, &u)) {
480		return (FALSE);
481	}
482	*cp = u;
483	return (TRUE);
484}
485
486/*
487 * XDR booleans
488 */
489bool_t
490xdr_bool(xdrs, bp)
491	XDR *xdrs;
492	bool_t *bp;
493{
494	long lb;
495
496	switch (xdrs->x_op) {
497
498	case XDR_ENCODE:
499		lb = *bp ? XDR_TRUE : XDR_FALSE;
500		return (XDR_PUTLONG(xdrs, &lb));
501
502	case XDR_DECODE:
503		if (!XDR_GETLONG(xdrs, &lb)) {
504			return (FALSE);
505		}
506		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
507		return (TRUE);
508
509	case XDR_FREE:
510		return (TRUE);
511	}
512	/* NOTREACHED */
513	return (FALSE);
514}
515
516/*
517 * XDR enumerations
518 */
519bool_t
520xdr_enum(xdrs, ep)
521	XDR *xdrs;
522	enum_t *ep;
523{
524	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
525
526	/*
527	 * enums are treated as ints
528	 */
529	/* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
530		return (xdr_long(xdrs, (long *)(void *)ep));
531	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
532		return (xdr_int(xdrs, (int *)(void *)ep));
533	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
534		return (xdr_short(xdrs, (short *)(void *)ep));
535	} else {
536		return (FALSE);
537	}
538}
539
540/*
541 * XDR opaque data
542 * Allows the specification of a fixed size sequence of opaque bytes.
543 * cp points to the opaque object and cnt gives the byte length.
544 */
545bool_t
546xdr_opaque(xdrs, cp, cnt)
547	XDR *xdrs;
548	caddr_t cp;
549	u_int cnt;
550{
551	u_int rndup;
552	static int crud[BYTES_PER_XDR_UNIT];
553
554	/*
555	 * if no data we are done
556	 */
557	if (cnt == 0)
558		return (TRUE);
559
560	/*
561	 * round byte count to full xdr units
562	 */
563	rndup = cnt % BYTES_PER_XDR_UNIT;
564	if (rndup > 0)
565		rndup = BYTES_PER_XDR_UNIT - rndup;
566
567	if (xdrs->x_op == XDR_DECODE) {
568		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
569			return (FALSE);
570		}
571		if (rndup == 0)
572			return (TRUE);
573		return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
574	}
575
576	if (xdrs->x_op == XDR_ENCODE) {
577		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
578			return (FALSE);
579		}
580		if (rndup == 0)
581			return (TRUE);
582		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
583	}
584
585	if (xdrs->x_op == XDR_FREE) {
586		return (TRUE);
587	}
588
589	return (FALSE);
590}
591
592/*
593 * XDR counted bytes
594 * *cpp is a pointer to the bytes, *sizep is the count.
595 * If *cpp is NULL maxsize bytes are allocated
596 */
597bool_t
598xdr_bytes(xdrs, cpp, sizep, maxsize)
599	XDR *xdrs;
600	char **cpp;
601	u_int *sizep;
602	u_int maxsize;
603{
604	char *sp = *cpp;  /* sp is the actual string pointer */
605	u_int nodesize;
606	bool_t ret, allocated = FALSE;
607
608	/*
609	 * first deal with the length since xdr bytes are counted
610	 */
611	if (! xdr_u_int(xdrs, sizep)) {
612		return (FALSE);
613	}
614	nodesize = *sizep;
615	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
616		return (FALSE);
617	}
618
619	/*
620	 * now deal with the actual bytes
621	 */
622	switch (xdrs->x_op) {
623
624	case XDR_DECODE:
625		if (nodesize == 0) {
626			return (TRUE);
627		}
628		if (sp == NULL) {
629			*cpp = sp = mem_alloc(nodesize);
630			allocated = TRUE;
631		}
632		if (sp == NULL) {
633			warnx("xdr_bytes: out of memory");
634			return (FALSE);
635		}
636		/* FALLTHROUGH */
637
638	case XDR_ENCODE:
639		ret = xdr_opaque(xdrs, sp, nodesize);
640		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
641			if (allocated == TRUE) {
642				free(sp);
643				*cpp = NULL;
644			}
645		}
646		return (ret);
647
648	case XDR_FREE:
649		if (sp != NULL) {
650			mem_free(sp, nodesize);
651			*cpp = NULL;
652		}
653		return (TRUE);
654	}
655	/* NOTREACHED */
656	return (FALSE);
657}
658
659/*
660 * Implemented here due to commonality of the object.
661 */
662bool_t
663xdr_netobj(xdrs, np)
664	XDR *xdrs;
665	struct netobj *np;
666{
667
668	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
669}
670
671/*
672 * XDR a descriminated union
673 * Support routine for discriminated unions.
674 * You create an array of xdrdiscrim structures, terminated with
675 * an entry with a null procedure pointer.  The routine gets
676 * the discriminant value and then searches the array of xdrdiscrims
677 * looking for that value.  It calls the procedure given in the xdrdiscrim
678 * to handle the discriminant.  If there is no specific routine a default
679 * routine may be called.
680 * If there is no specific or default routine an error is returned.
681 */
682bool_t
683xdr_union(xdrs, dscmp, unp, choices, dfault)
684	XDR *xdrs;
685	enum_t *dscmp;		/* enum to decide which arm to work on */
686	char *unp;		/* the union itself */
687	const struct xdr_discrim *choices;	/* [value, xdr proc] for each arm */
688	xdrproc_t dfault;	/* default xdr routine */
689{
690	enum_t dscm;
691
692	/*
693	 * we deal with the discriminator;  it's an enum
694	 */
695	if (! xdr_enum(xdrs, dscmp)) {
696		return (FALSE);
697	}
698	dscm = *dscmp;
699
700	/*
701	 * search choices for a value that matches the discriminator.
702	 * if we find one, execute the xdr routine for that value.
703	 */
704	for (; choices->proc != NULL_xdrproc_t; choices++) {
705		if (choices->value == dscm)
706			return ((*(choices->proc))(xdrs, unp));
707	}
708
709	/*
710	 * no match - execute the default xdr routine if there is one
711	 */
712	return ((dfault == NULL_xdrproc_t) ? FALSE :
713	    (*dfault)(xdrs, unp));
714}
715
716
717/*
718 * Non-portable xdr primitives.
719 * Care should be taken when moving these routines to new architectures.
720 */
721
722
723/*
724 * XDR null terminated ASCII strings
725 * xdr_string deals with "C strings" - arrays of bytes that are
726 * terminated by a NULL character.  The parameter cpp references a
727 * pointer to storage; If the pointer is null, then the necessary
728 * storage is allocated.  The last parameter is the max allowed length
729 * of the string as specified by a protocol.
730 */
731bool_t
732xdr_string(xdrs, cpp, maxsize)
733	XDR *xdrs;
734	char **cpp;
735	u_int maxsize;
736{
737	char *sp = *cpp;  /* sp is the actual string pointer */
738	u_int size;
739	u_int nodesize;
740	bool_t ret, allocated = FALSE;
741
742	/*
743	 * first deal with the length since xdr strings are counted-strings
744	 */
745	switch (xdrs->x_op) {
746	case XDR_FREE:
747		if (sp == NULL) {
748			return(TRUE);	/* already free */
749		}
750		/* FALLTHROUGH */
751	case XDR_ENCODE:
752		size = strlen(sp);
753		break;
754	case XDR_DECODE:
755		break;
756	}
757	if (! xdr_u_int(xdrs, &size)) {
758		return (FALSE);
759	}
760	if (size > maxsize) {
761		return (FALSE);
762	}
763	nodesize = size + 1;
764
765	/*
766	 * now deal with the actual bytes
767	 */
768	switch (xdrs->x_op) {
769
770	case XDR_DECODE:
771		if (nodesize == 0) {
772			return (TRUE);
773		}
774		if (sp == NULL) {
775			*cpp = sp = mem_alloc(nodesize);
776			allocated = TRUE;
777		}
778		if (sp == NULL) {
779			warnx("xdr_string: out of memory");
780			return (FALSE);
781		}
782		sp[size] = 0;
783		/* FALLTHROUGH */
784
785	case XDR_ENCODE:
786		ret = xdr_opaque(xdrs, sp, size);
787		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
788			if (allocated == TRUE) {
789				free(sp);
790				*cpp = NULL;
791			}
792		}
793		return (ret);
794
795	case XDR_FREE:
796		mem_free(sp, nodesize);
797		*cpp = NULL;
798		return (TRUE);
799	}
800	/* NOTREACHED */
801	return (FALSE);
802}
803
804/*
805 * Wrapper for xdr_string that can be called directly from
806 * routines like clnt_call
807 */
808bool_t
809xdr_wrapstring(xdrs, cpp)
810	XDR *xdrs;
811	char **cpp;
812{
813	return xdr_string(xdrs, cpp, RPC_MAXDATASIZE);
814}
815
816/*
817 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
818 * are in the "non-portable" section because they require that a `long long'
819 * be a 64-bit type.
820 *
821 *	--thorpej@netbsd.org, November 30, 1999
822 */
823
824/*
825 * XDR 64-bit integers
826 */
827bool_t
828xdr_int64_t(xdrs, llp)
829	XDR *xdrs;
830	int64_t *llp;
831{
832	u_long ul[2];
833
834	switch (xdrs->x_op) {
835	case XDR_ENCODE:
836		ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff;
837		ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff;
838		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
839			return (FALSE);
840		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
841	case XDR_DECODE:
842		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
843			return (FALSE);
844		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
845			return (FALSE);
846		*llp = (int64_t)
847		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
848		return (TRUE);
849	case XDR_FREE:
850		return (TRUE);
851	}
852	/* NOTREACHED */
853	return (FALSE);
854}
855
856
857/*
858 * XDR unsigned 64-bit integers
859 */
860bool_t
861xdr_u_int64_t(xdrs, ullp)
862	XDR *xdrs;
863	u_int64_t *ullp;
864{
865	u_long ul[2];
866
867	switch (xdrs->x_op) {
868	case XDR_ENCODE:
869		ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
870		ul[1] = (u_long)(*ullp) & 0xffffffff;
871		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
872			return (FALSE);
873		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
874	case XDR_DECODE:
875		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
876			return (FALSE);
877		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
878			return (FALSE);
879		*ullp = (u_int64_t)
880		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
881		return (TRUE);
882	case XDR_FREE:
883		return (TRUE);
884	}
885	/* NOTREACHED */
886	return (FALSE);
887}
888
889/*
890 * XDR unsigned 64-bit integers
891 */
892bool_t
893xdr_uint64_t(xdrs, ullp)
894	XDR *xdrs;
895	uint64_t *ullp;
896{
897	u_long ul[2];
898
899	switch (xdrs->x_op) {
900	case XDR_ENCODE:
901		ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
902		ul[1] = (u_long)(*ullp) & 0xffffffff;
903		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
904			return (FALSE);
905		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
906	case XDR_DECODE:
907		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
908			return (FALSE);
909		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
910			return (FALSE);
911		*ullp = (u_int64_t)
912		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
913		return (TRUE);
914	case XDR_FREE:
915		return (TRUE);
916	}
917	/* NOTREACHED */
918	return (FALSE);
919}
920
921
922/*
923 * XDR hypers
924 */
925bool_t
926xdr_hyper(xdrs, llp)
927	XDR *xdrs;
928	longlong_t *llp;
929{
930
931	/*
932	 * Don't bother open-coding this; it's a fair amount of code.  Just
933	 * call xdr_int64_t().
934	 */
935	return (xdr_int64_t(xdrs, (int64_t *)llp));
936}
937
938
939/*
940 * XDR unsigned hypers
941 */
942bool_t
943xdr_u_hyper(xdrs, ullp)
944	XDR *xdrs;
945	u_longlong_t *ullp;
946{
947
948	/*
949	 * Don't bother open-coding this; it's a fair amount of code.  Just
950	 * call xdr_u_int64_t().
951	 */
952	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
953}
954
955
956/*
957 * XDR longlong_t's
958 */
959bool_t
960xdr_longlong_t(xdrs, llp)
961	XDR *xdrs;
962	longlong_t *llp;
963{
964
965	/*
966	 * Don't bother open-coding this; it's a fair amount of code.  Just
967	 * call xdr_int64_t().
968	 */
969	return (xdr_int64_t(xdrs, (int64_t *)llp));
970}
971
972
973/*
974 * XDR u_longlong_t's
975 */
976bool_t
977xdr_u_longlong_t(xdrs, ullp)
978	XDR *xdrs;
979	u_longlong_t *ullp;
980{
981
982	/*
983	 * Don't bother open-coding this; it's a fair amount of code.  Just
984	 * call xdr_u_int64_t().
985	 */
986	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
987}
988