int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//                                         argc[2] : Server Program Number
	//                                         argc[3] : Number of testes function calls
	//                                         other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1;	//Default test result set to FAILED
	int progNum = atoi(argc[2]);
	CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
	char addrbuf[ADDRBUFSIZE];
	enum clnt_stat cs;
	int var_snd = 0;
	int var_rec = -1;
	struct timeval tv;
	int nbCall = atoi(argc[3]);
	int nbOk = 0;
	int i;

	//Initialization
	if (run_mode) {
		printf("Before creation\n");
	}

	tv.tv_sec = 0;
	tv.tv_usec = 100;

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *)NULL) {
		//syslog(LOG_ERR, "getnetconfigent for udp failed");
		fprintf(stderr, "err nconf\n");
		printf("5\n");
		exit(5);
	}

	svcaddr.len = 0;
	svcaddr.maxlen = ADDRBUFSIZE;
	svcaddr.buf = addrbuf;

	if (svcaddr.buf == NULL) {
		printf("5\n");
		exit(5);
	}
	//printf("svcaddr reserved (%s)\n", argc[1]);

	if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, argc[1])) {
		fprintf(stderr, "rpcb_getaddr failed!!\n");
		printf("5\n");
		exit(5);
	}
	//printf("svc get\n");

	client = clnt_tli_create(RPC_ANYFD, nconf, &svcaddr,
				 progNum, VERSNUM, 0, 0);
	/**/ for (i = 0; i < nbCall; i++) {
		cs = clnt_call(client, PROCNUM,
			       (xdrproc_t) xdr_int, (char *)&var_snd,
			       (xdrproc_t) xdr_int, (char *)&var_rec, tv);
		if (cs == RPC_SUCCESS)
			nbOk++;
	}

	if (run_mode == 1) {
		printf("Aimed : %d\n", nbCall);
		printf("Got : %d\n", nbOk);
	}

	test_status = (nbOk == nbCall) ? 0 : 1;

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	clnt_destroy(client);

	return test_status;
}
Beispiel #2
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 0; //Default test result set to PASSED
	int progNum = atoi(argc[2]);
    CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
    char addrbuf[ADDRBUFSIZE];
	enum clnt_stat cs;
	struct timeval tv;
	//Sent variables
	int intSnd;
	double dblSnd;
	long lngSnd;
	char *strSnd;
	//Received variables
	int intRec;
	double dblRec;
	long lngRec;
	char *strRec;

	//Test initialization
	tv.tv_sec = 0;
	tv.tv_usec = 100;

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *) NULL)
	{
		fprintf(stderr, "err nconf\n");
		printf("5\n");
		exit(5);
	}

	svcaddr.len = 0;
	svcaddr.maxlen = ADDRBUFSIZE;
	svcaddr.buf = addrbuf;

	if (svcaddr.buf == NULL)
	{
    	printf("5\n");
		exit(5);
    }

	if (!rpcb_getaddr(progNum, VERSNUM, nconf,
                               &svcaddr, argc[1]))
    {
    	fprintf(stderr, "rpcb_getaddr failed!!\n");
    	printf("5\n");
    	exit(1);
    }

	//Call tested procedure several times
	//Int test : call INTPROCNUM RPC
	intSnd = -65536;

	cs = rpcb_rmtcall(nconf, argc[1], progNum, VERSNUM, INTPROCNUM,
	                  (xdrproc_t) xdr_int, (char *)&intSnd,
	                  (xdrproc_t) xdr_int, (char *)&intRec,
	                  tv, &svcaddr);

	if (intSnd != intRec)
		test_status = 1;
	if (run_mode == 1)
		printf("Send (int) : %d, Received : %d\n", intSnd, intRec);

	//Test positive number
	intSnd = 16777216;

	cs = rpcb_rmtcall(nconf, argc[1], progNum, VERSNUM, INTPROCNUM,
	                  (xdrproc_t) xdr_int, (char *)&intSnd,
	                  (xdrproc_t) xdr_int, (char *)&intRec,
	                  tv, &svcaddr);

	if (intSnd != intRec)
		test_status = 1;
	if (run_mode == 1)
		printf("Send (int) : %d, Received : %d\n", intSnd, intRec);

	//Long test : call LNGPROCNUM RPC
	lngSnd = -430000;

	cs = rpcb_rmtcall(nconf, argc[1], progNum, VERSNUM, LNGPROCNUM,
	                  (xdrproc_t) xdr_long, (char *)&lngSnd,
	                  (xdrproc_t) xdr_long, (char *)&lngRec,
	                  tv, &svcaddr);

	if (lngSnd != lngRec)
		test_status = 1;
	if (run_mode == 1)
		printf("Send (long) : %ld, Received : %ld\n", lngSnd, lngRec);

	//Double test : call DBLPROCNUM RPC
	dblSnd = -1735.63000f;

	cs = rpcb_rmtcall(nconf, argc[1], progNum, VERSNUM, DBLPROCNUM,
	                  (xdrproc_t) xdr_double, (char *)&dblSnd,
	                  (xdrproc_t) xdr_double, (char *)&dblRec,
	                  tv, &svcaddr);

	if (dblSnd != dblRec)
		test_status = 1;
	if (run_mode == 1)
		printf("Send (double) : %lf, Received : %lf\n", dblSnd, dblRec);

	//String test : call STRPROCNUM RPC
	strSnd = "text to send.";
	strRec = (char *)malloc(64 * sizeof(char));

	cs = rpcb_rmtcall(nconf, argc[1], progNum, VERSNUM, STRPROCNUM,
	                  (xdrproc_t) xdr_wrapstring, (char *)&strSnd,
	                  (xdrproc_t) xdr_wrapstring, (char *)&strRec,
	                  tv, &svcaddr);

	if (strcmp(strSnd, strRec))
		test_status = 1;
	if (run_mode == 1)
		printf("Send (string) : %s, Received : %s\n", strSnd, strRec);

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
Beispiel #3
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//                                         argc[2] : Server Program Number
	//                                         other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1;	//Default test result set to FAILED
	int progNum = atoi(argc[2]);
	CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
	char addrbuf[ADDRBUFSIZE];
	enum clnt_stat cs;
	int var_snd = 0;
	int var_rec = -1;
	struct timeval tv;

	//Initialization
	if (run_mode) {
		printf("Before creation\n");
		printf("client : %d\n", client);
		printf("nconf : %d\n", nconf);
	}

	tv.tv_sec = 0;
	tv.tv_usec = 100;

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *)NULL) {
		fprintf(stderr, "err nconf\n");
		printf("5\n");
		exit(5);
	}

	svcaddr.len = 0;
	svcaddr.maxlen = ADDRBUFSIZE;
	svcaddr.buf = addrbuf;

	if (svcaddr.buf == NULL) {
		printf("5\n");
		exit(5);
	}

	if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, argc[1])) {
		fprintf(stderr, "rpcb_getaddr failed!!\n");
		printf("5\n");
		exit(5);
	}

	cs = rpcb_rmtcall(nconf, argc[1], progNum, VERSNUM, PROCNUM,
			  (xdrproc_t) xdr_int, (char *)&var_snd,
			  (xdrproc_t) xdr_int, (char *)&var_rec, tv, &svcaddr);

	test_status = (cs == RPC_SUCCESS) ? 0 : 1;

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
Beispiel #4
0
/*
 * Nfs server daemon mostly just a user context for nfssvc()
 *
 * 1 - do file descriptor and signal cleanup
 * 2 - fork the nfsd(s)
 * 3 - create server socket(s)
 * 4 - register socket with rpcbind
 *
 * For connectionless protocols, just pass the socket into the kernel via.
 * nfssvc().
 * For connection based sockets, loop doing accepts. When you get a new
 * socket from accept, pass the msgsock into the kernel via. nfssvc().
 * The arguments are:
 *	-r - reregister with rpcbind
 *	-d - unregister with rpcbind
 *	-t - support tcp nfs clients
 *	-u - support udp nfs clients
 *	-e - forces it to run a server that supports nfsv4
 * followed by "n" which is the number of nfsds' to fork off
 */
