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(XDR * xdrs __unused,void * ptr __unused)87 xdr_void(XDR *xdrs __unused, void *ptr __unused)
88 {
89 return (TRUE);
90 }
91
92 /*
93 * XDR integers
94 */
95 bool_t
xdr_int(XDR * xdrs,int * ip)96 xdr_int(XDR *xdrs, int *ip)
97 {
98 long l;
99
100 switch (xdrs->x_op) {
101
102 case XDR_ENCODE:
103 l = (long) *ip;
104 return (XDR_PUTLONG(xdrs, &l));
105
106 case XDR_DECODE:
107 if (!XDR_GETLONG(xdrs, &l)) {
108 return (FALSE);
109 }
110 *ip = (int) l;
111 return (TRUE);
112
113 case XDR_FREE:
114 return (TRUE);
115 }
116 /* NOTREACHED */
117 return (FALSE);
118 }
119
120 /*
121 * XDR unsigned integers
122 */
123 bool_t
xdr_u_int(XDR * xdrs,u_int * up)124 xdr_u_int(XDR *xdrs, u_int *up)
125 {
126 u_long l;
127
128 switch (xdrs->x_op) {
129
130 case XDR_ENCODE:
131 l = (u_long) *up;
132 return (XDR_PUTLONG(xdrs, (long *)&l));
133
134 case XDR_DECODE:
135 if (!XDR_GETLONG(xdrs, (long *)&l)) {
136 return (FALSE);
137 }
138 *up = (u_int) l;
139 return (TRUE);
140
141 case XDR_FREE:
142 return (TRUE);
143 }
144 /* NOTREACHED */
145 return (FALSE);
146 }
147
148
149 /*
150 * XDR long integers
151 * same as xdr_u_long - open coded to save a proc call!
152 */
153 bool_t
xdr_long(XDR * xdrs,long * lp)154 xdr_long(XDR *xdrs, long *lp)
155 {
156 switch (xdrs->x_op) {
157 case XDR_ENCODE:
158 return (XDR_PUTLONG(xdrs, lp));
159 case XDR_DECODE:
160 return (XDR_GETLONG(xdrs, lp));
161 case XDR_FREE:
162 return (TRUE);
163 }
164 /* NOTREACHED */
165 return (FALSE);
166 }
167
168 /*
169 * XDR unsigned long integers
170 * same as xdr_long - open coded to save a proc call!
171 */
172 bool_t
xdr_u_long(XDR * xdrs,u_long * ulp)173 xdr_u_long(XDR *xdrs, u_long *ulp)
174 {
175 switch (xdrs->x_op) {
176 case XDR_ENCODE:
177 return (XDR_PUTLONG(xdrs, (long *)ulp));
178 case XDR_DECODE:
179 return (XDR_GETLONG(xdrs, (long *)ulp));
180 case XDR_FREE:
181 return (TRUE);
182 }
183 /* NOTREACHED */
184 return (FALSE);
185 }
186
187
188 /*
189 * XDR 32-bit integers
190 * same as xdr_u_int32_t - open coded to save a proc call!
191 */
192 bool_t
xdr_int32_t(XDR * xdrs,int32_t * int32_p)193 xdr_int32_t(XDR *xdrs, int32_t *int32_p)
194 {
195 long l;
196
197 switch (xdrs->x_op) {
198
199 case XDR_ENCODE:
200 l = (long) *int32_p;
201 return (XDR_PUTLONG(xdrs, &l));
202
203 case XDR_DECODE:
204 if (!XDR_GETLONG(xdrs, &l)) {
205 return (FALSE);
206 }
207 *int32_p = (int32_t) l;
208 return (TRUE);
209
210 case XDR_FREE:
211 return (TRUE);
212 }
213 /* NOTREACHED */
214 return (FALSE);
215 }
216
217 /*
218 * XDR unsigned 32-bit integers
219 * same as xdr_int32_t - open coded to save a proc call!
220 */
221 bool_t
xdr_u_int32_t(XDR * xdrs,u_int32_t * u_int32_p)222 xdr_u_int32_t(XDR *xdrs, u_int32_t *u_int32_p)
223 {
224 u_long l;
225
226 switch (xdrs->x_op) {
227
228 case XDR_ENCODE:
229 l = (u_long) *u_int32_p;
230 return (XDR_PUTLONG(xdrs, (long *)&l));
231
232 case XDR_DECODE:
233 if (!XDR_GETLONG(xdrs, (long *)&l)) {
234 return (FALSE);
235 }
236 *u_int32_p = (u_int32_t) l;
237 return (TRUE);
238
239 case XDR_FREE:
240 return (TRUE);
241 }
242 /* NOTREACHED */
243 return (FALSE);
244 }
245
246 /*
247 * XDR unsigned 32-bit integers
248 * same as xdr_int32_t - open coded to save a proc call!
249 */
250 bool_t
xdr_uint32_t(XDR * xdrs,uint32_t * u_int32_p)251 xdr_uint32_t(XDR *xdrs, uint32_t *u_int32_p)
252 {
253 u_long l;
254
255 switch (xdrs->x_op) {
256
257 case XDR_ENCODE:
258 l = (u_long) *u_int32_p;
259 return (XDR_PUTLONG(xdrs, (long *)&l));
260
261 case XDR_DECODE:
262 if (!XDR_GETLONG(xdrs, (long *)&l)) {
263 return (FALSE);
264 }
265 *u_int32_p = (u_int32_t) l;
266 return (TRUE);
267
268 case XDR_FREE:
269 return (TRUE);
270 }
271 /* NOTREACHED */
272 return (FALSE);
273 }
274
275 /*
276 * XDR short integers
277 */
278 bool_t
xdr_short(XDR * xdrs,short * sp)279 xdr_short(XDR *xdrs, short *sp)
280 {
281 long l;
282
283 switch (xdrs->x_op) {
284
285 case XDR_ENCODE:
286 l = (long) *sp;
287 return (XDR_PUTLONG(xdrs, &l));
288
289 case XDR_DECODE:
290 if (!XDR_GETLONG(xdrs, &l)) {
291 return (FALSE);
292 }
293 *sp = (short) l;
294 return (TRUE);
295
296 case XDR_FREE:
297 return (TRUE);
298 }
299 /* NOTREACHED */
300 return (FALSE);
301 }
302
303 /*
304 * XDR unsigned short integers
305 */
306 bool_t
xdr_u_short(XDR * xdrs,u_short * usp)307 xdr_u_short(XDR *xdrs, u_short *usp)
308 {
309 u_long l;
310
311 switch (xdrs->x_op) {
312
313 case XDR_ENCODE:
314 l = (u_long) *usp;
315 return (XDR_PUTLONG(xdrs, (long *)&l));
316
317 case XDR_DECODE:
318 if (!XDR_GETLONG(xdrs, (long *)&l)) {
319 return (FALSE);
320 }
321 *usp = (u_short) l;
322 return (TRUE);
323
324 case XDR_FREE:
325 return (TRUE);
326 }
327 /* NOTREACHED */
328 return (FALSE);
329 }
330
331
332 /*
333 * XDR 16-bit integers
334 */
335 bool_t
xdr_int16_t(XDR * xdrs,int16_t * int16_p)336 xdr_int16_t(XDR *xdrs, int16_t *int16_p)
337 {
338 long l;
339
340 switch (xdrs->x_op) {
341
342 case XDR_ENCODE:
343 l = (long) *int16_p;
344 return (XDR_PUTLONG(xdrs, &l));
345
346 case XDR_DECODE:
347 if (!XDR_GETLONG(xdrs, &l)) {
348 return (FALSE);
349 }
350 *int16_p = (int16_t) l;
351 return (TRUE);
352
353 case XDR_FREE:
354 return (TRUE);
355 }
356 /* NOTREACHED */
357 return (FALSE);
358 }
359
360 /*
361 * XDR unsigned 16-bit integers
362 */
363 bool_t
xdr_u_int16_t(XDR * xdrs,u_int16_t * u_int16_p)364 xdr_u_int16_t(XDR *xdrs, u_int16_t *u_int16_p)
365 {
366 u_long l;
367
368 switch (xdrs->x_op) {
369
370 case XDR_ENCODE:
371 l = (u_long) *u_int16_p;
372 return (XDR_PUTLONG(xdrs, (long *)&l));
373
374 case XDR_DECODE:
375 if (!XDR_GETLONG(xdrs, (long *)&l)) {
376 return (FALSE);
377 }
378 *u_int16_p = (u_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 */
391 bool_t
xdr_uint16_t(XDR * xdrs,uint16_t * u_int16_p)392 xdr_uint16_t(XDR *xdrs, uint16_t *u_int16_p)
393 {
394 u_long l;
395
396 switch (xdrs->x_op) {
397
398 case XDR_ENCODE:
399 l = (u_long) *u_int16_p;
400 return (XDR_PUTLONG(xdrs, (long *)&l));
401
402 case XDR_DECODE:
403 if (!XDR_GETLONG(xdrs, (long *)&l)) {
404 return (FALSE);
405 }
406 *u_int16_p = (u_int16_t) l;
407 return (TRUE);
408
409 case XDR_FREE:
410 return (TRUE);
411 }
412 /* NOTREACHED */
413 return (FALSE);
414 }
415
416
417 /*
418 * XDR a char
419 */
420 bool_t
xdr_char(XDR * xdrs,char * cp)421 xdr_char(XDR *xdrs, char *cp)
422 {
423 u_int i;
424
425 i = *((unsigned char *)cp);
426 if (!xdr_u_int(xdrs, &i)) {
427 return (FALSE);
428 }
429 *((unsigned char *)cp) = i;
430 return (TRUE);
431 }
432
433 /*
434 * XDR an unsigned char
435 */
436 bool_t
xdr_u_char(XDR * xdrs,u_char * cp)437 xdr_u_char(XDR *xdrs, u_char *cp)
438 {
439 u_int u;
440
441 u = (*cp);
442 if (!xdr_u_int(xdrs, &u)) {
443 return (FALSE);
444 }
445 *cp = u;
446 return (TRUE);
447 }
448
449 /*
450 * XDR booleans
451 */
452 bool_t
xdr_bool(XDR * xdrs,bool_t * bp)453 xdr_bool(XDR *xdrs, bool_t *bp)
454 {
455 long lb;
456
457 switch (xdrs->x_op) {
458
459 case XDR_ENCODE:
460 lb = *bp ? XDR_TRUE : XDR_FALSE;
461 return (XDR_PUTLONG(xdrs, &lb));
462
463 case XDR_DECODE:
464 if (!XDR_GETLONG(xdrs, &lb)) {
465 return (FALSE);
466 }
467 *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
468 return (TRUE);
469
470 case XDR_FREE:
471 return (TRUE);
472 }
473 /* NOTREACHED */
474 return (FALSE);
475 }
476
477 /*
478 * XDR enumerations
479 */
480 bool_t
xdr_enum(XDR * xdrs,enum_t * ep)481 xdr_enum(XDR *xdrs, enum_t *ep)
482 {
483 enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
484
485 /*
486 * enums are treated as ints
487 */
488 /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
489 return (xdr_long(xdrs, (long *)(void *)ep));
490 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
491 return (xdr_int(xdrs, (int *)(void *)ep));
492 } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
493 return (xdr_short(xdrs, (short *)(void *)ep));
494 } else {
495 return (FALSE);
496 }
497 }
498
499 /*
500 * XDR opaque data
501 * Allows the specification of a fixed size sequence of opaque bytes.
502 * cp points to the opaque object and cnt gives the byte length.
503 */
504 bool_t
xdr_opaque(XDR * xdrs,caddr_t cp,u_int cnt)505 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
506 {
507 u_int rndup;
508 static int crud[BYTES_PER_XDR_UNIT];
509
510 /*
511 * if no data we are done
512 */
513 if (cnt == 0)
514 return (TRUE);
515
516 /*
517 * round byte count to full xdr units
518 */
519 rndup = cnt % BYTES_PER_XDR_UNIT;
520 if (rndup > 0)
521 rndup = BYTES_PER_XDR_UNIT - rndup;
522
523 if (xdrs->x_op == XDR_DECODE) {
524 if (!XDR_GETBYTES(xdrs, cp, cnt)) {
525 return (FALSE);
526 }
527 if (rndup == 0)
528 return (TRUE);
529 return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
530 }
531
532 if (xdrs->x_op == XDR_ENCODE) {
533 if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
534 return (FALSE);
535 }
536 if (rndup == 0)
537 return (TRUE);
538 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
539 }
540
541 if (xdrs->x_op == XDR_FREE) {
542 return (TRUE);
543 }
544
545 return (FALSE);
546 }
547
548 /*
549 * XDR counted bytes
550 * *cpp is a pointer to the bytes, *sizep is the count.
551 * If *cpp is NULL maxsize bytes are allocated
552 */
553 bool_t
xdr_bytes(XDR * xdrs,char ** cpp,u_int * sizep,u_int maxsize)554 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
555 {
556 char *sp = *cpp; /* sp is the actual string pointer */
557 u_int nodesize;
558 bool_t ret, allocated = FALSE;
559
560 /*
561 * first deal with the length since xdr bytes are counted
562 */
563 if (! xdr_u_int(xdrs, sizep)) {
564 return (FALSE);
565 }
566 nodesize = *sizep;
567 if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
568 return (FALSE);
569 }
570
571 /*
572 * now deal with the actual bytes
573 */
574 switch (xdrs->x_op) {
575
576 case XDR_DECODE:
577 if (nodesize == 0) {
578 return (TRUE);
579 }
580 if (sp == NULL) {
581 *cpp = sp = mem_alloc(nodesize);
582 allocated = TRUE;
583 }
584 if (sp == NULL) {
585 warnx("xdr_bytes: out of memory");
586 return (FALSE);
587 }
588 /* FALLTHROUGH */
589
590 case XDR_ENCODE:
591 ret = xdr_opaque(xdrs, sp, nodesize);
592 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
593 if (allocated == TRUE) {
594 free(sp);
595 *cpp = NULL;
596 }
597 }
598 return (ret);
599
600 case XDR_FREE:
601 if (sp != NULL) {
602 mem_free(sp, nodesize);
603 *cpp = NULL;
604 }
605 return (TRUE);
606 }
607 /* NOTREACHED */
608 return (FALSE);
609 }
610
611 /*
612 * Implemented here due to commonality of the object.
613 */
614 bool_t
xdr_netobj(XDR * xdrs,struct netobj * np)615 xdr_netobj(XDR *xdrs, struct netobj *np)
616 {
617
618 return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
619 }
620
621 /*
622 * XDR a discriminated union
623 * Support routine for discriminated unions.
624 * You create an array of xdrdiscrim structures, terminated with
625 * an entry with a null procedure pointer. The routine gets
626 * the discriminant value and then searches the array of xdrdiscrims
627 * looking for that value. It calls the procedure given in the xdrdiscrim
628 * to handle the discriminant. If there is no specific routine a default
629 * routine may be called.
630 * If there is no specific or default routine an error is returned.
631 */
632 bool_t
xdr_union(XDR * xdrs,enum_t * dscmp,char * unp,const struct xdr_discrim * choices,xdrproc_t dfault)633 xdr_union(XDR *xdrs, enum_t *dscmp, char *unp, const struct xdr_discrim *choices, xdrproc_t dfault)
634 /*
635 * XDR *xdrs;
636 * enum_t *dscmp; // enum to decide which arm to work on
637 * char *unp; // the union itself
638 * const struct xdr_discrim *choices; // [value, xdr proc] for each arm
639 * xdrproc_t dfault; // default xdr routine
640 */
641 {
642 enum_t dscm;
643
644 /*
645 * we deal with the discriminator; it's an enum
646 */
647 if (! xdr_enum(xdrs, dscmp)) {
648 return (FALSE);
649 }
650 dscm = *dscmp;
651
652 /*
653 * search choices for a value that matches the discriminator.
654 * if we find one, execute the xdr routine for that value.
655 */
656 for (; choices->proc != NULL_xdrproc_t; choices++) {
657 if (choices->value == dscm)
658 return ((*(choices->proc))(xdrs, unp));
659 }
660
661 /*
662 * no match - execute the default xdr routine if there is one
663 */
664 return ((dfault == NULL_xdrproc_t) ? FALSE :
665 (*dfault)(xdrs, unp));
666 }
667
668
669 /*
670 * Non-portable xdr primitives.
671 * Care should be taken when moving these routines to new architectures.
672 */
673
674
675 /*
676 * XDR null terminated ASCII strings
677 * xdr_string deals with "C strings" - arrays of bytes that are
678 * terminated by a NULL character. The parameter cpp references a
679 * pointer to storage; If the pointer is null, then the necessary
680 * storage is allocated. The last parameter is the max allowed length
681 * of the string as specified by a protocol.
682 */
683 bool_t
xdr_string(XDR * xdrs,char ** cpp,u_int maxsize)684 xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
685 {
686 char *sp = *cpp; /* sp is the actual string pointer */
687 u_int size;
688 u_int nodesize;
689 bool_t ret, allocated = FALSE;
690
691 /*
692 * first deal with the length since xdr strings are counted-strings
693 */
694 switch (xdrs->x_op) {
695 case XDR_FREE:
696 if (sp == NULL) {
697 return(TRUE); /* already free */
698 }
699 /* FALLTHROUGH */
700 case XDR_ENCODE:
701 size = strlen(sp);
702 break;
703 case XDR_DECODE:
704 break;
705 }
706 if (! xdr_u_int(xdrs, &size)) {
707 return (FALSE);
708 }
709 if (size > maxsize) {
710 return (FALSE);
711 }
712 nodesize = size + 1;
713
714 /*
715 * now deal with the actual bytes
716 */
717 switch (xdrs->x_op) {
718
719 case XDR_DECODE:
720 if (nodesize == 0) {
721 return (TRUE);
722 }
723 if (sp == NULL) {
724 *cpp = sp = mem_alloc(nodesize);
725 allocated = TRUE;
726 }
727 if (sp == NULL) {
728 warnx("xdr_string: out of memory");
729 return (FALSE);
730 }
731 sp[size] = 0;
732 /* FALLTHROUGH */
733
734 case XDR_ENCODE:
735 ret = xdr_opaque(xdrs, sp, size);
736 if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
737 if (allocated == TRUE) {
738 free(sp);
739 *cpp = NULL;
740 }
741 }
742 return (ret);
743
744 case XDR_FREE:
745 mem_free(sp, nodesize);
746 *cpp = NULL;
747 return (TRUE);
748 }
749 /* NOTREACHED */
750 return (FALSE);
751 }
752
753 /*
754 * Wrapper for xdr_string that can be called directly from
755 * routines like clnt_call
756 */
757 bool_t
xdr_wrapstring(XDR * xdrs,char ** cpp)758 xdr_wrapstring(XDR *xdrs, char **cpp)
759 {
760 return xdr_string(xdrs, cpp, RPC_MAXDATASIZE);
761 }
762
763 /*
764 * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
765 * are in the "non-portable" section because they require that a `long long'
766 * be a 64-bit type.
767 *
768 * --thorpej@netbsd.org, November 30, 1999
769 */
770
771 /*
772 * XDR 64-bit integers
773 */
774 bool_t
xdr_int64_t(XDR * xdrs,int64_t * llp)775 xdr_int64_t(XDR *xdrs, int64_t *llp)
776 {
777 u_long ul[2];
778
779 switch (xdrs->x_op) {
780 case XDR_ENCODE:
781 ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff;
782 ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff;
783 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
784 return (FALSE);
785 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
786 case XDR_DECODE:
787 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
788 return (FALSE);
789 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
790 return (FALSE);
791 *llp = (int64_t)
792 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
793 return (TRUE);
794 case XDR_FREE:
795 return (TRUE);
796 }
797 /* NOTREACHED */
798 return (FALSE);
799 }
800
801
802 /*
803 * XDR unsigned 64-bit integers
804 */
805 bool_t
xdr_u_int64_t(XDR * xdrs,u_int64_t * ullp)806 xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp)
807 {
808 u_long ul[2];
809
810 switch (xdrs->x_op) {
811 case XDR_ENCODE:
812 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
813 ul[1] = (u_long)(*ullp) & 0xffffffff;
814 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
815 return (FALSE);
816 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
817 case XDR_DECODE:
818 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
819 return (FALSE);
820 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
821 return (FALSE);
822 *ullp = (u_int64_t)
823 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
824 return (TRUE);
825 case XDR_FREE:
826 return (TRUE);
827 }
828 /* NOTREACHED */
829 return (FALSE);
830 }
831
832 /*
833 * XDR unsigned 64-bit integers
834 */
835 bool_t
xdr_uint64_t(XDR * xdrs,uint64_t * ullp)836 xdr_uint64_t(XDR *xdrs, uint64_t *ullp)
837 {
838 u_long ul[2];
839
840 switch (xdrs->x_op) {
841 case XDR_ENCODE:
842 ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
843 ul[1] = (u_long)(*ullp) & 0xffffffff;
844 if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
845 return (FALSE);
846 return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
847 case XDR_DECODE:
848 if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
849 return (FALSE);
850 if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
851 return (FALSE);
852 *ullp = (u_int64_t)
853 (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
854 return (TRUE);
855 case XDR_FREE:
856 return (TRUE);
857 }
858 /* NOTREACHED */
859 return (FALSE);
860 }
861
862
863 /*
864 * XDR hypers
865 */
866 bool_t
xdr_hyper(XDR * xdrs,longlong_t * llp)867 xdr_hyper(XDR *xdrs, longlong_t *llp)
868 {
869
870 /*
871 * Don't bother open-coding this; it's a fair amount of code. Just
872 * call xdr_int64_t().
873 */
874 return (xdr_int64_t(xdrs, (int64_t *)llp));
875 }
876
877
878 /*
879 * XDR unsigned hypers
880 */
881 bool_t
xdr_u_hyper(XDR * xdrs,u_longlong_t * ullp)882 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp)
883 {
884
885 /*
886 * Don't bother open-coding this; it's a fair amount of code. Just
887 * call xdr_u_int64_t().
888 */
889 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
890 }
891
892
893 /*
894 * XDR longlong_t's
895 */
896 bool_t
xdr_longlong_t(XDR * xdrs,longlong_t * llp)897 xdr_longlong_t(XDR *xdrs, 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(XDR * xdrs,u_longlong_t * ullp)912 xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp)
913 {
914
915 /*
916 * Don't bother open-coding this; it's a fair amount of code. Just
917 * call xdr_u_int64_t().
918 */
919 return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp));
920 }
921