1 /* $NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $ */
2
3 /*-
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Copyright (c) 2010, Oracle America, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
11 *
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials
17 * provided with the distribution.
18 * * Neither the name of the "Oracle America, Inc." nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /*
37 * xdr.c, Generic XDR routines implementation.
38 *
39 * These are the "generic" xdr routines used to serialize and de-serialize
40 * most common data items. See xdr.h for more info on the interface to
41 * xdr.
42 */
43
44 #include "namespace.h"
45 #include <err.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49
50 #include <rpc/rpc.h>
51 #include <rpc/rpc_com.h>
52 #include <rpc/types.h>
53 #include <rpc/xdr.h>
54 #include "un-namespace.h"
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
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
xdr_free(xdrproc_t proc,void * objp)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
xdr_void(void)87 xdr_void(void)
88 {
89
90 return (TRUE);
91 }
92
93
94 /*
95 * XDR integers
96 */
97 bool_t
xdr_int(XDR * xdrs,int * ip)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
xdr_u_int(XDR * xdrs,u_int * up)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
xdr_long(XDR * xdrs,long * lp)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
xdr_u_long(XDR * xdrs,u_long * ulp)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
xdr_int32_t(XDR * xdrs,int32_t * int32_p)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
xdr_u_int32_t(XDR * xdrs,u_int32_t * u_int32_p)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
xdr_uint32_t(XDR * xdrs,uint32_t * u_int32_p)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
xdr_short(XDR * xdrs,short * sp)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
xdr_u_short(XDR * xdrs,u_short * usp)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
xdr_int16_t(XDR * xdrs,int16_t * int16_p)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
xdr_u_int16_t(XDR * xdrs,u_int16_t * u_int16_p)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 * XDR unsigned 16-bit integers
392 */
393 bool_t
xdr_uint16_t(XDR * xdrs,uint16_t * u_int16_p)394 xdr_uint16_t(XDR *xdrs, uint16_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 /*
420 * XDR a char
421 */
422 bool_t
xdr_char(XDR * xdrs,char * cp)423 xdr_char(XDR *xdrs, char *cp)
424 {
425 u_int i;
426
427 i = *((unsigned char *)cp);
428 if (!xdr_u_int(xdrs, &i)) {
429 return (FALSE);
430 }
431 *((unsigned char *)cp) = i;
432 return (TRUE);
433 }
434
435 /*
436 * XDR an unsigned char
437 */
438 bool_t
xdr_u_char(XDR * xdrs,u_char * cp)439 xdr_u_char(XDR *xdrs, u_char *cp)
440 {
441 u_int u;
442
443 u = (*cp);
444 if (!xdr_u_int(xdrs, &u)) {
445 return (FALSE);
446 }
447 *cp = u;
448 return (TRUE);
449 }
450
451 /*
452 * XDR booleans
453 */
454 bool_t
xdr_bool(XDR * xdrs,bool_t * bp)455 xdr_bool(XDR *xdrs, bool_t *bp)
456 {
457 long lb;
458
459 switch (xdrs->x_op) {
460
461 case XDR_ENCODE:
462 lb = *bp ? XDR_TRUE : XDR_FALSE;
463 return (XDR_PUTLONG(xdrs, &lb));
464
465 case XDR_DECODE:
466 if (!XDR_GETLONG(xdrs, &lb)) {
467 return (FALSE);
468 }
469 *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
470 return (TRUE);
471
472 case XDR_FREE:
473 return (TRUE);
474 }
475 /* NOTREACHED */
476 return (FALSE);
477 }
478
479 /*
480 * XDR enumerations
481 */
482 bool_t
xdr_enum(XDR * xdrs,enum_t * ep)483 xdr_enum(XDR *xdrs, enum_t *ep)
484 {
485 enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
486
487 /*
488 * enums are treated as ints
489 */
490 /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
491 return (xdr_long(xdrs, (long *)(void *)ep));
492 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
493 return (xdr_int(xdrs, (int *)(void *)ep));
494 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
495 return (xdr_short(xdrs, (short *)(void *)ep));
496 } else {
497 return (FALSE);
498 }
499 }
500
501 /*
502 * XDR opaque data
503 * Allows the specification of a fixed size sequence of opaque bytes.
504 * cp points to the opaque object and cnt gives the byte length.
505 */
506 bool_t
xdr_opaque(XDR * xdrs,caddr_t cp,u_int cnt)507 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
508 {
509 u_int rndup;
510 static int crud[BYTES_PER_XDR_UNIT];
511
512 /*
513 * if no data we are done
514 */
515 if (cnt == 0)
516 return (TRUE);
517
518 /*
519 * round byte count to full xdr units
520 */
521 rndup = cnt % BYTES_PER_XDR_UNIT;
522 if (rndup > 0)
523 rndup = BYTES_PER_XDR_UNIT - rndup;
524
525 if (xdrs->x_op == XDR_DECODE) {
526 if (!XDR_GETBYTES(xdrs, cp, cnt)) {
527 return (FALSE);
528 }
529 if (rndup == 0)
530 return (TRUE);
531 return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
532 }
533
534 if (xdrs->x_op == XDR_ENCODE) {
535 if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
536 return (FALSE);
537 }
538 if (rndup == 0)
539 return (TRUE);
540 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
541 }
542
543 if (xdrs->x_op == XDR_FREE) {
544 return (TRUE);
545 }
546
547 return (FALSE);
548 }
549
550 /*
551 * XDR counted bytes
552 * *cpp is a pointer to the bytes, *sizep is the count.
553 * If *cpp is NULL maxsize bytes are allocated
554 */
555 bool_t
xdr_bytes(XDR * xdrs,char ** cpp,u_int * sizep,u_int maxsize)556 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
557 {
558 char *sp = *cpp; /* sp is the actual string pointer */
559 u_int nodesize;
560 bool_t ret, allocated = FALSE;
561
562 /*
563 * first deal with the length since xdr bytes are counted
564 */
565 if (! xdr_u_int(xdrs, sizep)) {
566 return (FALSE);
567 }
568 nodesize = *sizep;
569 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
570 return (FALSE);
571 }
572
573 /*
574 * now deal with the actual bytes
575 */
576 switch (xdrs->x_op) {
577
578 case XDR_DECODE:
579 if (nodesize == 0) {
580 return (TRUE);
581 }
582 if (sp == NULL) {
583 *cpp = sp = mem_alloc(nodesize);
584 allocated = TRUE;
585 }
586 if (sp == NULL) {
587 warnx("xdr_bytes: out of memory");
588 return (FALSE);
589 }
590 /* FALLTHROUGH */
591
592 case XDR_ENCODE:
593 ret = xdr_opaque(xdrs, sp, nodesize);
594 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
595 if (allocated == TRUE) {
596 free(sp);
597 *cpp = NULL;
598 }
599 }
600 return (ret);
601
602 case XDR_FREE:
603 if (sp != NULL) {
604 mem_free(sp, nodesize);
605 *cpp = NULL;
606 }
607 return (TRUE);
608 }
609 /* NOTREACHED */
610 return (FALSE);
611 }
612
613 /*
614 * Implemented here due to commonality of the object.
615 */
616 bool_t
xdr_netobj(XDR * xdrs,struct netobj * np)617 xdr_netobj(XDR *xdrs, struct netobj *np)
618 {
619
620 return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
621 }
622
623 /*
624 * XDR a discriminated union
625 * Support routine for discriminated unions.
626 * You create an array of xdrdiscrim structures, terminated with
627 * an entry with a null procedure pointer. The routine gets
628 * the discriminant value and then searches the array of xdrdiscrims
629 * looking for that value. It calls the procedure given in the xdrdiscrim
630 * to handle the discriminant. If there is no specific routine a default
631 * routine may be called.
632 * If there is no specific or default routine an error is returned.
633 */
634 bool_t
xdr_union(XDR * xdrs,enum_t * dscmp,char * unp,const struct xdr_discrim * choices,xdrproc_t dfault)635 xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, const struct xdr_discrim *choices, xdrproc_t dfault)
636 /*
637 * XDR *xdrs;
638 * enum_t *dscmp; // enum to decide which arm to work on
639 * char *unp; // the union itself
640 * const struct xdr_discrim *choices; // [value, xdr proc] for each arm
641 * xdrproc_t dfault; // default xdr routine
642 */
643 {
644 enum_t dscm;
645
646 /*
647 * we deal with the discriminator; it's an enum
648 */
649 if (! xdr_enum(xdrs, dscmp)) {
650 return (FALSE);
651 }
652 dscm = *dscmp;
653
654 /*
655 * search choices for a value that matches the discriminator.
656 * if we find one, execute the xdr routine for that value.
657 */
658 for (; choices->proc != NULL_xdrproc_t; choices++) {
659 if (choices->value == dscm)
660 return ((*(choices->proc))(xdrs, unp));
661 }
662
663 /*
664 * no match - execute the default xdr routine if there is one
665 */
666 return ((dfault == NULL_xdrproc_t) ? FALSE :
667 (*dfault)(xdrs, unp));
668 }
669
670
671 /*
672 * Non-portable xdr primitives.
673 * Care should be taken when moving these routines to new architectures.
674 */
675
676
677 /*
678 * XDR null terminated ASCII strings
679 * xdr_string deals with "C strings" - arrays of bytes that are
680 * terminated by a NULL character. The parameter cpp references a
681 * pointer to storage; If the pointer is null, then the necessary
682 * storage is allocated. The last parameter is the max allowed length
683 * of the string as specified by a protocol.
684 */
685 bool_t
xdr_string(XDR * xdrs,char ** cpp,u_int maxsize)686 xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
687 {
688 char *sp = *cpp; /* sp is the actual string pointer */
689 u_int size;
690 u_int nodesize;
691 bool_t ret, allocated = FALSE;
692
693 /*
694 * first deal with the length since xdr strings are counted-strings
695 */
696 switch (xdrs->x_op) {
697 case XDR_FREE:
698 if (sp == NULL) {
699 return(TRUE); /* already free */
700 }
701 /* FALLTHROUGH */
702 case XDR_ENCODE:
703 size = strlen(sp);
704 break;
705 case XDR_DECODE:
706 break;
707 }
708 if (! xdr_u_int(xdrs, &size)) {
709 return (FALSE);
710 }
711 if (size > maxsize) {
712 return (FALSE);
713 }
714 nodesize = size + 1;
715
716 /*
717 * now deal with the actual bytes
718 */
719 switch (xdrs->x_op) {
720
721 case XDR_DECODE:
722 if (nodesize == 0) {
723 return (TRUE);
724 }
725 if (sp == NULL) {
726 *cpp = sp = mem_alloc(nodesize);
727 allocated = TRUE;
728 }
729 if (sp == NULL) {
730 warnx("xdr_string: out of memory");
731 return (FALSE);
732 }
733 sp[size] = 0;
734 /* FALLTHROUGH */
735
736 case XDR_ENCODE:
737 ret = xdr_opaque(xdrs, sp, size);
738 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
739 if (allocated == TRUE) {
740 free(sp);
741 *cpp = NULL;
742 }
743 }
744 return (ret);
745
746 case XDR_FREE:
747 mem_free(sp, nodesize);
748 *cpp = NULL;
749 return (TRUE);
750 }
751 /* NOTREACHED */
752 return (FALSE);
753 }
754
755 /*
756 * Wrapper for xdr_string that can be called directly from
757 * routines like clnt_call
758 */
759 bool_t
xdr_wrapstring(XDR * xdrs,char ** cpp)760 xdr_wrapstring(XDR *xdrs, char **cpp)
761 {
762 return xdr_string(xdrs, cpp, RPC_MAXDATASIZE);
763 }
764
765 /*
766 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
767 * are in the "non-portable" section because they require that a `long long'
768 * be a 64-bit type.
769 *
770 * --thorpej@netbsd.org, November 30, 1999
771 */
772
773 /*
774 * XDR 64-bit integers
775 */
776 bool_t
xdr_int64_t(XDR * xdrs,int64_t * llp)777 xdr_int64_t(XDR *xdrs, int64_t *llp)
778 {
779 u_long ul[2];
780
781 switch (xdrs->x_op) {
782 case XDR_ENCODE:
783 ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff;
784 ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff;
785 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
786 return (FALSE);
787 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
788 case XDR_DECODE:
789 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
790 return (FALSE);
791 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
792 return (FALSE);
793 *llp = (int64_t)
794 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
795 return (TRUE);
796 case XDR_FREE:
797 return (TRUE);
798 }
799 /* NOTREACHED */
800 return (FALSE);
801 }
802
803
804 /*
805 * XDR unsigned 64-bit integers
806 */
807 bool_t
xdr_u_int64_t(XDR * xdrs,u_int64_t * ullp)808 xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp)
809 {
810 u_long ul[2];
811
812 switch (xdrs->x_op) {
813 case XDR_ENCODE:
814 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
815 ul[1] = (u_long)(*ullp) & 0xffffffff;
816 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
817 return (FALSE);
818 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
819 case XDR_DECODE:
820 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
821 return (FALSE);
822 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
823 return (FALSE);
824 *ullp = (u_int64_t)
825 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
826 return (TRUE);
827 case XDR_FREE:
828 return (TRUE);
829 }
830 /* NOTREACHED */
831 return (FALSE);
832 }
833
834 /*
835 * XDR unsigned 64-bit integers
836 */
837 bool_t
xdr_uint64_t(XDR * xdrs,uint64_t * ullp)838 xdr_uint64_t(XDR *xdrs, uint64_t *ullp)
839 {
840 u_long ul[2];
841
842 switch (xdrs->x_op) {
843 case XDR_ENCODE:
844 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
845 ul[1] = (u_long)(*ullp) & 0xffffffff;
846 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
847 return (FALSE);
848 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
849 case XDR_DECODE:
850 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
851 return (FALSE);
852 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
853 return (FALSE);
854 *ullp = (u_int64_t)
855 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
856 return (TRUE);
857 case XDR_FREE:
858 return (TRUE);
859 }
860 /* NOTREACHED */
861 return (FALSE);
862 }
863
864
865 /*
866 * XDR hypers
867 */
868 bool_t
xdr_hyper(XDR * xdrs,longlong_t * llp)869 xdr_hyper(XDR *xdrs, longlong_t *llp)
870 {
871
872 /*
873 * Don't bother open-coding this; it's a fair amount of code. Just
874 * call xdr_int64_t().
875 */
876 return (xdr_int64_t(xdrs, (int64_t *)llp));
877 }
878
879
880 /*
881 * XDR unsigned hypers
882 */
883 bool_t
xdr_u_hyper(XDR * xdrs,u_longlong_t * ullp)884 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp)
885 {
886
887 /*
888 * Don't bother open-coding this; it's a fair amount of code. Just
889 * call xdr_u_int64_t().
890 */
891 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
892 }
893
894
895 /*
896 * XDR longlong_t's
897 */
898 bool_t
xdr_longlong_t(XDR * xdrs,longlong_t * llp)899 xdr_longlong_t(XDR *xdrs, longlong_t *llp)
900 {
901
902 /*
903 * Don't bother open-coding this; it's a fair amount of code. Just
904 * call xdr_int64_t().
905 */
906 return (xdr_int64_t(xdrs, (int64_t *)llp));
907 }
908
909
910 /*
911 * XDR u_longlong_t's
912 */
913 bool_t
xdr_u_longlong_t(XDR * xdrs,u_longlong_t * ullp)914 xdr_u_longlong_t(XDR *xdrs, 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