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