⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portmap.c

📁 rpc机制在vxworks上的实现源代码
💻 C
字号:
/* portmap.c - rpc portmap daemon *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1984 by Sun Microsystems, Inc. *//* * portmap.c, Implements the program,version to port number mapping for rpc. *//* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part.  Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California  94043 *//*modification history--------------------01q,05nov01,vvv  fixed compilation warning01p,15oct01,rae  merge from truestack ver 01q, base 01o (AE / 5_X)01o,15sep93,kdl  changed svcudp_create() call to only pass one param (SPR #2427)01n,11aug93,jmm  Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h01m,04jun92,wmd  added forward declarations required for gcc960 v2.0.01l,26may92,rrr  the tree shuffle01k,04oct91,rrr  passed through the ansification filter		  -changed includes to have absolute path from h/		  -changed VOID to void		  -changed copyright notice01j,11jan91,shl  added keyword ENCAP_PARMS and RMTCALLARGS01i,25oct90,dnw  removed include of utime.h.01h,11may90,yao  added missing modification history (01g) for the last checkin.01g,09may90,yao  typecasted malloc to (char *).01f,19apr90,hjb  de-linted.01e,27oct89,hjb  changed exit (1) to taskSuspend (0).01d,05apr88,gae  changed fprintf() to printErr().01c,24nov87,gae  removed include of netdb.h.01b,24oct87,dnw  changed call to rpcInit() to rpcTaskInit().*/#include "rpc/rpc.h"#include "rpc/pmap_prot.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "vxWorks.h"#include "memLib.h"#include "memPartLib.h"#include "rpcLib.h"#include "sockLib.h"#include "stdio.h"#include "unistd.h"#include "taskLib.h"#include "stdlib.h"#include "rpc/get_myaddr.h"void reg_service();void pmapRegister ();LOCAL void  callit();static int debugging = 0;voidportmapd (){	SVCXPRT *xprt;	int sock;	struct sockaddr_in addr;	int len = sizeof(struct sockaddr_in);	rpcTaskInit ();	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {		perror("portmap cannot create socket");		taskSuspend (0);	}	addr.sin_addr.s_addr = 0;	addr.sin_family = AF_INET;	addr.sin_port = htons((u_short) PMAPPORT);	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {		perror("portmap cannot bind");		taskSuspend (0);	}	if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {		printErr ("couldn't do udp_create\n");		taskSuspend (0);	}	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {		perror("portmap cannot create socket");		taskSuspend (0);	}	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {		perror("portmap cannot bind");		taskSuspend (0);	}	if ((xprt = svctcp_create(sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE))	    == (SVCXPRT *)NULL) {		printErr ("couldn't do tcp_create\n");		taskSuspend (0);	}        (void) svc_register (xprt, PMAPPROG, PMAPVERS, reg_service, (int)NULL);	svc_run();	printErr ("run_svc returned unexpectedly\n");	abort();}struct pmaplist *pmaplist;static struct pmaplist *find_service(prog, vers, prot)	u_long prog;	u_long vers;{	register struct pmaplist *hit = NULL;	register struct pmaplist *pml;	for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {		if ((pml->pml_map.pm_prog != prog) ||			(pml->pml_map.pm_prot != prot))			continue;		hit = pml;		if (pml->pml_map.pm_vers == vers)		    break;	}	return (hit);}/* * 1 OK, 0 not */void reg_service(rqstp, xprt)	struct svc_req *rqstp;	SVCXPRT *xprt;{	struct pmap reg;	struct pmaplist *pml, *prevpml, *fnd;	int ans, port;	caddr_t t;	switch ((int)rqstp->rq_proc) {	case PMAPPROC_NULL:		/*		 * Null proc call		 */		if ((!svc_sendreply(xprt, xdr_void, (char *)NULL)) &&		    debugging) {			abort();		}		break;	case PMAPPROC_SET:		/*		 * Set a program,version to port mapping		 */		if (!svc_getargs(xprt, xdr_pmap, &reg))			svcerr_decode(xprt);		else {			/*			 * check to see if already used			 * find_service returns a hit even if			 * the versions don't match, so check for it			 */			fnd = find_service(reg.pm_prog, reg.pm_vers,				(int) reg.pm_prot);			if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {				if (fnd->pml_map.pm_port == reg.pm_port) {					ans = 1;					goto done;				}				else {					ans = 0;					goto done;				}			} else {				/*				 * add to END of list				 */				pml = (struct pmaplist *)				      KHEAP_ALLOC((u_int)sizeof(struct pmaplist));				pml->pml_map = reg;				pml->pml_next = 0;				if (pmaplist == 0) {					pmaplist = pml;				} else {					for (fnd= pmaplist; fnd->pml_next != 0;					    fnd = fnd->pml_next);					fnd->pml_next = pml;				}				ans = 1;			}		done:			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&			    debugging) {				printErr ("svc_sendreply\n");				abort();			}		}		break;	case PMAPPROC_UNSET:		/*		 * Remove a program,version to port mapping.		 */		if (!svc_getargs(xprt, xdr_pmap, &reg))			svcerr_decode(xprt);		else {			ans = 0;			for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {				if ((pml->pml_map.pm_prog != reg.pm_prog) ||					(pml->pml_map.pm_vers != reg.pm_vers)) {					/* both pml & prevpml move forwards */					prevpml = pml;					pml = pml->pml_next;					continue;				}				/* found it; pml moves forward, prevpml stays */				ans = 1;				t = (caddr_t)pml;				pml = pml->pml_next;				if (prevpml == NULL)					pmaplist = pml;				else					prevpml->pml_next = pml;				KHEAP_FREE(t);			}			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&			    debugging) {				printErr ("svc_sendreply\n");				abort();			}		}		break;	case PMAPPROC_GETPORT:		/*		 * Lookup the mapping for a program,version and return its port		 */		if (!svc_getargs(xprt, xdr_pmap, &reg))			svcerr_decode(xprt);		else {			fnd = find_service(reg.pm_prog, reg.pm_vers,				(int)reg.pm_prot);			if (fnd)				port = fnd->pml_map.pm_port;			else				port = 0;			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) &&			    debugging) {				printErr ("svc_sendreply\n");				abort();			}		}		break;	case PMAPPROC_DUMP:		/*		 * Return the current set of mapped program,version		 */		if (!svc_getargs(xprt, xdr_void, NULL))			svcerr_decode(xprt);		else {			if ((!svc_sendreply(xprt, xdr_pmaplist,			    (caddr_t)&pmaplist)) && debugging) {				printErr ("svc_sendreply\n");				abort();			}		}		break;	case PMAPPROC_CALLIT:		/*		 * Calls a procedure on the local machine.  If the requested		 * procedure is not registered this procedure does not return		 * error information!!		 * This procedure is only supported on rpc/udp and calls via		 * rpc/udp.  It passes null authentication parameters.		 */		callit(rqstp, xprt);		break;	default:		svcerr_noproc(xprt);		break;	}}/* * Stuff for the rmtcall service */#define ARGSIZE 9000typedef struct encap_parms {	u_long arglen;	char *args;} ENCAP_PARMS;static bool_txdr_encap_parms(xdrs, epp)	XDR *xdrs;	struct encap_parms *epp;{	return (xdr_bytes(xdrs, &(epp->args), (u_int *) &(epp->arglen),		(u_int) ARGSIZE));}typedef struct rmtcallargs {	u_long	rmt_prog;	u_long	rmt_vers;	u_long	rmt_port;	u_long	rmt_proc;	struct encap_parms rmt_args;} RMTCALLARGS;static bool_txdr_rmtcall_args(xdrs, cap)	register XDR *xdrs;	register struct rmtcallargs *cap;{	/* does not get a port number */	if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&	    xdr_u_long(xdrs, &(cap->rmt_vers)) &&	    xdr_u_long(xdrs, &(cap->rmt_proc))) {		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));	}	return (FALSE);}static bool_txdr_rmtcall_result(xdrs, cap)	register XDR *xdrs;	register struct rmtcallargs *cap;{	if (xdr_u_long(xdrs, &(cap->rmt_port)))		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));	return (FALSE);}/* * only worries about the struct encap_parms part of struct rmtcallargs. * The arglen must already be set!! */static bool_txdr_opaque_parms(xdrs, cap)	XDR *xdrs;	struct rmtcallargs *cap;{	return (xdr_opaque(xdrs, cap->rmt_args.args,		(u_int)cap->rmt_args.arglen));}/* * This routine finds and sets the length of incoming opaque paraters * and then calls xdr_opaque_parms. */static bool_txdr_len_opaque_parms(xdrs, cap)	register XDR *xdrs;	struct rmtcallargs *cap;{	register u_int beginpos, lowpos, highpos, currpos, pos;	beginpos = lowpos = pos = xdr_getpos(xdrs);	highpos = lowpos + ARGSIZE;	while ((int)(highpos - lowpos) >= 0) {		currpos = (lowpos + highpos) / 2;		if (xdr_setpos(xdrs, currpos)) {			pos = currpos;			lowpos = currpos + 1;		} else {			highpos = currpos - 1;		}	}	xdr_setpos(xdrs, beginpos);	cap->rmt_args.arglen = pos - beginpos;	return (xdr_opaque_parms(xdrs, cap));}/* * Call a remote procedure service * This procedure is very quiet when things go wrong. * The proc is written to support broadcast rpc.  In the broadcast case, * a machine should shut-up instead of complain, less the requestor be * overrun with complaints at the expense of not hearing a valid reply ... */static voidcallit(rqstp, xprt)	struct svc_req *rqstp;	SVCXPRT *xprt;{	char buf[2000];	struct rmtcallargs a;	struct pmaplist *pml;	u_short port;	struct sockaddr_in me;	int socket = -1;	CLIENT *client;	struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;	struct timeval timeout;	timeout.tv_sec = 5;	timeout.tv_usec = 0;	a.rmt_args.args = buf;	if (!svc_getargs(xprt, xdr_rmtcall_args, &a))	    return;	if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)	    return;	port = pml->pml_map.pm_port;	get_myaddress(&me);	me.sin_port = htons(port);	client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);	if (client != (CLIENT *)NULL) {		if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {			client->cl_auth = authunix_create(au->aup_machname,			   au->aup_uid, au->aup_gid, (int) au->aup_len,			   au->aup_gids);		}		a.rmt_port = (u_long)port;		if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,		    xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {			svc_sendreply(xprt, xdr_rmtcall_result, (char *) &a);		}		AUTH_DESTROY(client->cl_auth);		clnt_destroy(client);	}	(void)close(socket);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -