rpc.mountd: Checking RPC Procedure ID before process it
[nfs-utils.git] / support / nfs / rpcdispatch.c
1 /*
2  * support/nfs/rcpdispatch.c
3  *
4  * Generic RPC dispatcher.
5  *
6  * Copyright (C) 1995, 1996, Olaf Kirch <okir@monad.swb.de>
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <stdio.h>
14 #include <rpc/rpc.h>
15 #include <rpc/pmap_clnt.h>
16 #include <signal.h>
17 #include <arpa/inet.h>
18 #include <netdb.h>
19 #include <string.h>
20 #include "rpcmisc.h"
21 #include "xlog.h"
22
23 void
24 rpc_dispatch(struct svc_req *rqstp, SVCXPRT *transp,
25                         struct rpc_dtable *dtable, int nvers,
26                         void *argp, void *resp)
27 {
28         struct rpc_dentry       *dent;
29
30         if (((int)rqstp->rq_vers) > nvers) {
31                 svcerr_progvers(transp, 1, nvers);
32                 return;
33         }
34         dtable += (rqstp->rq_vers - 1);
35         if (((int)rqstp->rq_proc) > dtable->nproc) {
36                 svcerr_noproc(transp);
37                 return;
38         }
39
40         if (dtable->nproc <= rqstp->rq_proc) {
41                 svcerr_noproc(transp);
42                 return;
43         }
44
45         dent = dtable->entries + rqstp->rq_proc;
46
47         if (dent->func == NULL) {
48                 svcerr_noproc(transp);
49                 return;
50         }
51
52         memset(argp, 0, dent->xdr_arg_size);
53         memset(resp, 0, dent->xdr_res_size);
54
55         if (!svc_getargs(transp, dent->xdr_arg_fn, argp)) {
56                 svcerr_decode(transp);
57                 return;
58         }
59
60         if ((dent->func)(rqstp, argp, resp) && resp != 0) {
61                 if (!svc_sendreply(transp, dent->xdr_res_fn, (caddr_t)resp)) 
62                         svcerr_systemerr(transp);
63         }
64         if (!svc_freeargs(transp, dent->xdr_arg_fn, argp)) {
65                 xlog(L_ERROR, "failed to free RPC arguments");
66                 exit (2);
67         }
68 }