int
main(int argc, char **argv)
{
	struct nfsd_addsock_args addsockargs;
	struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
	struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
	struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
	struct sockaddr_in inetpeer;
	struct sockaddr_in6 inet6peer;
	fd_set ready, sockbits;
	fd_set v4bits, v6bits;
	int ch, connect_type_cnt, i, maxsock, msgsock;
	socklen_t len;
	int on = 1, unregister, reregister, sock;
	int tcp6sock, ip6flag, tcpflag, tcpsock;
	int udpflag, ecode, error, s;
	int bindhostc, bindanyflag, rpcbreg, rpcbregcnt;
	int nfssvc_addsock;
	int longindex = 0;
	const char *lopt;
	char **bindhost = NULL;
	pid_t pid;

	nfsdcnt = DEFNFSDCNT;
	unregister = reregister = tcpflag = maxsock = 0;
	bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
	getopt_shortopts = "ah:n:rdtue";
	getopt_usage =
	    "usage:\n"
	    "  nfsd [-ardtue] [-h bindip]\n"
	    "       [-n numservers] [--minthreads #] [--maxthreads #]\n";
	while ((ch = getopt_long(argc, argv, getopt_shortopts, longopts,
		    &longindex)) != -1)
		switch (ch) {
		case 'a':
			bindanyflag = 1;
			break;
		case 'n':
			set_nfsdcnt(atoi(optarg));
			break;
		case 'h':
			bindhostc++;
			bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
			if (bindhost == NULL) 
				errx(1, "Out of memory");
			bindhost[bindhostc-1] = strdup(optarg);
			if (bindhost[bindhostc-1] == NULL)
				errx(1, "Out of memory");
			break;
		case 'r':
			reregister = 1;
			break;
		case 'd':
			unregister = 1;
			break;
		case 't':
			tcpflag = 1;
			break;
		case 'u':
			udpflag = 1;
			break;
		case 'e':
			/* now a no-op, since this is the default */
			break;
		case 0:
			lopt = longopts[longindex].name;
			if (!strcmp(lopt, "minthreads")) {
				minthreads = atoi(optarg);
			} else if (!strcmp(lopt, "maxthreads")) {
				maxthreads = atoi(optarg);
			}
			break;
		default:
		case '?':
			usage();
		};
	if (!tcpflag && !udpflag)
		udpflag = 1;
	argv += optind;
	argc -= optind;
	if (minthreads_set && maxthreads_set && minthreads > maxthreads)
		errx(EX_USAGE,
		    "error: minthreads(%d) can't be greater than "
		    "maxthreads(%d)", minthreads, maxthreads);

	/*
	 * XXX
	 * Backward compatibility, trailing number is the count of daemons.
	 */
	if (argc > 1)
		usage();
	if (argc == 1)
		set_nfsdcnt(atoi(argv[0]));

	/*
	 * Unless the "-o" option was specified, try and run "nfsd".
	 * If "-o" was specified, try and run "nfsserver".
	 */
	if (modfind("nfsd") < 0) {
		/* Not present in kernel, try loading it */
		if (kldload("nfsd") < 0 || modfind("nfsd") < 0)
			errx(1, "NFS server is not available");
	}

	ip6flag = 1;
	s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
	if (s == -1) {
		if (errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT)
			err(1, "socket");
		ip6flag = 0;
	} else if (getnetconfigent("udp6") == NULL ||
		getnetconfigent("tcp6") == NULL) {
		ip6flag = 0;
	}
	if (s != -1)
		close(s);

	if (bindhostc == 0 || bindanyflag) {
		bindhostc++;
		bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
		if (bindhost == NULL) 
			errx(1, "Out of memory");
		bindhost[bindhostc-1] = strdup("*");
		if (bindhost[bindhostc-1] == NULL) 
			errx(1, "Out of memory");
	}

	if (unregister) {
		unregistration();
		exit (0);
	}
	if (reregister) {
		if (udpflag) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
			if (ecode != 0)
				err(1, "getaddrinfo udp: %s", gai_strerror(ecode));
			nconf_udp = getnetconfigent("udp");
			if (nconf_udp == NULL)
				err(1, "getnetconfigent udp failed");
			nb_udp.buf = ai_udp->ai_addr;
			nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp, &nb_udp)) ||
			    (!rpcb_set(NFS_PROGRAM, 3, nconf_udp, &nb_udp)))
				err(1, "rpcb_set udp failed");
			freeaddrinfo(ai_udp);
		}
		if (udpflag && ip6flag) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
			if (ecode != 0)
				err(1, "getaddrinfo udp6: %s", gai_strerror(ecode));
			nconf_udp6 = getnetconfigent("udp6");
			if (nconf_udp6 == NULL)
				err(1, "getnetconfigent udp6 failed");
			nb_udp6.buf = ai_udp6->ai_addr;
			nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp6, &nb_udp6)) ||
			    (!rpcb_set(NFS_PROGRAM, 3, nconf_udp6, &nb_udp6)))
				err(1, "rpcb_set udp6 failed");
			freeaddrinfo(ai_udp6);
		}
		if (tcpflag) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
			if (ecode != 0)
				err(1, "getaddrinfo tcp: %s", gai_strerror(ecode));
			nconf_tcp = getnetconfigent("tcp");
			if (nconf_tcp == NULL)
				err(1, "getnetconfigent tcp failed");
			nb_tcp.buf = ai_tcp->ai_addr;
			nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp, &nb_tcp)) ||
			    (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp, &nb_tcp)))
				err(1, "rpcb_set tcp failed");
			freeaddrinfo(ai_tcp);
		}
		if (tcpflag && ip6flag) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
			if (ecode != 0)
				err(1, "getaddrinfo tcp6: %s", gai_strerror(ecode));
			nconf_tcp6 = getnetconfigent("tcp6");
			if (nconf_tcp6 == NULL)
				err(1, "getnetconfigent tcp6 failed");
			nb_tcp6.buf = ai_tcp6->ai_addr;
			nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp6, &nb_tcp6)) ||
			    (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp6, &nb_tcp6)))
				err(1, "rpcb_set tcp6 failed");
			freeaddrinfo(ai_tcp6);
		}
		exit (0);
	}
	if (debug == 0) {
		daemon(0, 0);
		(void)signal(SIGHUP, SIG_IGN);
		(void)signal(SIGINT, SIG_IGN);
		/*
		 * nfsd sits in the kernel most of the time.  It needs
		 * to ignore SIGTERM/SIGQUIT in order to stay alive as long
		 * as possible during a shutdown, otherwise loopback
		 * mounts will not be able to unmount. 
		 */
		(void)signal(SIGTERM, SIG_IGN);
		(void)signal(SIGQUIT, SIG_IGN);
	}
	(void)signal(SIGSYS, nonfs);
	(void)signal(SIGCHLD, reapchild);
	(void)signal(SIGUSR2, backup_stable);

	openlog("nfsd", LOG_PID | (debug ? LOG_PERROR : 0), LOG_DAEMON);

	/*
	 * For V4, we open the stablerestart file and call nfssvc()
	 * to get it loaded. This is done before the daemons do the
	 * regular nfssvc() call to service NFS requests.
	 * (This way the file remains open until the last nfsd is killed
	 *  off.)
	 * It and the backup copy will be created as empty files
	 * the first time this nfsd is started and should never be
	 * deleted/replaced if at all possible. It should live on a
	 * local, non-volatile storage device that does not do hardware
	 * level write-back caching. (See SCSI doc for more information
	 * on how to prevent write-back caching on SCSI disks.)
	 */
	open_stable(&stablefd, &backupfd);
	if (stablefd < 0) {
		syslog(LOG_ERR, "Can't open %s: %m\n", NFSD_STABLERESTART);
		exit(1);
	}
	/* This system call will fail for old kernels, but that's ok. */
	nfssvc(NFSSVC_BACKUPSTABLE, NULL);
	if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) {
		syslog(LOG_ERR, "Can't read stable storage file: %m\n");
		exit(1);
	}
	nfssvc_addsock = NFSSVC_NFSDADDSOCK;
	nfssvc_nfsd = NFSSVC_NFSDNFSD;

	if (tcpflag) {
		/*
		 * For TCP mode, we fork once to start the first
		 * kernel nfsd thread. The kernel will add more
		 * threads as needed.
		 */
		pid = fork();
		if (pid == -1) {
			syslog(LOG_ERR, "fork: %m");
			nfsd_exit(1);
		}
		if (pid) {
			children[0] = pid;
		} else {
			(void)signal(SIGUSR1, child_cleanup);
			setproctitle("server");
			start_server(0);
		}
	}

	(void)signal(SIGUSR1, cleanup);
	FD_ZERO(&v4bits);
	FD_ZERO(&v6bits);
	FD_ZERO(&sockbits);
 
	rpcbregcnt = 0;
	/* Set up the socket for udp and rpcb register it. */
	if (udpflag) {
		rpcbreg = 0;
		for (i = 0; i < bindhostc; i++) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			if (setbindhost(&ai_udp, bindhost[i], hints) == 0) {
				rpcbreg = 1;
				rpcbregcnt++;
				if ((sock = socket(ai_udp->ai_family,
				    ai_udp->ai_socktype,
				    ai_udp->ai_protocol)) < 0) {
					syslog(LOG_ERR,
					    "can't create udp socket");
					nfsd_exit(1);
				}
				if (bind(sock, ai_udp->ai_addr,
				    ai_udp->ai_addrlen) < 0) {
					syslog(LOG_ERR,
					    "can't bind udp addr %s: %m",
					    bindhost[i]);
					nfsd_exit(1);
				}
				freeaddrinfo(ai_udp);
				addsockargs.sock = sock;
				addsockargs.name = NULL;
				addsockargs.namelen = 0;
				if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
					syslog(LOG_ERR, "can't Add UDP socket");
					nfsd_exit(1);
				}
				(void)close(sock);
			}
		}
		if (rpcbreg == 1) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
			if (ecode != 0) {
				syslog(LOG_ERR, "getaddrinfo udp: %s",
				   gai_strerror(ecode));
				nfsd_exit(1);
			}
			nconf_udp = getnetconfigent("udp");
			if (nconf_udp == NULL)
				err(1, "getnetconfigent udp failed");
			nb_udp.buf = ai_udp->ai_addr;
			nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp, &nb_udp)) ||
			    (!rpcb_set(NFS_PROGRAM, 3, nconf_udp, &nb_udp)))
				err(1, "rpcb_set udp failed");
			freeaddrinfo(ai_udp);
		}
	}

	/* Set up the socket for udp6 and rpcb register it. */
	if (udpflag && ip6flag) {
		rpcbreg = 0;
		for (i = 0; i < bindhostc; i++) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			if (setbindhost(&ai_udp6, bindhost[i], hints) == 0) {
				rpcbreg = 1;
				rpcbregcnt++;
				if ((sock = socket(ai_udp6->ai_family,
				    ai_udp6->ai_socktype,
				    ai_udp6->ai_protocol)) < 0) {
					syslog(LOG_ERR,
						"can't create udp6 socket");
					nfsd_exit(1);
				}
				if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
				    &on, sizeof on) < 0) {
					syslog(LOG_ERR,
					    "can't set v6-only binding for "
					    "udp6 socket: %m");
					nfsd_exit(1);
				}
				if (bind(sock, ai_udp6->ai_addr,
				    ai_udp6->ai_addrlen) < 0) {
					syslog(LOG_ERR,
					    "can't bind udp6 addr %s: %m",
					    bindhost[i]);
					nfsd_exit(1);
				}
				freeaddrinfo(ai_udp6);
				addsockargs.sock = sock;
				addsockargs.name = NULL;
				addsockargs.namelen = 0;
				if (nfssvc(nfssvc_addsock, &addsockargs) < 0) {
					syslog(LOG_ERR,
					    "can't add UDP6 socket");
					nfsd_exit(1);
				}
				(void)close(sock);    
			}
		}
		if (rpcbreg == 1) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
			if (ecode != 0) {
				syslog(LOG_ERR, "getaddrinfo udp6: %s",
				   gai_strerror(ecode));
				nfsd_exit(1);
			}
			nconf_udp6 = getnetconfigent("udp6");
			if (nconf_udp6 == NULL)
				err(1, "getnetconfigent udp6 failed");
			nb_udp6.buf = ai_udp6->ai_addr;
			nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_udp6, &nb_udp6)) ||
			    (!rpcb_set(NFS_PROGRAM, 3, nconf_udp6, &nb_udp6)))
				err(1, "rpcb_set udp6 failed");
			freeaddrinfo(ai_udp6);
		}
	}

	/* Set up the socket for tcp and rpcb register it. */
	if (tcpflag) {
		rpcbreg = 0;
		for (i = 0; i < bindhostc; i++) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			if (setbindhost(&ai_tcp, bindhost[i], hints) == 0) {
				rpcbreg = 1;
				rpcbregcnt++;
				if ((tcpsock = socket(AF_INET, SOCK_STREAM,
				    0)) < 0) {
					syslog(LOG_ERR,
					    "can't create tcp socket");
					nfsd_exit(1);
				}
				if (setsockopt(tcpsock, SOL_SOCKET,
				    SO_REUSEADDR,
				    (char *)&on, sizeof(on)) < 0)
					syslog(LOG_ERR,
					     "setsockopt SO_REUSEADDR: %m");
				if (bind(tcpsock, ai_tcp->ai_addr,
				    ai_tcp->ai_addrlen) < 0) {
					syslog(LOG_ERR,
					    "can't bind tcp addr %s: %m",
					    bindhost[i]);
					nfsd_exit(1);
				}
				if (listen(tcpsock, -1) < 0) {
					syslog(LOG_ERR, "listen failed");
					nfsd_exit(1);
				}
				freeaddrinfo(ai_tcp);
				FD_SET(tcpsock, &sockbits);
				FD_SET(tcpsock, &v4bits); 
				maxsock = tcpsock;
				connect_type_cnt++;
			}
		}
		if (rpcbreg == 1) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			ecode = getaddrinfo(NULL, "nfs", &hints,
			     &ai_tcp);
			if (ecode != 0) {
				syslog(LOG_ERR, "getaddrinfo tcp: %s",
				   gai_strerror(ecode));
				nfsd_exit(1);
			}
			nconf_tcp = getnetconfigent("tcp");
			if (nconf_tcp == NULL)
				err(1, "getnetconfigent tcp failed");
			nb_tcp.buf = ai_tcp->ai_addr;
			nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp,
			    &nb_tcp)) || (!rpcb_set(NFS_PROGRAM, 3,
			    nconf_tcp, &nb_tcp)))
				err(1, "rpcb_set tcp failed");
			freeaddrinfo(ai_tcp);
		}
	}

	/* Set up the socket for tcp6 and rpcb register it. */
	if (tcpflag && ip6flag) {
		rpcbreg = 0;
		for (i = 0; i < bindhostc; i++) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			if (setbindhost(&ai_tcp6, bindhost[i], hints) == 0) {
				rpcbreg = 1;
				rpcbregcnt++;
				if ((tcp6sock = socket(ai_tcp6->ai_family,
				    ai_tcp6->ai_socktype,
				    ai_tcp6->ai_protocol)) < 0) {
					syslog(LOG_ERR,
					    "can't create tcp6 socket");
					nfsd_exit(1);
				}
				if (setsockopt(tcp6sock, SOL_SOCKET,
				    SO_REUSEADDR,
				    (char *)&on, sizeof(on)) < 0)
					syslog(LOG_ERR,
					    "setsockopt SO_REUSEADDR: %m");
				if (setsockopt(tcp6sock, IPPROTO_IPV6,
				    IPV6_V6ONLY, &on, sizeof on) < 0) {
					syslog(LOG_ERR,
					"can't set v6-only binding for tcp6 "
					    "socket: %m");
					nfsd_exit(1);
				}
				if (bind(tcp6sock, ai_tcp6->ai_addr,
				    ai_tcp6->ai_addrlen) < 0) {
					syslog(LOG_ERR,
					    "can't bind tcp6 addr %s: %m",
					    bindhost[i]);
					nfsd_exit(1);
				}
				if (listen(tcp6sock, -1) < 0) {
					syslog(LOG_ERR, "listen failed");
					nfsd_exit(1);
				}
				freeaddrinfo(ai_tcp6);
				FD_SET(tcp6sock, &sockbits);
				FD_SET(tcp6sock, &v6bits);
				if (maxsock < tcp6sock)
					maxsock = tcp6sock;
				connect_type_cnt++;
			}
		}
		if (rpcbreg == 1) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
			if (ecode != 0) {
				syslog(LOG_ERR, "getaddrinfo tcp6: %s",
				   gai_strerror(ecode));
				nfsd_exit(1);
			}
			nconf_tcp6 = getnetconfigent("tcp6");
			if (nconf_tcp6 == NULL)
				err(1, "getnetconfigent tcp6 failed");
			nb_tcp6.buf = ai_tcp6->ai_addr;
			nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
			if ((!rpcb_set(NFS_PROGRAM, 2, nconf_tcp6, &nb_tcp6)) ||
			    (!rpcb_set(NFS_PROGRAM, 3, nconf_tcp6, &nb_tcp6)))
				err(1, "rpcb_set tcp6 failed");
			freeaddrinfo(ai_tcp6);
		}
	}

	if (rpcbregcnt == 0) {
		syslog(LOG_ERR, "rpcb_set() failed, nothing to do: %m");
		nfsd_exit(1);
	}

	if (tcpflag && connect_type_cnt == 0) {
		syslog(LOG_ERR, "tcp connects == 0, nothing to do: %m");
		nfsd_exit(1);
	}

	setproctitle("master");
	/*
	 * We always want a master to have a clean way to to shut nfsd down
	 * (with unregistration): if the master is killed, it unregisters and
	 * kills all children. If we run for UDP only (and so do not have to
	 * loop waiting waiting for accept), we instead make the parent
	 * a "server" too. start_server will not return.
	 */
	if (!tcpflag)
		start_server(1);

	/*
	 * Loop forever accepting connections and passing the sockets
	 * into the kernel for the mounts.
	 */
	for (;;) {
		ready = sockbits;
		if (connect_type_cnt > 1) {
			if (select(maxsock + 1,
			    &ready, NULL, NULL, NULL) < 1) {
				error = errno;
				if (error == EINTR)
					continue;
				syslog(LOG_ERR, "select failed: %m");
				nfsd_exit(1);
			}
		}
		for (tcpsock = 0; tcpsock <= maxsock; tcpsock++) {
			if (FD_ISSET(tcpsock, &ready)) {
				if (FD_ISSET(tcpsock, &v4bits)) {
					len = sizeof(inetpeer);
					if ((msgsock = accept(tcpsock,
					    (struct sockaddr *)&inetpeer, &len)) < 0) {
						error = errno;
						syslog(LOG_ERR, "accept failed: %m");
						if (error == ECONNABORTED ||
						    error == EINTR)
							continue;
						nfsd_exit(1);
					}
					memset(inetpeer.sin_zero, 0,
						sizeof(inetpeer.sin_zero));
					if (setsockopt(msgsock, SOL_SOCKET,
					    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
						syslog(LOG_ERR,
						    "setsockopt SO_KEEPALIVE: %m");
					addsockargs.sock = msgsock;
					addsockargs.name = (caddr_t)&inetpeer;
					addsockargs.namelen = len;
					nfssvc(nfssvc_addsock, &addsockargs);
					(void)close(msgsock);
				} else if (FD_ISSET(tcpsock, &v6bits)) {
					len = sizeof(inet6peer);
					if ((msgsock = accept(tcpsock,
					    (struct sockaddr *)&inet6peer,
					    &len)) < 0) {
						error = errno;
						syslog(LOG_ERR,
						     "accept failed: %m");
						if (error == ECONNABORTED ||
						    error == EINTR)
							continue;
						nfsd_exit(1);
					}
					if (setsockopt(msgsock, SOL_SOCKET,
					    SO_KEEPALIVE, (char *)&on,
					    sizeof(on)) < 0)
						syslog(LOG_ERR, "setsockopt "
						    "SO_KEEPALIVE: %m");
					addsockargs.sock = msgsock;
					addsockargs.name = (caddr_t)&inet6peer;
					addsockargs.namelen = len;
					nfssvc(nfssvc_addsock, &addsockargs);
					(void)close(msgsock);
				}
			}
		}
	}
}
Beispiel #5
0
CreateWellKnownSockets ()
{
    struct t_bind bind_addr;
    struct netconfig *nconf;
    struct nd_hostserv service;
    struct nd_addrlist *servaddrs;
    char *name, *localHostname();
    char bindbuf[15];
    int it;

    if (request_port == 0)
	return;
    Debug ("creating UDP stream %d\n", request_port);

    nconf = getnetconfigent("udp");
    if (!nconf) {
	t_error("getnetconfigent udp");
	return;
    }

    xdmcpFd = t_open(nconf->nc_device, O_RDWR, NULL);
    if (xdmcpFd == -1) {
	LogError ("XDMCP stream creation failed\n");
	t_error ("t_open");
	return;
    }
    name = localHostname ();
    registerHostname (name, strlen (name));
    RegisterCloseOnFork (xdmcpFd);

    service.h_host = HOST_SELF;
    sprintf(bindbuf, "%d", request_port);
    service.h_serv = bindbuf;
    netdir_getbyname(nconf, &service, &servaddrs);
    freenetconfigent(nconf);

    bind_addr.qlen = 5;
    bind_addr.addr.buf = servaddrs->n_addrs[0].buf;
    bind_addr.addr.len = servaddrs->n_addrs[0].len;
    it = t_bind(xdmcpFd, &bind_addr, &bind_addr);
    netdir_free(servaddrs, ND_ADDRLIST);
    if (it < 0)
    {
	LogError ("error binding STREAMS address %d\n", request_port);
	t_error("t_bind");	/* also goes to log file */
	t_close (xdmcpFd);
	xdmcpFd = -1;
	return;
    }
    WellKnownSocketsMax = xdmcpFd;
    FD_SET (xdmcpFd, &WellKnownSocketsMask);

    chooserFd = t_open ("/dev/tcp", O_RDWR, NULL);
    Debug ("Created chooser fd %d\n", chooserFd);
    if (chooserFd == -1)
    {
	LogError ("chooser stream creation failed\n");
	t_error("t_open chooser");
	return;
    }
    if (chooserFd > WellKnownSocketsMax)
	WellKnownSocketsMax = chooserFd;
    FD_SET (chooserFd, &WellKnownSocketsMask);
}
Beispiel #6
0
/*
 * Initialize sockets and congestion for a new NFS connection.
 * We do not free the sockaddr if error.
 */
int
nfs_connect(struct nfsmount *nmp)
{
	int rcvreserve, sndreserve;
	int pktscale;
	struct sockaddr *saddr;
	struct ucred *origcred;
	struct thread *td = curthread;
	CLIENT *client;
	struct netconfig *nconf;
	rpcvers_t vers;
	int one = 1, retries;
	struct timeval timo;

	/*
	 * We need to establish the socket using the credentials of
	 * the mountpoint.  Some parts of this process (such as
	 * sobind() and soconnect()) will use the curent thread's
	 * credential instead of the socket credential.  To work
	 * around this, temporarily change the current thread's
	 * credential to that of the mountpoint.
	 *
	 * XXX: It would be better to explicitly pass the correct
	 * credential to sobind() and soconnect().
	 */
	origcred = td->td_ucred;
	td->td_ucred = nmp->nm_mountp->mnt_cred;
	saddr = nmp->nm_nam;

	vers = NFS_VER2;
	if (nmp->nm_flag & NFSMNT_NFSV3)
		vers = NFS_VER3;
	else if (nmp->nm_flag & NFSMNT_NFSV4)
		vers = NFS_VER4;
	if (saddr->sa_family == AF_INET)
		if (nmp->nm_sotype == SOCK_DGRAM)
			nconf = getnetconfigent("udp");
		else
			nconf = getnetconfigent("tcp");
	else
		if (nmp->nm_sotype == SOCK_DGRAM)
			nconf = getnetconfigent("udp6");
		else
			nconf = getnetconfigent("tcp6");

	/*
	 * Get buffer reservation size from sysctl, but impose reasonable
	 * limits.
	 */
	pktscale = nfs_bufpackets;
	if (pktscale < 2)
		pktscale = 2;
	if (pktscale > 64)
		pktscale = 64;
	mtx_lock(&nmp->nm_mtx);
	if (nmp->nm_sotype == SOCK_DGRAM) {
		sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * pktscale;
		rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
		    NFS_MAXPKTHDR) * pktscale;
	} else if (nmp->nm_sotype == SOCK_SEQPACKET) {
		sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * pktscale;
		rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
		    NFS_MAXPKTHDR) * pktscale;
	} else {
		if (nmp->nm_sotype != SOCK_STREAM)
			panic("nfscon sotype");
		sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
		    sizeof (u_int32_t)) * pktscale;
		rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR +
		    sizeof (u_int32_t)) * pktscale;
	}
	mtx_unlock(&nmp->nm_mtx);

	client = clnt_reconnect_create(nconf, saddr, NFS_PROG, vers,
	    sndreserve, rcvreserve);
	CLNT_CONTROL(client, CLSET_WAITCHAN, "nfsreq");
	if (nmp->nm_flag & NFSMNT_INT)
		CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one);
	if (nmp->nm_flag & NFSMNT_RESVPORT)
		CLNT_CONTROL(client, CLSET_PRIVPORT, &one);
	if ((nmp->nm_flag & NFSMNT_SOFT) != 0) {
		if (nmp->nm_sotype == SOCK_DGRAM)
			/*
			 * For UDP, the large timeout for a reconnect will
			 * be set to "nm_retry * nm_timeo / 2", so we only
			 * want to do 2 reconnect timeout retries.
			 */
			retries = 2;
		else
			retries = nmp->nm_retry;
	} else
		retries = INT_MAX;
	CLNT_CONTROL(client, CLSET_RETRIES, &retries);

	/*
	 * For UDP, there are 2 timeouts:
	 * - CLSET_RETRY_TIMEOUT sets the initial timeout for the timer
	 *   that does a retransmit of an RPC request using the same socket
	 *   and xid. This is what you normally want to do, since NFS
	 *   servers depend on "same xid" for their Duplicate Request Cache.
	 * - timeout specified in CLNT_CALL_MBUF(), which specifies when
	 *   retransmits on the same socket should fail and a fresh socket
	 *   created. Each of these timeouts counts as one CLSET_RETRIES,
	 *   as set above.
	 * Set the initial retransmit timeout for UDP. This timeout doesn't
	 * exist for TCP and the following call just fails, which is ok.
	 */
	timo.tv_sec = nmp->nm_timeo / NFS_HZ;
	timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * 1000000 / NFS_HZ;
	CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, &timo);

	mtx_lock(&nmp->nm_mtx);
	if (nmp->nm_client) {
		/*
		 * Someone else already connected.
		 */
		CLNT_RELEASE(client);
	} else
		nmp->nm_client = client;

	/*
	 * Protocols that do not require connections may be optionally left
	 * unconnected for servers that reply from a port other than NFS_PORT.
	 */
	if (!(nmp->nm_flag & NFSMNT_NOCONN)) {
		mtx_unlock(&nmp->nm_mtx);
		CLNT_CONTROL(client, CLSET_CONNECT, &one);
	} else
		mtx_unlock(&nmp->nm_mtx);

	/* Restore current thread's credentials. */
	td->td_ucred = origcred;

	mtx_lock(&nmp->nm_mtx);
	/* Initialize other non-zero congestion variables. */
	nfs_init_rtt(nmp);
	mtx_unlock(&nmp->nm_mtx);
	return (0);
}
Beispiel #7
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 0; //Default test result set to PASSED
	int progNum = atoi(argc[2]);
    int recVar = -1;
    CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct timeval tv;
	enum clnt_stat rslt;
	//Sent variables
	int intSnd;
	double dblSnd;
	long lngSnd;
	char *strSnd;
	//Received variables
	int intRec;
	double dblRec;
	long lngRec;
	char *strRec;

	//Test initialization
	//create client using intermediate level API
	nconf = getnetconfigent("udp");

    if ((struct netconfig *)nconf == NULL)
    {
    	//Test failed
    	printf("5\n");
    	return 5;
    }

    tv.tv_sec = 1;
	tv.tv_usec = 1;

    client = clnt_tp_create_timed(argc[1], progNum,
                                  VERSNUM, (struct netconfig *)nconf, &tv);

    if (client == NULL)
    {
    	printf("5\n");
    	return 5;
    }

	//Call tested procedure several times
	//Int test : call INTPROCNUM RPC
	intSnd = -65536;

	rslt = clnt_call(client, INTPROCNUM,
					 (xdrproc_t)xdr_int, (char *)&intSnd, // xdr_in
                     (xdrproc_t)xdr_int, (char *)&intRec, // xdr_out
                     tv);

	if (intSnd != intRec)
		test_status = 1;
	if (run_mode == 1)
		printf("Send (int) : %d, Received : %d\n", intSnd, intRec);

	//Test positive number
	intSnd = 16777216;

	rslt = clnt_call(client, INTPROCNUM,
					 (xdrproc_t)xdr_int, (char *)&intSnd, // xdr_in
                     (xdrproc_t)xdr_int, (char *)&intRec, // xdr_out
                     tv);

	if (intSnd != intRec)
		test_status = 1;
	if (run_mode == 1)
		printf("Send (int) : %d, Received : %d\n", intSnd, intRec);

	//Long test : call LNGPROCNUM RPC
	lngSnd = -430000;

	rslt = clnt_call(client, LNGPROCNUM,
					 (xdrproc_t)xdr_long, (char *)&lngSnd, // xdr_in
                     (xdrproc_t)xdr_long, (char *)&lngRec, // xdr_out
                     tv);

	if (lngSnd != lngRec)
		test_status = 1;
	if (run_mode == 1)
		printf("Send (long) : %ld, Received : %ld\n", lngSnd, lngRec);

	//Double test : call DBLPROCNUM RPC
	dblSnd = -1735.63000f;

	rslt = clnt_call(client, DBLPROCNUM,
					 (xdrproc_t)xdr_double, (char *)&dblSnd, // xdr_in
                     (xdrproc_t)xdr_double, (char *)&dblRec, // xdr_out
                     tv);

	if (dblSnd != dblRec)
		test_status = 1;
	if (run_mode == 1)
		printf("Send (double) : %lf, Received : %lf\n", dblSnd, dblRec);

	//String test : call STRPROCNUM RPC
	strSnd = "text to send.";
	strRec = (char *)malloc(64 * sizeof(char));

	rslt = clnt_call(client, STRPROCNUM,
					 (xdrproc_t)xdr_wrapstring, (char *)&strSnd, // xdr_in
                     (xdrproc_t)xdr_wrapstring, (char *)&strRec, // xdr_out
                     tv);

	if (strcmp(strSnd, strRec))
		test_status = 1;
	if (run_mode == 1)
		printf("Send (string) : %s, Received : %s\n", strSnd, strRec);

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
Beispiel #8
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 0; //Default test result set to PASS
	int progNum = atoi(argc[2]);
	int i;
	params paramList[NBCASE];
	SVCXPRT *transp = NULL;
	struct netconfig *nconf = NULL;

	//Initialization
    if (run_mode)
    {
    	printf("Before creation\n");
		printf("nconf : %d\n", nconf);
	}

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *) NULL)
	{
		//syslog(LOG_ERR, "getnetconfigent for udp failed");
		fprintf(stderr, "err nconf\n");
		printf("5\n");
		exit(1);
	}

	//Test arguments initialization
	paramList[0].bufmin = 0;
	paramList[0].bufmax = 2147483647;
	paramList[1].bufmin = 2147483647;
	paramList[1].bufmax = 0;
	paramList[2].bufmin = 2147483647;
	paramList[2].bufmax = 2147483647;

	//Call tested function using all tests cases
	for (i = 0; i < NBCASE; i++)
	{
		//Debug mode prints
		if (run_mode == 1)
		{
			printf("Test using values : %d ", paramList[i].bufmin);
			printf("%d", paramList[i].bufmax);
			printf("\n");
		}

		//Call function
		transp = svc_tli_create(RPC_ANYFD, nconf,
                            	(struct t_bind *)NULL,
                            	paramList[i].bufmin, paramList[i].bufmax);

		//Check result
		if (transp == NULL)
		{
			//test has failed
			test_status = 1;
			break;
		}
	}

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
Beispiel #9
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case
	
	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 0; //Default test result set to PASS
	int progNum = atoi(argc[2]);
	char nettype[16] = "visible";
	CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct timeval tv;
	bool_t rslt = 0;
	int fd = 0;
	struct netconfig *tst_nconf;
	unsigned long clver;

	//First, test initialization
	nconf = getnetconfigent("udp");
	
    if ((struct netconfig *)nconf == NULL) 
    {
    	//Test failed
    	printf("1\n");
    	return 1;
    }
    
    tv.tv_sec = 10;
	tv.tv_usec = 20;

    client = clnt_tp_create_timed(argc[1], progNum,
                                  VERSNUM, (struct netconfig *)nconf, &tv);
    if (client == (CLIENT *)NULL)
    {
    	//No client creation
    	printf("1\n");
    	return 1;
    }
	
	//Call tested function using all tests cases
	rslt = clnt_control(client, CLGET_SVC_ADDR, (struct netbuf *)&tst_nconf);
	if (rslt == 0)
	{
		test_status = 1;
	}
	
	rslt = clnt_control(client, CLGET_TIMEOUT, (struct timeval *)&tv);
	if (rslt == 0)
	{
		test_status = 1;
	}
	
	rslt = clnt_control(client, CLGET_FD, (int *)&fd);
	if (rslt == 0)
	{
		test_status = 1;
	}
	
	rslt = clnt_control(client, CLGET_VERS, (unsigned long *)&clver);
	if (rslt == 0)
	{
		test_status = 1;
	}
	
	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);
	
	return test_status;
}
Beispiel #10
0
int
main(int argc, char *argv[])
{
	struct netconfig *nconf;
	void *nc_handle;	/* Net config handle */
	struct rlimit rl;
	int maxrec = RPC_MAXDATASIZE;

	parseargs(argc, argv);

	/* Check that another rpcbind isn't already running. */
	if ((rpcbindlockfd = (open(RPCBINDDLOCK,
	    O_RDONLY|O_CREAT, 0444))) == -1)
		err(1, "%s", RPCBINDDLOCK);

	if(flock(rpcbindlockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK)
		errx(1, "another rpcbind is already running. Aborting");

	getrlimit(RLIMIT_NOFILE, &rl);
	if (rl.rlim_cur < 128) {
		if (rl.rlim_max <= 128)
			rl.rlim_cur = rl.rlim_max;
		else
			rl.rlim_cur = 128;
		setrlimit(RLIMIT_NOFILE, &rl);
	}
	openlog("rpcbind", LOG_CONS, LOG_DAEMON);
	if (geteuid()) { /* This command allowed only to root */
		fprintf(stderr, "Sorry. You are not superuser\n");
		exit(1);
	}

	/*
	 * Make sure we use the local service file 
	 * for service lookkups
	 */
	__nss_configure_lookup("services", "files");

	nc_handle = setnetconfig(); 	/* open netconfig file */
	if (nc_handle == NULL) {
		syslog(LOG_ERR, "could not read /etc/netconfig");
		exit(1);
	}

	nconf = getnetconfigent("local");
	if (nconf == NULL)
		nconf = getnetconfigent("unix");
	if (nconf == NULL) {
		syslog(LOG_ERR, "%s: can't find local transport\n", argv[0]);
		exit(1);
	}
	
	rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);

	init_transport(nconf);

	while ((nconf = getnetconfig(nc_handle))) {
		if (nconf->nc_flag & NC_VISIBLE)
			init_transport(nconf);
	}
	endnetconfig(nc_handle);

#ifdef PORTMAP
	if (!udptrans)
		udptrans = "";
	if (!tcptrans)
		tcptrans = "";
#endif

	/* catch the usual termination signals for graceful exit */
	(void) signal(SIGCHLD, reap);
	(void) signal(SIGINT, terminate);
	(void) signal(SIGTERM, terminate);
	(void) signal(SIGQUIT, terminate);
	/* ignore others that could get sent */
	(void) signal(SIGPIPE, SIG_IGN);
	(void) signal(SIGHUP, SIG_IGN);
	(void) signal(SIGUSR1, SIG_IGN);
	(void) signal(SIGUSR2, SIG_IGN);

	if (debugging) {
#ifdef RPCBIND_DEBUG 
		printf("rpcbind debugging enabled.");
		if (doabort) {
			printf("  Will abort on errors!\n");
		} else {
			printf("\n");
		}
#endif
	} else {
		if (daemon(0, 0)) 
        		err(1, "fork failed");
	}

	if (runasdaemon || rpcbinduser) {
		struct passwd *p;
		char *id = runasdaemon ? RUN_AS : rpcbinduser;

		/*
		 * Make sure we use the local password file
		 * for these lookups.
		 */
		__nss_configure_lookup("passwd", "files");

		if((p = getpwnam(id)) == NULL) {
			syslog(LOG_ERR, "cannot get uid of '%s': %m", id);
			exit(1);
		}
                if (setgid(p->pw_gid) == -1) {
                        syslog(LOG_ERR, "setgid to '%s' (%d) failed: %m", id, p->pw_gid);
                        exit(1);
                }
		if (setuid(p->pw_uid) == -1) {
			syslog(LOG_ERR, "setuid to '%s' (%d) failed: %m", id, p->pw_uid);
			exit(1);
		}
	}

#ifdef WARMSTART
	if (warmstart) {
		read_warmstart();
	}
#endif

	network_init();

	my_svc_run();
	syslog(LOG_ERR, "svc_run returned unexpectedly");
	rpcbind_abort();
	/* NOTREACHED */

	return 0;
}
Beispiel #11
0
int
main(int argc, char **argv)
{
	struct stat buf;
	int ret;
	char scratch[BUFSIZ];
	char log[BUFSIZ];
	char olog[BUFSIZ];
	char *scratch_p = scratch;
	char *mytag_p;
	FILE *fp;
	extern char *getenv();
	char *parse();
	int	c;
	extern	char *optarg;
	extern	int optind;
	int i;
	char	*Mytag_p = Mytag;

	/* Get my port monitor tag out of the environment		*/
	if ((mytag_p = getenv("PMTAG")) == NULL) {
		/* no place to write */
		exit(1);
	}
	strcpy(Mytag, mytag_p);

	/* open log file */
	sprintf(log, "%s/%s/%s", ALTDIR, Mytag_p, LOGNAME);
	sprintf(olog, "%s/%s/%s", ALTDIR, Mytag_p, OLOGNAME);
	if (stat(log, &buf) == 0) {
		/* file exists, try and save it but if we can't don't worry */
		unlink(olog);
		rename(log, olog);
	}
	if ((i = open(log, O_WRONLY|O_CREAT|O_APPEND, 0444)) < 0)
		logexit(1, nologfile);
	/* as stated above, the log file should be file descriptor 5 */
	if ((ret = fcntl(i, F_DUPFD, 5)) != 5)
		logexit(1, nologfile);
	Logfp = fdopen(ret, "a+");

	/* Get my port monitor tag out of the environment		*/
	if ((mytag_p = getenv("PMTAG")) == NULL) {
		logexit(1, nopmtag);
	}
	strcpy(Mytag, mytag_p);

	(void) umask(022);
	Readdb = FALSE;

	if (geteuid() != (uid_t) 0) {
		logmessage("Must be root to start listener");
		logexit(1, badstart);
	}

	while ((c = getopt(argc, argv, "m:")) != EOF) 
		switch (c) {
		case 'm':
			Minor_prefix = optarg;
			break;
		default:
			logexit(1, usage);
			break;
		}

	if ((Netspec = argv[optind]) == NULL) {
		logexit(1, usage);
	}
	if ((Netconf = getnetconfigent(Netspec)) == NULL) {
		sprintf(scratch, "no netconfig entry for <%s>", Netspec);
		logmessage(scratch);
		logexit(1, badstart);
	}
	if (!Minor_prefix)
		Minor_prefix = argv[optind];

	if ((int) strlen(Netspec) > PATHSIZE)  {
		logmessage(badnspmsg);
		logexit(1, badstart);
	}

	/* 
	 * SAC will start the listener in the correct directory, so we
	 * don't need to chdir there, as we did in older versions
	 */

	strcpy(Provbuf, "/dev/");
	strcat(Provbuf, Netspec);

	(void) umask(0);

	init_files();		/* open Accept, Sac, Pm, Pass files	*/
	pid_open();		/* create pid file			*/

#ifdef	DEBUGMODE
	sprintf(scratch, "%s/%s/%s", ALTDIR, Mytag, DBGNAME);
	Debugfp = fopen(scratch, "w");
#endif


#ifdef	DEBUGMODE
	if ((!Logfp) || (!Debugfp)) 
#else
	if (!Logfp)
#endif
		logexit(1, badstart);

/*
 * In case we started with no environment, find out what timezone we're
 * in.  This will get passed to children, so only need to do once.
 */

	if (getenv("TZ") == NULL) {
		fp = fopen(TZFILE, "r");
		if (fp) {
			while (fgets(tzenv, BUFSIZ, fp)) {
				if (tzenv[strlen(tzenv) - 1] == '\n')
					tzenv[strlen(tzenv) - 1] = '\0';
				if (!strncmp(TZSTR, tzenv, strlen(TZSTR))) {
					putenv(parse(tzenv));
					break;
				}
			}
			fclose(fp);
		}
		else {
			sprintf(scratch, "couldn't open %s, default to GMT",
			    TZFILE);
			logmessage(scratch);
		}
	}

	logmessage("@(#)listen:listen.c	1.19.9.1");

#ifdef	DEBUGMODE
	logmessage("Listener process with DEBUG capability");
#endif

	sprintf(scratch, "Listener port monitor tag: %s", Mytag_p);
	logmessage(scratch);
	DEBUG((9, "Minor prefix: %s  Netspec %s", Minor_prefix, Netspec));

	/* fill in Pmmesg fields that always stay the same */

	Pmmsg.pm_maxclass = MAXCLASS;
	strcpy(Pmmsg.pm_tag, Mytag_p);
	Pmmsg.pm_size = 0;

	/* Find out what state to start in.  If not in env, exit */
	if ((scratch_p = getenv("ISTATE")) == NULL)
		logexit(1, "ERROR: ISTATE variable not set in environment");
	
	if (!strcmp(scratch_p, "enabled")) {
		State = PM_ENABLED;
		logmessage("Starting state: ENABLED");
	}
	else {
		State = PM_DISABLED;
		logmessage("Starting state: DISABLED");
	}

	/* try to get my "basename"		*/
	Progname = strrchr(argv[0], '/');
	if (Progname && Progname[1])
		++Progname;
	else
		Progname = argv[0];

	catch_signals();

	/* 
	 * Allocate memory for private address and file descriptor table 
	 * Here we are assuming that no matter how many private addresses
	 * exist in the system if the system limit is 20 then we will only
	 * get 20 file descriptors
	 */

	Ndesc = ulimit(4,0L);		/* get num of file des on system */

	read_dbf(DB_INIT);
	net_open();			/* init, open, bind names 	*/

	for (i = 3; i < Ndesc; i++)  {	/* leave stdout, stderr open	*/
		fcntl(i, F_SETFD, 1);	/* set close on exec flag*/
	}

	logmessage("Initialization Complete");

	listen();
	return (0);
}
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//                                         argc[2] : Server Program Number
	//                                         argc[3] : Number of test call
	//                                         other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 0;	//Default test result set to FAILED
	int i;
	double *resultTbl;
	struct timeval tv1, tv2;
	struct timezone tz;
	long long diff;
	double rslt;
	int progNum = atoi(argc[2]);
	int sndVar = 0;
	int recVar = -1;
	CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct timeval tv;
	enum clnt_stat cs;

	//Test initialisation
	maxIter = atoi(argc[3]);
	resultTbl = (double *)malloc(maxIter * sizeof(double));

	nconf = getnetconfigent("udp");

	if ((struct netconfig *)nconf == NULL) {
		//Test failed
		printf("5\n");
		return 5;
	}

	tv.tv_sec = 1;
	tv.tv_usec = 1;

	client = clnt_tp_create_timed(argc[1], progNum,
				      VERSNUM, (struct netconfig *)nconf, &tv);

	if (client == NULL) {
		printf("5\n");
		return 5;
	}
	//Call tested function several times
	for (i = 0; i < maxIter; i++) {
		//Tic
		gettimeofday(&tv1, &tz);

		//Call function
		cs = clnt_call(client, PROCNUM, (xdrproc_t) xdr_int, (char *)&sndVar,	// xdr_in
			       (xdrproc_t) xdr_int, (char *)&recVar,	// xdr_out
			       tv);

		//Toc
		gettimeofday(&tv2, &tz);

		//Add function execution time (toc-tic)
		diff =
		    (tv2.tv_sec - tv1.tv_sec) * 1000000L + (tv2.tv_usec -
							    tv1.tv_usec);
		rslt = (double)diff / 1000;

		if (cs == RPC_SUCCESS) {
			resultTbl[i] = rslt;
		} else {
			test_status = 1;
			break;
		}

		if (run_mode) {
			fprintf(stderr, "lf time  = %lf usecn\n", resultTbl[i]);
		}
	}

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);
	printf("%lf %d\n", average(resultTbl), maxIter);
	printf("%lf\n", mini(resultTbl));
	printf("%lf\n", maxi(resultTbl));

	return test_status;
}
Beispiel #13
0
int
rpcbind_main(void *arg)
#endif
{
	struct netconfig *nconf;
	void *nc_handle;	/* Net config handle */
	struct rlimit rl;
	int maxrec = RPC_MAXDATASIZE;

#ifdef RPCBIND_RUMP
	svc_fdset_init(SVC_FDSET_MT);
#else
	parseargs(argc, argv);
#endif

	if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
		err(EXIT_FAILURE, "getrlimit(RLIMIT_NOFILE)");

	if (rl.rlim_cur < 128) {
		if (rl.rlim_max <= 128)
			rl.rlim_cur = rl.rlim_max;
		else
			rl.rlim_cur = 128;
		if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
			err(EXIT_FAILURE, "setrlimit(RLIMIT_NOFILE)");
	}
	nc_handle = setnetconfig(); 	/* open netconfig file */
	if (nc_handle == NULL)
		errx(EXIT_FAILURE, "could not read /etc/netconfig");
#ifdef PORTMAP
	udptrans = "";
	tcptrans = "";
#endif

	nconf = getnetconfigent("local");
	if (nconf == NULL)
		errx(EXIT_FAILURE, "can't find local transport");

	rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);

	init_transport(nconf);

	while ((nconf = getnetconfig(nc_handle))) {
		if (nconf->nc_flag & NC_VISIBLE)
			init_transport(nconf);
	}
	endnetconfig(nc_handle);

	/* catch the usual termination signals for graceful exit */
	(void) signal(SIGCHLD, reap);
	(void) signal(SIGINT, terminate);
	(void) signal(SIGTERM, terminate);
	(void) signal(SIGQUIT, terminate);
	/* ignore others that could get sent */
	(void) signal(SIGPIPE, SIG_IGN);
