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