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