/*
 * network.c -- Provide common network functions for NFS mount/umount
 *
 * Copyright (C) 2007 Oracle.  All rights reserved.
 * Copyright (C) 2007 Chuck Lever <chuck.lever@oracle.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <ctype.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <time.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>

#include "sockaddr.h"
#include "xcommon.h"
#include "mount.h"
#include "nls.h"
#include "nfs_mount.h"
#include "mount_constants.h"
#include "nfsrpc.h"
#include "parse_opt.h"
#include "network.h"
#include "conffile.h"

#define PMAP_TIMEOUT	(10)
#define CONNECT_TIMEOUT	(20)
#define MOUNT_TIMEOUT	(30)

extern int nfs_mount_data_version;
extern char *progname;
extern int verbose;

static const char *nfs_ns_pgmtbl[] = {
	"status",
	NULL,
};

static const char *nfs_mnt_pgmtbl[] = {
	"mount",
	"mountd",
	NULL,
};

static const char *nfs_nfs_pgmtbl[] = {
	"nfs",
	"nfsprog",
	NULL,
};

static const char *nfs_transport_opttbl[] = {
	"udp",
	"tcp",
	"proto",
	NULL,
};

static const char *nfs_version_opttbl[] = {
	"v2",
	"v3",
	"v4",
	"vers",
	"nfsvers",
	NULL,
};

static const unsigned long nfs_to_mnt[] = {
	0,
	0,
	1,
	3,
};

static const unsigned long mnt_to_nfs[] = {
	0,
	2,
	2,
	3,
};

/*
 * Map an NFS version into the corresponding Mountd version
 */
unsigned long nfsvers_to_mnt(const unsigned long vers)
{
	if (vers <= 3)
		return nfs_to_mnt[vers];
	return 0;
}

/*
 * Map a Mountd version into the corresponding NFS version
 */
static unsigned long mntvers_to_nfs(const unsigned long vers)
{
	if (vers <= 3)
		return mnt_to_nfs[vers];
	return 0;
}

static const unsigned int probe_udp_only[] = {
	IPPROTO_UDP,
	0,
};

static const unsigned int probe_udp_first[] = {
	IPPROTO_UDP,
	IPPROTO_TCP,
	0,
};

static const unsigned int probe_tcp_first[] = {
	IPPROTO_TCP,
	IPPROTO_UDP,
	0,
};

static const unsigned long probe_nfs2_only[] = {
	2,
	0,
};

static const unsigned long probe_nfs3_first[] = {
	3,
	2,
	0,
};

static const unsigned long probe_mnt1_first[] = {
	1,
	2,
	0,
};

static const unsigned long probe_mnt3_first[] = {
	3,
	1,
	2,
	0,
};

static const unsigned int *nfs_default_proto(void);
#ifdef MOUNT_CONFIG
static const unsigned int *nfs_default_proto()
{
	extern unsigned long config_default_proto;
	/*
	 * If the default proto has been set and 
	 * its not TCP, start with UDP
	 */
	if (config_default_proto && config_default_proto != IPPROTO_TCP)
		return probe_udp_first;

	return probe_tcp_first; 
}
#else
static const unsigned int *nfs_default_proto() 
{
	return probe_tcp_first; 
}
#endif /* MOUNT_CONFIG */

/**
 * nfs_lookup - resolve hostname to an IPv4 or IPv6 socket address
 * @hostname: pointer to C string containing DNS hostname to resolve
 * @family: address family hint
 * @sap: pointer to buffer to fill with socket address
 * @len: IN: size of buffer to fill; OUT: size of socket address
 *
 * Returns 1 and places a socket address at @sap if successful;
 * otherwise zero.
 */
int nfs_lookup(const char *hostname, const sa_family_t family,
		struct sockaddr *sap, socklen_t *salen)
{
	struct addrinfo *gai_results;
	struct addrinfo gai_hint = {
#ifdef HAVE_DECL_AI_ADDRCONFIG
		.ai_flags	= AI_ADDRCONFIG,
#endif	/* HAVE_DECL_AI_ADDRCONFIG */
		.ai_family	= family,
	};
	socklen_t len = *salen;
	int error, ret = 0;

	*salen = 0;

	error = getaddrinfo(hostname, NULL, &gai_hint, &gai_results);
	switch (error) {
	case 0:
		break;
	case EAI_SYSTEM:
		nfs_error(_("%s: DNS resolution failed for %s: %s"),
			progname, hostname, strerror(errno));
		return ret;
	default:
		nfs_error(_("%s: DNS resolution failed for %s: %s"),
			progname, hostname, gai_strerror(error));
		return ret;
	}

	switch (gai_results->ai_addr->sa_family) {
	case AF_INET:
	case AF_INET6:
		if (len >= gai_results->ai_addrlen) {
			*salen = gai_results->ai_addrlen;
			memcpy(sap, gai_results->ai_addr, *salen);
			ret = 1;
		}
		break;
	default:
		/* things are really broken if we get here, so warn */
		nfs_error(_("%s: unrecognized DNS resolution results for %s"),
				progname, hostname);
		break;
	}

	freeaddrinfo(gai_results);
	return ret;
}

/**
 * nfs_gethostbyname - resolve a hostname to an IPv4 address
 * @hostname: pointer to a C string containing a DNS hostname
 * @sin: returns an IPv4 address 
 *
 * Returns 1 if successful, otherwise zero.
 */
int nfs_gethostbyname(const char *hostname, struct sockaddr_in *sin)
{
	socklen_t len = sizeof(*sin);

	return nfs_lookup(hostname, AF_INET, (struct sockaddr *)sin, &len);
}

/**
 * nfs_string_to_sockaddr - convert string address to sockaddr
 * @address:	pointer to presentation format address to convert
 * @sap:	pointer to socket address buffer to fill in
 * @salen:	IN: length of address buffer
 *		OUT: length of converted socket address
 *
 * Convert a presentation format address string to a socket address.
 * Similar to nfs_lookup(), but the DNS query is squelched, and it
 * won't make any noise if the getaddrinfo() call fails.
 *
 * Returns 1 and fills in @sap and @salen if successful; otherwise zero.
 *
 * See RFC 4038 section 5.1 or RFC 3513 section 2.2 for more details
 * on presenting IPv6 addresses as text strings.
 */
int nfs_string_to_sockaddr(const char *address, struct sockaddr *sap,
			   socklen_t *salen)
{
	struct addrinfo *gai_results;
	struct addrinfo gai_hint = {
		.ai_flags	= AI_NUMERICHOST,
	};
	socklen_t len = *salen;
	int ret = 0;

	*salen = 0;

	if (getaddrinfo(address, NULL, &gai_hint, &gai_results) == 0) {
		switch (gai_results->ai_addr->sa_family) {
		case AF_INET:
		case AF_INET6:
			if (len >= gai_results->ai_addrlen) {
				*salen = gai_results->ai_addrlen;
				memcpy(sap, gai_results->ai_addr, *salen);
				ret = 1;
			}
			break;
		}
		freeaddrinfo(gai_results);
	}

	return ret;
}

/**
 * nfs_present_sockaddr - convert sockaddr to string
 * @sap: pointer to socket address to convert
 * @salen: length of socket address
 * @buf: pointer to buffer to fill in
 * @buflen: length of buffer
 *
 * Convert the passed-in sockaddr-style address to presentation format.
 * The presentation format address is placed in @buf and is
 * '\0'-terminated.
 *
 * Returns 1 if successful; otherwise zero.
 *
 * See RFC 4038 section 5.1 or RFC 3513 section 2.2 for more details
 * on presenting IPv6 addresses as text strings.
 */
int nfs_present_sockaddr(const struct sockaddr *sap, const socklen_t salen,
			 char *buf, const size_t buflen)
{
#ifdef HAVE_GETNAMEINFO
	int result;

	result = getnameinfo(sap, salen, buf, buflen,
					NULL, 0, NI_NUMERICHOST);
	if (!result)
		return 1;

	nfs_error(_("%s: invalid server address: %s"), progname,
			gai_strerror(result));
	return 0;
#else	/* HAVE_GETNAMEINFO */
	char *addr;

	if (sap->sa_family == AF_INET) {
		addr = inet_ntoa(((struct sockaddr_in *)sap)->sin_addr);
		if (addr && strlen(addr) < buflen) {
			strcpy(buf, addr);
			return 1;
		}
	}

	nfs_error(_("%s: invalid server address"), progname);
	return 0;
#endif	/* HAVE_GETNAMEINFO */
}

/*
 * Attempt to connect a socket, but time out after "timeout" seconds.
 *
 * On error return, caller closes the socket.
 */
static int connect_to(int fd, struct sockaddr *addr,
			socklen_t addrlen, int timeout)
{
	int ret, saved;
	fd_set rset, wset;
	struct timeval tv = {
		.tv_sec = timeout,
	};

	saved = fcntl(fd, F_GETFL, 0);
	fcntl(fd, F_SETFL, saved | O_NONBLOCK);

	ret = connect(fd, addr, addrlen);
	if (ret < 0 && errno != EINPROGRESS)
		return -1;
	if (ret == 0)
		goto out;

	FD_ZERO(&rset);
	FD_SET(fd, &rset);
	wset = rset;
	ret = select(fd + 1, &rset, &wset, NULL, &tv);
	if (ret == 0) {
		errno = ETIMEDOUT;
		return -1;
	}
	if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) {
		int error;
		socklen_t len = sizeof(error);
		if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
			return -1;
		if (error) {
			errno = error;
			return -1;
		}
	} else
		return -1;

out:
	fcntl(fd, F_SETFL, saved);
	return 0;
}

/*
 * Create a socket that is locally bound to a reserved or non-reserved port.
 *
 * The caller should check rpc_createerr to determine the cause of any error.
 */
static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
			unsigned int timeout, int resvp, int conn)
{
	int so, cc, type;
	struct sockaddr_in laddr;
	socklen_t namelen = sizeof(laddr);

	type = (p_prot == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM);
	if ((so = socket (AF_INET, type, p_prot)) < 0)
		goto err_socket;

	laddr.sin_family = AF_INET;
	laddr.sin_port = 0;
	laddr.sin_addr.s_addr = htonl(INADDR_ANY);
	if (resvp) {
		if (bindresvport(so, &laddr) < 0)
			goto err_bindresvport;
	} else {
		cc = bind(so, (struct sockaddr *)&laddr, namelen);
		if (cc < 0)
			goto err_bind;
	}
	if (type == SOCK_STREAM || (conn && type == SOCK_DGRAM)) {
		cc = connect_to(so, (struct sockaddr *)saddr, namelen,
				timeout);
		if (cc < 0)
			goto err_connect;
	}
	return so;

err_socket:
	rpc_createerr.cf_stat = RPC_SYSTEMERROR;
	rpc_createerr.cf_error.re_errno = errno;
	if (verbose) {
		nfs_error(_("%s: Unable to create %s socket: errno %d (%s)\n"),
			progname, p_prot == IPPROTO_UDP ? _("UDP") : _("TCP"),
			errno, strerror(errno));
	}
	return RPC_ANYSOCK;

err_bindresvport:
	rpc_createerr.cf_stat = RPC_SYSTEMERROR;
	rpc_createerr.cf_error.re_errno = errno;
	if (verbose) {
		nfs_error(_("%s: Unable to bindresvport %s socket: errno %d"
				" (%s)\n"),
			progname, p_prot == IPPROTO_UDP ? _("UDP") : _("TCP"),
			errno, strerror(errno));
	}
	close(so);
	return RPC_ANYSOCK;

err_bind:
	rpc_createerr.cf_stat = RPC_SYSTEMERROR;
	rpc_createerr.cf_error.re_errno = errno;
	if (verbose) {
		nfs_error(_("%s: Unable to bind to %s socket: errno %d (%s)\n"),
			progname, p_prot == IPPROTO_UDP ? _("UDP") : _("TCP"),
			errno, strerror(errno));
	}
	close(so);
	return RPC_ANYSOCK;

err_connect:
	rpc_createerr.cf_stat = RPC_SYSTEMERROR;
	rpc_createerr.cf_error.re_errno = errno;
	if (verbose) {
		nfs_error(_("%s: Unable to connect to %s:%d, errno %d (%s)\n"),
			progname, inet_ntoa(saddr->sin_addr),
			ntohs(saddr->sin_port), errno, strerror(errno));
	}
	close(so);
	return RPC_ANYSOCK;
}

static void nfs_pp_debug(const struct sockaddr *sap, const socklen_t salen,
			 const rpcprog_t program, const rpcvers_t version,
			 const unsigned short protocol,
			 const unsigned short port)
{
	char buf[NI_MAXHOST];

	if (!verbose)
		return;

	if (nfs_present_sockaddr(sap, salen, buf, sizeof(buf)) == 0) {
		buf[0] = '\0';
		strcat(buf, "unknown host");
	}

	fprintf(stderr, _("%s: trying %s prog %lu vers %lu prot %s port %d\n"),
			progname, buf, (unsigned long)program,
			(unsigned long)version,
			(protocol == IPPROTO_UDP ? _("UDP") : _("TCP")),
			port);
}

static void nfs_pp_debug2(const char *str)
{
	if (!verbose)
		return;

	if (rpc_createerr.cf_error.re_status == RPC_CANTRECV ||
	    rpc_createerr.cf_error.re_status == RPC_CANTSEND)
		nfs_error(_("%s: portmap query %s%s - %s"),
				progname, str, clnt_spcreateerror(""),
				strerror(rpc_createerr.cf_error.re_errno));
	else
		nfs_error(_("%s: portmap query %s%s"),
				progname, str, clnt_spcreateerror(""));
}

/*
 * Use the portmapper to discover whether or not the service we want is
 * available. The lists 'versions' and 'protos' define ordered sequences
 * of service versions and udp/tcp protocols to probe for.
 *
 * Returns 1 if the requested service port is unambiguous and pingable;
 * @pmap is filled in with the version, port, and transport protocol used
 * during the successful ping.  Note that if a port is already specified
 * in @pmap and it matches the rpcbind query result, nfs_probe_port() does
 * not perform an RPC ping.
 * 
 * If an error occurs or the requested service isn't available, zero is
 * returned; rpccreateerr.cf_stat is set to reflect the nature of the error.
 */
static int nfs_probe_port(const struct sockaddr *sap, const socklen_t salen,
			  struct pmap *pmap, const unsigned long *versions,
			  const unsigned int *protos)
{
	union nfs_sockaddr address;
	struct sockaddr *saddr = &address.sa;
	const unsigned long prog = pmap->pm_prog, *p_vers;
	const unsigned int prot = (u_int)pmap->pm_prot, *p_prot;
	const u_short port = (u_short) pmap->pm_port;
	unsigned long vers = pmap->pm_vers;
	unsigned short p_port;

	memcpy(saddr, sap, salen);
	p_prot = prot ? &prot : protos;
	p_vers = vers ? &vers : versions;

	for (;;) {
		if (verbose)
			printf(_("%s: prog %lu, trying vers=%lu, prot=%u\n"),
				progname, prog, *p_vers, *p_prot);
		p_port = nfs_getport(saddr, salen, prog, *p_vers, *p_prot);
		if (p_port) {
			if (!port || port == p_port) {
				nfs_set_port(saddr, p_port);
				nfs_pp_debug(saddr, salen, prog, *p_vers,
						*p_prot, p_port);
				if (nfs_rpc_ping(saddr, salen, prog,
							*p_vers, *p_prot, NULL))
					goto out_ok;
			} else
				rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
		}
		if (rpc_createerr.cf_stat != RPC_PROGNOTREGISTERED &&
		    rpc_createerr.cf_stat != RPC_TIMEDOUT &&
		    rpc_createerr.cf_stat != RPC_CANTRECV &&
		    rpc_createerr.cf_stat != RPC_PROGVERSMISMATCH)
			break;

		if (!prot) {
			if (*++p_prot) {
				nfs_pp_debug2("retrying");
				continue;
			}
			p_prot = protos;
		}
		if (rpc_createerr.cf_stat == RPC_TIMEDOUT ||
		    rpc_createerr.cf_stat == RPC_CANTRECV)
			break;

		if (vers || !*++p_vers)
			break;
	}

	nfs_pp_debug2("failed");
	return 0;

out_ok:
	if (!vers)
		pmap->pm_vers = *p_vers;
	if (!prot)
		pmap->pm_prot = *p_prot;
	if (!port)
		pmap->pm_port = p_port;
	nfs_clear_rpc_createerr();
	return 1;
}
/*
 * Probe a server's NFS service to determine which versions and
 * transport protocols are supported.
 *
 * Returns 1 if the requested service port is unambiguous and pingable;
 * @pmap is filled in with the version, port, and transport protocol used
 * during the successful ping.  If all three are already specified, simply
 * return success without an rpcbind query or RPC ping (we may be trying
 * to mount an NFS service that is not advertised via rpcbind).
 *
 * If an error occurs or the requested service isn't available, zero is
 * returned; rpccreateerr.cf_stat is set to reflect the nature of the error.
 */
static int nfs_probe_nfsport(const struct sockaddr *sap, const socklen_t salen,
				struct pmap *pmap)
{
	if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
		return 1;

