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