#ifndef RPCBIND_RUMP
	(void) signal(SIGHUP, SIG_IGN);
#endif
	(void) signal(SIGUSR1, SIG_IGN);
	(void) signal(SIGUSR2, SIG_IGN);
#ifdef WARMSTART
	if (warmstart) {
		read_warmstart();
	}
#endif
	if (debugging) {
		printf("rpcbind debugging enabled.");
		if (doabort) {
			printf("  Will abort on errors!\n");
		} else {
			printf("\n");
		}
	} else {
		if (daemon(0, 0))
			err(EXIT_FAILURE, "fork failed");
	}

	openlog("rpcbind", 0, LOG_DAEMON);
	pidfile(NULL);

	if (runasdaemon) {
		struct passwd *p;

		if((p = getpwnam(RUN_AS)) == NULL) {
			syslog(LOG_ERR, "cannot get uid of daemon: %m");
			exit(EXIT_FAILURE);
		}
		if (setuid(p->pw_uid) == -1) {
			syslog(LOG_ERR, "setuid to daemon failed: %m");
			exit(EXIT_FAILURE);
		}
	}

	network_init();

#ifdef RPCBIND_RUMP
	sem_post(&gensem);
#endif
	my_svc_run();
	syslog(LOG_ERR, "svc_run returned unexpectedly");
	rpcbind_abort();
	/* NOTREACHED */

	return EXIT_SUCCESS;
}
Beispiel #14
0
int
main(int argc, char *argv[])
{
	pid_t pid;
	int i;
	int connmaxrec = RPC_MAXDATASIZE;

	/*
	 * Set non-blocking mode and maximum record size for
	 * connection oriented RPC transports.
	 */
	if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &connmaxrec)) {
		msgout("unable to set maximum RPC record size");
	}

	/*
	 * If stdin looks like a TLI endpoint, we assume
	 * that we were started by a port monitor. If
	 * t_getstate fails with TBADF, this is not a
	 * TLI endpoint.
	 */
	if (t_getstate(0) != -1 || t_errno != TBADF) {
		char *netid;
		struct netconfig *nconf = NULL;
		SVCXPRT *transp;
		int pmclose;
		extern char *getenv();

		_rpcpmstart = 1;
		openlog("rusers", LOG_PID, LOG_DAEMON);
		if ((netid = getenv("NLSPROVIDER")) == NULL) {
#ifdef DEBUG
			msgout("cannot get transport name");
#endif
		} else if ((nconf = getnetconfigent(netid)) == NULL) {
#ifdef DEBUG
			msgout("cannot get transport info");
#endif
		}
		if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
			msgout("cannot create server handle");
			exit(1);
		}
		if (nconf)
			freenetconfigent(nconf);
		if (!svc_reg(transp, RUSERSPROG, RUSERSVERS_3, rusers_service,
				0)) {
	msgout("unable to register (RUSERSPROG, RUSERSVERS_3).");
			exit(1);
		}
		if (!svc_reg(transp, RUSERSPROG, RUSERSVERS_IDLE,
				rusers_service, 0)) {
	msgout("unable to register (RUSERSPROG, RUSERSVERS_IDLE).");
			exit(1);
		}
		(void) signal(SIGALRM, closedown);
		(void) alarm(_RPCSVC_CLOSEDOWN);
		svc_run();
		msgout("svc_run returned");
		exit(1);
		/* NOTREACHED */
	}
