xref: /freebsd/sys/xdr/xdr.c (revision a5d1cf5e362a2e3c3ebdf6d8f2b86658a6d0b9d6)
1 /*	$NetBSD: xdr.c,v 1.22 2000/07/06 03:10:35 christos Exp $	*/
2 
3 /*
4  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5  * unrestricted use provided that this legend is included on all tape
6  * media and as a part of the software program in whole or part.  Users
7  * may copy or modify Sun RPC without charge, but are not authorized
8  * to license or distribute it to anyone else except as part of a product or
9  * program developed by the user.
10  *
11  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14  *
15  * Sun RPC is provided with no support and without any obligation on the
16  * part of Sun Microsystems, Inc. to assist in its use, correction,
17  * modification or enhancement.
18  *
19  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21  * OR ANY PART THEREOF.
22  *
23  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24  * or profits or other special, indirect and consequential damages, even if
25  * Sun has been advised of the possibility of such damages.
26  *
27  * Sun Microsystems, Inc.
28  * 2550 Garcia Avenue
29  * Mountain View, California  94043
30  */
31 
32 #include <sys/cdefs.h>
33 /*
34  * xdr.c, Generic XDR routines implementation.
35  *
36  * Copyright (C) 1986, Sun Microsystems, Inc.
37  *
38  * These are the "generic" xdr routines used to serialize and de-serialize
39  * most common data items.  See xdr.h for more info on the interface to
40  * xdr.
41  */
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
47 #include <sys/module.h>
48 
49 #include <rpc/rpc.h>
50 #include <rpc/rpc_com.h>
51 #include <rpc/types.h>
52 #include <rpc/xdr.h>
53 
54 typedef quad_t          longlong_t;     /* ANSI long long type */
55 typedef u_quad_t        u_longlong_t;   /* ANSI unsigned long long type */
56 
57 /*
58  * constants specific to the xdr "protocol"
59  */
60 #define XDR_FALSE	((long) 0)
61 #define XDR_TRUE	((long) 1)
62 
63 MALLOC_DEFINE(M_RPC, "rpc", "Remote Procedure Call");
64 
65 /*
66  * for unit alignment
67  */
68 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
69 
70 /*
71  * Free a data structure using XDR
72  * Not a filter, but a convenient utility nonetheless
73  */
74 void
xdr_free(xdrproc_t proc,void * objp)75 xdr_free(xdrproc_t proc, void *objp)
76 {
77 	XDR x;
78 
79 	x.x_op = XDR_FREE;
80 	(*proc)(&x, objp);
81 }
82 
83 /*
84  * XDR nothing
85  */
86 bool_t
xdr_void(XDR * xrds __unused,void * ptr __unused)87 xdr_void(XDR *xrds __unused, void *ptr __unused)
88 {
89 	return (TRUE);
90 }
91 
92 /*
93  * XDR integers
94  */
95 bool_t
xdr_int(XDR * xdrs,int * ip)96 xdr_int(XDR *xdrs, int *ip)
97 {
98 	long l;
99 
100 	switch (xdrs->x_op) {
101 	case XDR_ENCODE:
102 		l = (long) *ip;
103 		return (XDR_PUTLONG(xdrs, &l));
104 
105 	case XDR_DECODE:
106 		if (!XDR_GETLONG(xdrs, &l)) {
107 			return (FALSE);
108 		}
109 		*ip = (int) l;
110 		return (TRUE);
111 
112 	case XDR_FREE:
113 		return (TRUE);
114 	}
115 	/* NOTREACHED */
116 	return (FALSE);
117 }
118 
119 /*
120  * XDR unsigned integers
121  */
122 bool_t
xdr_u_int(XDR * xdrs,u_int * up)123 xdr_u_int(XDR *xdrs, u_int *up)
124 {
125 	u_long l;
126 
127 	switch (xdrs->x_op) {
128 	case XDR_ENCODE:
129 		l = (u_long) *up;
130 		return (XDR_PUTLONG(xdrs, (long *)&l));
131 
132 	case XDR_DECODE:
133 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
134 			return (FALSE);
135 		}
136 		*up = (u_int) l;
137 		return (TRUE);
138 
139 	case XDR_FREE:
140 		return (TRUE);
141 	}
142 	/* NOTREACHED */
143 	return (FALSE);
144 }
145 
146 /*
147  * XDR long integers
148  * same as xdr_u_long - open coded to save a proc call!
149  */
150 bool_t
xdr_long(XDR * xdrs,long * lp)151 xdr_long(XDR *xdrs, long *lp)
152 {
153 	switch (xdrs->x_op) {
154 	case XDR_ENCODE:
155 		return (XDR_PUTLONG(xdrs, lp));
156 	case XDR_DECODE:
157 		return (XDR_GETLONG(xdrs, lp));
158 	case XDR_FREE:
159 		return (TRUE);
160 	}
161 	/* NOTREACHED */
162 	return (FALSE);
163 }
164 
165 /*
166  * XDR unsigned long integers
167  * same as xdr_long - open coded to save a proc call!
168  */
169 bool_t
xdr_u_long(XDR * xdrs,u_long * ulp)170 xdr_u_long(XDR *xdrs, u_long *ulp)
171 {
172 	switch (xdrs->x_op) {
173 	case XDR_ENCODE:
174 		return (XDR_PUTLONG(xdrs, (long *)ulp));
175 	case XDR_DECODE:
176 		return (XDR_GETLONG(xdrs, (long *)ulp));
177 	case XDR_FREE:
178 		return (TRUE);
179 	}
180 	/* NOTREACHED */
181 	return (FALSE);
182 }
183 
184 /*
185  * XDR 32-bit integers
186  * same as xdr_uint32_t - open coded to save a proc call!
187  */
188 bool_t
xdr_int32_t(XDR * xdrs,int32_t * int32_p)189 xdr_int32_t(XDR *xdrs, int32_t *int32_p)
190 {
191 	long l;
192 
193 	switch (xdrs->x_op) {
194 	case XDR_ENCODE:
195 		l = (long) *int32_p;
196 		return (XDR_PUTLONG(xdrs, &l));
197 
198 	case XDR_DECODE:
199 		if (!XDR_GETLONG(xdrs, &l)) {
200 			return (FALSE);
201 		}
202 		*int32_p = (int32_t) l;
203 		return (TRUE);
204 
205 	case XDR_FREE:
206 		return (TRUE);
207 	}
208 	/* NOTREACHED */
209 	return (FALSE);
210 }
211 
212 /*
213  * XDR unsigned 32-bit integers
214  * same as xdr_int32_t - open coded to save a proc call!
215  */
216 bool_t
xdr_uint32_t(XDR * xdrs,uint32_t * uint32_p)217 xdr_uint32_t(XDR *xdrs, uint32_t *uint32_p)
218 {
219 	u_long l;
220 
221 	switch (xdrs->x_op) {
222 	case XDR_ENCODE:
223 		l = (u_long) *uint32_p;
224 		return (XDR_PUTLONG(xdrs, (long *)&l));
225 
226 	case XDR_DECODE:
227 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
228 			return (FALSE);
229 		}
230 		*uint32_p = (uint32_t) l;
231 		return (TRUE);
232 
233 	case XDR_FREE:
234 		return (TRUE);
235 	}
236 	/* NOTREACHED */
237 	return (FALSE);
238 }
239 
240 /*
241  * XDR short integers
242  */
243 bool_t
xdr_short(XDR * xdrs,short * sp)244 xdr_short(XDR *xdrs, short *sp)
245 {
246 	long l;
247 
248 	switch (xdrs->x_op) {
249 	case XDR_ENCODE:
250 		l = (long) *sp;
251 		return (XDR_PUTLONG(xdrs, &l));
252 
253 	case XDR_DECODE:
254 		if (!XDR_GETLONG(xdrs, &l)) {
255 			return (FALSE);
256 		}
257 		*sp = (short) l;
258 		return (TRUE);
259 
260 	case XDR_FREE:
261 		return (TRUE);
262 	}
263 	/* NOTREACHED */
264 	return (FALSE);
265 }
266 
267 /*
268  * XDR unsigned short integers
269  */
270 bool_t
xdr_u_short(XDR * xdrs,u_short * usp)271 xdr_u_short(XDR *xdrs, u_short *usp)
272 {
273 	u_long l;
274 
275 	switch (xdrs->x_op) {
276 	case XDR_ENCODE:
277 		l = (u_long) *usp;
278 		return (XDR_PUTLONG(xdrs, (long *)&l));
279 
280 	case XDR_DECODE:
281 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
282 			return (FALSE);
283 		}
284 		*usp = (u_short) l;
285 		return (TRUE);
286 
287 	case XDR_FREE:
288 		return (TRUE);
289 	}
290 	/* NOTREACHED */
291 	return (FALSE);
292 }
293 
294 /*
295  * XDR 16-bit integers
296  */
297 bool_t
xdr_int16_t(XDR * xdrs,int16_t * int16_p)298 xdr_int16_t(XDR *xdrs, int16_t *int16_p)
299 {
300 	long l;
301 
302 	switch (xdrs->x_op) {
303 	case XDR_ENCODE:
304 		l = (long) *int16_p;
305 		return (XDR_PUTLONG(xdrs, &l));
306 
307 	case XDR_DECODE:
308 		if (!XDR_GETLONG(xdrs, &l)) {
309 			return (FALSE);
310 		}
311 		*int16_p = (int16_t) l;
312 		return (TRUE);
313 
314 	case XDR_FREE:
315 		return (TRUE);
316 	}
317 	/* NOTREACHED */
318 	return (FALSE);
319 }
320 
321 /*
322  * XDR unsigned 16-bit integers
323  */
324 bool_t
xdr_uint16_t(XDR * xdrs,uint16_t * uint16_p)325 xdr_uint16_t(XDR *xdrs, uint16_t *uint16_p)
326 {
327 	u_long l;
328 
329 	switch (xdrs->x_op) {
330 	case XDR_ENCODE:
331 		l = (u_long) *uint16_p;
332 		return (XDR_PUTLONG(xdrs, (long *)&l));
333 
334 	case XDR_DECODE:
335 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
336 			return (FALSE);
337 		}
338 		*uint16_p = (uint16_t) l;
339 		return (TRUE);
340 
341 	case XDR_FREE:
342 		return (TRUE);
343 	}
344 	/* NOTREACHED */
345 	return (FALSE);
346 }
347 
348 /*
349  * XDR a char
350  */
351 bool_t
xdr_char(XDR * xdrs,char * cp)352 xdr_char(XDR *xdrs, char *cp)
353 {
354 	u_int i;
355 
356 	i = *((unsigned char *)cp);
357 	if (!xdr_u_int(xdrs, &i)) {
358 		return (FALSE);
359 	}
360 	*((unsigned char *)cp) = i;
361 	return (TRUE);
362 }
363 
364 /*
365  * XDR an unsigned char
366  */
367 bool_t
xdr_u_char(XDR * xdrs,u_char * cp)368 xdr_u_char(XDR *xdrs, u_char *cp)
369 {
370 	u_int u;
371 
372 	u = (*cp);
373 	if (!xdr_u_int(xdrs, &u)) {
374 		return (FALSE);
375 	}
376 	*cp = u;
377 	return (TRUE);
378 }
379 
380 /*
381  * XDR booleans
382  */
383 bool_t
xdr_bool(XDR * xdrs,bool_t * bp)384 xdr_bool(XDR *xdrs, bool_t *bp)
385 {
386 	long lb;
387 
388 	switch (xdrs->x_op) {
389 	case XDR_ENCODE:
390 		lb = *bp ? XDR_TRUE : XDR_FALSE;
391 		return (XDR_PUTLONG(xdrs, &lb));
392 
393 	case XDR_DECODE:
394 		if (!XDR_GETLONG(xdrs, &lb)) {
395 			return (FALSE);
396 		}
397 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
398 		return (TRUE);
399 
400 	case XDR_FREE:
401 		return (TRUE);
402 	}
403 	/* NOTREACHED */
404 	return (FALSE);
405 }
406 
407 /*
408  * XDR enumerations
409  */
410 bool_t
xdr_enum(XDR * xdrs,enum_t * ep)411 xdr_enum(XDR *xdrs, enum_t *ep)
412 {
413 	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
414 
415 	/*
416 	 * enums are treated as ints
417 	 */
418 	/* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
419 		return (xdr_long(xdrs, (long *)(void *)ep));
420 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
421 		return (xdr_int(xdrs, (int *)(void *)ep));
422 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
423 		return (xdr_short(xdrs, (short *)(void *)ep));
424 	} else {
425 		return (FALSE);
426 	}
427 }
428 
429 /*
430  * XDR opaque data
431  * Allows the specification of a fixed size sequence of opaque bytes.
432  * cp points to the opaque object and cnt gives the byte length.
433  */
434 bool_t
xdr_opaque(XDR * xdrs,caddr_t cp,u_int cnt)435 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
436 {
437 	u_int rndup;
438 	static int crud[BYTES_PER_XDR_UNIT];
439 
440 	/*
441 	 * if no data we are done
442 	 */
443 	if (cnt == 0)
444 		return (TRUE);
445 
446 	/*
447 	 * round byte count to full xdr units
448 	 */
449 	rndup = cnt % BYTES_PER_XDR_UNIT;
450 	if (rndup > 0)
451 		rndup = BYTES_PER_XDR_UNIT - rndup;
452 
453 	if (xdrs->x_op == XDR_DECODE) {
454 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
455 			return (FALSE);
456 		}
457 		if (rndup == 0)
458 			return (TRUE);
459 		return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
460 	}
461 
462 	if (xdrs->x_op == XDR_ENCODE) {
463 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
464 			return (FALSE);
465 		}
466 		if (rndup == 0)
467 			return (TRUE);
468 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
469 	}
470 
471 	if (xdrs->x_op == XDR_FREE) {
472 		return (TRUE);
473 	}
474 
475 	return (FALSE);
476 }
477 
478 /*
479  * XDR counted bytes
480  * *cpp is a pointer to the bytes, *sizep is the count.
481  * If *cpp is NULL maxsize bytes are allocated
482  */
483 bool_t
xdr_bytes(XDR * xdrs,char ** cpp,u_int * sizep,u_int maxsize)484 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
485 {
486 	char *sp = *cpp;  /* sp is the actual string pointer */
487 	u_int nodesize;
488 	bool_t ret, allocated = FALSE;
489 
490 	/*
491 	 * first deal with the length since xdr bytes are counted
492 	 */
493 	if (! xdr_u_int(xdrs, sizep)) {
494 		return (FALSE);
495 	}
496 	nodesize = *sizep;
497 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
498 		return (FALSE);
499 	}
500 
501 	/*
502 	 * now deal with the actual bytes
503 	 */
504 	switch (xdrs->x_op) {
505 	case XDR_DECODE:
506 		if (nodesize == 0) {
507 			return (TRUE);
508 		}
509 		if (sp == NULL) {
510 			*cpp = sp = mem_alloc(nodesize);
511 			allocated = TRUE;
512 		}
513 		if (sp == NULL) {
514 			printf("xdr_bytes: out of memory");
515 			return (FALSE);
516 		}
517 		/* FALLTHROUGH */
518 
519 	case XDR_ENCODE:
520 		ret = xdr_opaque(xdrs, sp, nodesize);
521 		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
522 			if (allocated == TRUE) {
523 				mem_free(sp, nodesize);
524 				*cpp = NULL;
525 			}
526 		}
527 		return (ret);
528 
529 	case XDR_FREE:
530 		if (sp != NULL) {
531 			mem_free(sp, nodesize);
532 			*cpp = NULL;
533 		}
534 		return (TRUE);
535 	}
536 	/* NOTREACHED */
537 	return (FALSE);
538 }
539 
540 /*
541  * Implemented here due to commonality of the object.
542  */
543 bool_t
xdr_netobj(XDR * xdrs,struct netobj * np)544 xdr_netobj(XDR *xdrs, struct netobj *np)
545 {
546 
547 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
548 }
549 
550 /*
551  * XDR a descriminated union
552  * Support routine for discriminated unions.
553  * You create an array of xdrdiscrim structures, terminated with
554  * an entry with a null procedure pointer.  The routine gets
555  * the discriminant value and then searches the array of xdrdiscrims
556  * looking for that value.  It calls the procedure given in the xdrdiscrim
557  * to handle the discriminant.  If there is no specific routine a default
558  * routine may be called.
559  * If there is no specific or default routine an error is returned.
560  */
561 bool_t
xdr_union(XDR * xdrs,enum_t * dscmp,char * unp,const struct xdr_discrim * choices,xdrproc_t dfault)562 xdr_union(XDR *xdrs,
563     enum_t *dscmp,		/* enum to decide which arm to work on */
564     char *unp,				/* the union itself */
565     const struct xdr_discrim *choices,	/* [value, xdr proc] for each arm */
566     xdrproc_t dfault)			/* default xdr routine */
567 {
568 	enum_t dscm;
569 
570 	/*
571 	 * we deal with the discriminator;  it's an enum
572 	 */
573 	if (! xdr_enum(xdrs, dscmp)) {
574 		return (FALSE);
575 	}
576 	dscm = *dscmp;
577 
578 	/*
579 	 * search choices for a value that matches the discriminator.
580 	 * if we find one, execute the xdr routine for that value.
581 	 */
582 	for (; choices->proc != NULL_xdrproc_t; choices++) {
583 		if (choices->value == dscm)
584 			return ((*(choices->proc))(xdrs, unp));
585 	}
586 
587 	/*
588 	 * no match - execute the default xdr routine if there is one
589 	 */
590 	return ((dfault == NULL_xdrproc_t) ? FALSE :
591 	    (*dfault)(xdrs, unp));
592 }
593 
594 /*
595  * Non-portable xdr primitives.
596  * Care should be taken when moving these routines to new architectures.
597  */
598 
599 /*
600  * XDR null terminated ASCII strings
601  * xdr_string deals with "C strings" - arrays of bytes that are
602  * terminated by a NULL character.  The parameter cpp references a
603  * pointer to storage; If the pointer is null, then the necessary
604  * storage is allocated.  The last parameter is the max allowed length
605  * of the string as specified by a protocol.
606  */
607 bool_t
xdr_string(XDR * xdrs,char ** cpp,u_int maxsize)608 xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
609 {
610 	char *sp = *cpp;  /* sp is the actual string pointer */
611 	u_int size;
612 	u_int nodesize;
613 	bool_t ret, allocated = FALSE;
614 
615 	/*
616 	 * first deal with the length since xdr strings are counted-strings
617 	 */
618 	switch (xdrs->x_op) {
619 	case XDR_FREE:
620 		if (sp == NULL) {
621 			return(TRUE);	/* already free */
622 		}
623 		/* FALLTHROUGH */
624 	case XDR_ENCODE:
625 		size = strlen(sp);
626 		break;
627 	case XDR_DECODE:
628 		break;
629 	}
630 	if (! xdr_u_int(xdrs, &size)) {
631 		return (FALSE);
632 	}
633 	if (size > maxsize) {
634 		return (FALSE);
635 	}
636 	nodesize = size + 1;
637 
638 	/*
639 	 * now deal with the actual bytes
640 	 */
641 	switch (xdrs->x_op) {
642 	case XDR_DECODE:
643 		if (nodesize == 0) {
644 			return (TRUE);
645 		}
646 		if (sp == NULL) {
647 			*cpp = sp = mem_alloc(nodesize);
648 			allocated = TRUE;
649 		}
650 		if (sp == NULL) {
651 			printf("xdr_string: out of memory");
652 			return (FALSE);
653 		}
654 		sp[size] = 0;
655 		/* FALLTHROUGH */
656 
657 	case XDR_ENCODE:
658 		ret = xdr_opaque(xdrs, sp, size);
659 		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
660 			if (allocated == TRUE) {
661 				mem_free(sp, nodesize);
662 				*cpp = NULL;
663 			}
664 		}
665 		return (ret);
666 
667 	case XDR_FREE:
668 		mem_free(sp, nodesize);
669 		*cpp = NULL;
670 		return (TRUE);
671 	}
672 	/* NOTREACHED */
673 	return (FALSE);
674 }
675 
676 /*
677  * Wrapper for xdr_string that can be called directly from
678  * routines like clnt_call
679  */
680 bool_t
xdr_wrapstring(XDR * xdrs,char ** cpp)681 xdr_wrapstring(XDR *xdrs, char **cpp)
682 {
683 	return xdr_string(xdrs, cpp, RPC_MAXDATASIZE);
684 }
685 
686 /*
687  * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t()
688  * are in the "non-portable" section because they require that a `long long'
689  * be a 64-bit type.
690  *
691  *	--thorpej@netbsd.org, November 30, 1999
692  */
693 
694 /*
695  * XDR 64-bit integers
696  */
697 bool_t
xdr_int64_t(XDR * xdrs,int64_t * llp)698 xdr_int64_t(XDR *xdrs, int64_t *llp)
699 {
700 	u_long ul[2];
701 
702 	switch (xdrs->x_op) {
703 	case XDR_ENCODE:
704 		ul[0] = (u_long)((uint64_t)*llp >> 32) & 0xffffffff;
705 		ul[1] = (u_long)((uint64_t)*llp) & 0xffffffff;
706 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
707 			return (FALSE);
708 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
709 	case XDR_DECODE:
710 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
711 			return (FALSE);
712 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
713 			return (FALSE);
714 		*llp = (int64_t)
715 		    (((uint64_t)ul[0] << 32) | ((uint64_t)ul[1]));
716 		return (TRUE);
717 	case XDR_FREE:
718 		return (TRUE);
719 	}
720 	/* NOTREACHED */
721 	return (FALSE);
722 }
723 
724 /*
725  * XDR unsigned 64-bit integers
726  */
727 bool_t
xdr_uint64_t(XDR * xdrs,uint64_t * ullp)728 xdr_uint64_t(XDR *xdrs, uint64_t *ullp)
729 {
730 	u_long ul[2];
731 
732 	switch (xdrs->x_op) {
733 	case XDR_ENCODE:
734 		ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
735 		ul[1] = (u_long)(*ullp) & 0xffffffff;
736 		if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
737 			return (FALSE);
738 		return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
739 	case XDR_DECODE:
740 		if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
741 			return (FALSE);
742 		if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
743 			return (FALSE);
744 		*ullp = (uint64_t)
745 		    (((uint64_t)ul[0] << 32) | ((uint64_t)ul[1]));
746 		return (TRUE);
747 	case XDR_FREE:
748 		return (TRUE);
749 	}
750 	/* NOTREACHED */
751 	return (FALSE);
752 }
753 
754 /*
755  * XDR hypers
756  */
757 bool_t
xdr_hyper(XDR * xdrs,longlong_t * llp)758 xdr_hyper(XDR *xdrs, longlong_t *llp)
759 {
760 
761 	/*
762 	 * Don't bother open-coding this; it's a fair amount of code.  Just
763 	 * call xdr_int64_t().
764 	 */
765 	return (xdr_int64_t(xdrs, (int64_t *)llp));
766 }
767 
768 /*
769  * XDR unsigned hypers
770  */
771 bool_t
xdr_u_hyper(XDR * xdrs,u_longlong_t * ullp)772 xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp)
773 {
774 
775 	/*
776 	 * Don't bother open-coding this; it's a fair amount of code.  Just
777 	 * call xdr_uint64_t().
778 	 */
779 	return (xdr_uint64_t(xdrs, (uint64_t *)ullp));
780 }
781 
782 /*
783  * XDR longlong_t's
784  */
785 bool_t
xdr_longlong_t(XDR * xdrs,longlong_t * llp)786 xdr_longlong_t(XDR *xdrs, longlong_t *llp)
787 {
788 
789 	/*
790 	 * Don't bother open-coding this; it's a fair amount of code.  Just
791 	 * call xdr_int64_t().
792 	 */
793 	return (xdr_int64_t(xdrs, (int64_t *)llp));
794 }
795 
796 /*
797  * XDR u_longlong_t's
798  */
799 bool_t
xdr_u_longlong_t(XDR * xdrs,u_longlong_t * ullp)800 xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp)
801 {
802 
803 	/*
804 	 * Don't bother open-coding this; it's a fair amount of code.  Just
805 	 * call xdr_uint64_t().
806 	 */
807 	return (xdr_uint64_t(xdrs, (uint64_t *)ullp));
808 }
809 
810 /*
811  * Kernel module glue
812  */
813 static int
xdr_modevent(module_t mod,int type,void * data)814 xdr_modevent(module_t mod, int type, void *data)
815 {
816 
817         return (0);
818 }
819 static moduledata_t xdr_mod = {
820         "xdr",
821         xdr_modevent,
822         NULL,
823 };
824 DECLARE_MODULE(xdr, xdr_mod, SI_SUB_VFS, SI_ORDER_ANY);
825 MODULE_VERSION(xdr, 1);
826