	if (nfs_mount_data_version >= 4) {
		const unsigned int *probe_proto;

		probe_proto = nfs_default_proto();

		return nfs_probe_port(sap, salen, pmap,
					probe_nfs3_first, probe_proto);
	} else
		return nfs_probe_port(sap, salen, pmap,
					probe_nfs2_only, probe_udp_only);
}

/*
 * Probe a server's mountd service to determine which versions and
 * transport protocols are supported.
 *
 * Returns 1 if the requested service port is unambiguous and pingable;
 * @pmap is filled in with the version, port, and transport protocol used
 * during the successful ping.  If all three are already specified, simply
 * return success without an rpcbind query or RPC ping (we may be trying
 * to mount an NFS service that is not advertised via rpcbind).
 * 
 * If an error occurs or the requested service isn't available, zero is
 * returned; rpccreateerr.cf_stat is set to reflect the nature of the error.
 */
static int nfs_probe_mntport(const struct sockaddr *sap, const socklen_t salen,
				struct pmap *pmap)
{
	if (pmap->pm_vers && pmap->pm_prot && pmap->pm_port)
		return 1;

	if (nfs_mount_data_version >= 4)
		return nfs_probe_port(sap, salen, pmap,
					probe_mnt3_first, probe_udp_first);
	else
		return nfs_probe_port(sap, salen, pmap,
					probe_mnt1_first, probe_udp_only);
}

/*
 * Probe a server's mountd service to determine which versions and
 * transport protocols are supported.  Invoked when the protocol
 * version is already known for both the NFS and mountd service.
 *
 * Returns 1 and fills in both @pmap structs if the requested service
 * ports are unambiguous and pingable.  Otherwise zero is returned;
 * rpccreateerr.cf_stat is set to reflect the nature of the error.
 */
static int nfs_probe_version_fixed(const struct sockaddr *mnt_saddr,
			const socklen_t mnt_salen,
			struct pmap *mnt_pmap,
			const struct sockaddr *nfs_saddr,
			const socklen_t nfs_salen,
			struct pmap *nfs_pmap)
{
	if (!nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap))
		return 0;
	return nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap);
}

/**
 * nfs_probe_bothports - discover the RPC endpoints of mountd and NFS server
 * @mnt_saddr:	pointer to socket address of mountd server
 * @mnt_salen:	length of mountd server's address
 * @mnt_pmap:	IN: partially filled-in mountd RPC service tuple;
 *		OUT: fully filled-in mountd RPC service tuple
 * @nfs_saddr:	pointer to socket address of NFS server
 * @nfs_salen:	length of NFS server's address
 * @nfs_pmap:	IN: partially filled-in NFS RPC service tuple;
 *		OUT: fully filled-in NFS RPC service tuple
 *
 * Returns 1 and fills in both @pmap structs if the requested service
 * ports are unambiguous and pingable.  Otherwise zero is returned;
 * rpccreateerr.cf_stat is set to reflect the nature of the error.
 */
int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
			const socklen_t mnt_salen,
			struct pmap *mnt_pmap,
			const struct sockaddr *nfs_saddr,
			const socklen_t nfs_salen,
			struct pmap *nfs_pmap)
{
	struct pmap save_nfs, save_mnt;
	const unsigned long *probe_vers;

	if (mnt_pmap->pm_vers && !nfs_pmap->pm_vers)
		nfs_pmap->pm_vers = mntvers_to_nfs(mnt_pmap->pm_vers);
	else if (nfs_pmap->pm_vers && !mnt_pmap->pm_vers)
		mnt_pmap->pm_vers = nfsvers_to_mnt(nfs_pmap->pm_vers);

	if (nfs_pmap->pm_vers)
		return nfs_probe_version_fixed(mnt_saddr, mnt_salen, mnt_pmap,
					       nfs_saddr, nfs_salen, nfs_pmap);

	memcpy(&save_nfs, nfs_pmap, sizeof(save_nfs));
	memcpy(&save_mnt, mnt_pmap, sizeof(save_mnt));
	probe_vers = (nfs_mount_data_version >= 4) ?
			probe_mnt3_first : probe_mnt1_first;

	for (; *probe_vers; probe_vers++) {
		nfs_pmap->pm_vers = mntvers_to_nfs(*probe_vers);
		if (nfs_probe_nfsport(nfs_saddr, nfs_salen, nfs_pmap) != 0) {
			mnt_pmap->pm_vers = *probe_vers;
			if (nfs_probe_mntport(mnt_saddr, mnt_salen, mnt_pmap) != 0)
				return 1;
			memcpy(mnt_pmap, &save_mnt, sizeof(*mnt_pmap));
		}
		switch (rpc_createerr.cf_stat) {
		case RPC_PROGVERSMISMATCH:
		case RPC_PROGNOTREGISTERED:
			break;
		default:
			return 0;
		}
		memcpy(nfs_pmap, &save_nfs, sizeof(*nfs_pmap));
	}

	return 0;
}

/**
 * probe_bothports - discover the RPC endpoints of mountd and NFS server
 * @mnt_server: pointer to address and pmap argument for mountd results
 * @nfs_server: pointer to address and pmap argument for NFS server
 *
 * This is the legacy API that takes "clnt_addr_t" for both servers,
 * but supports only AF_INET addresses.
 *
 * Returns 1 and fills in the pmap field in both clnt_addr_t structs
 * if the requested service ports are unambiguous and pingable.
 * Otherwise zero is returned; rpccreateerr.cf_stat is set to reflect
 * the nature of the error.
 */
int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server)
{
	return nfs_probe_bothports((struct sockaddr *)&mnt_server->saddr,
					sizeof(mnt_server->saddr),
					&mnt_server->pmap,
					(struct sockaddr *)&nfs_server->saddr,
					sizeof(nfs_server->saddr),
					&nfs_server->pmap);
}

