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