xref: /dragonfly/lib/libc/xdr/xdr.c (revision 279dd846)
1 /*
2  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3  * unrestricted use provided that this legend is included on all tape
4  * media and as a part of the software program in whole or part.  Users
5  * may copy or modify Sun RPC without charge, but are not authorized
6  * to license or distribute it to anyone else except as part of a product or
7  * program developed by the user.
8  *
9  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12  *
13  * Sun RPC is provided with no support and without any obligation on the
14  * part of Sun Microsystems, Inc. to assist in its use, correction,
15  * modification or enhancement.
16  *
17  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19  * OR ANY PART THEREOF.
20  *
21  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22  * or profits or other special, indirect and consequential damages, even if
23  * Sun has been advised of the possibility of such damages.
24  *
25  * Sun Microsystems, Inc.
26  * 2550 Garcia Avenue
27  * Mountain View, California  94043
28  *
29  * @(#)xdr.c 1.35 87/08/12
30  * @(#)xdr.c	2.1 88/07/29 4.0 RPCSRC
31  * $NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $
32  * $FreeBSD: src/lib/libc/xdr/xdr.c,v 1.14 2004/10/16 06:32:43 obrien Exp $
33  */
34 
35 /*
36  * xdr.c, Generic XDR routines implementation.
37  *
38  * Copyright (C) 1986, Sun Microsystems, Inc.
39  *
40  * These are the "generic" xdr routines used to serialize and de-serialize
41  * most common data items.  See xdr.h for more info on the interface to
42  * xdr.
43  */
44 
45 #include "namespace.h"
46 #include <err.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 
51 #include <rpc/types.h>
52 #include <rpc/xdr.h>
53 #include "un-namespace.h"
54 
55 typedef quad_t          longlong_t;     /* ANSI long long type */
56 typedef u_quad_t        u_longlong_t;   /* ANSI unsigned long long type */
57 
58 /*
59  * constants specific to the xdr "protocol"
60  */
61 #define XDR_FALSE	((long) 0)
62 #define XDR_TRUE	((long) 1)
63 #define LASTUNSIGNED	((u_int) 0-1)
64 
65 /*
66  * for unit alignment
67  */
68 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
69 
70 /*
71  * Free a data structure using XDR
72  * Not a filter, but a convenient utility nonetheless
73  */
74 void
75 xdr_free(xdrproc_t proc, void *objp)
76 {
77 	XDR x;
78 
79 	x.x_op = XDR_FREE;
80 	(*proc)(&x, objp);
81 }
82 
83 /*
84  * XDR nothing
85  */
86 bool_t
87 xdr_void(void)
88 {
89 
90 	return (TRUE);
91 }
92 
93 
94 /*
95  * XDR integers
96  */
97 bool_t
98 xdr_int(XDR *xdrs, int *ip)
99 {
100 	long l;
101 
102 	switch (xdrs->x_op) {
103 
104 	case XDR_ENCODE:
105 		l = (long) *ip;
106 		return (XDR_PUTLONG(xdrs, &l));
107 
108 	case XDR_DECODE:
109 		if (!XDR_GETLONG(xdrs, &l)) {
110 			return (FALSE);
111 		}
112 		*ip = (int) l;
113 		return (TRUE);
114 
115 	case XDR_FREE:
116 		return (TRUE);
117 	}
118 	/* NOTREACHED */
119 	return (FALSE);
120 }
121 
122 /*
123  * XDR unsigned integers
124  */
125 bool_t
126 xdr_u_int(XDR *xdrs, u_int *up)
127 {
128 	u_long l;
129 
130 	switch (xdrs->x_op) {
131 
132 	case XDR_ENCODE:
133 		l = (u_long) *up;
134 		return (XDR_PUTLONG(xdrs, (long *)&l));
135 
136 	case XDR_DECODE:
137 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
138 			return (FALSE);
139 		}
140 		*up = (u_int) l;
141 		return (TRUE);
142 
143 	case XDR_FREE:
144 		return (TRUE);
145 	}
146 	/* NOTREACHED */
147 	return (FALSE);
148 }
149 
150 
151 /*
152  * XDR long integers
153  * same as xdr_u_long - open coded to save a proc call!
154  */
155 bool_t
156 xdr_long(XDR *xdrs, long *lp)
157 {
158 	switch (xdrs->x_op) {
159 	case XDR_ENCODE:
160 		return (XDR_PUTLONG(xdrs, lp));
161 	case XDR_DECODE:
162 		return (XDR_GETLONG(xdrs, lp));
163 	case XDR_FREE:
164 		return (TRUE);
165 	}
166 	/* NOTREACHED */
167 	return (FALSE);
168 }
169 
170 /*
171  * XDR unsigned long integers
172  * same as xdr_long - open coded to save a proc call!
173  */
174 bool_t
175 xdr_u_long(XDR *xdrs, u_long *ulp)
176 {
177 	switch (xdrs->x_op) {
178 	case XDR_ENCODE:
179 		return (XDR_PUTLONG(xdrs, (long *)ulp));
180 	case XDR_DECODE:
181 		return (XDR_GETLONG(xdrs, (long *)ulp));
182 	case XDR_FREE:
183 		return (TRUE);
184 	}
185 	/* NOTREACHED */
186 	return (FALSE);
187 }
188 
189 
190 /*
191  * XDR 32-bit integers
192  * same as xdr_u_int32_t - open coded to save a proc call!
193  */
194 bool_t
195 xdr_int32_t(XDR *xdrs, int32_t *int32_p)
196 {
197 	long l;
198 
199 	switch (xdrs->x_op) {
200 
201 	case XDR_ENCODE:
202 		l = (long) *int32_p;
203 		return (XDR_PUTLONG(xdrs, &l));
204 
205 	case XDR_DECODE:
206 		if (!XDR_GETLONG(xdrs, &l)) {
207 			return (FALSE);
208 		}
209 		*int32_p = (int32_t) l;
210 		return (TRUE);
211 
212 	case XDR_FREE:
213 		return (TRUE);
214 	}
215 	/* NOTREACHED */
216 	return (FALSE);
217 }
218 
219 /*
220  * XDR unsigned 32-bit integers
221  * same as xdr_int32_t - open coded to save a proc call!
222  */
223 bool_t
224 xdr_u_int32_t(XDR *xdrs, u_int32_t *u_int32_p)
225 {
226 	u_long l;
227 
228 	switch (xdrs->x_op) {
229 
230 	case XDR_ENCODE:
231 		l = (u_long) *u_int32_p;
232 		return (XDR_PUTLONG(xdrs, (long *)&l));
233 
234 	case XDR_DECODE:
235 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
236 			return (FALSE);
237 		}
238 		*u_int32_p = (u_int32_t) l;
239 		return (TRUE);
240 
241 	case XDR_FREE:
242 		return (TRUE);
243 	}
244 	/* NOTREACHED */
245 	return (FALSE);
246 }
247 
248 /*
249  * XDR unsigned 32-bit integers
250  * same as xdr_int32_t - open coded to save a proc call!
251  */
252 bool_t
253 xdr_uint32_t(XDR *xdrs, uint32_t *u_int32_p)
254 {
255 	u_long l;
256 
257 	switch (xdrs->x_op) {
258 
259 	case XDR_ENCODE:
260 		l = (u_long) *u_int32_p;
261 		return (XDR_PUTLONG(xdrs, (long *)&l));
262 
263 	case XDR_DECODE:
264 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
265 			return (FALSE);
266 		}
267 		*u_int32_p = (u_int32_t) l;
268 		return (TRUE);
269 
270 	case XDR_FREE:
271 		return (TRUE);
272 	}
273 	/* NOTREACHED */
274 	return (FALSE);
275 }
276 
277 /*
278  * XDR short integers
279  */
280 bool_t
281 xdr_short(XDR *xdrs, short *sp)
282 {
283 	long l;
284 
285 	switch (xdrs->x_op) {
286 
287 	case XDR_ENCODE:
288 		l = (long) *sp;
289 		return (XDR_PUTLONG(xdrs, &l));
290 
291 	case XDR_DECODE:
292 		if (!XDR_GETLONG(xdrs, &l)) {
293 			return (FALSE);
294 		}
295 		*sp = (short) l;
296 		return (TRUE);
297 
298 	case XDR_FREE:
299 		return (TRUE);
300 	}
301 	/* NOTREACHED */
302 	return (FALSE);
303 }
304 
305 /*
306  * XDR unsigned short integers
307  */
308 bool_t
309 xdr_u_short(XDR *xdrs, u_short *usp)
310 {
311 	u_long l;
312 
313 	switch (xdrs->x_op) {
314 
315 	case XDR_ENCODE:
316 		l = (u_long) *usp;
317 		return (XDR_PUTLONG(xdrs, (long *)&l));
318 
319 	case XDR_DECODE:
320 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
321 			return (FALSE);
322 		}
323 		*usp = (u_short) l;
324 		return (TRUE);
325 
326 	case XDR_FREE:
327 		return (TRUE);
328 	}
329 	/* NOTREACHED */
330 	return (FALSE);
331 }
332 
333 
334 /*
335  * XDR 16-bit integers
336  */
337 bool_t
338 xdr_int16_t(XDR *xdrs, int16_t *int16_p)
339 {
340 	long l;
341 
342 	switch (xdrs->x_op) {
343 
344 	case XDR_ENCODE:
345 		l = (long) *int16_p;
346 		return (XDR_PUTLONG(xdrs, &l));
347 
348 	case XDR_DECODE:
349 		if (!XDR_GETLONG(xdrs, &l)) {
350 			return (FALSE);
351 		}
352 		*int16_p = (int16_t) l;
353 		return (TRUE);
354 
355 	case XDR_FREE:
356 		return (TRUE);
357 	}
358 	/* NOTREACHED */
359 	return (FALSE);
360 }
361 
362 /*
363  * XDR unsigned 16-bit integers
364  */
365 bool_t
366 xdr_u_int16_t(XDR *xdrs, u_int16_t *u_int16_p)
367 {
368 	u_long l;
369 
370 	switch (xdrs->x_op) {
371 
372 	case XDR_ENCODE:
373 		l = (u_long) *u_int16_p;
374 		return (XDR_PUTLONG(xdrs, (long *)&l));
375 
376 	case XDR_DECODE:
377 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
378 			return (FALSE);
379 		}
380 		*u_int16_p = (u_int16_t) l;
381 		return (TRUE);
382 
383 	case XDR_FREE:
384 		return (TRUE);
385 	}
386 	/* NOTREACHED */
387 	return (FALSE);
388 }
389 
390 
391 /*
392  * XDR a char
393  */
394 bool_t
395 xdr_char(XDR *xdrs, char *cp)
396 {
397 	int i;
398 
399 	i = (*cp);
400 	if (!xdr_int(xdrs, &i)) {
401 		return (FALSE);
402 	}
403 	*cp = i;
404 	return (TRUE);
405 }
406 
407 /*
408  * XDR an unsigned char
409  */
410 bool_t
411 xdr_u_char(XDR *xdrs, u_char *cp)
412 {
413 	u_int u;
414 
415 	u = (*cp);
416 	if (!xdr_u_int(xdrs, &u)) {
417 		return (FALSE);
418 	}
419 	*cp = u;
420 	return (TRUE);
421 }
422 
423 /*
424  * XDR booleans
425  */
426 bool_t
427 xdr_bool(XDR *xdrs, bool_t *bp)
428 {
429 	long lb;
430 
431 	switch (xdrs->x_op) {
432 
433 	case XDR_ENCODE:
434 		lb = *bp ? XDR_TRUE : XDR_FALSE;
435 		return (XDR_PUTLONG(xdrs, &lb));
436 
437 	case XDR_DECODE:
438 		if (!XDR_GETLONG(xdrs, &lb)) {
439 			return (FALSE);
440 		}
441 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
442 		return (TRUE);
443 
444 	case XDR_FREE:
445 		return (TRUE);
446 	}
447 	/* NOTREACHED */
448 	return (FALSE);
449 }
450 
451 /*
452  * XDR enumerations
453  */
454 bool_t
455 xdr_enum(XDR *xdrs, enum_t *ep)
456 {
457 	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
458 
459 	/*
460 	 * enums are treated as ints
461 	 */
462 	/* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
463 		return (xdr_long(xdrs, (long *)(void *)ep));
464 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
465 		return (xdr_int(xdrs, (int *)(void *)ep));
466 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
467 		return (xdr_short(xdrs, (short *)(void *)ep));
468 	} else {
469 		return (FALSE);
470 	}
471 }
472 
473 /*
474  * XDR opaque data
475  * Allows the specification of a fixed size sequence of opaque bytes.
476  * cp points to the opaque object and cnt gives the byte length.
477  */
478 bool_t
479 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
480 {
481 	u_int rndup;
482 	static int crud[BYTES_PER_XDR_UNIT];
483 
484 	/*
485 	 * if no data we are done
486 	 */
487 	if (cnt == 0)
488 		return (TRUE);
489 
490 	/*
491 	 * round byte count to full xdr units
492 	 */
493 	rndup = cnt % BYTES_PER_XDR_UNIT;
494 	if (rndup > 0)
495 		rndup = BYTES_PER_XDR_UNIT - rndup;
496 
497 	if (xdrs->x_op == XDR_DECODE) {
498 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
499 			return (FALSE);
500 		}
501 		if (rndup == 0)
502 			return (TRUE);
503 		return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
504 	}
505 
506 	if (xdrs->x_op == XDR_ENCODE) {
507 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
508 			return (FALSE);
509 		}
510 		if (rndup == 0)
511 			return (TRUE);
512 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
513 	}
514 
515 	if (xdrs->x_op == XDR_FREE) {
516 		return (TRUE);
517 	}
518 
519 	return (FALSE);
520 }
521 
522 /*
523  * XDR counted bytes
524  * *cpp is a pointer to the bytes, *sizep is the count.
525  * If *cpp is NULL maxsize bytes are allocated
526  */
527 bool_t
528 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
529 {
530 	char *sp = *cpp;  /* sp is the actual string pointer */
531 	u_int nodesize;
532 
533 	/*
534 	 * first deal with the length since xdr bytes are counted
535 	 */
536 	if (! xdr_u_int(xdrs, sizep)) {
537 		return (FALSE);
538 	}
539 	nodesize = *sizep;
540 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
541 		return (FALSE);
542 	}
543 
544 	/*
545 	 * now deal with the actual bytes
546 	 */
547 	switch (xdrs->x_op) {
548 
549 	case XDR_DECODE:
550 		if (nodesize == 0) {
551 			return (TRUE);
552 		}
553 		if (sp == NULL) {
554 			*cpp = sp = mem_alloc(nodesize);
555 		}
556 		if (sp == NULL) {
557 			warnx("xdr_bytes: out of memory");
558 			return (FALSE);
559 		}
560 		/* FALLTHROUGH */
561 
562 	case XDR_ENCODE:
563 		return (xdr_opaque(xdrs, sp, nodesize));
564 
565 	case XDR_FREE:
566 		if (sp != NULL) {
567 			mem_free(sp, nodesize);
568 			*cpp = NULL;
569 		}
570 		return (TRUE);
571 	}
572 	/* NOTREACHED */
573 	return (FALSE);
574 }
575 
576 /*
577  * Implemented here due to commonality of the object.
578  */
579 bool_t
580 xdr_netobj(XDR *xdrs, struct netobj *np)
581 {
582 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
583 }
584 
585 /*
586  * XDR a descriminated union
587  * Support routine for discriminated unions.
588  * You create an array of xdrdiscrim structures, terminated with
589  * an entry with a null procedure pointer.  The routine gets
590  * the discriminant value and then searches the array of xdrdiscrims
591  * looking for that value.  It calls the procedure given in the xdrdiscrim
592  * to handle the discriminant.  If there is no specific routine a default
593  * routine may be called.
594  * If there is no specific or default routine an error is returned.
595  *
596  * Parameters:
597  *     dscmp:	enum to decide which ar to work on
598  *     unp:	the union itself
599  *     choices:	[value, xdr proc] for each arm
600  *     dfault:	default xdr routine
601  */
602 bool_t
603 xdr_union(XDR *xdrs, enum_t *dscmp, char *unp,
604 	  const struct xdr_discrim *choices, xdrproc_t dfault)
605 {
606 	enum_t dscm;
607 
608 	/*
609 	 * we deal with the discriminator;  it's an enum
610 	 */
611 	if (! xdr_enum(xdrs, dscmp)) {
612 		return (FALSE);
613 	}
614 	dscm = *dscmp;
615 
616 	/*
617 	 * search choices for a value that matches the discriminator.
618 	 * if we find one, execute the xdr routine for that value.
619 	 */
620 	for (; choices->proc != NULL_xdrproc_t; choices++) {
621 		if (choices->value == dscm)
622 			return ((*(choices->proc))(xdrs, unp));
623 	}
624 
625 	/*
626 	 * no match - execute the default xdr routine if there is one
627 	 */
628 	return ((dfault == NULL_xdrproc_t) ? FALSE :
629 	    (*dfault)(xdrs, unp));
630 }
631 
632 
633 /*
634  * Non-portable xdr primitives.
635  * Care should be taken when moving these routines to new architectures.
636  */
637 
638 
639 /*
640  * XDR null terminated ASCII strings
641  * xdr_string deals with "C strings" - arrays of bytes that are
642  * terminated by a NULL character.  The parameter cpp references a
643  * pointer to storage; If the pointer is null, then the necessary
644  * storage is allocated.  The last parameter is the max allowed length
645  * of the string as specified by a protocol.
646  */
647 bool_t
648 xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
649 {
650 	char *sp = *cpp;  /* sp is the actual string pointer */
651 	u_int size;
652 	u_int nodesize;
653 
654 	/*
655 	 * first deal with the length since xdr strings are counted-strings
656 	 */
657 	switch (xdrs->x_op) {
658 	case XDR_FREE:
659 		if (sp == NULL) {
660 			return(TRUE);	/* already free */
661 		}
662 		/* FALLTHROUGH */
663 	case XDR_ENCODE:
664 		size = strlen(sp);
665 		break;
666 	case XDR_DECODE:
667 		break;
668 	}
669 	if (! xdr_u_int(xdrs, &size)) {
670 		return (FALSE);
671 	}
672 	if (size > maxsize) {
673 		return (FALSE);
674 	}
675 	nodesize = size + 1;
676 
677 	/*
678 	 * now deal with the actual bytes
679 	 */
680 	switch (xdrs->x_op) {
681 
682 	case XDR_DECODE:
683 		if (nodesize == 0) {
684 			return (TRUE);
685 		}
686 		if (sp == NULL)
687 			*cpp = sp = mem_alloc(nodesize);
688 		if (sp == NULL) {
689 			warnx("xdr_string: out of memory");
690 			return (FALSE);
691 		}
692 		sp[size] = 0;
693 		/* FALLTHROUGH */
694 
695 	case XDR_ENCODE:
696 		return (xdr_opaque(xdrs, sp, size));
697 
698 	case XDR_FREE:
699 		mem_free(sp, nodesize);
700 		*cpp = NULL;
701 		return (TRUE);
702 	}
703 	/* NOTREACHED */
704 	return (FALSE);
705 }
706 
707 /*
708  * Wrapper for xdr_string that can be called directly from
709  * routines like clnt_call
710  */
711 bool_t
712 xdr_wrapstring(XDR *xdrs, char **cpp)
713 {
714 	return xdr_string(xdrs, cpp, LASTUNSIGNED);
715 }
716 
717 /*
718  * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
719  * are in the "non-portable" section because they require that a `long long'
720  * be a 64-bit type.
721  *
722  *	--thorpej@netbsd.org, November 30, 1999
723  */
724 
725 /*
726  * XDR 64-bit integers
727  */
728 bool_t
729 xdr_int64_t(XDR *xdrs, int64_t *llp)
730 {
731 	u_long ul[2];
732 
733 	switch (xdrs->x_op) {
734 	case XDR_ENCODE:
735 		ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff;
736 		ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff;
737 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
738 			return (FALSE);
739 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
740 	case XDR_DECODE:
741 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
742 			return (FALSE);
743 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
744 			return (FALSE);
745 		*llp = (int64_t)
746 		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
747 		return (TRUE);
748 	case XDR_FREE:
749 		return (TRUE);
750 	}
751 	/* NOTREACHED */
752 	return (FALSE);
753 }
754 
755 
756 /*
757  * XDR unsigned 64-bit integers
758  */
759 bool_t
760 xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp)
761 {
762 	u_long ul[2];
763 
764 	switch (xdrs->x_op) {
765 	case XDR_ENCODE:
766 		ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
767 		ul[1] = (u_long)(*ullp) & 0xffffffff;
768 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
769 			return (FALSE);
770 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
771 	case XDR_DECODE:
772 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
773 			return (FALSE);
774 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
775 			return (FALSE);
776 		*ullp = (u_int64_t)
777 		    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
778 		return (TRUE);
779 	case XDR_FREE:
780 		return (TRUE);
781 	}
782 	/* NOTREACHED */
783 	return (FALSE);
784 }
785 
786 /*
787  * XDR unsigned 64-bit integers
788  */
789 bool_t
790 xdr_uint64_t(XDR *xdrs, uint64_t *ullp)
791 {
792 	u_long ul[2];
793 
794 	switch (xdrs->x_op) {
795 	case XDR_ENCODE:
796 		ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
797 		ul[1] = (u_long)(*ullp) & 0xffffffff;
798 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
799 			return (FALSE);
800 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
801 	case XDR_DECODE:
802 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
803 			return (FALSE);
804 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
805 			return (FALSE);
806 		*ullp = (uint64_t)
807 		    (((uint64_t)ul[0] << 32) | ((uint64_t)ul[1]));
808 		return (TRUE);
809 	case XDR_FREE:
810 		return (TRUE);
811 	}
812 	/* NOTREACHED */
813 	return (FALSE);
814 }
815 
816 
817 /*
818  * XDR hypers
819  */
820 bool_t
821 xdr_hyper(XDR *xdrs, longlong_t *llp)
822 {
823 
824 	/*
825 	 * Don't bother open-coding this; it's a fair amount of code.  Just
826 	 * call xdr_int64_t().
827 	 */
828 	return (xdr_int64_t(xdrs, (int64_t *)llp));
829 }
830 
831 
832 /*
833  * XDR unsigned hypers
834  */
835 bool_t
836 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp)
837 {
838 
839 	/*
840 	 * Don't bother open-coding this; it's a fair amount of code.  Just
841 	 * call xdr_u_int64_t().
842 	 */
843 	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
844 }
845 
846 
847 /*
848  * XDR longlong_t's
849  */
850 bool_t
851 xdr_longlong_t(XDR *xdrs, longlong_t *llp)
852 {
853 
854 	/*
855 	 * Don't bother open-coding this; it's a fair amount of code.  Just
856 	 * call xdr_int64_t().
857 	 */
858 	return (xdr_int64_t(xdrs, (int64_t *)llp));
859 }
860 
861 
862 /*
863  * XDR u_longlong_t's
864  */
865 bool_t
866 xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp)
867 {
868 
869 	/*
870 	 * Don't bother open-coding this; it's a fair amount of code.  Just
871 	 * call xdr_u_int64_t().
872 	 */
873 	return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
874 }
875