static int nfs_probe_statd(void)
{
	struct sockaddr_in addr = {
		.sin_family		= AF_INET,
		.sin_addr.s_addr	= htonl(INADDR_LOOPBACK),
	};
	rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);

	return nfs_getport_ping((struct sockaddr *)&addr, sizeof(addr),
				program, (rpcvers_t)1, IPPROTO_UDP);
}

/**
 * start_statd - attempt to start rpc.statd
 *
 * Returns 1 if statd is running; otherwise zero.
 */
int start_statd(void)
{
#ifdef START_STATD
	struct stat stb;
#endif

	if (nfs_probe_statd())
		return 1;

#ifdef START_STATD
	if (stat(START_STATD, &stb) == 0) {
		if (S_ISREG(stb.st_mode) && (stb.st_mode & S_IXUSR)) {
			pid_t pid = fork();
			switch (pid) {
			case 0: /* child */
				execl(START_STATD, START_STATD, NULL);
				exit(1);
			case -1: /* error */
				nfs_error(_("%s: fork failed: %s"),
						progname, strerror(errno));
				break;
			default: /* parent */
				waitpid(pid, NULL,0);
				break;
			}
			if (nfs_probe_statd())
				return 1;
		}
	}
#endif

	return 0;
}

/**
 * nfs_advise_umount - ask the server to remove a share from it's rmtab
 * @sap: pointer to IP address of server to call
 * @salen: length of server address
 * @pmap: partially filled-in mountd RPC service tuple
 * @argp: directory path of share to "unmount"
 *
 * Returns one if the unmount call succeeded; zero if the unmount
 * failed for any reason;  rpccreateerr.cf_stat is set to reflect
 * the nature of the error.
 *
 * We use a fast timeout since this call is advisory only.
 */
int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
		      const struct pmap *pmap, const dirpath *argp)
{
	union nfs_sockaddr address;
	struct sockaddr *saddr = &address.sa;
	struct pmap mnt_pmap = *pmap;
	struct timeval timeout = {
		.tv_sec		= MOUNT_TIMEOUT >> 3,
	};
	CLIENT *client;
	enum clnt_stat res = 0;

	memcpy(saddr, sap, salen);
	if (nfs_probe_mntport(saddr, salen, &mnt_pmap) == 0) {
		if (verbose)
			nfs_error(_("%s: Failed to discover mountd port%s"),
				progname, clnt_spcreateerror(""));
		return 0;
	}
	nfs_set_port(saddr, mnt_pmap.pm_port);

	client = nfs_get_priv_rpcclient(saddr, salen, mnt_pmap.pm_prot,
					mnt_pmap.pm_prog, mnt_pmap.pm_vers,
					&timeout);
	if (client == NULL) {
		if (verbose)
			nfs_error(_("%s: Failed to create RPC client%s"),
				progname, clnt_spcreateerror(""));
		return 0;
	}

	client->cl_auth = authunix_create_default();

	res = CLNT_CALL(client, MOUNTPROC_UMNT,
			(xdrproc_t)xdr_dirpath, (caddr_t)argp,
			(xdrproc_t)xdr_void, NULL,
			timeout);
	if (res != RPC_SUCCESS) {
		rpc_createerr.cf_stat = res;
		CLNT_GETERR(client, &rpc_createerr.cf_error);
		if (verbose)
			nfs_error(_("%s: UMNT call failed: %s"),
				progname, clnt_sperrno(res));

	}
	auth_destroy(client->cl_auth);
	CLNT_DESTROY(client);

	if (res != RPC_SUCCESS)
		return 0;
	return 1;
}

/**
 * nfs_call_umount - ask the server to remove a share from it's rmtab
 * @mnt_server: address of RPC MNT program server
 * @argp: directory path of share to "unmount"
 *
 * Returns one if the unmount call succeeded; zero if the unmount
 * failed for any reason.
 *
 * Note that a side effect of calling this function is that rpccreateerr
 * is set.
 */
int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
{
	struct sockaddr *sap = (struct sockaddr *)&mnt_server->saddr;
	socklen_t salen = sizeof(mnt_server->saddr);
	struct pmap *pmap = &mnt_server->pmap;
	CLIENT *clnt;
	enum clnt_stat res = 0;
	int msock;

	if (!nfs_probe_mntport(sap, salen, pmap))
		return 0;
	clnt = mnt_openclnt(mnt_server, &msock);
	if (!clnt)
		return 0;
	res = clnt_call(clnt, MOUNTPROC_UMNT,
			(xdrproc_t)xdr_dirpath, (caddr_t)argp,
			(xdrproc_t)xdr_void, NULL,
			TIMEOUT);
	mnt_closeclnt(clnt, msock);

	if (res == RPC_SUCCESS)
		return 1;
	return 0;
}

/**
 * mnt_openclnt - get a handle for a remote mountd service
 * @mnt_server: address and pmap arguments of mountd service
 * @msock: returns a file descriptor of the underlying transport socket
 *
 * Returns an active handle for the remote's mountd service
 */
CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
{
	struct sockaddr_in *mnt_saddr = &mnt_server->saddr;
	struct pmap *mnt_pmap = &mnt_server->pmap;
	CLIENT *clnt = NULL;

	mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
	*msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, MOUNT_TIMEOUT,
				TRUE, FALSE);
	if (*msock == RPC_ANYSOCK) {
		if (rpc_createerr.cf_error.re_errno == EADDRINUSE)
			/*
			 * Probably in-use by a TIME_WAIT connection,
			 * It is worth waiting a while and trying again.
			 */
			rpc_createerr.cf_stat = RPC_TIMEDOUT;
		return NULL;
	}

	switch (mnt_pmap->pm_prot) {
	case IPPROTO_UDP:
		clnt = clntudp_bufcreate(mnt_saddr,
					 mnt_pmap->pm_prog, mnt_pmap->pm_vers,
					 RETRY_TIMEOUT, msock,
					 MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
		break;
	case IPPROTO_TCP:
		clnt = clnttcp_create(mnt_saddr,
				      mnt_pmap->pm_prog, mnt_pmap->pm_vers,
				      msock,
				      MNT_SENDBUFSIZE, MNT_RECVBUFSIZE);
		break;
	}
	if (clnt) {
		/* try to mount hostname:dirname */
		clnt->cl_auth = authunix_create_default();
		return clnt;
	}
	return NULL;
}

