コード例 #1
0
ファイル: network.c プロジェクト: AllardJ/Tomato
/**
 * 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);
}
コード例 #2
0
ファイル: stropts.c プロジェクト: greearb/nfs-utils-ct
/*
 * Reconstruct the mount option string based on a portmapper probe
 * of the server.  Returns one if the server's portmapper returned
 * something we can use, otherwise zero.
 *
 * To handle version and transport protocol fallback properly, we
 * need to parse some of the mount options in order to set up a
 * portmap probe.  Mount options that nfs_rewrite_pmap_mount_options()
 * doesn't recognize are left alone.
 *
 * Returns TRUE if rewriting was successful; otherwise
 * FALSE is returned if some failure occurred.
 */
static int
nfs_rewrite_pmap_mount_options(struct mount_options *options, int checkv4,
			       struct local_bind_info *local_ip)
{
	union nfs_sockaddr nfs_address;
	struct sockaddr *nfs_saddr = &nfs_address.sa;
	socklen_t nfs_salen = sizeof(nfs_address);
	struct pmap nfs_pmap;
	union nfs_sockaddr mnt_address;
	struct sockaddr *mnt_saddr = &mnt_address.sa;
	socklen_t mnt_salen = sizeof(mnt_address);
	unsigned long protocol;
	struct pmap mnt_pmap;

	/*
	 * Version and transport negotiation is not required
	 * and does not work for RDMA mounts.
	 */
	if (!nfs_nfs_protocol(options, &protocol)) {
		errno = EINVAL;
		return 0;
	}
	if (protocol == NFSPROTO_RDMA)
		goto out;

	/*
	 * Extract just the options needed to contact server.
	 * Bail now if any of these have bad values.
	 */
	if (!nfs_extract_server_addresses(options, nfs_saddr, &nfs_salen,
						mnt_saddr, &mnt_salen)) {
		errno = EINVAL;
		return 0;
	}
	if (!nfs_options2pmap(options, &nfs_pmap, &mnt_pmap)) {
		errno = EINVAL;
		return 0;
	}

	/*
	 * The kernel NFS client doesn't support changing the RPC
	 * program number for these services, so force the value of
	 * these fields before probing the server's ports.
	 */
	nfs_pmap.pm_prog = NFS_PROGRAM;
	mnt_pmap.pm_prog = MOUNTPROG;

	/*
	 * If the server's rpcbind service isn't available, we can't
	 * negotiate.  Bail now if we can't contact it.
	 */
	if (!nfs_probe_bothports(mnt_saddr, mnt_salen, &mnt_pmap,
				 nfs_saddr, nfs_salen, &nfs_pmap, checkv4,
				 local_ip)) {
		errno = ESPIPE;
		if (rpc_createerr.cf_stat == RPC_PROGNOTREGISTERED)
			errno = EOPNOTSUPP;
		else if (rpc_createerr.cf_stat == RPC_AUTHERROR)
			errno = EACCES;
		else if (rpc_createerr.cf_stat == RPC_TIMEDOUT)
			errno = ETIMEDOUT;
		else if (rpc_createerr.cf_stat == RPC_PROGVERSMISMATCH)
			errno = EPROTONOSUPPORT;
		else if (rpc_createerr.cf_error.re_errno != 0)
			errno = rpc_createerr.cf_error.re_errno;
		return 0;
	}

	if (!nfs_construct_new_options(options, nfs_saddr, &nfs_pmap,
					mnt_saddr, &mnt_pmap)) {
		if (rpc_createerr.cf_stat == RPC_UNKNOWNPROTO)
			errno = EPROTONOSUPPORT;
		else
			errno = EINVAL;
		return 0;
	}

out:
	errno = 0;
	return 1;
}