xref: /freebsd/sys/xdr/xdr.c (revision f9bc005b8ef3b507a5ecbc2d7fe4411ef70eff38)
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/types.h>
50 #include <rpc/xdr.h>
51 
52 typedef quad_t          longlong_t;     /* ANSI long long type */
53 typedef u_quad_t        u_longlong_t;   /* ANSI unsigned long long type */
54 
55 /*
56  * constants specific to the xdr "protocol"
57  */
58 #define XDR_FALSE	((long) 0)
59 #define XDR_TRUE	((long) 1)
60 
61 MALLOC_DEFINE(M_RPC, "rpc", "Remote Procedure Call");
62 
63 /*
64  * for unit alignment
65  */
66 static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
67 
68 /*
69  * Free a data structure using XDR
70  * Not a filter, but a convenient utility nonetheless
71  */
72 void
73 xdr_free(xdrproc_t proc, void *objp)
74 {
75 	XDR x;
76 
77 	x.x_op = XDR_FREE;
78 	(*proc)(&x, objp);
79 }
80 
81 /*
82  * XDR nothing
83  */
84 bool_t
85 xdr_void(XDR *xrds __unused, void *ptr __unused)
86 {
87 	return (TRUE);
88 }
89 
90 /*
91  * XDR integers
92  */
93 bool_t
94 xdr_int(XDR *xdrs, int *ip)
95 {
96 	long l;
97 
98 	switch (xdrs->x_op) {
99 	case XDR_ENCODE:
100 		l = (long) *ip;
101 		return (XDR_PUTLONG(xdrs, &l));
102 
103 	case XDR_DECODE:
104 		if (!XDR_GETLONG(xdrs, &l)) {
105 			return (FALSE);
106 		}
107 		*ip = (int) l;
108 		return (TRUE);
109 
110 	case XDR_FREE:
111 		return (TRUE);
112 	}
113 	/* NOTREACHED */
114 	return (FALSE);
115 }
116 
117 /*
118  * XDR unsigned integers
119  */
120 bool_t
121 xdr_u_int(XDR *xdrs, u_int *up)
122 {
123 	u_long l;
124 
125 	switch (xdrs->x_op) {
126 	case XDR_ENCODE:
127 		l = (u_long) *up;
128 		return (XDR_PUTLONG(xdrs, (long *)&l));
129 
130 	case XDR_DECODE:
131 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
132 			return (FALSE);
133 		}
134 		*up = (u_int) l;
135 		return (TRUE);
136 
137 	case XDR_FREE:
138 		return (TRUE);
139 	}
140 	/* NOTREACHED */
141 	return (FALSE);
142 }
143 
144 /*
145  * XDR long integers
146  * same as xdr_u_long - open coded to save a proc call!
147  */
148 bool_t
149 xdr_long(XDR *xdrs, long *lp)
150 {
151 	switch (xdrs->x_op) {
152 	case XDR_ENCODE:
153 		return (XDR_PUTLONG(xdrs, lp));
154 	case XDR_DECODE:
155 		return (XDR_GETLONG(xdrs, lp));
156 	case XDR_FREE:
157 		return (TRUE);
158 	}
159 	/* NOTREACHED */
160 	return (FALSE);
161 }
162 
163 /*
164  * XDR unsigned long integers
165  * same as xdr_long - open coded to save a proc call!
166  */
167 bool_t
168 xdr_u_long(XDR *xdrs, u_long *ulp)
169 {
170 	switch (xdrs->x_op) {
171 	case XDR_ENCODE:
172 		return (XDR_PUTLONG(xdrs, (long *)ulp));
173 	case XDR_DECODE:
174 		return (XDR_GETLONG(xdrs, (long *)ulp));
175 	case XDR_FREE:
176 		return (TRUE);
177 	}
178 	/* NOTREACHED */
179 	return (FALSE);
180 }
181 
182 /*
183  * XDR 32-bit integers
184  * same as xdr_uint32_t - open coded to save a proc call!
185  */
186 bool_t
187 xdr_int32_t(XDR *xdrs, int32_t *int32_p)
188 {
189 	long l;
190 
191 	switch (xdrs->x_op) {
192 	case XDR_ENCODE:
193 		l = (long) *int32_p;
194 		return (XDR_PUTLONG(xdrs, &l));
195 
196 	case XDR_DECODE:
197 		if (!XDR_GETLONG(xdrs, &l)) {
198 			return (FALSE);
199 		}
200 		*int32_p = (int32_t) l;
201 		return (TRUE);
202 
203 	case XDR_FREE:
204 		return (TRUE);
205 	}
206 	/* NOTREACHED */
207 	return (FALSE);
208 }
209 
210 /*
211  * XDR unsigned 32-bit integers
212  * same as xdr_int32_t - open coded to save a proc call!
213  */
214 bool_t
215 xdr_uint32_t(XDR *xdrs, uint32_t *uint32_p)
216 {
217 	u_long l;
218 
219 	switch (xdrs->x_op) {
220 	case XDR_ENCODE:
221 		l = (u_long) *uint32_p;
222 		return (XDR_PUTLONG(xdrs, (long *)&l));
223 
224 	case XDR_DECODE:
225 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
226 			return (FALSE);
227 		}
228 		*uint32_p = (uint32_t) l;
229 		return (TRUE);
230 
231 	case XDR_FREE:
232 		return (TRUE);
233 	}
234 	/* NOTREACHED */
235 	return (FALSE);
236 }
237 
238 /*
239  * XDR short integers
240  */
241 bool_t
242 xdr_short(XDR *xdrs, short *sp)
243 {
244 	long l;
245 
246 	switch (xdrs->x_op) {
247 	case XDR_ENCODE:
248 		l = (long) *sp;
249 		return (XDR_PUTLONG(xdrs, &l));
250 
251 	case XDR_DECODE:
252 		if (!XDR_GETLONG(xdrs, &l)) {
253 			return (FALSE);
254 		}
255 		*sp = (short) l;
256 		return (TRUE);
257 
258 	case XDR_FREE:
259 		return (TRUE);
260 	}
261 	/* NOTREACHED */
262 	return (FALSE);
263 }
264 
265 /*
266  * XDR unsigned short integers
267  */
268 bool_t
269 xdr_u_short(XDR *xdrs, u_short *usp)
270 {
271 	u_long l;
272 
273 	switch (xdrs->x_op) {
274 	case XDR_ENCODE:
275 		l = (u_long) *usp;
276 		return (XDR_PUTLONG(xdrs, (long *)&l));
277 
278 	case XDR_DECODE:
279 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
280 			return (FALSE);
281 		}
282 		*usp = (u_short) l;
283 		return (TRUE);
284 
285 	case XDR_FREE:
286 		return (TRUE);
287 	}
288 	/* NOTREACHED */
289 	return (FALSE);
290 }
291 
292 /*
293  * XDR 16-bit integers
294  */
295 bool_t
296 xdr_int16_t(XDR *xdrs, int16_t *int16_p)
297 {
298 	long l;
299 
300 	switch (xdrs->x_op) {
301 	case XDR_ENCODE:
302 		l = (long) *int16_p;
303 		return (XDR_PUTLONG(xdrs, &l));
304 
305 	case XDR_DECODE:
306 		if (!XDR_GETLONG(xdrs, &l)) {
307 			return (FALSE);
308 		}
309 		*int16_p = (int16_t) l;
310 		return (TRUE);
311 
312 	case XDR_FREE:
313 		return (TRUE);
314 	}
315 	/* NOTREACHED */
316 	return (FALSE);
317 }
318 
319 /*
320  * XDR unsigned 16-bit integers
321  */
322 bool_t
323 xdr_uint16_t(XDR *xdrs, uint16_t *uint16_p)
324 {
325 	u_long l;
326 
327 	switch (xdrs->x_op) {
328 	case XDR_ENCODE:
329 		l = (u_long) *uint16_p;
330 		return (XDR_PUTLONG(xdrs, (long *)&l));
331 
332 	case XDR_DECODE:
333 		if (!XDR_GETLONG(xdrs, (long *)&l)) {
334 			return (FALSE);
335 		}
336 		*uint16_p = (uint16_t) l;
337 		return (TRUE);
338 
339 	case XDR_FREE:
340 		return (TRUE);
341 	}
342 	/* NOTREACHED */
343 	return (FALSE);
344 }
345 
346 /*
347  * XDR a char
348  */
349 bool_t
350 xdr_char(XDR *xdrs, char *cp)
351 {
352 	u_int i;
353 
354 	i = *((unsigned char *)cp);
355 	if (!xdr_u_int(xdrs, &i)) {
356 		return (FALSE);
357 	}
358 	*((unsigned char *)cp) = i;
359 	return (TRUE);
360 }
361 
362 /*
363  * XDR an unsigned char
364  */
365 bool_t
366 xdr_u_char(XDR *xdrs, u_char *cp)
367 {
368 	u_int u;
369 
370 	u = (*cp);
371 	if (!xdr_u_int(xdrs, &u)) {
372 		return (FALSE);
373 	}
374 	*cp = u;
375 	return (TRUE);
376 }
377 
378 /*
379  * XDR booleans
380  */
381 bool_t
382 xdr_bool(XDR *xdrs, bool_t *bp)
383 {
384 	long lb;
385 
386 	switch (xdrs->x_op) {
387 	case XDR_ENCODE:
388 		lb = *bp ? XDR_TRUE : XDR_FALSE;
389 		return (XDR_PUTLONG(xdrs, &lb));
390 
391 	case XDR_DECODE:
392 		if (!XDR_GETLONG(xdrs, &lb)) {
393 			return (FALSE);
394 		}
395 		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
396 		return (TRUE);
397 
398 	case XDR_FREE:
399 		return (TRUE);
400 	}
401 	/* NOTREACHED */
402 	return (FALSE);
403 }
404 
405 /*
406  * XDR enumerations
407  */
408 bool_t
409 xdr_enum(XDR *xdrs, enum_t *ep)
410 {
411 	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
412 
413 	/*
414 	 * enums are treated as ints
415 	 */
416 	/* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
417 		return (xdr_long(xdrs, (long *)(void *)ep));
418 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
419 		return (xdr_int(xdrs, (int *)(void *)ep));
420 	} else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
421 		return (xdr_short(xdrs, (short *)(void *)ep));
422 	} else {
423 		return (FALSE);
424 	}
425 }
426 
427 /*
428  * XDR opaque data
429  * Allows the specification of a fixed size sequence of opaque bytes.
430  * cp points to the opaque object and cnt gives the byte length.
431  */
432 bool_t
433 xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
434 {
435 	u_int rndup;
436 	static int crud[BYTES_PER_XDR_UNIT];
437 
438 	/*
439 	 * if no data we are done
440 	 */
441 	if (cnt == 0)
442 		return (TRUE);
443 
444 	/*
445 	 * round byte count to full xdr units
446 	 */
447 	rndup = cnt % BYTES_PER_XDR_UNIT;
448 	if (rndup > 0)
449 		rndup = BYTES_PER_XDR_UNIT - rndup;
450 
451 	if (xdrs->x_op == XDR_DECODE) {
452 		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
453 			return (FALSE);
454 		}
455 		if (rndup == 0)
456 			return (TRUE);
457 		return (XDR_GETBYTES(xdrs, (caddr_t)(void *)crud, rndup));
458 	}
459 
460 	if (xdrs->x_op == XDR_ENCODE) {
461 		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
462 			return (FALSE);
463 		}
464 		if (rndup == 0)
465 			return (TRUE);
466 		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
467 	}
468 
469 	if (xdrs->x_op == XDR_FREE) {
470 		return (TRUE);
471 	}
472 
473 	return (FALSE);
474 }
475 
476 /*
477  * XDR counted bytes
478  * *cpp is a pointer to the bytes, *sizep is the count.
479  * If *cpp is NULL maxsize bytes are allocated
480  */
481 bool_t
482 xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize)
483 {
484 	char *sp = *cpp;  /* sp is the actual string pointer */
485 	u_int nodesize;
486 	bool_t ret, allocated = FALSE;
487 
488 	/*
489 	 * first deal with the length since xdr bytes are counted
490 	 */
491 	if (! xdr_u_int(xdrs, sizep)) {
492 		return (FALSE);
493 	}
494 	nodesize = *sizep;
495 	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
496 		return (FALSE);
497 	}
498 
499 	/*
500 	 * now deal with the actual bytes
501 	 */
502 	switch (xdrs->x_op) {
503 	case XDR_DECODE:
504 		if (nodesize == 0) {
505 			return (TRUE);
506 		}
507 		if (sp == NULL) {
508 			*cpp = sp = mem_alloc(nodesize);
509 			allocated = TRUE;
510 		}
511 		if (sp == NULL) {
512 			printf("xdr_bytes: out of memory");
513 			return (FALSE);
514 		}
515 		/* FALLTHROUGH */
516 
517 	case XDR_ENCODE:
518 		ret = xdr_opaque(xdrs, sp, nodesize);
519 		if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) {
520 			if (allocated == TRUE) {
521 				mem_free(sp, nodesize);
522 				*cpp = NULL;
523 			}
524 		}
525 		return (ret);
526 
527 	case XDR_FREE:
528 		if (sp != NULL) {
529 			mem_free(sp, nodesize);
530 			*cpp = NULL;
531 		}
532 		return (TRUE);
533 	}
534 	/* NOTREACHED */
535 	return (FALSE);
536 }
537 
538 /*
539  * Implemented here due to commonality of the object.
540  */
541 bool_t
542 xdr_netobj(XDR *xdrs, struct netobj *np)
543 {
544 
545 	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
546 }
547 
548 /*
549  * XDR a descriminated union
550  * Support routine for discriminated unions.
551  * You create an array of xdrdiscrim structures, terminated with
552  * an entry with a null procedure pointer.  The routine gets
553  * the discriminant value and then searches the array of xdrdiscrims
554  * looking for that value.  It calls the procedure given in the xdrdiscrim
555  * to handle the discriminant.  If there is no specific routine a default
556  * routine may be called.
557  * If there is no specific or default routine an error is returned.
558  */
559 bool_t
560 xdr_union(XDR *xdrs,
561     enum_t *dscmp,		/* enum to decide which arm to work on */
562     char *unp,				/* the union itself */
563     const struct xdr_discrim *choices,	/* [value, xdr proc] for each arm */
564     xdrproc_t dfault)			/* default xdr routine */
565 {
566 	enum_t dscm;
567 
568 	/*
569 	 * we deal with the discriminator;  it's an enum
570 	 */
571 	if (! xdr_enum(xdrs, dscmp)) {
572 		return (FALSE);
573 	}
574 	dscm = *dscmp;
575 
576 	/*
577 	 * search choices for a value that matches the discriminator.
578 	 * if we find one, execute the xdr routine for that value.
579 	 */
580 	for (; choices->proc != NULL_xdrproc_t; choices++) {
581 		if (choices->value == dscm)
582 			return ((*(choices->proc))(xdrs, unp));
583 	}
584 
585 	/*
586 	 * no match - execute the default xdr routine if there is one
587 	 */
588 	return ((dfault == NULL_xdrproc_t) ? FALSE :
589 	    (*dfault)(xdrs, unp));
590 }
591 
592 /*
593  * Non-portable xdr primitives.
594  * Care should be taken when moving these routines to new architectures.
595  */
596 
597 /*
598  * XDR null terminated ASCII strings
599  * xdr_string deals with "C strings" - arrays of bytes that are
600  * terminated by a NULL character.  The parameter cpp references a
601  * pointer to storage; If the pointer is null, then the necessary
602  * storage is allocated.  The last parameter is the max allowed length
603  * of the string as specified by a protocol.
604  */
605 bool_t
606 xdr_string(XDR *xdrs, char **cpp, u_int maxsize)
607 {
608 	char *sp = *cpp;  /* sp is the actual string pointer */
609 	u_int size;
610 	u_int nodesize;
611 	bool_t ret, allocated = FALSE;
612 
613 	/*
614 	 * first deal with the length since xdr strings are counted-strings
615 	 */
616 	switch (xdrs->x_op) {
617 	case XDR_FREE:
618 		if (sp == NULL) {
619 			return(TRUE);	/* already free */
620 		}
621 		/*
622 		 * XXX: buggy software may call this without a third
623 		 * argument via xdr_free().  Ignore maxsize since it may
624 		 * be invalid.  Otherwise, if it's very small, we might
625 		 * fail to free the string.
626 		 */
627 		maxsize = ~0U;
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, ~0U));
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