/**
 * mnt_closeclnt - terminate a handle for a remote mountd service
 * @clnt: pointer to an active handle for a remote mountd service
 * @msock: file descriptor of the underlying transport socket
 *
 */
void mnt_closeclnt(CLIENT *clnt, int msock)
{
	auth_destroy(clnt->cl_auth);
	clnt_destroy(clnt);
	close(msock);
}

/**
 * clnt_ping - send an RPC ping to the remote RPC service endpoint
 * @saddr: server's address
 * @prog: target RPC program number
 * @vers: target RPC version number
 * @prot: target RPC protocol
 * @caddr: filled in with our network address
 *
 * Sigh... GETPORT queries don't actually check the version number.
 * In order to make sure that the server actually supports the service
 * we're requesting, we open an RPC client, and fire off a NULL
 * RPC call.
 *
 * caddr is the network address that the server will use to call us back.
 * On multi-homed clients, this address depends on which NIC we use to
 * route requests to the server.
 *
 * Returns one if successful, otherwise zero.
 */
int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
		const unsigned long vers, const unsigned int prot,
		struct sockaddr_in *caddr)
{
	CLIENT *clnt = NULL;
	int sock, stat;
	static char clnt_res;
	struct sockaddr dissolve;

	rpc_createerr.cf_stat = stat = 0;
	sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE);
	if (sock == RPC_ANYSOCK) {
		if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) {
			/*
			 * TCP timeout. Bubble up the error to see 
			 * how it should be handled.
			 */
			rpc_createerr.cf_stat = RPC_TIMEDOUT;
		}
		return 0;
	}

	if (caddr) {
		/* Get the address of our end of this connection */
		socklen_t len = sizeof(*caddr);
		if (getsockname(sock, caddr, &len) != 0)
			caddr->sin_family = 0;
	}

	switch(prot) {
	case IPPROTO_UDP:
		/* The socket is connected (so we could getsockname successfully),
		 * but some servers on multi-homed hosts reply from
		 * the wrong address, so if we stay connected, we lose the reply.
		 */
		dissolve.sa_family = AF_UNSPEC;
		connect(sock, &dissolve, sizeof(dissolve));

		clnt = clntudp_bufcreate(saddr, prog, vers,
					 RETRY_TIMEOUT, &sock,
					 RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
		break;
	case IPPROTO_TCP:
		clnt = clnttcp_create(saddr, prog, vers, &sock,
				      RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
		break;
	}
	if (!clnt) {
		close(sock);
		return 0;
	}
	memset(&clnt_res, 0, sizeof(clnt_res));
	stat = clnt_call(clnt, NULLPROC,
			 (xdrproc_t)xdr_void, (caddr_t)NULL,
			 (xdrproc_t)xdr_void, (caddr_t)&clnt_res,
			 TIMEOUT);
	if (stat) {
		clnt_geterr(clnt, &rpc_createerr.cf_error);
		rpc_createerr.cf_stat = stat;
	}
	clnt_destroy(clnt);
	close(sock);

	if (stat == RPC_SUCCESS)
		return 1;
	else
		return 0;
}

/*
 * Try a getsockname() on a connected datagram socket.
 *
 * Returns 1 and fills in @buf if successful; otherwise, zero.
 *
 * A connected datagram socket prevents leaving a socket in TIME_WAIT.
 * This conserves the ephemeral port number space, helping reduce failed
 * socket binds during mount storms.
 */
static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen,
			   struct sockaddr *buf, socklen_t *buflen)
{
	struct sockaddr_in sin = {
		.sin_family		= AF_INET,
		.sin_addr.s_addr	= htonl(INADDR_ANY),
	};
	struct sockaddr_in6 sin6 = {
		.sin6_family		= AF_INET6,
		.sin6_addr		= IN6ADDR_ANY_INIT,
	};
	int sock;

	sock = socket(sap->sa_family, SOCK_DGRAM, IPPROTO_UDP);
	if (sock < 0)
		return 0;

	switch (sap->sa_family) {
	case AF_INET:
		if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
			close(sock);
			return 0;
		}
		break;
	case AF_INET6:
		if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
			close(sock);
			return 0;
		}
		break;
	default:
		errno = EAFNOSUPPORT;
		return 0;
	}

	if (connect(sock, sap, salen) < 0) {
		close(sock);
		return 0;
	}

	return !getsockname(sock, buf, buflen);
}

/*
 * Try to generate an address that prevents the server from calling us.
 *
 * Returns 1 and fills in @buf if successful; otherwise, zero.
 */
static int nfs_ca_gai(const struct sockaddr *sap,
		      struct sockaddr *buf, socklen_t *buflen)
{
	struct addrinfo *gai_results;
	struct addrinfo gai_hint = {
		.ai_family	= sap->sa_family,
		.ai_flags	= AI_PASSIVE,	/* ANYADDR */
	};

	if (getaddrinfo(NULL, "", &gai_hint, &gai_results))
		return 0;

	*buflen = gai_results->ai_addrlen;
	memcpy(buf, gai_results->ai_addr, *buflen);

	freeaddrinfo(gai_results);

	return 1;
}

/**
 * nfs_callback_address - acquire our local network address
 * @sap: pointer to address of remote
 * @sap_len: length of address
 * @buf: pointer to buffer to be filled in with local network address
 * @buflen: IN: length of buffer to fill in; OUT: length of filled-in address
 *
 * Discover a network address that an NFSv4 server can use to call us back.
 * On multi-homed clients, this address depends on which NIC we use to
 * route requests to the server.
 *
 * Returns 1 and fills in @buf if an unambiguous local address is
 * available; returns 1 and fills in an appropriate ANYADDR address
 * if a local address isn't available; otherwise, returns zero.
 */
