1*31bdb48aSchristos /*	$NetBSD: nfs_prot_svc.c,v 1.1.1.3 2015/01/17 16:34:15 christos Exp $	*/
2a53f50b9Schristos 
3a53f50b9Schristos /*
4*31bdb48aSchristos  * Copyright (c) 1997-2014 Erez Zadok
5a53f50b9Schristos  * Copyright (c) 1989 Jan-Simon Pendry
6a53f50b9Schristos  * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
7a53f50b9Schristos  * Copyright (c) 1989 The Regents of the University of California.
8a53f50b9Schristos  * All rights reserved.
9a53f50b9Schristos  *
10a53f50b9Schristos  * This code is derived from software contributed to Berkeley by
11a53f50b9Schristos  * Jan-Simon Pendry at Imperial College, London.
12a53f50b9Schristos  *
13a53f50b9Schristos  * Redistribution and use in source and binary forms, with or without
14a53f50b9Schristos  * modification, are permitted provided that the following conditions
15a53f50b9Schristos  * are met:
16a53f50b9Schristos  * 1. Redistributions of source code must retain the above copyright
17a53f50b9Schristos  *    notice, this list of conditions and the following disclaimer.
18a53f50b9Schristos  * 2. Redistributions in binary form must reproduce the above copyright
19a53f50b9Schristos  *    notice, this list of conditions and the following disclaimer in the
20a53f50b9Schristos  *    documentation and/or other materials provided with the distribution.
21*31bdb48aSchristos  * 3. Neither the name of the University nor the names of its contributors
22a53f50b9Schristos  *    may be used to endorse or promote products derived from this software
23a53f50b9Schristos  *    without specific prior written permission.
24a53f50b9Schristos  *
25a53f50b9Schristos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26a53f50b9Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27a53f50b9Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28a53f50b9Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29a53f50b9Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30a53f50b9Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31a53f50b9Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32a53f50b9Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33a53f50b9Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34a53f50b9Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35a53f50b9Schristos  * SUCH DAMAGE.
36a53f50b9Schristos  *
37a53f50b9Schristos  *
38a53f50b9Schristos  * File: am-utils/amd/nfs_prot_svc.c
39a53f50b9Schristos  *
40a53f50b9Schristos  */
41a53f50b9Schristos 
42a53f50b9Schristos #ifdef HAVE_CONFIG_H
43a53f50b9Schristos # include <config.h>
44a53f50b9Schristos #endif /* HAVE_CONFIG_H */
45a53f50b9Schristos #include <am_defs.h>
46a53f50b9Schristos #include <amd.h>
47a53f50b9Schristos 
48a53f50b9Schristos /* external definitions */
49a53f50b9Schristos extern voidp nfsproc_null_2_svc(voidp, struct svc_req *);
50a53f50b9Schristos extern nfsattrstat *nfsproc_getattr_2_svc(am_nfs_fh *, struct svc_req *);
51a53f50b9Schristos extern nfsattrstat *nfsproc_setattr_2_svc(nfssattrargs *, struct svc_req *);
52a53f50b9Schristos extern voidp nfsproc_root_2_svc(voidp, struct svc_req *);
53a53f50b9Schristos extern nfsdiropres *nfsproc_lookup_2_svc(nfsdiropargs *, struct svc_req *);
54a53f50b9Schristos extern nfsreadlinkres *nfsproc_readlink_2_svc(am_nfs_fh *, struct svc_req *);
55a53f50b9Schristos extern nfsreadres *nfsproc_read_2_svc(nfsreadargs *, struct svc_req *);
56a53f50b9Schristos extern voidp nfsproc_writecache_2_svc(voidp, struct svc_req *);
57a53f50b9Schristos extern nfsattrstat *nfsproc_write_2_svc(nfswriteargs *, struct svc_req *);
58a53f50b9Schristos extern nfsdiropres *nfsproc_create_2_svc(nfscreateargs *, struct svc_req *);
59a53f50b9Schristos extern nfsstat *nfsproc_remove_2_svc(nfsdiropargs *, struct svc_req *);
60a53f50b9Schristos extern nfsstat *nfsproc_rename_2_svc(nfsrenameargs *, struct svc_req *);
61a53f50b9Schristos extern nfsstat *nfsproc_link_2_svc(nfslinkargs *, struct svc_req *);
62a53f50b9Schristos extern nfsstat *nfsproc_symlink_2_svc(nfssymlinkargs *, struct svc_req *);
63a53f50b9Schristos extern nfsdiropres *nfsproc_mkdir_2_svc(nfscreateargs *, struct svc_req *);
64a53f50b9Schristos extern nfsstat *nfsproc_rmdir_2_svc(nfsdiropargs *, struct svc_req *);
65a53f50b9Schristos extern nfsreaddirres *nfsproc_readdir_2_svc(nfsreaddirargs *, struct svc_req *);
66a53f50b9Schristos extern nfsstatfsres *nfsproc_statfs_2_svc(am_nfs_fh *, struct svc_req *);
67a53f50b9Schristos 
68a53f50b9Schristos /* global variables */
69a53f50b9Schristos SVCXPRT *current_transp;
70*31bdb48aSchristos dispatcher_t nfs_dispatcher = nfs_program_2;
71a53f50b9Schristos 
72a53f50b9Schristos /* typedefs */
73a53f50b9Schristos typedef char *(*nfssvcproc_t)(voidp, struct svc_req *);
74a53f50b9Schristos 
75a53f50b9Schristos 
76a53f50b9Schristos void
nfs_program_2(struct svc_req * rqstp,SVCXPRT * transp)77a53f50b9Schristos nfs_program_2(struct svc_req *rqstp, SVCXPRT *transp)
78a53f50b9Schristos {
79a53f50b9Schristos   union {
80a53f50b9Schristos     am_nfs_fh		nfsproc_getattr_2_arg;
81a53f50b9Schristos     nfssattrargs	nfsproc_setattr_2_arg;
82a53f50b9Schristos     nfsdiropargs	nfsproc_lookup_2_arg;
83a53f50b9Schristos     am_nfs_fh		nfsproc_readlink_2_arg;
84a53f50b9Schristos     nfsreadargs		nfsproc_read_2_arg;
85a53f50b9Schristos     nfswriteargs	nfsproc_write_2_arg;
86a53f50b9Schristos     nfscreateargs	nfsproc_create_2_arg;
87a53f50b9Schristos     nfsdiropargs	nfsproc_remove_2_arg;
88a53f50b9Schristos     nfsrenameargs	nfsproc_rename_2_arg;
89a53f50b9Schristos     nfslinkargs		nfsproc_link_2_arg;
90a53f50b9Schristos     nfssymlinkargs	nfsproc_symlink_2_arg;
91a53f50b9Schristos     nfscreateargs	nfsproc_mkdir_2_arg;
92a53f50b9Schristos     nfsdiropargs	fsproc_rmdir_2_arg;
93a53f50b9Schristos     nfsreaddirargs	nfsproc_readdir_2_arg;
94a53f50b9Schristos     am_nfs_fh		nfsproc_statfs_2_arg;
95a53f50b9Schristos   } argument;
96a53f50b9Schristos   char *result;
97a53f50b9Schristos   xdrproc_t xdr_argument, xdr_result;
98a53f50b9Schristos   nfssvcproc_t local;
99a53f50b9Schristos 
100a53f50b9Schristos #ifdef HAVE_TRANSPORT_TYPE_TLI
101a53f50b9Schristos   /*
102a53f50b9Schristos    * On TLI systems we don't use an INET network type, but a "ticlts" (see
103a53f50b9Schristos    * /etc/netconfig and conf/transp_tli.c:create_nfs_service).  This means
104a53f50b9Schristos    * that packets could only come from the loopback interface, and we don't
105a53f50b9Schristos    * need to check them and filter possibly spoofed packets.  Therefore we
106a53f50b9Schristos    * only need to check if the UID caller is correct.
107a53f50b9Schristos    */
108a53f50b9Schristos # ifdef HAVE___RPC_GET_LOCAL_UID
109a53f50b9Schristos   uid_t u;
110a53f50b9Schristos   /* extern definition for an internal libnsl function */
111a53f50b9Schristos   extern int __rpc_get_local_uid(SVCXPRT *transp, uid_t *uid);
112a53f50b9Schristos   if (__rpc_get_local_uid(transp, &u) >= 0  &&  u != 0) {
113a53f50b9Schristos     plog(XLOG_WARNING, "ignoring request from UID %ld, must be 0", (long) u);
114a53f50b9Schristos     return;
115a53f50b9Schristos   }
116a53f50b9Schristos # else /* not HAVE___RPC_GET_LOCAL_UID */
117a53f50b9Schristos   dlog("cannot verify local uid for rpc request");
118a53f50b9Schristos # endif /* HAVE___RPC_GET_LOCAL_UID */
119a53f50b9Schristos #else /* not HAVE_TRANPORT_TYPE_TLI */
120a53f50b9Schristos   struct sockaddr_in *sinp;
121a53f50b9Schristos   char dq[20], dq2[28];
122a53f50b9Schristos   sinp = amu_svc_getcaller(rqstp->rq_xprt);
123a53f50b9Schristos # ifdef MNT2_NFS_OPT_RESVPORT
124a53f50b9Schristos   /* Verify that the request comes from a reserved port */
125a53f50b9Schristos   if (sinp &&
126a53f50b9Schristos       ntohs(sinp->sin_port) >= IPPORT_RESERVED &&
127a53f50b9Schristos       !(gopt.flags & CFM_NFS_INSECURE_PORT)) {
128a53f50b9Schristos     plog(XLOG_WARNING, "ignoring request from %s:%u, port not reserved",
129a53f50b9Schristos 	 inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
130a53f50b9Schristos 	 ntohs(sinp->sin_port));
131a53f50b9Schristos     return;
132a53f50b9Schristos   }
133a53f50b9Schristos # endif /* MNT2_NFS_OPT_RESVPORT */
134a53f50b9Schristos   /* if the address does not match, ignore the request */
135a53f50b9Schristos   if (sinp && (sinp->sin_addr.s_addr != myipaddr.s_addr)) {
136a53f50b9Schristos     if (gopt.flags & CFM_NFS_ANY_INTERFACE) {
137a53f50b9Schristos       if (!is_interface_local(sinp->sin_addr.s_addr)) {
138a53f50b9Schristos 	plog(XLOG_WARNING, "ignoring request from %s:%u, not a local interface",
139a53f50b9Schristos 	     inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
140a53f50b9Schristos 	     ntohs(sinp->sin_port));
141a53f50b9Schristos       }
142a53f50b9Schristos     } else {
143a53f50b9Schristos       plog(XLOG_WARNING, "ignoring request from %s:%u, expected %s",
144a53f50b9Schristos 	   inet_dquad(dq, sizeof(dq), sinp->sin_addr.s_addr),
145a53f50b9Schristos 	   ntohs(sinp->sin_port),
146a53f50b9Schristos 	   inet_dquad(dq2, sizeof(dq2), myipaddr.s_addr));
147a53f50b9Schristos       return;
148a53f50b9Schristos     }
149a53f50b9Schristos   }
150a53f50b9Schristos #endif /* not HAVE_TRANPORT_TYPE_TLI */
151a53f50b9Schristos 
152a53f50b9Schristos   current_transp = NULL;
153a53f50b9Schristos 
154a53f50b9Schristos   switch (rqstp->rq_proc) {
155a53f50b9Schristos 
156a53f50b9Schristos   case NFSPROC_NULL:
157a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_void;
158a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_void;
159a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_null_2_svc;
160a53f50b9Schristos     break;
161a53f50b9Schristos 
162a53f50b9Schristos   case NFSPROC_GETATTR:
163a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_nfs_fh;
164a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_attrstat;
165a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_getattr_2_svc;
166a53f50b9Schristos     break;
167a53f50b9Schristos 
168a53f50b9Schristos   case NFSPROC_SETATTR:
169a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_sattrargs;
170a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_attrstat;
171a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_setattr_2_svc;
172a53f50b9Schristos     break;
173a53f50b9Schristos 
174a53f50b9Schristos   case NFSPROC_ROOT:
175a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_void;
176a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_void;
177a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_root_2_svc;
178a53f50b9Schristos     break;
179a53f50b9Schristos 
180a53f50b9Schristos   case NFSPROC_LOOKUP:
181a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_diropargs;
182a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_diropres;
183a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_lookup_2_svc;
184a53f50b9Schristos     /*
185a53f50b9Schristos      * Cheap way to pass transp down to amfs_auto_lookuppn so it can
186a53f50b9Schristos      * be stored in the am_node structure and later used for
187a53f50b9Schristos      * quick_reply().
188a53f50b9Schristos      */
189a53f50b9Schristos     current_transp = transp;
190a53f50b9Schristos     break;
191a53f50b9Schristos 
192a53f50b9Schristos   case NFSPROC_READLINK:
193a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_nfs_fh;
194a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_readlinkres;
195a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_readlink_2_svc;
196a53f50b9Schristos     break;
197a53f50b9Schristos 
198a53f50b9Schristos   case NFSPROC_READ:
199a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_readargs;
200a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_readres;
201a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_read_2_svc;
202a53f50b9Schristos     break;
203a53f50b9Schristos 
204a53f50b9Schristos   case NFSPROC_WRITECACHE:
205a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_void;
206a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_void;
207a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_writecache_2_svc;
208a53f50b9Schristos     break;
209a53f50b9Schristos 
210a53f50b9Schristos   case NFSPROC_WRITE:
211a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_writeargs;
212a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_attrstat;
213a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_write_2_svc;
214a53f50b9Schristos     break;
215a53f50b9Schristos 
216a53f50b9Schristos   case NFSPROC_CREATE:
217a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_createargs;
218a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_diropres;
219a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_create_2_svc;
220a53f50b9Schristos     break;
221a53f50b9Schristos 
222a53f50b9Schristos   case NFSPROC_REMOVE:
223a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_diropargs;
224a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_nfsstat;
225a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_remove_2_svc;
226a53f50b9Schristos     break;
227a53f50b9Schristos 
228a53f50b9Schristos   case NFSPROC_RENAME:
229a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_renameargs;
230a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_nfsstat;
231a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_rename_2_svc;
232a53f50b9Schristos     break;
233a53f50b9Schristos 
234a53f50b9Schristos   case NFSPROC_LINK:
235a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_linkargs;
236a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_nfsstat;
237a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_link_2_svc;
238a53f50b9Schristos     break;
239a53f50b9Schristos 
240a53f50b9Schristos   case NFSPROC_SYMLINK:
241a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_symlinkargs;
242a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_nfsstat;
243a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_symlink_2_svc;
244a53f50b9Schristos     break;
245a53f50b9Schristos 
246a53f50b9Schristos   case NFSPROC_MKDIR:
247a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_createargs;
248a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_diropres;
249a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_mkdir_2_svc;
250a53f50b9Schristos     break;
251a53f50b9Schristos 
252a53f50b9Schristos   case NFSPROC_RMDIR:
253a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_diropargs;
254a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_nfsstat;
255a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_rmdir_2_svc;
256a53f50b9Schristos     break;
257a53f50b9Schristos 
258a53f50b9Schristos   case NFSPROC_READDIR:
259a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_readdirargs;
260a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_readdirres;
261a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_readdir_2_svc;
262a53f50b9Schristos     break;
263a53f50b9Schristos 
264a53f50b9Schristos   case NFSPROC_STATFS:
265a53f50b9Schristos     xdr_argument = (xdrproc_t) xdr_nfs_fh;
266a53f50b9Schristos     xdr_result = (xdrproc_t) xdr_statfsres;
267a53f50b9Schristos     local = (nfssvcproc_t) nfsproc_statfs_2_svc;
268a53f50b9Schristos     break;
269a53f50b9Schristos 
270a53f50b9Schristos   default:
271a53f50b9Schristos     svcerr_noproc(transp);
272a53f50b9Schristos     return;
273a53f50b9Schristos   }
274a53f50b9Schristos 
275a53f50b9Schristos   memset((char *) &argument, 0, sizeof(argument));
276a53f50b9Schristos   if (!svc_getargs(transp,
277a53f50b9Schristos 		   (XDRPROC_T_TYPE) xdr_argument,
278a53f50b9Schristos 		   (SVC_IN_ARG_TYPE) &argument)) {
279a53f50b9Schristos     plog(XLOG_ERROR,
280a53f50b9Schristos 	 "NFS xdr decode failed for %d %d %d",
281a53f50b9Schristos 	 (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
282a53f50b9Schristos     svcerr_decode(transp);
283a53f50b9Schristos     return;
284a53f50b9Schristos   }
285a53f50b9Schristos   result = (*local) (&argument, rqstp);
286a53f50b9Schristos 
287a53f50b9Schristos   current_transp = NULL;
288a53f50b9Schristos 
289a53f50b9Schristos   if (result != NULL && !svc_sendreply(transp,
290a53f50b9Schristos 				       (XDRPROC_T_TYPE) xdr_result,
291a53f50b9Schristos 				       result)) {
292a53f50b9Schristos     svcerr_systemerr(transp);
293a53f50b9Schristos   }
294a53f50b9Schristos   if (!svc_freeargs(transp,
295a53f50b9Schristos 		    (XDRPROC_T_TYPE) xdr_argument,
296a53f50b9Schristos 		    (SVC_IN_ARG_TYPE) & argument)) {
297a53f50b9Schristos     plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_2");
298a53f50b9Schristos     going_down(1);
299a53f50b9Schristos   }
300a53f50b9Schristos }
301*31bdb48aSchristos 
302*31bdb48aSchristos void
nfs_program_3(struct svc_req * rqstp,register SVCXPRT * transp)303*31bdb48aSchristos nfs_program_3(struct svc_req *rqstp, register SVCXPRT *transp)
304*31bdb48aSchristos {
305*31bdb48aSchristos   union {
306*31bdb48aSchristos     am_GETATTR3args am_nfs3_getattr_3_arg;
307*31bdb48aSchristos     am_SETATTR3args am_nfs3_setattr_3_arg;
308*31bdb48aSchristos     am_LOOKUP3args am_nfs3_lookup_3_arg;
309*31bdb48aSchristos     am_ACCESS3args am_nfs3_access_3_arg;
310*31bdb48aSchristos     am_READLINK3args am_nfs3_readlink_3_arg;
311*31bdb48aSchristos     am_READ3args am_nfs3_read_3_arg;
312*31bdb48aSchristos     am_WRITE3args am_nfs3_write_3_arg;
313*31bdb48aSchristos     am_CREATE3args am_nfs3_create_3_arg;
314*31bdb48aSchristos     am_MKDIR3args am_nfs3_mkdir_3_arg;
315*31bdb48aSchristos     am_SYMLINK3args am_nfs3_symlink_3_arg;
316*31bdb48aSchristos     am_MKNOD3args am_nfs3_mknod_3_arg;
317*31bdb48aSchristos     am_REMOVE3args am_nfs3_remove_3_arg;
318*31bdb48aSchristos     am_RMDIR3args am_nfs3_rmdir_3_arg;
319*31bdb48aSchristos     am_RENAME3args am_nfs3_rename_3_arg;
320*31bdb48aSchristos     am_LINK3args am_nfs3_link_3_arg;
321*31bdb48aSchristos     am_READDIR3args am_nfs3_readdir_3_arg;
322*31bdb48aSchristos     am_READDIRPLUS3args am_nfs3_readdirplus_3_arg;
323*31bdb48aSchristos     am_FSSTAT3args am_nfs3_fsstat_3_arg;
324*31bdb48aSchristos     am_FSINFO3args am_nfs3_fsinfo_3_arg;
325*31bdb48aSchristos     am_PATHCONF3args am_nfs3_pathconf_3_arg;
326*31bdb48aSchristos     am_COMMIT3args am_nfs3_commit_3_arg;
327*31bdb48aSchristos   } argument;
328*31bdb48aSchristos   char *result;
329*31bdb48aSchristos   xdrproc_t _xdr_argument, _xdr_result;
330*31bdb48aSchristos   nfssvcproc_t local;
331*31bdb48aSchristos 
332*31bdb48aSchristos   switch (rqstp->rq_proc) {
333*31bdb48aSchristos   case AM_NFS3_NULL:
334*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_void;
335*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_void;
336*31bdb48aSchristos     local = (nfssvcproc_t) am_nfs3_null_3_svc;
337*31bdb48aSchristos     break;
338*31bdb48aSchristos 
339*31bdb48aSchristos   case AM_NFS3_GETATTR:
340*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_GETATTR3args;
341*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_GETATTR3res;
342*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_getattr_3_svc;
343*31bdb48aSchristos     break;
344*31bdb48aSchristos 
345*31bdb48aSchristos   case AM_NFS3_SETATTR:
346*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_SETATTR3args;
347*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_SETATTR3res;
348*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_setattr_3_svc;
349*31bdb48aSchristos     break;
350*31bdb48aSchristos 
351*31bdb48aSchristos   case AM_NFS3_LOOKUP:
352*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_LOOKUP3args;
353*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_LOOKUP3res;
354*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_lookup_3_svc;
355*31bdb48aSchristos     break;
356*31bdb48aSchristos 
357*31bdb48aSchristos   case AM_NFS3_ACCESS:
358*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_ACCESS3args;
359*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_ACCESS3res;
360*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_access_3_svc;
361*31bdb48aSchristos     break;
362*31bdb48aSchristos 
363*31bdb48aSchristos   case AM_NFS3_READLINK:
364*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_READLINK3args;
365*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_READLINK3res;
366*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readlink_3_svc;
367*31bdb48aSchristos     break;
368*31bdb48aSchristos 
369*31bdb48aSchristos   case AM_NFS3_READ:
370*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_READ3args;
371*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_READ3res;
372*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_read_3_svc;
373*31bdb48aSchristos     break;
374*31bdb48aSchristos 
375*31bdb48aSchristos   case AM_NFS3_WRITE:
376*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_WRITE3args;
377*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_WRITE3res;
378*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_write_3_svc;
379*31bdb48aSchristos     break;
380*31bdb48aSchristos 
381*31bdb48aSchristos   case AM_NFS3_CREATE:
382*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_CREATE3args;
383*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_CREATE3res;
384*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_create_3_svc;
385*31bdb48aSchristos     break;
386*31bdb48aSchristos 
387*31bdb48aSchristos   case AM_NFS3_MKDIR:
388*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_MKDIR3args;
389*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_MKDIR3res;
390*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_mkdir_3_svc;
391*31bdb48aSchristos     break;
392*31bdb48aSchristos 
393*31bdb48aSchristos   case AM_NFS3_SYMLINK:
394*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_SYMLINK3args;
395*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_SYMLINK3res;
396*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_symlink_3_svc;
397*31bdb48aSchristos     break;
398*31bdb48aSchristos 
399*31bdb48aSchristos   case AM_NFS3_MKNOD:
400*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_MKNOD3args;
401*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_MKNOD3res;
402*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_mknod_3_svc;
403*31bdb48aSchristos     break;
404*31bdb48aSchristos 
405*31bdb48aSchristos   case AM_NFS3_REMOVE:
406*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_REMOVE3args;
407*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_REMOVE3res;
408*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_remove_3_svc;
409*31bdb48aSchristos     break;
410*31bdb48aSchristos 
411*31bdb48aSchristos   case AM_NFS3_RMDIR:
412*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_RMDIR3args;
413*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_RMDIR3res;
414*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_rmdir_3_svc;
415*31bdb48aSchristos     break;
416*31bdb48aSchristos 
417*31bdb48aSchristos   case AM_NFS3_RENAME:
418*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_RENAME3args;
419*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_RENAME3res;
420*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_rename_3_svc;
421*31bdb48aSchristos     break;
422*31bdb48aSchristos 
423*31bdb48aSchristos   case AM_NFS3_LINK:
424*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_LINK3args;
425*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_LINK3res;
426*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_link_3_svc;
427*31bdb48aSchristos     break;
428*31bdb48aSchristos 
429*31bdb48aSchristos   case AM_NFS3_READDIR:
430*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_READDIR3args;
431*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_READDIR3res;
432*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readdir_3_svc;
433*31bdb48aSchristos     break;
434*31bdb48aSchristos 
435*31bdb48aSchristos   case AM_NFS3_READDIRPLUS:
436*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_READDIRPLUS3args;
437*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_READDIRPLUS3res;
438*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_readdirplus_3_svc;
439*31bdb48aSchristos     break;
440*31bdb48aSchristos 
441*31bdb48aSchristos   case AM_NFS3_FSSTAT:
442*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_FSSTAT3args;
443*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_FSSTAT3res;
444*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_fsstat_3_svc;
445*31bdb48aSchristos     break;
446*31bdb48aSchristos 
447*31bdb48aSchristos   case AM_NFS3_FSINFO:
448*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_FSINFO3args;
449*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_FSINFO3res;
450*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_fsinfo_3_svc;
451*31bdb48aSchristos     break;
452*31bdb48aSchristos 
453*31bdb48aSchristos   case AM_NFS3_PATHCONF:
454*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_PATHCONF3args;
455*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_PATHCONF3res;
456*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_pathconf_3_svc;
457*31bdb48aSchristos     break;
458*31bdb48aSchristos 
459*31bdb48aSchristos   case AM_NFS3_COMMIT:
460*31bdb48aSchristos     _xdr_argument = (xdrproc_t) xdr_am_COMMIT3args;
461*31bdb48aSchristos     _xdr_result = (xdrproc_t) xdr_am_COMMIT3res;
462*31bdb48aSchristos     local = (nfssvcproc_t) (char *(*)(char *, struct svc_req *)) am_nfs3_commit_3_svc;
463*31bdb48aSchristos     break;
464*31bdb48aSchristos 
465*31bdb48aSchristos   default:
466*31bdb48aSchristos     svcerr_noproc (transp);
467*31bdb48aSchristos     return;
468*31bdb48aSchristos   }
469*31bdb48aSchristos 
470*31bdb48aSchristos   memset ((char *)&argument, 0, sizeof (argument));
471*31bdb48aSchristos 
472*31bdb48aSchristos   if (!svc_getargs(transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
473*31bdb48aSchristos     plog(XLOG_ERROR,
474*31bdb48aSchristos 	 "NFS xdr decode failed for %d %d %d",
475*31bdb48aSchristos 	 (int) rqstp->rq_prog, (int) rqstp->rq_vers, (int) rqstp->rq_proc);
476*31bdb48aSchristos     svcerr_decode(transp);
477*31bdb48aSchristos     return;
478*31bdb48aSchristos   }
479*31bdb48aSchristos 
480*31bdb48aSchristos   result = (*local) (&argument, rqstp);
481*31bdb48aSchristos   if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {
482*31bdb48aSchristos     svcerr_systemerr (transp);
483*31bdb48aSchristos   }
484*31bdb48aSchristos 
485*31bdb48aSchristos   if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {
486*31bdb48aSchristos     plog(XLOG_FATAL, "unable to free rpc arguments in nfs_program_3");
487*31bdb48aSchristos     going_down(1);
488*31bdb48aSchristos   }
489*31bdb48aSchristos   return;
490*31bdb48aSchristos }
491