#ifndef RPC_SVC_FG
	pid = fork();
	if (pid < 0) {
		perror("rpc.rusersd: cannot fork");
		exit(1);
	}
	if (pid)
		exit(0);
	for (i = 0; i < 20; i++)
		(void) close(i);
	setsid();
	openlog("rusers", LOG_PID, LOG_DAEMON);
#endif
	if (!svc_create(rusers_service, RUSERSPROG, RUSERSVERS_3, "netpath")) {
	    msgout("unable to create (RUSERSPROG, RUSERSVERS_3) for netpath");
		exit(1);
	}
	if (!svc_create(rusers_service, RUSERSPROG, RUSERSVERS_IDLE,
			"netpath")) {
	    msgout(
		"unable to create (RUSERSPROG, RUSERSVERS_IDLE) for netpath");
		exit(1);
	}

	svc_run();
	msgout("svc_run returned");
	return (1);
}
Beispiel #15
0
/*
 * Nfs server daemon mostly just a user context for nfssvc()
 *
 * 1 - do file descriptor and signal cleanup
 * 2 - fork the nfsd(s)
 * 3 - create server socket(s)
 * 4 - register socket with rpcbind
 *
 * For connectionless protocols, just pass the socket into the kernel via.
 * nfssvc().
 * For connection based sockets, loop doing accepts. When you get a new
 * socket from accept, pass the msgsock into the kernel via. nfssvc().
 * The arguments are:
 *	-r - reregister with rpcbind
 *	-d - unregister with rpcbind
 *	-t - support tcp nfs clients
 *	-u - support udp nfs clients
 * followed by "n" which is the number of nfsds' to fork off
 */