int nfs_callback_address(const struct sockaddr *sap, const socklen_t salen,
			 struct sockaddr *buf, socklen_t *buflen)
{
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)buf;

	if (nfs_ca_sockname(sap, salen, buf, buflen) == 0)
		if (nfs_ca_gai(sap, buf, buflen) == 0)
			goto out_failed;

	/*
	 * The server can't use an interface ID that was generated
	 * here on the client, so always clear sin6_scope_id.
	 */
	if (sin6->sin6_family == AF_INET6)
		sin6->sin6_scope_id = 0;

	return 1;

out_failed:
	*buflen = 0;
	if (verbose)
		nfs_error(_("%s: failed to construct callback address"),
				progname);
	return 0;
}

/*
 * "nfsprog" is supported only by the legacy mount command.  The
 * kernel mount client does not support this option.
 *
 * Returns TRUE if @program contains a valid value for this option,
 * or FALSE if the option was specified with an invalid value.
 */
static int
nfs_nfs_program(struct mount_options *options, unsigned long *program)
{
	long tmp;

	switch (po_get_numeric(options, "nfsprog", &tmp)) {
	case PO_NOT_FOUND:
		break;
	case PO_FOUND:
		if (tmp > 0) {
			*program = tmp;
			return 1;
		}
	case PO_BAD_VALUE:
		return 0;
	}

	/*
	 * NFS RPC program wasn't specified.  The RPC program
	 * cannot be determined via an rpcbind query.
	 */
	*program = nfs_getrpcbyname(NFSPROG, nfs_nfs_pgmtbl);
	return 1;
}

/*
 * Returns TRUE if @version contains a valid value for this option,
 * or FALSE if the option was specified with an invalid value.
 */
int
nfs_nfs_version(struct mount_options *options, unsigned long *version)
{
	long tmp;

	switch (po_rightmost(options, nfs_version_opttbl)) {
	case 0:	/* v2 */
		*version = 2;
		return 1;
	case 1: /* v3 */
		*version = 3;
		return 1;
	case 2: /* v4 */
		*version = 4;
		return 1;
	case 3:	/* vers */
		switch (po_get_numeric(options, "vers", &tmp)) {
		case PO_FOUND:
			if (tmp >= 2 && tmp <= 4) {
				*version = tmp;
				return 1;
			}
			return 0;
		case PO_NOT_FOUND:
			nfs_error(_("%s: option parsing error\n"),
					progname);
		case PO_BAD_VALUE:
			return 0;
		}
	case 4: /* nfsvers */
		switch (po_get_numeric(options, "nfsvers", &tmp)) {
		case PO_FOUND:
			if (tmp >= 2 && tmp <= 4) {
				*version = tmp;
				return 1;
			}
			return 0;
		case PO_NOT_FOUND:
			nfs_error(_("%s: option parsing error\n"),
					progname);
		case PO_BAD_VALUE:
			return 0;
		}
	}

	/*
	 * NFS version wasn't specified.  The pmap version value
	 * will be filled in later by an rpcbind query in this case.
	 */
	*version = 0;
	return 1;
}

/*
 * Returns TRUE if @protocol contains a valid value for this option,
 * or FALSE if the option was specified with an invalid value. On
 * error, errno is set.
 */
int
nfs_nfs_protocol(struct mount_options *options, unsigned long *protocol)
{
	sa_family_t family;
	char *option;

	switch (po_rightmost(options, nfs_transport_opttbl)) {
	case 0:	/* udp */
		*protocol = IPPROTO_UDP;
		return 1;
	case 1: /* tcp */
		*protocol = IPPROTO_TCP;
		return 1;
	case 2: /* proto */
		option = po_get(options, "proto");
		if (option != NULL) {
			if (!nfs_get_proto(option, &family, protocol)) {
				errno = EPROTONOSUPPORT;
				return 0;
			}
			return 1;
		}
	}

	/*
	 * NFS transport protocol wasn't specified.  The pmap
	 * protocol value will be filled in later by an rpcbind
	 * query in this case.
	 */
	*protocol = 0;
	return 1;
}

/*
 * Returns TRUE if @port contains a valid value for this option,
 * or FALSE if the option was specified with an invalid value.
 */
static int
nfs_nfs_port(struct mount_options *options, unsigned long *port)
{
	long tmp;

	switch (po_get_numeric(options, "port", &tmp)) {
	case PO_NOT_FOUND:
		break;
	case PO_FOUND:
		if (tmp >= 1 && tmp <= 65535) {
			*port = tmp;
			return 1;
		}
	case PO_BAD_VALUE:
		return 0;
	}

	/*
	 * NFS service port wasn't specified.  The pmap port value
	 * will be filled in later by an rpcbind query in this case.
	 */
	*port = 0;
	return 1;
}

#ifdef IPV6_SUPPORTED
sa_family_t	config_default_family = AF_UNSPEC;

static int
nfs_verify_family(sa_family_t family)
{
	return 1;
}
#else /* IPV6_SUPPORTED */
sa_family_t	config_default_family = AF_INET;

static int
nfs_verify_family(sa_family_t family)
{
	if (family != AF_INET)
		return 0;

	return 1;
}
#endif /* IPV6_SUPPORTED */

/*
 * Returns TRUE and fills in @family if a valid NFS protocol option
 * is found, or FALSE if the option was specified with an invalid value
 * or if the protocol family isn't supported. On error, errno is set.
 */
