xref: /freebsd/sys/rpc/rpc_generic.c (revision d876124d6ae9d56da5b4ff4c6015efd1d0c9222a)
1 /*	$NetBSD: rpc_generic.c,v 1.4 2000/09/28 09:07:04 kleink 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  * Copyright (c) 1986-1991 by Sun Microsystems Inc.
33  */
34 
35 /* #pragma ident	"@(#)rpc_generic.c	1.17	94/04/24 SMI" */
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
38 
39 /*
40  * rpc_generic.c, Miscl routines for RPC.
41  *
42  */
43 
44 #include "opt_inet6.h"
45 
46 #include <sys/param.h>
47 #include <sys/kernel.h>
48 #include <sys/malloc.h>
49 #include <sys/module.h>
50 #include <sys/proc.h>
51 #include <sys/protosw.h>
52 #include <sys/sbuf.h>
53 #include <sys/systm.h>
54 #include <sys/socket.h>
55 #include <sys/socketvar.h>
56 #include <sys/syslog.h>
57 
58 #include <rpc/rpc.h>
59 #include <rpc/nettype.h>
60 
61 #include <rpc/rpc_com.h>
62 
63 #if __FreeBSD_version < 700000
64 #define strrchr rindex
65 #endif
66 
67 struct handle {
68 	NCONF_HANDLE *nhandle;
69 	int nflag;		/* Whether NETPATH or NETCONFIG */
70 	int nettype;
71 };
72 
73 static const struct _rpcnettype {
74 	const char *name;
75 	const int type;
76 } _rpctypelist[] = {
77 	{ "netpath", _RPC_NETPATH },
78 	{ "visible", _RPC_VISIBLE },
79 	{ "circuit_v", _RPC_CIRCUIT_V },
80 	{ "datagram_v", _RPC_DATAGRAM_V },
81 	{ "circuit_n", _RPC_CIRCUIT_N },
82 	{ "datagram_n", _RPC_DATAGRAM_N },
83 	{ "tcp", _RPC_TCP },
84 	{ "udp", _RPC_UDP },
85 	{ 0, _RPC_NONE }
86 };
87 
88 struct netid_af {
89 	const char	*netid;
90 	int		af;
91 	int		protocol;
92 };
93 
94 static const struct netid_af na_cvt[] = {
95 	{ "udp",  AF_INET,  IPPROTO_UDP },
96 	{ "tcp",  AF_INET,  IPPROTO_TCP },
97 #ifdef INET6
98 	{ "udp6", AF_INET6, IPPROTO_UDP },
99 	{ "tcp6", AF_INET6, IPPROTO_TCP },
100 #endif
101 	{ "local", AF_LOCAL, 0 }
102 };
103 
104 struct rpc_createerr rpc_createerr;
105 
106 /*
107  * Find the appropriate buffer size
108  */
109 u_int
110 /*ARGSUSED*/
111 __rpc_get_t_size(int af, int proto, int size)
112 {
113 	int maxsize, defsize;
114 
115 	maxsize = 256 * 1024;	/* XXX */
116 	switch (proto) {
117 	case IPPROTO_TCP:
118 		defsize = 64 * 1024;	/* XXX */
119 		break;
120 	case IPPROTO_UDP:
121 		defsize = UDPMSGSIZE;
122 		break;
123 	default:
124 		defsize = RPC_MAXDATASIZE;
125 		break;
126 	}
127 	if (size == 0)
128 		return defsize;
129 
130 	/* Check whether the value is within the upper max limit */
131 	return (size > maxsize ? (u_int)maxsize : (u_int)size);
132 }
133 
134 /*
135  * Find the appropriate address buffer size
136  */
137 u_int
138 __rpc_get_a_size(af)
139 	int af;
140 {
141 	switch (af) {
142 	case AF_INET:
143 		return sizeof (struct sockaddr_in);
144 #ifdef INET6
145 	case AF_INET6:
146 		return sizeof (struct sockaddr_in6);
147 #endif
148 	case AF_LOCAL:
149 		return sizeof (struct sockaddr_un);
150 	default:
151 		break;
152 	}
153 	return ((u_int)RPC_MAXADDRSIZE);
154 }
155 
156 #if 0
157 
158 /*
159  * Used to ping the NULL procedure for clnt handle.
160  * Returns NULL if fails, else a non-NULL pointer.
161  */
162 void *
163 rpc_nullproc(clnt)
164 	CLIENT *clnt;
165 {
166 	struct timeval TIMEOUT = {25, 0};
167 
168 	if (clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void, NULL,
169 		(xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS) {
170 		return (NULL);
171 	}
172 	return ((void *) clnt);
173 }
174 
175 #endif
176 
177 int
178 __rpc_socket2sockinfo(struct socket *so, struct __rpc_sockinfo *sip)
179 {
180 	int type, proto;
181 	struct sockaddr *sa;
182 	sa_family_t family;
183 	struct sockopt opt;
184 	int error;
185 
186 	error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
187 	if (error)
188 		return 0;
189 
190 	sip->si_alen = sa->sa_len;
191 	family = sa->sa_family;
192 	free(sa, M_SONAME);
193 
194 	opt.sopt_dir = SOPT_GET;
195 	opt.sopt_level = SOL_SOCKET;
196 	opt.sopt_name = SO_TYPE;
197 	opt.sopt_val = &type;
198 	opt.sopt_valsize = sizeof type;
199 	opt.sopt_td = NULL;
200 	error = sogetopt(so, &opt);
201 	if (error)
202 		return 0;
203 
204 	/* XXX */
205 	if (family != AF_LOCAL) {
206 		if (type == SOCK_STREAM)
207 			proto = IPPROTO_TCP;
208 		else if (type == SOCK_DGRAM)
209 			proto = IPPROTO_UDP;
210 		else
211 			return 0;
212 	} else
213 		proto = 0;
214 
215 	sip->si_af = family;
216 	sip->si_proto = proto;
217 	sip->si_socktype = type;
218 
219 	return 1;
220 }
221 
222 /*
223  * Linear search, but the number of entries is small.
224  */
225 int
226 __rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
227 {
228 	int i;
229 
230 	for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++)
231 		if (strcmp(na_cvt[i].netid, nconf->nc_netid) == 0 || (
232 		    strcmp(nconf->nc_netid, "unix") == 0 &&
233 		    strcmp(na_cvt[i].netid, "local") == 0)) {
234 			sip->si_af = na_cvt[i].af;
235 			sip->si_proto = na_cvt[i].protocol;
236 			sip->si_socktype =
237 			    __rpc_seman2socktype((int)nconf->nc_semantics);
238 			if (sip->si_socktype == -1)
239 				return 0;
240 			sip->si_alen = __rpc_get_a_size(sip->si_af);
241 			return 1;
242 		}
243 
244 	return 0;
245 }
246 
247 struct socket *
248 __rpc_nconf2socket(const struct netconfig *nconf)
249 {
250 	struct __rpc_sockinfo si;
251 	struct socket *so;
252 	int error;
253 
254 	if (!__rpc_nconf2sockinfo(nconf, &si))
255 		return 0;
256 
257 	so = NULL;
258 	error =  socreate(si.si_af, &so, si.si_socktype, si.si_proto,
259 	    curthread->td_ucred, curthread);
260 
261 	if (error)
262 		return NULL;
263 	else
264 		return so;
265 }
266 
267 char *
268 taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf)
269 {
270 	struct __rpc_sockinfo si;
271 
272 	if (!__rpc_nconf2sockinfo(nconf, &si))
273 		return NULL;
274 	return __rpc_taddr2uaddr_af(si.si_af, nbuf);
275 }
276 
277 struct netbuf *
278 uaddr2taddr(const struct netconfig *nconf, const char *uaddr)
279 {
280 	struct __rpc_sockinfo si;
281 
282 	if (!__rpc_nconf2sockinfo(nconf, &si))
283 		return NULL;
284 	return __rpc_uaddr2taddr_af(si.si_af, uaddr);
285 }
286 
287 char *
288 __rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
289 {
290 	char *ret;
291 	struct sbuf sb;
292 	struct sockaddr_in *sin;
293 	struct sockaddr_un *sun;
294 	char namebuf[INET_ADDRSTRLEN];
295 #ifdef INET6
296 	struct sockaddr_in6 *sin6;
297 	char namebuf6[INET6_ADDRSTRLEN];
298 #endif
299 	u_int16_t port;
300 
301 	sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND);
302 
303 	switch (af) {
304 	case AF_INET:
305 		sin = nbuf->buf;
306 		if (__rpc_inet_ntop(af, &sin->sin_addr, namebuf, sizeof namebuf)
307 		    == NULL)
308 			return NULL;
309 		port = ntohs(sin->sin_port);
310 		if (sbuf_printf(&sb, "%s.%u.%u", namebuf,
311 			((uint32_t)port) >> 8,
312 			port & 0xff) < 0)
313 			return NULL;
314 		break;
315 #ifdef INET6
316 	case AF_INET6:
317 		sin6 = nbuf->buf;
318 		if (__rpc_inet_ntop(af, &sin6->sin6_addr, namebuf6, sizeof namebuf6)
319 		    == NULL)
320 			return NULL;
321 		port = ntohs(sin6->sin6_port);
322 		if (sbuf_printf(&sb, "%s.%u.%u", namebuf6,
323 			((uint32_t)port) >> 8,
324 			port & 0xff) < 0)
325 			return NULL;
326 		break;
327 #endif
328 	case AF_LOCAL:
329 		sun = nbuf->buf;
330 		if (sbuf_printf(&sb, "%.*s", (int)(sun->sun_len -
331 			    offsetof(struct sockaddr_un, sun_path)),
332 			sun->sun_path) < 0)
333 			return (NULL);
334 		break;
335 	default:
336 		return NULL;
337 	}
338 
339 	sbuf_finish(&sb);
340 	ret = strdup(sbuf_data(&sb), M_RPC);
341 	sbuf_delete(&sb);
342 
343 	return ret;
344 }
345 
346 struct netbuf *
347 __rpc_uaddr2taddr_af(int af, const char *uaddr)
348 {
349 	struct netbuf *ret = NULL;
350 	char *addrstr, *p;
351 	unsigned port, portlo, porthi;
352 	struct sockaddr_in *sin;
353 #ifdef INET6
354 	struct sockaddr_in6 *sin6;
355 #endif
356 	struct sockaddr_un *sun;
357 
358 	port = 0;
359 	sin = NULL;
360 	addrstr = strdup(uaddr, M_RPC);
361 	if (addrstr == NULL)
362 		return NULL;
363 
364 	/*
365 	 * AF_LOCAL addresses are expected to be absolute
366 	 * pathnames, anything else will be AF_INET or AF_INET6.
367 	 */
368 	if (*addrstr != '/') {
369 		p = strrchr(addrstr, '.');
370 		if (p == NULL)
371 			goto out;
372 		portlo = (unsigned)strtol(p + 1, NULL, 10);
373 		*p = '\0';
374 
375 		p = strrchr(addrstr, '.');
376 		if (p == NULL)
377 			goto out;
378 		porthi = (unsigned)strtol(p + 1, NULL, 10);
379 		*p = '\0';
380 		port = (porthi << 8) | portlo;
381 	}
382 
383 	ret = (struct netbuf *)malloc(sizeof *ret, M_RPC, M_WAITOK);
384 	if (ret == NULL)
385 		goto out;
386 
387 	switch (af) {
388 	case AF_INET:
389 		sin = (struct sockaddr_in *)malloc(sizeof *sin, M_RPC,
390 		    M_WAITOK);
391 		if (sin == NULL)
392 			goto out;
393 		memset(sin, 0, sizeof *sin);
394 		sin->sin_family = AF_INET;
395 		sin->sin_port = htons(port);
396 		if (__rpc_inet_pton(AF_INET, addrstr, &sin->sin_addr) <= 0) {
397 			free(sin, M_RPC);
398 			free(ret, M_RPC);
399 			ret = NULL;
400 			goto out;
401 		}
402 		sin->sin_len = ret->maxlen = ret->len = sizeof *sin;
403 		ret->buf = sin;
404 		break;
405 #ifdef INET6
406 	case AF_INET6:
407 		sin6 = (struct sockaddr_in6 *)malloc(sizeof *sin6, M_RPC,
408 		    M_WAITOK);
409 		if (sin6 == NULL)
410 			goto out;
411 		memset(sin6, 0, sizeof *sin6);
412 		sin6->sin6_family = AF_INET6;
413 		sin6->sin6_port = htons(port);
414 		if (__rpc_inet_pton(AF_INET6, addrstr, &sin6->sin6_addr) <= 0) {
415 			free(sin6, M_RPC);
416 			free(ret, M_RPC);
417 			ret = NULL;
418 			goto out;
419 		}
420 		sin6->sin6_len = ret->maxlen = ret->len = sizeof *sin6;
421 		ret->buf = sin6;
422 		break;
423 #endif
424 	case AF_LOCAL:
425 		sun = (struct sockaddr_un *)malloc(sizeof *sun, M_RPC,
426 		    M_WAITOK);
427 		if (sun == NULL)
428 			goto out;
429 		memset(sun, 0, sizeof *sun);
430 		sun->sun_family = AF_LOCAL;
431 		strncpy(sun->sun_path, addrstr, sizeof(sun->sun_path) - 1);
432 		ret->len = ret->maxlen = sun->sun_len = SUN_LEN(sun);
433 		ret->buf = sun;
434 		break;
435 	default:
436 		break;
437 	}
438 out:
439 	free(addrstr, M_RPC);
440 	return ret;
441 }
442 
443 int
444 __rpc_seman2socktype(int semantics)
445 {
446 	switch (semantics) {
447 	case NC_TPI_CLTS:
448 		return SOCK_DGRAM;
449 	case NC_TPI_COTS_ORD:
450 		return SOCK_STREAM;
451 	case NC_TPI_RAW:
452 		return SOCK_RAW;
453 	default:
454 		break;
455 	}
456 
457 	return -1;
458 }
459 
460 int
461 __rpc_socktype2seman(int socktype)
462 {
463 	switch (socktype) {
464 	case SOCK_DGRAM:
465 		return NC_TPI_CLTS;
466 	case SOCK_STREAM:
467 		return NC_TPI_COTS_ORD;
468 	case SOCK_RAW:
469 		return NC_TPI_RAW;
470 	default:
471 		break;
472 	}
473 
474 	return -1;
475 }
476 
477 /*
478  * Returns the type of the network as defined in <rpc/nettype.h>
479  * If nettype is NULL, it defaults to NETPATH.
480  */
481 static int
482 getnettype(const char *nettype)
483 {
484 	int i;
485 
486 	if ((nettype == NULL) || (nettype[0] == 0)) {
487 		return (_RPC_NETPATH);	/* Default */
488 	}
489 
490 #if 0
491 	nettype = strlocase(nettype);
492 #endif
493 	for (i = 0; _rpctypelist[i].name; i++)
494 		if (strcasecmp(nettype, _rpctypelist[i].name) == 0) {
495 			return (_rpctypelist[i].type);
496 		}
497 	return (_rpctypelist[i].type);
498 }
499 
500 /*
501  * For the given nettype (tcp or udp only), return the first structure found.
502  * This should be freed by calling freenetconfigent()
503  */
504 struct netconfig *
505 __rpc_getconfip(const char *nettype)
506 {
507 	char *netid;
508 	static char *netid_tcp = (char *) NULL;
509 	static char *netid_udp = (char *) NULL;
510 	struct netconfig *dummy;
511 
512 	if (!netid_udp && !netid_tcp) {
513 		struct netconfig *nconf;
514 		void *confighandle;
515 
516 		if (!(confighandle = setnetconfig())) {
517 			log(LOG_ERR, "rpc: failed to open " NETCONFIG);
518 			return (NULL);
519 		}
520 		while ((nconf = getnetconfig(confighandle)) != NULL) {
521 			if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
522 				if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
523 					netid_tcp = strdup(nconf->nc_netid,
524 					    M_RPC);
525 				} else
526 				if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
527 					netid_udp = strdup(nconf->nc_netid,
528 					    M_RPC);
529 				}
530 			}
531 		}
532 		endnetconfig(confighandle);
533 	}
534 	if (strcmp(nettype, "udp") == 0)
535 		netid = netid_udp;
536 	else if (strcmp(nettype, "tcp") == 0)
537 		netid = netid_tcp;
538 	else {
539 		return (NULL);
540 	}
541 	if ((netid == NULL) || (netid[0] == 0)) {
542 		return (NULL);
543 	}
544 	dummy = getnetconfigent(netid);
545 	return (dummy);
546 }
547 
548 /*
549  * Returns the type of the nettype, which should then be used with
550  * __rpc_getconf().
551  *
552  * For simplicity in the kernel, we don't support the NETPATH
553  * environment variable. We behave as userland would then NETPATH is
554  * unset, i.e. iterate over all visible entries in netconfig.
555  */
556 void *
557 __rpc_setconf(nettype)
558 	const char *nettype;
559 {
560 	struct handle *handle;
561 
562 	handle = (struct handle *) malloc(sizeof (struct handle),
563 	    M_RPC, M_WAITOK);
564 	switch (handle->nettype = getnettype(nettype)) {
565 	case _RPC_NETPATH:
566 	case _RPC_CIRCUIT_N:
567 	case _RPC_DATAGRAM_N:
568 		if (!(handle->nhandle = setnetconfig()))
569 			goto failed;
570 		handle->nflag = TRUE;
571 		break;
572 	case _RPC_VISIBLE:
573 	case _RPC_CIRCUIT_V:
574 	case _RPC_DATAGRAM_V:
575 	case _RPC_TCP:
576 	case _RPC_UDP:
577 		if (!(handle->nhandle = setnetconfig())) {
578 		        log(LOG_ERR, "rpc: failed to open " NETCONFIG);
579 			goto failed;
580 		}
581 		handle->nflag = FALSE;
582 		break;
583 	default:
584 		goto failed;
585 	}
586 
587 	return (handle);
588 
589 failed:
590 	free(handle, M_RPC);
591 	return (NULL);
592 }
593 
594 /*
595  * Returns the next netconfig struct for the given "net" type.
596  * __rpc_setconf() should have been called previously.
597  */
598 struct netconfig *
599 __rpc_getconf(void *vhandle)
600 {
601 	struct handle *handle;
602 	struct netconfig *nconf;
603 
604 	handle = (struct handle *)vhandle;
605 	if (handle == NULL) {
606 		return (NULL);
607 	}
608 	for (;;) {
609 		if (handle->nflag) {
610 			nconf = getnetconfig(handle->nhandle);
611 			if (nconf && !(nconf->nc_flag & NC_VISIBLE))
612 				continue;
613 		} else {
614 			nconf = getnetconfig(handle->nhandle);
615 		}
616 		if (nconf == NULL)
617 			break;
618 		if ((nconf->nc_semantics != NC_TPI_CLTS) &&
619 			(nconf->nc_semantics != NC_TPI_COTS) &&
620 			(nconf->nc_semantics != NC_TPI_COTS_ORD))
621 			continue;
622 		switch (handle->nettype) {
623 		case _RPC_VISIBLE:
624 			if (!(nconf->nc_flag & NC_VISIBLE))
625 				continue;
626 			/* FALLTHROUGH */
627 		case _RPC_NETPATH:	/* Be happy */
628 			break;
629 		case _RPC_CIRCUIT_V:
630 			if (!(nconf->nc_flag & NC_VISIBLE))
631 				continue;
632 			/* FALLTHROUGH */
633 		case _RPC_CIRCUIT_N:
634 			if ((nconf->nc_semantics != NC_TPI_COTS) &&
635 				(nconf->nc_semantics != NC_TPI_COTS_ORD))
636 				continue;
637 			break;
638 		case _RPC_DATAGRAM_V:
639 			if (!(nconf->nc_flag & NC_VISIBLE))
640 				continue;
641 			/* FALLTHROUGH */
642 		case _RPC_DATAGRAM_N:
643 			if (nconf->nc_semantics != NC_TPI_CLTS)
644 				continue;
645 			break;
646 		case _RPC_TCP:
647 			if (((nconf->nc_semantics != NC_TPI_COTS) &&
648 				(nconf->nc_semantics != NC_TPI_COTS_ORD)) ||
649 				(strcmp(nconf->nc_protofmly, NC_INET)
650 #ifdef INET6
651 				 && strcmp(nconf->nc_protofmly, NC_INET6))
652 #else
653 				)
654 #endif
655 				||
656 				strcmp(nconf->nc_proto, NC_TCP))
657 				continue;
658 			break;
659 		case _RPC_UDP:
660 			if ((nconf->nc_semantics != NC_TPI_CLTS) ||
661 				(strcmp(nconf->nc_protofmly, NC_INET)
662 #ifdef INET6
663 				&& strcmp(nconf->nc_protofmly, NC_INET6))
664 #else
665 				)
666 #endif
667 				||
668 				strcmp(nconf->nc_proto, NC_UDP))
669 				continue;
670 			break;
671 		}
672 		break;
673 	}
674 	return (nconf);
675 }
676 
677 void
678 __rpc_endconf(vhandle)
679 	void * vhandle;
680 {
681 	struct handle *handle;
682 
683 	handle = (struct handle *) vhandle;
684 	if (handle == NULL) {
685 		return;
686 	}
687 	endnetconfig(handle->nhandle);
688 	free(handle, M_RPC);
689 }
690 
691 int
692 __rpc_sockisbound(struct socket *so)
693 {
694 	struct sockaddr *sa;
695 	int error, bound;
696 
697 	error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
698 	if (error)
699 		return (0);
700 
701 	switch (sa->sa_family) {
702 		case AF_INET:
703 			bound = (((struct sockaddr_in *) sa)->sin_port != 0);
704 			break;
705 #ifdef INET6
706 		case AF_INET6:
707 			bound = (((struct sockaddr_in6 *) sa)->sin6_port != 0);
708 			break;
709 #endif
710 		case AF_LOCAL:
711 			/* XXX check this */
712 			bound = (((struct sockaddr_un *) sa)->sun_path[0] != '\0');
713 			break;
714 		default:
715 			bound = FALSE;
716 			break;
717 	}
718 
719 	free(sa, M_SONAME);
720 
721 	return bound;
722 }
723 
724 /*
725  * Kernel module glue
726  */
727 static int
728 krpc_modevent(module_t mod, int type, void *data)
729 {
730 
731 	return (0);
732 }
733 static moduledata_t krpc_mod = {
734 	"krpc",
735 	krpc_modevent,
736 	NULL,
737 };
738 DECLARE_MODULE(krpc, krpc_mod, SI_SUB_VFS, SI_ORDER_ANY);
739 
740 /* So that loader and kldload(2) can find us, wherever we are.. */
741 MODULE_VERSION(krpc, 1);
742