int
main(int argc, char **argv)
{
	struct nfsd_args nfsdargs;
	struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
	struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
	struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
	struct sockaddr_in inetpeer;
	struct sockaddr_in6 inet6peer;
	fd_set ready, sockbits;
	fd_set v4bits, v6bits;
	int ch, connect_type_cnt, i, maxsock, msgsock;
	socklen_t len;
	int on = 1, unregister, reregister, sock;
	int tcp6sock, ip6flag, tcpflag, tcpsock;
	int udpflag, ecode, s, srvcnt;
	int bindhostc, bindanyflag, rpcbreg, rpcbregcnt;
	char **bindhost = NULL;
	pid_t pid;
	struct vfsconf vfc;
	int error;

	error = getvfsbyname("nfs", &vfc);
	if (error && vfsisloadable("nfs")) {
		if (vfsload("nfs"))
			err(1, "vfsload(nfs)");
		endvfsent();	/* flush cache */
		error = getvfsbyname("nfs", &vfc);
	}
	if (error)
		errx(1, "NFS is not available in the running kernel");

	nfsdcnt = DEFNFSDCNT;
	unregister = reregister = tcpflag = maxsock = 0;
	bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
#define	GETOPT	"ah:n:rdtu"
#define	USAGE	"[-ardtu] [-n num_servers] [-h bindip]"
	while ((ch = getopt(argc, argv, GETOPT)) != -1)
		switch (ch) {
		case 'a':
			bindanyflag = 1;
			break;
		case 'n':
			nfsdcnt = atoi(optarg);
			if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
				warnx("nfsd count %d; reset to %d", nfsdcnt,
				    DEFNFSDCNT);
				nfsdcnt = DEFNFSDCNT;
			}
			break;
		case 'h':
			bindhostc++;
			bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
			if (bindhost == NULL)
				errx(1, "Out of memory");
			bindhost[bindhostc-1] = strdup(optarg);
			if (bindhost[bindhostc-1] == NULL)
				errx(1, "Out of memory");
			break;
		case 'r':
			reregister = 1;
			break;
		case 'd':
			unregister = 1;
			break;
		case 't':
			tcpflag = 1;
			break;
		case 'u':
			udpflag = 1;
			break;
		default:
		case '?':
			usage();
		};
	if (!tcpflag && !udpflag)
		udpflag = 1;
	argv += optind;
	argc -= optind;

	/*
	 * XXX
	 * Backward compatibility, trailing number is the count of daemons.
	 */
	if (argc > 1)
		usage();
	if (argc == 1) {
		nfsdcnt = atoi(argv[0]);
		if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
			warnx("nfsd count %d; reset to %d", nfsdcnt,
			    DEFNFSDCNT);
			nfsdcnt = DEFNFSDCNT;
		}
	}

	ip6flag = 1;
	s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
	if (s == -1) {
		if (errno != EPROTONOSUPPORT)
			err(1, "socket");
		ip6flag = 0;
	} else if (getnetconfigent("udp6") == NULL ||
		getnetconfigent("tcp6") == NULL) {
		ip6flag = 0;
	}
	if (s != -1)
		close(s);

	if (bindhostc == 0 || bindanyflag) {
		bindhostc++;
		bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
		if (bindhost == NULL)
			errx(1, "Out of memory");
		bindhost[bindhostc-1] = strdup("*");
		if (bindhost[bindhostc-1] == NULL)
			errx(1, "Out of memory");
	}

	if (unregister) {
		unregistration();
		exit (0);
	}
	if (reregister) {
		if (udpflag) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
			if (ecode != 0)
				err(1, "getaddrinfo udp: %s", gai_strerror(ecode));
			nconf_udp = getnetconfigent("udp");
			if (nconf_udp == NULL)
				err(1, "getnetconfigent udp failed");
			nb_udp.buf = ai_udp->ai_addr;
			nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
			if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp)) ||
			    (!rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp)))
				err(1, "rpcb_set udp failed");
			freeaddrinfo(ai_udp);
		}
		if (udpflag && ip6flag) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
			if (ecode != 0)
				err(1, "getaddrinfo udp6: %s", gai_strerror(ecode));
			nconf_udp6 = getnetconfigent("udp6");
			if (nconf_udp6 == NULL)
				err(1, "getnetconfigent udp6 failed");
			nb_udp6.buf = ai_udp6->ai_addr;
			nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
			if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6)) ||
			    (!rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6)))
				err(1, "rpcb_set udp6 failed");
			freeaddrinfo(ai_udp6);
		}
		if (tcpflag) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
			if (ecode != 0)
				err(1, "getaddrinfo tcp: %s", gai_strerror(ecode));
			nconf_tcp = getnetconfigent("tcp");
			if (nconf_tcp == NULL)
				err(1, "getnetconfigent tcp failed");
			nb_tcp.buf = ai_tcp->ai_addr;
			nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
			if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp)) ||
			    (!rpcb_set(RPCPROG_NFS, 3, nconf_tcp, &nb_tcp)))
				err(1, "rpcb_set tcp failed");
			freeaddrinfo(ai_tcp);
		}
		if (tcpflag && ip6flag) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
			if (ecode != 0)
				err(1, "getaddrinfo tcp6: %s", gai_strerror(ecode));
			nconf_tcp6 = getnetconfigent("tcp6");
			if (nconf_tcp6 == NULL)
				err(1, "getnetconfigent tcp6 failed");
			nb_tcp6.buf = ai_tcp6->ai_addr;
			nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
			if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6)) ||
			    (!rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6)))
				err(1, "rpcb_set tcp6 failed");
			freeaddrinfo(ai_tcp6);
		}
		exit (0);
	}
	if (debug == 0) {
		daemon(0, 0);
		signal(SIGHUP, SIG_IGN);
		signal(SIGINT, SIG_IGN);
		/*
		 * nfsd sits in the kernel most of the time.  It needs
		 * to ignore SIGTERM/SIGQUIT in order to stay alive as long
		 * as possible during a shutdown, otherwise loopback
		 * mounts will not be able to unmount.
		 */
		signal(SIGTERM, SIG_IGN);
		signal(SIGQUIT, SIG_IGN);
	}
	signal(SIGSYS, nonfs);
	signal(SIGCHLD, reapchild);

	openlog("nfsd", LOG_PID, LOG_DAEMON);

	/* If we use UDP only, we start the last server below. */
	srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1;
	for (i = 0; i < srvcnt; i++) {
		switch ((pid = fork())) {
		case -1:
			syslog(LOG_ERR, "fork: %m");
			nfsd_exit(1);
		case 0:
			break;
		default:
			children[i] = pid;
			continue;
		}
		signal(SIGUSR1, child_cleanup);
		setproctitle("server");

		start_server(0);
	}

	signal(SIGUSR1, cleanup);
	FD_ZERO(&v4bits);
	FD_ZERO(&v6bits);
	FD_ZERO(&sockbits);

	rpcbregcnt = 0;
	/* Set up the socket for udp and rpcb register it. */
	if (udpflag) {
		rpcbreg = 0;
		for (i = 0; i < bindhostc; i++) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			if (setbindhost(&ai_udp, bindhost[i], hints) == 0) {
				rpcbreg = 1;
				rpcbregcnt++;
				if ((sock = socket(ai_udp->ai_family,
				    ai_udp->ai_socktype,
				    ai_udp->ai_protocol)) < 0) {
					syslog(LOG_ERR,
					    "can't create udp socket");
					nfsd_exit(1);
				}
				if (bind(sock, ai_udp->ai_addr,
				    ai_udp->ai_addrlen) < 0) {
					syslog(LOG_ERR,
					    "can't bind udp addr %s: %m",
					    bindhost[i]);
					nfsd_exit(1);
				}
				freeaddrinfo(ai_udp);
				nfsdargs.sock = sock;
				nfsdargs.name = NULL;
				nfsdargs.namelen = 0;
				if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
					syslog(LOG_ERR, "can't Add UDP socket");
					nfsd_exit(1);
				}
				close(sock);
			}
		}
		if (rpcbreg == 1) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
			if (ecode != 0) {
				syslog(LOG_ERR, "getaddrinfo udp: %s",
				   gai_strerror(ecode));
				nfsd_exit(1);
			}
			nconf_udp = getnetconfigent("udp");
			if (nconf_udp == NULL)
				err(1, "getnetconfigent udp failed");
			nb_udp.buf = ai_udp->ai_addr;
			nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
			if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp)) ||
			    (!rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp)))
				err(1, "rpcb_set udp failed");
			freeaddrinfo(ai_udp);
		}
	}

	/* Set up the socket for udp6 and rpcb register it. */
	if (udpflag && ip6flag) {
		rpcbreg = 0;
		for (i = 0; i < bindhostc; i++) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			if (setbindhost(&ai_udp6, bindhost[i], hints) == 0) {
				rpcbreg = 1;
				rpcbregcnt++;
				if ((sock = socket(ai_udp6->ai_family,
				    ai_udp6->ai_socktype,
				    ai_udp6->ai_protocol)) < 0) {
					syslog(LOG_ERR,
						"can't create udp6 socket");
					nfsd_exit(1);
				}
				if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
				    &on, sizeof on) < 0) {
					syslog(LOG_ERR,
					    "can't set v6-only binding for "
					    "udp6 socket: %m");
					nfsd_exit(1);
				}
				if (bind(sock, ai_udp6->ai_addr,
				    ai_udp6->ai_addrlen) < 0) {
					syslog(LOG_ERR,
					    "can't bind udp6 addr %s: %m",
					    bindhost[i]);
					nfsd_exit(1);
				}
				freeaddrinfo(ai_udp6);
				nfsdargs.sock = sock;
				nfsdargs.name = NULL;
				nfsdargs.namelen = 0;
				if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
					syslog(LOG_ERR,
					    "can't add UDP6 socket");
					nfsd_exit(1);
				}
				close(sock);
			}
		}
		if (rpcbreg == 1) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_protocol = IPPROTO_UDP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
			if (ecode != 0) {
				syslog(LOG_ERR, "getaddrinfo udp6: %s",
				   gai_strerror(ecode));
				nfsd_exit(1);
			}
			nconf_udp6 = getnetconfigent("udp6");
			if (nconf_udp6 == NULL)
				err(1, "getnetconfigent udp6 failed");
			nb_udp6.buf = ai_udp6->ai_addr;
			nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
			if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6)) ||
			    (!rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6)))
				err(1, "rpcb_set udp6 failed");
			freeaddrinfo(ai_udp6);
		}
	}

	/* Set up the socket for tcp and rpcb register it. */
	if (tcpflag) {
		rpcbreg = 0;
		for (i = 0; i < bindhostc; i++) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			if (setbindhost(&ai_tcp, bindhost[i], hints) == 0) {
				rpcbreg = 1;
				rpcbregcnt++;
				if ((tcpsock = socket(AF_INET, SOCK_STREAM,
				    0)) < 0) {
					syslog(LOG_ERR,
					    "can't create tpc socket");
					nfsd_exit(1);
				}
				if (setsockopt(tcpsock, SOL_SOCKET,
				    SO_REUSEADDR,
				    (char *)&on, sizeof(on)) < 0)
					syslog(LOG_ERR,
					     "setsockopt SO_REUSEADDR: %m");
				if (bind(tcpsock, ai_tcp->ai_addr,
				    ai_tcp->ai_addrlen) < 0) {
					syslog(LOG_ERR,
					    "can't bind tcp addr %s: %m",
					    bindhost[i]);
					nfsd_exit(1);
				}
				if (listen(tcpsock, 64) < 0) {
					syslog(LOG_ERR, "listen failed");
					nfsd_exit(1);
				}
				freeaddrinfo(ai_tcp);
				FD_SET(tcpsock, &sockbits);
				FD_SET(tcpsock, &v4bits);
				maxsock = tcpsock;
				connect_type_cnt++;
			}
		}
		if (rpcbreg == 1) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			ecode = getaddrinfo(NULL, "nfs", &hints,
			     &ai_tcp);
			if (ecode != 0) {
				syslog(LOG_ERR, "getaddrinfo tcp: %s",
				   gai_strerror(ecode));
				nfsd_exit(1);
			}
			nconf_tcp = getnetconfigent("tcp");
			if (nconf_tcp == NULL)
				err(1, "getnetconfigent tcp failed");
			nb_tcp.buf = ai_tcp->ai_addr;
			nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
			if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp,
			    &nb_tcp)) || (!rpcb_set(RPCPROG_NFS, 3,
			    nconf_tcp, &nb_tcp)))
				err(1, "rpcb_set tcp failed");
			freeaddrinfo(ai_tcp);
		}
	}

	/* Set up the socket for tcp6 and rpcb register it. */
	if (tcpflag && ip6flag) {
		rpcbreg = 0;
		for (i = 0; i < bindhostc; i++) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			if (setbindhost(&ai_tcp6, bindhost[i], hints) == 0) {
				rpcbreg = 1;
				rpcbregcnt++;
				if ((tcp6sock = socket(ai_tcp6->ai_family,
				    ai_tcp6->ai_socktype,
				    ai_tcp6->ai_protocol)) < 0) {
					syslog(LOG_ERR,
					    "can't create tcp6 socket");
					nfsd_exit(1);
				}
				if (setsockopt(tcp6sock, SOL_SOCKET,
				    SO_REUSEADDR,
				    (char *)&on, sizeof(on)) < 0)
					syslog(LOG_ERR,
					    "setsockopt SO_REUSEADDR: %m");
				if (setsockopt(tcp6sock, IPPROTO_IPV6,
				    IPV6_V6ONLY, &on, sizeof on) < 0) {
					syslog(LOG_ERR,
					"can't set v6-only binding for tcp6 "
					    "socket: %m");
					nfsd_exit(1);
				}
				if (bind(tcp6sock, ai_tcp6->ai_addr,
				    ai_tcp6->ai_addrlen) < 0) {
					syslog(LOG_ERR,
					    "can't bind tcp6 addr %s: %m",
					    bindhost[i]);
					nfsd_exit(1);
				}
				if (listen(tcp6sock, 64) < 0) {
					syslog(LOG_ERR, "listen failed");
					nfsd_exit(1);
				}
				freeaddrinfo(ai_tcp6);
				FD_SET(tcp6sock, &sockbits);
				FD_SET(tcp6sock, &v6bits);
				if (maxsock < tcp6sock)
					maxsock = tcp6sock;
				connect_type_cnt++;
			}
		}
		if (rpcbreg == 1) {
			memset(&hints, 0, sizeof hints);
			hints.ai_flags = AI_PASSIVE;
			hints.ai_family = AF_INET6;
			hints.ai_socktype = SOCK_STREAM;
			hints.ai_protocol = IPPROTO_TCP;
			ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
			if (ecode != 0) {
				syslog(LOG_ERR, "getaddrinfo tcp6: %s",
				   gai_strerror(ecode));
				nfsd_exit(1);
			}
			nconf_tcp6 = getnetconfigent("tcp6");
			if (nconf_tcp6 == NULL)
				err(1, "getnetconfigent tcp6 failed");
			nb_tcp6.buf = ai_tcp6->ai_addr;
			nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
			if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6)) ||
			    (!rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6)))
				err(1, "rpcb_set tcp6 failed");
			freeaddrinfo(ai_tcp6);
		}
	}

	if (rpcbregcnt == 0) {
		syslog(LOG_ERR, "rpcb_set() failed, nothing to do: %m");
		nfsd_exit(1);
	}

	if (tcpflag && connect_type_cnt == 0) {
		syslog(LOG_ERR, "tcp connects == 0, nothing to do: %m");
		nfsd_exit(1);
	}

	setproctitle("master");
	/*
	 * We always want a master to have a clean way to to shut nfsd down
	 * (with unregistration): if the master is killed, it unregisters and
	 * kills all children. If we run for UDP only (and so do not have to
	 * loop waiting waiting for accept), we instead make the parent
	 * a "server" too. start_server will not return.
	 */
	if (!tcpflag)
		start_server(1);

	/*
	 * Loop forever accepting connections and passing the sockets
	 * into the kernel for the mounts.
	 */
	for (;;) {
		ready = sockbits;
		if (connect_type_cnt > 1) {
			if (select(maxsock + 1,
			    &ready, NULL, NULL, NULL) < 1) {
				syslog(LOG_ERR, "select failed: %m");
				if (errno == EINTR)
					continue;
				nfsd_exit(1);
			}
		}
		for (tcpsock = 0; tcpsock <= maxsock; tcpsock++) {
			if (FD_ISSET(tcpsock, &ready)) {
				if (FD_ISSET(tcpsock, &v4bits)) {
					len = sizeof(inetpeer);
					if ((msgsock = accept(tcpsock,
					    (struct sockaddr *)&inetpeer, &len)) < 0) {
						syslog(LOG_ERR, "accept failed: %m");
						if (errno == ECONNABORTED ||
						    errno == EINTR)
							continue;
						nfsd_exit(1);
					}
					memset(inetpeer.sin_zero, 0,
						sizeof(inetpeer.sin_zero));
					if (setsockopt(msgsock, SOL_SOCKET,
					    SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
						syslog(LOG_ERR,
						    "setsockopt SO_KEEPALIVE: %m");
					nfsdargs.sock = msgsock;
					nfsdargs.name = (caddr_t)&inetpeer;
					nfsdargs.namelen = len;
					nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
					close(msgsock);
				} else if (FD_ISSET(tcpsock, &v6bits)) {
					len = sizeof(inet6peer);
					if ((msgsock = accept(tcpsock,
					    (struct sockaddr *)&inet6peer,
					    &len)) < 0) {
						syslog(LOG_ERR,
						     "accept failed: %m");
						if (errno == ECONNABORTED ||
						    errno == EINTR)
							continue;
						nfsd_exit(1);
					}
					if (setsockopt(msgsock, SOL_SOCKET,
					    SO_KEEPALIVE, (char *)&on,
					    sizeof(on)) < 0)
						syslog(LOG_ERR, "setsockopt "
						    "SO_KEEPALIVE: %m");
					nfsdargs.sock = msgsock;
					nfsdargs.name = (caddr_t)&inet6peer;
					nfsdargs.namelen = len;
					nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
					close(msgsock);
				}
			}
		}
	}
}
Beispiel #16
0
/*
 * Create an rpc client attached to the mount daemon.
 */
CLIENT *
get_mount_client(char *host, struct sockaddr_in *unused_sin, struct timeval *tv, int *sock, u_long mnt_version)
{
  CLIENT *client;
  struct netbuf nb;
  struct netconfig *nc = NULL;
  struct sockaddr_in sin;

  nb.maxlen = sizeof(sin);
  nb.buf = (char *) &sin;

  /*
   * First try a TCP handler
   */

  /*
   * Find mountd address on TCP
   */
  if ((nc = getnetconfigent(NC_TCP)) == NULL) {
    plog(XLOG_ERROR, "getnetconfig for tcp failed: %s", nc_sperror());
    goto tryudp;
  }
  if (!rpcb_getaddr(MOUNTPROG, mnt_version, nc, &nb, host)) {
    /*
     * don't print error messages here, since mountd might legitimately
     * serve udp only
     */
    goto tryudp;
  }
  /*
   * Create privileged TCP socket
   */
  *sock = t_open(nc->nc_device, O_RDWR, 0);

  if (*sock < 0) {
    plog(XLOG_ERROR, "t_open %s: %m", nc->nc_device);
    goto tryudp;
  }
  if (bind_resv_port(*sock, (u_short *) 0) < 0)
    plog(XLOG_ERROR, "couldn't bind mountd socket to privileged port");

  if ((client = clnt_vc_create(*sock, &nb, MOUNTPROG, mnt_version, 0, 0))
      == (CLIENT *) NULL) {
    plog(XLOG_ERROR, "clnt_vc_create failed");
    t_close(*sock);
    goto tryudp;
  }
  /* tcp succeeded */
  dlog("get_mount_client: using tcp, port %d", sin.sin_port);
  if (nc)
    freenetconfigent(nc);
  return client;

tryudp:
  /* first free possibly previously allocated netconfig entry */
  if (nc)
    freenetconfigent(nc);

  /*
   * TCP failed so try UDP
   */

  /*
   * Find mountd address on UDP
   */
  if ((nc = getnetconfigent(NC_UDP)) == NULL) {
    plog(XLOG_ERROR, "getnetconfig for udp failed: %s", nc_sperror());
    goto badout;
  }
  if (!rpcb_getaddr(MOUNTPROG, mnt_version, nc, &nb, host)) {
    plog(XLOG_ERROR, "%s",
	 clnt_spcreateerror("couldn't get mountd address on udp"));
    goto badout;
  }
  /*
   * Create privileged UDP socket
   */
  *sock = t_open(nc->nc_device, O_RDWR, 0);

  if (*sock < 0) {
    plog(XLOG_ERROR, "t_open %s: %m", nc->nc_device);
    goto badout;		/* neither tcp not udp succeeded */
  }
  if (bind_resv_port(*sock, (u_short *) 0) < 0)
    plog(XLOG_ERROR, "couldn't bind mountd socket to privileged port");

  if ((client = clnt_dg_create(*sock, &nb, MOUNTPROG, mnt_version, 0, 0))
      == (CLIENT *) NULL) {
    plog(XLOG_ERROR, "clnt_dg_create failed");
    t_close(*sock);
    goto badout;		/* neither tcp not udp succeeded */
  }
  if (clnt_control(client, CLSET_RETRY_TIMEOUT, (char *) tv) == FALSE) {
    plog(XLOG_ERROR, "clnt_control CLSET_RETRY_TIMEOUT for udp failed");
    clnt_destroy(client);
    goto badout;		/* neither tcp not udp succeeded */
  }
  /* udp succeeded */
  dlog("get_mount_client: using udp, port %d", sin.sin_port);
  return client;

badout:
  /* failed */
  if (nc)
    freenetconfigent(nc);
  return NULL;
}
Beispiel #17
0
CLIENT *
get_client(struct sockaddr *host_addr, rpcvers_t vers)
{
	CLIENT *client;
	struct timeval retry_time, time_now;
	int error, i;
	const char *netid;
	struct netconfig *nconf;
	char host[NI_MAXHOST];
	uid_t old_euid;
	int clnt_fd;

	gettimeofday(&time_now, NULL);

	/*
	 * Search for the given client in the cache, zapping any expired
	 * entries that we happen to notice in passing.
	 */
	for (i = 0; i < CLIENT_CACHE_SIZE; i++) {
		client = clnt_cache_ptr[i];
		if (client && ((clnt_cache_time[i] + CLIENT_CACHE_LIFETIME)
		    < time_now.tv_sec)) {
			/* Cache entry has expired. */
			if (debug_level > 3)
				syslog(LOG_DEBUG, "Expired CLIENT* in cache");
			clnt_cache_time[i] = 0L;
			clnt_destroy(client);
			clnt_cache_ptr[i] = NULL;
			client = NULL;
		}
		if (client && !addrcmp((struct sockaddr *)&clnt_cache_addr[i],
		    host_addr) && clnt_cache_vers[i] == vers) {
			/* Found it! */
			if (debug_level > 3)
				syslog(LOG_DEBUG, "Found CLIENT* in cache");
			return (client);
		}
	}

	if (debug_level > 3)
		syslog(LOG_DEBUG, "CLIENT* not found in cache, creating");

	/* Not found in cache.  Free the next entry if it is in use. */
	if (clnt_cache_ptr[clnt_cache_next_to_use]) {
		clnt_destroy(clnt_cache_ptr[clnt_cache_next_to_use]);
		clnt_cache_ptr[clnt_cache_next_to_use] = NULL;
	}

	/*
	 * Need a host string for clnt_tp_create. Use NI_NUMERICHOST
	 * to avoid DNS lookups.
	 */
	error = getnameinfo(host_addr, host_addr->sa_len, host, sizeof host,
			    NULL, 0, NI_NUMERICHOST);
	if (error != 0) {
		syslog(LOG_ERR, "unable to get name string for caller: %s",
		       gai_strerror(error));
		return NULL;
	}

#if 1
	if (host_addr->sa_family == AF_INET6)
		netid = "udp6";
	else
		netid = "udp";
#else 
	if (host_addr->sa_family == AF_INET6)
		netid = "tcp6";
	else
		netid = "tcp";
#endif
	nconf = getnetconfigent(netid);
	if (nconf == NULL) {
		syslog(LOG_ERR, "could not get netconfig info for '%s': "
				"no /etc/netconfig file?", netid);
		return NULL;
	}

	client = clnt_tp_create(host, NLM_PROG, vers, nconf);
	freenetconfigent(nconf);

	if (!client) {
		syslog(LOG_ERR, "%s", clnt_spcreateerror("clntudp_create"));
		syslog(LOG_ERR, "Unable to return result to %s", host);
		return NULL;
	}

	/* Get the FD of the client, for bindresvport. */ 
	clnt_control(client, CLGET_FD, &clnt_fd);

	/* Regain root privileges, for bindresvport. */
	old_euid = geteuid();
	seteuid(0);

	/*
	 * Bind the client FD to a reserved port.
	 * Some NFS servers reject any NLM request from a non-reserved port. 
	 */ 
	bindresvport(clnt_fd, NULL);

	/* Drop root privileges again. */
	seteuid(old_euid);

	/* Success - update the cache entry */
	clnt_cache_ptr[clnt_cache_next_to_use] = client;
	memcpy(&clnt_cache_addr[clnt_cache_next_to_use], host_addr,
	    host_addr->sa_len);
	clnt_cache_vers[clnt_cache_next_to_use] = vers;
	clnt_cache_time[clnt_cache_next_to_use] = time_now.tv_sec;
	if (++clnt_cache_next_to_use >= CLIENT_CACHE_SIZE)
		clnt_cache_next_to_use = 0;

	/*
	 * Disable the default timeout, so we can specify our own in calls
	 * to clnt_call().  (Note that the timeout is a different concept
	 * from the retry period set in clnt_udp_create() above.)
	 */
	retry_time.tv_sec = -1;
	retry_time.tv_usec = -1;
	clnt_control(client, CLSET_TIMEOUT, (char *)&retry_time);

	if (debug_level > 3)
		syslog(LOG_DEBUG, "Created CLIENT* for %s", host);
	return client;
}
int nfs41_server_resolve(
    IN const char *hostname,
    IN unsigned short port,
    OUT multi_addr4 *addrs)
{
    int status = ERROR_BAD_NET_NAME;
    char service[16];
    struct addrinfo hints = { 0 }, *res, *info;
    struct netconfig *nconf;
    struct netbuf addr;
    char *netid, *uaddr;

    dprintf(SRVLVL, "--> nfs41_server_resolve(%s:%u)\n",
        hostname, port);

    addrs->count = 0;

    StringCchPrintfA(service, 16, "%u", port);

    /* request a list of tcp addrs for the given hostname,port */
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    if (getaddrinfo(hostname, service, &hints, &res) != 0)
        goto out;

    for (info = res; info != NULL; info = info->ai_next) {
        /* find the appropriate entry in /etc/netconfig */
        switch (info->ai_family) {
        case AF_INET:  netid = "tcp";  break;
        case AF_INET6: netid = "tcp6"; break;
        default: continue;
        }

        nconf = getnetconfigent(netid);
        if (nconf == NULL)
            continue;

        /* convert to a transport-independent universal address */
        addr.buf = info->ai_addr;
        addr.maxlen = addr.len = (unsigned int)info->ai_addrlen;

        uaddr = taddr2uaddr(nconf, &addr);
        freenetconfigent(nconf);

        if (uaddr == NULL)
            continue;

        StringCchCopyA(addrs->arr[addrs->count].netid,
            NFS41_NETWORK_ID_LEN+1, netid);
        StringCchCopyA(addrs->arr[addrs->count].uaddr,
            NFS41_UNIVERSAL_ADDR_LEN+1, uaddr);
        freeuaddr(uaddr);

        status = NO_ERROR;
        if (++addrs->count >= NFS41_ADDRS_PER_SERVER)
            break;
    }
    freeaddrinfo(res);
out:
    if (status)
        dprintf(SRVLVL, "<-- nfs41_server_resolve(%s:%u) returning "
            "error %d\n", hostname, port, status);
    else
        dprintf(SRVLVL, "<-- nfs41_server_resolve(%s:%u) returning "
            "%s\n", hostname, port, addrs->arr[0].uaddr);
    return status;
}
Beispiel #19
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   argc[3] : Number of test call
	//					   other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 0; //Default test result set to FAILED
	int i;
	double *resultTbl;
	struct timeval tv1,tv2;
    struct timezone tz;
    long long diff;
    double rslt;
	int progNum = atoi(argc[2]);
    CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
    char addrbuf[ADDRBUFSIZE];
	enum clnt_stat cs;
	int var_snd = 0;
	int var_rec = -1;
	struct timeval tv;

	//Test initialisation
    maxIter = atoi(argc[3]);
    resultTbl = (double *)malloc(maxIter * sizeof(double));

    tv.tv_sec = 0;
	tv.tv_usec = 100;

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *) NULL)
	{
		//syslog(LOG_ERR, "getnetconfigent for udp failed");
		fprintf(stderr, "err nconf\n");
		printf("5\n");
		exit(1);
	}

	svcaddr.len = 0;
	svcaddr.maxlen = ADDRBUFSIZE;
	svcaddr.buf = addrbuf;

	if (svcaddr.buf == NULL)
	{
    	/* if malloc() failed, print error messages and exit */
		printf("5\n");
  		exit(1);
    }

    //printf("svcaddr reserved (%s)\n", argc[1]);

	if (!rpcb_getaddr(progNum, VERSNUM, nconf,
                               &svcaddr, argc[1]))
    {
    	fprintf(stderr, "rpcb_getaddr failed!!\n");
		printf("5\n");
    	exit(1);
    }
    //printf("svc get\n");

	client = clnt_dg_create(RPC_ANYFD, &svcaddr,
			 				progNum, VERSNUM, 1024, 1024);

	if (client == NULL)
	{
		clnt_pcreateerror("ERR");
		exit(1);
	}

	//Call tested function several times
	for (i = 0; i < maxIter; i++)
	{
		//Tic
		gettimeofday(&tv1, &tz);

		//Call function
		cs = clnt_call(client, PROCNUM,
	               		(xdrproc_t)xdr_int, (char *)&var_snd,
	               		(xdrproc_t)xdr_int, (char *)&var_rec,
	               		tv);

		//Toc
		gettimeofday(&tv2, &tz);

		//Add function execution time (toc-tic)
		diff = (tv2.tv_sec-tv1.tv_sec) * 1000000L + (tv2.tv_usec-tv1.tv_usec);
		rslt = (double)diff / 1000;

    	if (cs == RPC_SUCCESS)
    	{
    		resultTbl[i] = rslt;
    	}
    	else
    	{
    		test_status = 1;
    		break;
    	}

    	if (run_mode)
    	{
    		fprintf(stderr, "lf time  = %lf usecn\n", resultTbl[i]);
    	}
	}

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);
	printf("%lf %d\n", average(resultTbl), maxIter);
	printf("%lf\n", mini(resultTbl));
	printf("%lf\n", maxi(resultTbl));

	return test_status;
}
Beispiel #20
0
void *my_thread_process (void * arg)
{
	int i;
	CLIENT *clnt = NULL;
	struct datas vars;
	static double result = 0;
    struct timeval total_timeout;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
    char addrbuf[ADDRBUFSIZE];
    
    total_timeout.tv_sec = 1;
	total_timeout.tv_usec = 1;
	
	nconf = getnetconfigent("udp");
	
    if ((struct netconfig *)nconf == NULL) 
    {
    	//Test failed
    	printf("5\n");
    	pthread_exit (5);
    }
    
    svcaddr.len = 0;
	svcaddr.maxlen = ADDRBUFSIZE;
	svcaddr.buf = addrbuf;
	
	if (svcaddr.buf == (char *)NULL)
	{
    	printf("5\n");
  		pthread_exit (5);
    }
    
    if (!rpcb_getaddr(progNum, VERSNUM, nconf,
                               &svcaddr, hostname))
    {
    	fprintf(stderr, "rpcb_getaddr failed!!\n");
    	printf("5\n");
    	pthread_exit (5);
    }
	
    clnt = clnt_dg_create(RPC_ANYFD, &svcaddr,
			 				progNum, VERSNUM, 1024, 1024);
	
	if (clnt == (CLIENT *)NULL)
	{
		printf("5\n");
		pthread_exit (5);
	}
	
	if (run_mode == 1)
	{
		fprintf(stderr, "Thread %d\n", atoi(arg));
	}
	
	vars.a = getRand();
	vars.b = getRand();
	vars.c = getRand();
		
	resTbl[atoi(arg)].locRes = vars.a + (vars.b * vars.c);
	
    clnt_call((CLIENT *)clnt, CALCTHREADPROC, 
				(xdrproc_t)xdr_datas, (char *)&vars, // xdr_in
                (xdrproc_t)xdr_double, (char *)&resTbl[atoi(arg)].svcRes, // xdr_out
				total_timeout);
	
	thread_array_result[atoi(arg)] = (resTbl[atoi(arg)].svcRes == resTbl[atoi(arg)].locRes) ? 0 : 1;
	
	if (run_mode == 1)
	{
		fprintf(stderr, "Thread #%d calc : %lf, received : %lf\n", 
		        atoi(arg), resTbl[atoi(arg)].locRes,
		        resTbl[atoi(arg)].svcRes);
	}
    
    pthread_exit (0);
}
Beispiel #21
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 0; //Default test result set to PASS
	int progNum = atoi(argc[2]);
	int i;
	params paramList[NBCASE];
	CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
    char addrbuf[ADDRBUFSIZE];
	bool_t rpcb_rslt;

	//Initialization
    if (run_mode)
    {
    	printf("Before creation\n");
		printf("client : %d\n", client);
		printf("nconf : %d\n", nconf);
	}

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *) NULL)
	{
		//syslog(LOG_ERR, "getnetconfigent for udp failed");
		fprintf(stderr, "err nconf\n");
		printf("5\n");
		exit(1);
	}

	svcaddr.len = 0;
	svcaddr.maxlen = ADDRBUFSIZE;
	svcaddr.buf = addrbuf;

	if (svcaddr.buf == NULL)
	{
    	/* if malloc() failed, print error messages and exit */
  		return 1;
    }

    //printf("svcaddr reserved (%s)\n", argc[1]);

	if (!rpcb_getaddr(progNum, VERSNUM, nconf,
                               &svcaddr, argc[1]))
    {
    	fprintf(stderr, "rpcb_getaddr failed!!\n");
		printf("5\n");
    	exit(1);
    }

	//Test arguments initialization
	paramList[0].bufmin = 0;
	paramList[0].bufmax = 2147483647;
	paramList[1].bufmin = 2147483647;
	paramList[1].bufmax = 0;
	paramList[2].bufmin = 2147483647;
	paramList[2].bufmax = 2147483647;

	//Call tested function using all tests cases
	for (i = 0; i < NBCASE; i++)
	{
		//Debug mode prints
		if (run_mode == 1)
		{
			printf("Test using values : %d ", paramList[i].bufmin);
			printf("%d", paramList[i].bufmax);
			printf("\n");
		}

		//Call function
		client = clnt_tli_create(RPC_ANYFD, nconf, &svcaddr,
	                         	 progNum, VERSNUM, paramList[i].bufmin, paramList[i].bufmax);

		//Check result
		if (client == NULL)
		{
			//test has failed
			test_status = 1;
			break;
		}
	}

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	return test_status;
}
Beispiel #22
0
	ans = bind(fd, (struct sockaddr *)na->buf, na->len);

	close(fd);
	free(na->buf);
	free(na);

	return (ans == 0 ? FALSE : TRUE);
}