int nfs_nfs_proto_family(struct mount_options *options,
				sa_family_t *family)
{
	unsigned long protocol;
	char *option;
	sa_family_t tmp_family = config_default_family;

	switch (po_rightmost(options, nfs_transport_opttbl)) {
	case 0:	/* udp */
	case 1: /* tcp */
		/* for compatibility; these are always AF_INET */
		*family = AF_INET;
		return 1;
	case 2: /* proto */
		option = po_get(options, "proto");
		if (option != NULL &&
		    !nfs_get_proto(option, &tmp_family, &protocol))
			goto out_err;
	}

	if (!nfs_verify_family(tmp_family))
		goto out_err;
	*family = tmp_family;
	return 1;
out_err:
	errno = EAFNOSUPPORT;
	return 0;
}

/*
 * "mountprog" is supported only by the legacy mount command.  The
 * kernel mount client does not support this option.
 *
 * Returns TRUE if @program contains a valid value for this option,
 * or FALSE if the option was specified with an invalid value.
 */
static int
nfs_mount_program(struct mount_options *options, unsigned long *program)
{
	long tmp;

	switch (po_get_numeric(options, "mountprog", &tmp)) {
	case PO_NOT_FOUND:
		break;
	case PO_FOUND:
		if (tmp > 0) {
			*program = tmp;
			return 1;
		}
	case PO_BAD_VALUE:
		return 0;
	}

	/*
	 * MNT RPC program wasn't specified.  The RPC program
	 * cannot be determined via an rpcbind query.
	 */
	*program = nfs_getrpcbyname(MOUNTPROG, nfs_mnt_pgmtbl);
	return 1;
}

/*
 * Returns TRUE if @version contains a valid value for this option,
 * or FALSE if the option was specified with an invalid value.
 */
static int
nfs_mount_version(struct mount_options *options, unsigned long *version)
{
	long tmp;

	switch (po_get_numeric(options, "mountvers", &tmp)) {
	case PO_NOT_FOUND:
		break;
	case PO_FOUND:
		if (tmp >= 1 && tmp <= 4) {
			*version = tmp;
			return 1;
		}
	case PO_BAD_VALUE:
		return 0;
	}

	/*
	 * MNT version wasn't specified.  The pmap version value
	 * will be filled in later by an rpcbind query in this case.
	 */
	*version = 0;
	return 1;
}

/*
 * Returns TRUE if @protocol contains a valid value for this option,
 * or FALSE if the option was specified with an invalid value. On
 * error, errno is set.
 */
static int
nfs_mount_protocol(struct mount_options *options, unsigned long *protocol)
{
	sa_family_t family;
	char *option;

	option = po_get(options, "mountproto");
	if (option != NULL) {
		if (!nfs_get_proto(option, &family, protocol)) {
			errno = EPROTONOSUPPORT;
			return 0;
		}
		return 1;
	}

	/*
	 * MNT transport protocol wasn't specified.  If the NFS
	 * transport protocol was specified, use that; otherwise
	 * set @protocol to zero.  The pmap protocol value will
	 * be filled in later by an rpcbind query in this case.
	 */
	return nfs_nfs_protocol(options, protocol);
}

/*
 * Returns TRUE if @port contains a valid value for this option,
 * or FALSE if the option was specified with an invalid value.
 */
static int
nfs_mount_port(struct mount_options *options, unsigned long *port)
{
	long tmp;

	switch (po_get_numeric(options, "mountport", &tmp)) {
	case PO_NOT_FOUND:
		break;
	case PO_FOUND:
		if (tmp >= 1 && tmp <= 65535) {
			*port = tmp;
			return 1;
		}
	case PO_BAD_VALUE:
		return 0;
	}

	/*
	 * MNT service port wasn't specified.  The pmap port value
	 * will be filled in later by an rpcbind query in this case.
	 */
	*port = 0;
	return 1;
}

/*
 * Returns TRUE and fills in @family if a valid MNT protocol option
 * is found, or FALSE if the option was specified with an invalid value
 * or if the protocol family isn't supported. On error, errno is set.
 */
int nfs_mount_proto_family(struct mount_options *options,
				sa_family_t *family)
{
	unsigned long protocol;
	char *option;
	sa_family_t tmp_family = config_default_family;

	option = po_get(options, "mountproto");
	if (option != NULL) {
		if (!nfs_get_proto(option, &tmp_family, &protocol))
			goto out_err;
		if (!nfs_verify_family(tmp_family))
			goto out_err;
		*family = tmp_family;
		return 1;
	}

	/*
	 * MNT transport protocol wasn't specified.  If the NFS
	 * transport protocol was specified, derive the family
	 * from that; otherwise, return the default family for
	 * NFS.
	 */
	return nfs_nfs_proto_family(options, family);
out_err:
	errno = EAFNOSUPPORT;
	return 0;
}

/**
 * nfs_options2pmap - set up pmap structs based on mount options
 * @options: pointer to mount options
 * @nfs_pmap: OUT: pointer to pmap arguments for NFS server
 * @mnt_pmap: OUT: pointer to pmap arguments for mountd server
 *
 * Returns TRUE if the pmap options specified in @options have valid
 * values; otherwise FALSE is returned.
 */
int nfs_options2pmap(struct mount_options *options,
		     struct pmap *nfs_pmap, struct pmap *mnt_pmap)
{
	if (!nfs_nfs_program(options, &nfs_pmap->pm_prog))
		return 0;
	if (!nfs_nfs_version(options, &nfs_pmap->pm_vers))
		return 0;
	if (!nfs_nfs_protocol(options, &nfs_pmap->pm_prot))
		return 0;
	if (!nfs_nfs_port(options, &nfs_pmap->pm_port))
		return 0;

	if (!nfs_mount_program(options, &mnt_pmap->pm_prog))
		return 0;
	if (!nfs_mount_version(options, &mnt_pmap->pm_vers))
		return 0;
	if (!nfs_mount_protocol(options, &mnt_pmap->pm_prot))
		return 0;
	if (!nfs_mount_port(options, &mnt_pmap->pm_port))
		return 0;

	return 1;
}
