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