int
add_bndlist(struct netconfig *nconf, struct netbuf *baddr __unused)
{
	struct fdlist *fdl;
	struct netconfig *newnconf;

	newnconf = getnetconfigent(nconf->nc_netid);
	if (newnconf == NULL)
		return (-1);
	fdl = malloc(sizeof (struct fdlist));
	if (fdl == NULL) {
		freenetconfigent(newnconf);
		syslog(LOG_ERR, "no memory!");
		return (-1);
	}
	fdl->nconf = newnconf;
	fdl->next = NULL;
	if (fdhead == NULL) {
		fdhead = fdl;
		fdtail = fdl;
	} else {
		fdtail->next = fdl;
Beispiel #23
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//                                         argc[2] : Server Program Number
	//                                         other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1;	//Default test result set to FAILED
	int progNum = atoi(argc[2]);
	CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
	char addrbuf[ADDRBUFSIZE];
	enum clnt_stat cs;
	int var_snd = 0;
	struct timeval tv;

	//Initialization
	if (run_mode) {
		printf("Before creation\n");
	}

	tv.tv_sec = 1;
	tv.tv_usec = 0;

	nconf = getnetconfigent("udp");
	if (nconf == NULL) {
		//syslog(LOG_ERR, "getnetconfigent for udp failed");
		printf("err nconf\n");
		exit(1);
	}

	svcaddr.len = 0;
	svcaddr.maxlen = ADDRBUFSIZE;
	svcaddr.buf = addrbuf;

	if (svcaddr.buf == NULL) {
		/* if malloc() failed, print error messages and exit */
		return 1;
	}
	//printf("svcaddr reserved (%s)\n", argc[1]);

	if (!rpcb_getaddr(progNum, VERSNUM, nconf, &svcaddr, argc[1])) {
		fprintf(stderr, "rpcb_getaddr failed!!\n");
		exit(1);
	}
	//printf("svc get\n");

	client = clnt_tli_create(RPC_ANYFD, nconf, &svcaddr, progNum, VERSNUM, 0, 0);	/* Wrong Program Version */

	cs = clnt_call(client, PROCNUM,
		       (xdrproc_t) xdr_int, (char *)&var_snd,
		       (xdrproc_t) xdr_int, (char *)&var_snd, tv);

	test_status = (cs == RPC_PROGVERSMISMATCH) ? 0 : 1;

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	clnt_destroy(client);

	return test_status;
}
Beispiel #24
0
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//					   argc[2] : Server Program Number
	//					   argc[3] : Number of testes function calls
	//					   other arguments depend on test case
	
	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	int run_mode = 0;
	int test_status = 1; //Default test result set to FAILED
	int progNum = atoi(argc[2]);
    int sndVar = 0;
    int recVar = -1;
    CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct timeval tv;
	enum clnt_stat rslt;
	int nbCall = atoi(argc[3]);
	int nbOk = 0;
	int i;
    
    //First, test initialization : create client using intermediate level API
	nconf = getnetconfigent("udp");
	
    if ((struct netconfig *)nconf == NULL) 
    {
    	//Test failed
    	printf("5\n");
    	return 5;
    }
    
    tv.tv_sec = 1;
	tv.tv_usec = 1;
	
    client = clnt_tp_create_timed(argc[1], progNum,
                                  VERSNUM, (struct netconfig *)nconf, &tv);
    
    if (client == (CLIENT *)NULL)
    {
    	printf("5\n");
    	return 5;
    }

	//Call routine
	for (i = 0; i < nbCall; i++)
	{
		rslt = clnt_call(client, PROCNUM,
					 (xdrproc_t)xdr_int, (char *)&sndVar, // xdr_in
                     (xdrproc_t)xdr_int, (char *)&recVar, // xdr_out
                     tv);
    	if (rslt == RPC_SUCCESS)
			nbOk++;
	}
	
	if (run_mode == 1)
	{
		printf("Aimed : %d\n", nbCall);
		printf("Got : %d\n", nbOk);
	}
	
	test_status = (nbOk == nbCall) ? 0 : 1;
    
	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);
	
	return test_status;
}
CLIENT * Creer_RPCClient( char * host, unsigned int programme, unsigned int version, 
                          unsigned short port, int sockfd )
{
  struct sockaddr_in6 adresse_rpc ;
  int                 sock = 0 ;
  CLIENT *            client ;
  struct timeval      intervalle ;
  int                 rc ;
  struct              netconfig * nconf ;
  struct netbuf       netbuf ;
  struct hostent    * hp ; 
 
  if( ( hp = gethostbyname2( host, AF_INET6 ) ) == NULL )
 	return NULL ;

  memset( &adresse_rpc, 0, (size_t)sizeof( adresse_rpc ) ) ;
  memcpy( (char *)&adresse_rpc.sin6_addr, (char *)hp->h_addr, hp->h_length ) ;
  adresse_rpc.sin6_port        = port ;
  adresse_rpc.sin6_family      = AF_INET6 ;
  adresse_rpc.sin6_scope_id    = if_nametoindex( ifname ) ;

  sock               = sockfd ;
  intervalle.tv_sec  = TIMEOUT_SEC ;
  intervalle.tv_usec = 0 ;
  
  if( sock > 0 )
    {
      if( port > 0 )
        {
          /* En tcp, il faut que la socket soit connectee sur le service en face si on n'utilise pas RPC_ANYSOCK 
           * ATTENTION, ceci est une feature non documentee des RPC clientes (j'ai vu ca dans les sources) */
          if( connect( sock, (struct sockaddr *)&adresse_rpc, sizeof( adresse_rpc ) ) < 0 )
            fprintf( stderr, "connect impossible sur le serveur RPC\n" ) ;
        }
      else
        {
          /* Dans ce cas, on ne connait pas le port en face, donc connect impossible, on prend RPC_ANYSOCK 
           * mais uniquement apres avoir ferme la socket 'sock' qui ne sert a rien ici */
          close( sock ) ;
          sock = RPC_ANYSOCK ;
        }
    }

  /* initialisation des structures de TI-RPC */
  if( ( nconf = (struct netconfig *)getnetconfigent( "tcp6" ) ) == NULL )
   {
     fprintf( stderr, "Erreur de getnetconfigent\n" ) ;
     exit( 1 ) ;
   }

  netbuf.maxlen = sizeof( adresse_rpc );
  netbuf.len    = sizeof( adresse_rpc );
  netbuf.buf    = &adresse_rpc;

  /* Creation et allocation du client */
  if( ( client = clnt_tli_create( sock, 
                                  nconf, 
                                  &netbuf, 
                                  programme,  
                                  version, 
                                  SEND_SIZE,  
                                  RECV_SIZE ) ) == NULL )
   {
      char erreur[100] ;
      char entete[100] ;
      
      return NULL ;
    }
  
  return client ;
} /* Creer_RPCClient */
Beispiel #26
0
int
main(int argc, char *argv[])
{
	pid_t pid;
	int c;
	char *progname = argv[0];
	int connmaxrec = RPC_MAXDATASIZE;

	while ((c = getopt(argc, argv, "d")) != -1)
		switch ((char)c) {
		case 'd':
			debug++;
			break;
		default:
			(void) fprintf(stderr, "usage: %s [-d]\n", progname);
			exit(EXIT_FAILURE);
		}


	/*
	 * Set non-blocking mode and maximum record size for
	 * connection oriented RPC transports.
	 */
	if (!rpc_control(RPC_SVC_CONNMAXREC_SET, &connmaxrec)) {
		msgout("unable to set maximum RPC record size");
	}

	/*
	 * If stdin looks like a TLI endpoint, we assume
	 * that we were started by a port monitor. If
	 * t_getstate fails with TBADF, this is not a
	 * TLI endpoint.
	 */
	if (t_getstate(0) != -1 || t_errno != TBADF) {
		char *netid;
		struct netconfig *nconf = NULL;
		SVCXPRT *transp;
		int pmclose;

		if ((netid = getenv("NLSPROVIDER")) == NULL) {
			if (debug)
				msgout("cannot get transport name");
		} else if ((nconf = getnetconfigent(netid)) == NULL) {
			if (debug)
				msgout("cannot get transport info");
		}
		pmclose = (t_getstate(0) != T_DATAXFER);
		if ((transp = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {
			msgout("cannot create server handle");
			exit(EXIT_FAILURE);
		}
		if (nconf)
			freenetconfigent(nconf);
		if (!svc_reg(transp, BOOTPARAMPROG, BOOTPARAMVERS,
		    bootparamprog_1, 0)) {
			msgout("unable to register (BOOTPARAMPROG, "
			    "BOOTPARAMVERS).");
			exit(EXIT_FAILURE);
		}
		if (pmclose) {
			(void) signal(SIGALRM, closedown);
			(void) alarm(_RPCSVC_CLOSEDOWN);
		}

		svc_run();
		exit(EXIT_FAILURE);
		/* NOTREACHED */
	}

	/*
	 * run this process in the background only if it was started from
	 * a shell and the debug flag was not given.
	 */
	if (!server_child && !debug) {
		pid = fork();
		if (pid < 0) {
			perror("cannot fork");
			exit(EXIT_FAILURE);
		}
		if (pid)
			exit(EXIT_SUCCESS);

		closefrom(0);
		(void) setsid();
	}

	/*
	 * messges go to syslog if the program was started by
	 * another server, or if it was run from the command line without
	 * the debug flag.
	 */
	if (server_child || !debug)
		openlog("bootparam_prot", LOG_PID, LOG_DAEMON);

	if (debug) {
		if (debug == 1)
			msgout("in debug mode.");
		else
			msgout("in debug mode (level %d).", debug);
	}

	if (!svc_create(bootparamprog_1, BOOTPARAMPROG, BOOTPARAMVERS,
			"netpath")) {
		msgout("unable to create (BOOTPARAMPROG, BOOTPARAMVERS) "
		    "for netpath.");
		exit(EXIT_FAILURE);
	}

	svc_run();
	msgout("svc_run returned");
	return (EXIT_FAILURE);
}
Beispiel #27
0
static void
get_xdmcp_sock(void)
{
#ifdef STREAMSCONN
    struct netconfig *nconf;

    if ((xdmcpSocket = t_open("/dev/udp", O_RDWR, 0)) < 0) {
        XdmcpWarning("t_open() of /dev/udp failed");
        return;
    }

    if (t_bind(xdmcpSocket, NULL, NULL) < 0) {
        XdmcpWarning("UDP socket creation failed");
        t_error("t_bind(xdmcpSocket) failed");
        t_close(xdmcpSocket);
        return;
    }

    /*
     * This part of the code looks contrived. It will actually fit in nicely
     * when the CLTS part of Xtrans is implemented.
     */

    if ((nconf = getnetconfigent("udp")) == NULL) {
        XdmcpWarning("UDP socket creation failed: getnetconfigent()");
        t_unbind(xdmcpSocket);
        t_close(xdmcpSocket);
        return;
    }

    if (netdir_options(nconf, ND_SET_BROADCAST, xdmcpSocket, NULL)) {
        XdmcpWarning("UDP set broadcast option failed: netdir_options()");
        freenetconfigent(nconf);
        t_unbind(xdmcpSocket);
        t_close(xdmcpSocket);
        return;
    }

    freenetconfigent(nconf);
#else
    int soopts = 1;

#if defined(IPv6) && defined(AF_INET6)
    if ((xdmcpSocket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
        XdmcpWarning("INET6 UDP socket creation failed");
#endif
    if ((xdmcpSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        XdmcpWarning("UDP socket creation failed");
#ifdef SO_BROADCAST
    else if (setsockopt(xdmcpSocket, SOL_SOCKET, SO_BROADCAST, (char *) &soopts,
                        sizeof(soopts)) < 0)
        XdmcpWarning("UDP set broadcast socket-option failed");
#endif                          /* SO_BROADCAST */
    if (xdmcpSocket >= 0 && xdm_from != NULL) {
        if (bind(xdmcpSocket, (struct sockaddr *) &FromAddress,
                 FromAddressLen) < 0) {
            FatalError("Xserver: failed to bind to -from address: %s\n",
                       xdm_from);
        }
    }
#endif                          /* STREAMSCONN */
}
CLIENT * Creer_RPCClient( unsigned int adresse, unsigned int programme, unsigned int version, 
                          unsigned short port, int sockfd )
{
  struct sockaddr_in adresse_rpc ;
  int                sock = 0 ;
  CLIENT *           client ;
  struct timeval     intervalle ;
  int                rc ;
  struct             netconfig * nconf ;
  struct netbuf      netbuf ;
 
  memset( &adresse_rpc, 0, (size_t)sizeof( adresse_rpc ) ) ;
  adresse_rpc.sin_port        = port ;
  adresse_rpc.sin_family      = AF_INET ;
  adresse_rpc.sin_addr.s_addr = adresse ;

  sock               = sockfd ;
  intervalle.tv_sec  = TIMEOUT_SEC ;
  intervalle.tv_usec = 0 ;
  
  if( sock > 0 )
    {
      if( port > 0 )
        {
          /* En tcp, il faut que la socket soit connectee sur le service en face si on n'utilise pas RPC_ANYSOCK 
           * ATTENTION, ceci est une feature non documentee des RPC clientes (j'ai vu ca dans les sources) */
          if( connect( sock, (struct sockaddr *)&adresse_rpc, sizeof( adresse_rpc ) ) < 0 )
            fprintf( stderr, "connect impossible sur le serveur RPC\n" ) ;
        }
      else
        {
          /* Dans ce cas, on ne connait pas le port en face, donc connect impossible, on prend RPC_ANYSOCK 
           * mais uniquement apres avoir ferme la socket 'sock' qui ne sert a rien ici */
          close( sock ) ;
          sock = RPC_ANYSOCK ;
        }
    }

  /* initialisation des structures de TI-RPC */
  if( ( nconf = (struct netconfig *)getnetconfigent( "tcp" ) ) == NULL )
   {
     fprintf( stderr, "Erreur de getnetconfigent\n" ) ;
     exit( 1 ) ;
   }

  netbuf.maxlen = sizeof( adresse_rpc );
  netbuf.len    = sizeof( adresse_rpc );
  netbuf.buf    = &adresse_rpc;

  /* Creation et allocation du client */
  if( ( client = clnt_tli_create( sock, 
                                  nconf, 
                                  &netbuf, 
                                  programme,  
                                  version, 
                                  SEND_SIZE,  
                                  RECV_SIZE ) ) == NULL )
   {
      char erreur[100] ;
      char entete[100] ;
      
      sprintf( entete, "Creation RPC %d|%d|0x%x:%d|%d", programme, version, adresse, port, sock ) ;
      strcpy( erreur, clnt_spcreateerror( entete ) ) ;
          fprintf( stderr, "%s", erreur ) ;
          
          return NULL ;
    }
  
  return client ;
} /* Creer_RPCClient */
Beispiel #29
0
void *my_thread_process (void * arg)
{
	CLIENT *client = NULL;
	struct netconfig *nconf = NULL;
	struct netbuf svcaddr;
    char addrbuf[ADDRBUFSIZE];
	enum clnt_stat cs;
	int var_snd = 10;
	int var_rec = -1;
	struct timeval tv;
	int i;

	if (run_mode == 1)
	{
		fprintf(stderr, "Thread %d\n", atoi(arg));
	}

	tv.tv_sec = 0;
	tv.tv_usec = 100;

	nconf = getnetconfigent("udp");
	if (nconf == (struct netconfig *) NULL)
	{
		//syslog(LOG_ERR, "getnetconfigent for udp failed");
		printf("err nconf\n");
		pthread_exit (1);
	}

	svcaddr.len = 0;
	svcaddr.maxlen = ADDRBUFSIZE;
	svcaddr.buf = addrbuf;

	if (svcaddr.buf == NULL)
	{
    	pthread_exit (1);
    }

    //printf("svcaddr reserved (%s)\n", argc[1]);

	if (!rpcb_getaddr(progNum + atoi(arg), VERSNUM, nconf,
                               &svcaddr, hostname))
    {
    	fprintf(stderr, "rpcb_getaddr failed!!\n");
    	pthread_exit (1);
    }
    //printf("svc get\n");

	client = clnt_dg_create(RPC_ANYFD, &svcaddr,
			 				progNum + atoi(arg), VERSNUM, 1024, 1024);

	if (client == NULL)
	{
		clnt_pcreateerror("ERR");
		pthread_exit (1);
	}

	for (i = 0; i < callNb; i++)
	{
		cs = clnt_call(client, PROCNUM,
	               		(xdrproc_t)xdr_int, (char *)&var_snd,
	               		(xdrproc_t)xdr_int, (char *)&var_rec,
	               		tv);

		thread_array_result[atoi(arg)] += (cs == RPC_SUCCESS);
    }

    pthread_exit (0);
}
Beispiel #30
0
static void
nfsauth_access(auth_req *argp, auth_res *result)
{
	struct netconfig *nconf;
	struct nd_hostservlist *clnames = NULL;
	struct netbuf nbuf;
	struct share *sh;
	char tmp[MAXIPADDRLEN];
	char *host = NULL;

	result->auth_perm = NFSAUTH_DENIED;

	/*
	 * Convert the client's address to a hostname
	 */
	nconf = getnetconfigent(argp->req_netid);
	if (nconf == NULL) {
		syslog(LOG_ERR, "No netconfig entry for %s", argp->req_netid);
		return;
	}

	nbuf.len = argp->req_client.n_len;
	nbuf.buf = argp->req_client.n_bytes;

	if (netdir_getbyaddr(nconf, &clnames, &nbuf)) {
		host = &tmp[0];
		if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
			struct sockaddr_in *sa;

			/* LINTED pointer alignment */
			sa = (struct sockaddr_in *)nbuf.buf;
			(void) inet_ntoa_r(sa->sin_addr, tmp);
		} else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
			struct sockaddr_in6 *sa;
			/* LINTED pointer */
			sa = (struct sockaddr_in6 *)nbuf.buf;
			(void) inet_ntop(AF_INET6, sa->sin6_addr.s6_addr,
				    tmp, INET6_ADDRSTRLEN);
		}
		clnames = anon_client(host);
	}

	/*
	 * Now find the export
	 */
	sh = findentry(argp->req_path);
	if (sh == NULL) {
		syslog(LOG_ERR, "%s not exported", argp->req_path);
		goto done;
	}

	result->auth_perm = check_client(sh, &nbuf, clnames, argp->req_flavor);

	sharefree(sh);

	if (result->auth_perm == NFSAUTH_DENIED) {
		syslog(LOG_ERR, "%s denied access to %s",
			clnames->h_hostservs[0].h_host, argp->req_path);
	}

done:
	freenetconfigent(nconf);
	if (clnames)
		netdir_free(clnames, ND_HOSTSERVLIST);
}