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