home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
lan
/
soss.arj
/
SRC
/
PMAP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-22
|
4KB
|
147 lines
/*
* pmap.c --
* Portmapper program for PC NFS file server.
* Service runs on top of the net daemon (netd.c).
* This is a partial implementation of the UNIX port mapper
* portmap(8c).
*
* Author:
* See-Mong Tan, 6/12/88
* portmapper bug fixed 3/23/89
*/
#include "common.h"
/*
* bool_t pmap_init() --
* Portmapper initializer. Called by the net daemon. Creates
* and registers it's own transport handler and dispatch routine.
* Returns TRUE if successful, or FALSE if an error occurred.
*/
bool_t pmap_init()
{
SVCXPRT *transp;
struct sockaddr_in addr;
int sock;
addr.sin_family = AF_INET;
addr.sin_port = htons(PMAPPORT);
addr.sin_addr.s_addr = INADDR_ANY;
if ((sock = sock_create(SOCK_DGRAM, IPPROTO_UDP, &addr)) < 0) {
(void) fprintf(stderr, "pmap: cannot create UDP socket\n");
return FALSE;
}
if ((transp = svcudp_create(sock, 0)) == (SVCXPRT *) NULL)
return FALSE;
if (! svc_register(transp, PMAPPROG, PMAPVERS,
pmap_dispatch, IPPROTO_UDP)) {
(void) fprintf(stderr, "pmap_init: cannot register handle\n");
sock_close(sock);
return FALSE;
}
return TRUE;
}
/*
* bool_t pmap_dispatch(struct svc_req *rqstp, SVCXPRT *transp) --
* Dispatch routine for portmapper. This is only a partial
* implementation, in particular, PMAPPROC_SET and PMAPPROC_UNSET
* are not supported.
*/
bool_t pmap_dispatch(rqstp, transp)
struct svc_req *rqstp;
SVCXPRT *transp;
{
int NOTSUPP = 0; /* error not supported */
struct pmap reg;
struct sockaddr_in addr;
int port;
switch((int) rqstp->rq_proc) {
case PMAPPROC_NULL: /* NULL procedure call */
if (NFS_VERBOSE)
(void) printf(">>> PMMAPPROC_NULL\n");
if (! svc_sendreply(transp, xdr_void, NULL))
(void) fprintf(stderr, "pmap: cannot send reply\n");
break;
case PMAPPROC_SET: /* these reqeusts are not supported */
case PMAPPROC_UNSET:
if (NFS_VERBOSE)
(void) printf("pmap: PMAPPROC_SET/UNSET\n");
if (! svc_sendreply(transp, xdr_int, &NOTSUPP))
(void) fprintf(stderr, "pmap: cannot send reply\n");
break;
case PMAPPROC_GETPORT: /* get a port */
if (NFS_VERBOSE)
(void) printf("\n>>> PMAPPROC_GETPORT\t");
if (! svc_getargs(transp, xdr_pmap, ®)) {
svcerr_decode(transp);
break;
}
if (NFS_VERBOSE)
(void) printf("--> prog = %ld, vers = %ld:\t",
reg.pm_prog, reg.pm_vers);
if (reg.pm_prog == NFS_PROGRAM && reg.pm_vers == NFS_VERSION) {
port = NFS_PORT;
if (NFS_VERBOSE)
(void) printf(" --> NFS_PORT\n");
if (! svc_sendreply(transp, xdr_int, (caddr_t)&port)) {
(void) fprintf(stderr,
"pmap: cannot send reply\n");
break;
}
break;
}
if (reg.pm_prog== MOUNTPROG && reg.pm_vers== MOUNTVERS) {
port = MOUNTPORT;
if (NFS_VERBOSE)
(void) printf("--> MOUNTPORT\n");
if (! svc_sendreply(transp, xdr_int, (caddr_t)&port)) {
(void) fprintf(stderr, "pmap: cannot reply\n");
break;
}
break;
}
/* everything else is not supported */
port = 0;
if (NFS_VERBOSE)
(void) printf("--> NO PORT REGISTERED\n");
if (! svc_sendreply(transp, xdr_int, (caddr_t)&port))
(void) fprintf(stderr, "cannot reply\n");
break;
/* The fix for the portmapper bug discovered by
* Stephen Nahm follows
*/
case PMAPPROC_CALLIT:
if (NFS_VERBOSE)
(void) printf(">>> PMAPPROC_DUMP/PMAPPROC_CALLIT\n");
break; /* should break out and not reply */
case PMAPPROC_DUMP:
/* FALLTHROUGH */
default:
svcerr_noproc(transp);
}
}
/*
* bool_t xdr_pmap(XDR *xdrs, struct pmap *regs) --
* XDR a pmap request.
*/
bool_t xdr_pmap(xdrs, regs)
XDR *xdrs;
struct pmap *regs;
{
if (xdr_u_long(xdrs, ®s->pm_prog) &&
xdr_u_long(xdrs, ®s->pm_vers) &&
xdr_u_long(xdrs, ®s->pm_prot))
return (xdr_u_long(xdrs, ®s->pm_port));
return (FALSE);
}