Esempio n. 1
0
/*
 * Determine whether to append a 'mountaddr=' option.  The option is needed if:
 *
 *   1. "mounthost=" was specified, or
 *   2. The address families for proto= and mountproto= are different.
 */
static int nfs_fix_mounthost_option(struct mount_options *options,
		const char *nfs_hostname)
{
	union nfs_sockaddr address;
	struct sockaddr *sap = &address.sa;
	socklen_t salen = sizeof(address);
	sa_family_t nfs_family, mnt_family;
	char *mounthost;

	if (!nfs_nfs_proto_family(options, &nfs_family))
		return 0;
	if (!nfs_mount_proto_family(options, &mnt_family))
		return 0;

	mounthost = po_get(options, "mounthost");
	if (mounthost == NULL) {
		if (nfs_family == mnt_family)
			return 1;
		mounthost = (char *)nfs_hostname;
	}

	if (!nfs_lookup(mounthost, mnt_family, sap, &salen)) {
		nfs_error(_("%s: unable to determine mount server's address"),
				progname);
		return 0;
	}

	return nfs_append_generic_address_option(sap, salen,
							"mountaddr", options);
}
Esempio n. 2
0
/*
 * Returns the transport protocol to use for the mount service
 *
 * Returns the IPPROTO_ value specified by the mountproto option, or
 * if that doesn't exist, the IPPROTO_ value specified for NFS
 * itself.
 */
static unsigned short nfs_mount_protocol(struct mount_options *options)
{
	char *option;

	option = po_get(options, "mountproto");
	if (option) {
		if (strcmp(option, "tcp") == 0)
			return IPPROTO_TCP;
		if (strcmp(option, "udp") == 0)
			return IPPROTO_UDP;
	}

	return nfs_nfs_version(options);
}
Esempio n. 3
0
/*
 * Returns the NFS transport protocol specified by the given mount options
 *
 * Returns the IPPROTO_ value specified by the given mount options, or
 * IPPROTO_UDP if all fails.
 */
static unsigned short nfs_nfs_protocol(struct mount_options *options)
{
	char *option;

	switch (po_rightmost(options, nfs_transport_opttbl)) {
	case 1: /* tcp */
		return IPPROTO_TCP;
	case 2: /* proto */
		option = po_get(options, "proto");
		if (option) {
			if (strcmp(option, "tcp") == 0)
				return IPPROTO_TCP;
			if (strcmp(option, "udp") == 0)
				return IPPROTO_UDP;
		}
	}

	return IPPROTO_UDP;
}
Esempio n. 4
0
/*
 * Set up mandatory non-version specific NFS mount options.
 *
 * Returns 1 if successful; otherwise zero.
 */
static int nfs_validate_options(struct nfsmount_info *mi)
{
	struct addrinfo hint = {
		.ai_protocol	= (int)IPPROTO_UDP,
	};
	sa_family_t family;
	int error;
	char *option;

	if (!nfs_parse_devname(mi->spec, &mi->hostname, NULL))
		return 0;

	if (!nfs_nfs_proto_family(mi->options, &family))
		return 0;

	hint.ai_family = (int)family;
	error = getaddrinfo(mi->hostname, NULL, &hint, &mi->address);
	if (error != 0) {
		nfs_error(_("%s: Failed to resolve server %s: %s"),
			progname, mi->hostname, gai_strerror(error));
		mi->address = NULL;
		return 0;
	}

	if (!nfs_set_version(mi))
		return 0;

	if (!nfs_append_sloppy_option(mi->options))
		return 0;

	if (!nfs_append_addr_option(mi->address->ai_addr,
					mi->address->ai_addrlen, mi->options))
		return 0;

	option = po_get(mi->options, "srcaddr");
	if (option) {
		struct local_bind_info *local_ip;
		local_ip = malloc(sizeof(*local_ip));
		memset(local_ip, 0, sizeof(*local_ip));
		if (nfs_parse_local_bind(local_ip, option,
					 mi->address->ai_addr->sa_family) >= 0) {
			mi->local_ip = local_ip;
		} else {
			free(local_ip);
			return 0;
		}
	}

	return 1;
}

/*
 * Get NFS/mnt server addresses from mount options
 *
 * Returns 1 and fills in @nfs_saddr, @nfs_salen, @mnt_saddr, and @mnt_salen
 * if all goes well; otherwise zero.
 */
static int nfs_extract_server_addresses(struct mount_options *options,
					struct sockaddr *nfs_saddr,
					socklen_t *nfs_salen,
					struct sockaddr *mnt_saddr,
					socklen_t *mnt_salen)
{
	char *option;

	option = po_get(options, "addr");
	if (option == NULL)
		return 0;
	if (!nfs_string_to_sockaddr(option, nfs_saddr, nfs_salen))
		return 0;

	option = po_get(options, "mountaddr");
	if (option == NULL) {
		memcpy(mnt_saddr, nfs_saddr, *nfs_salen);
		*mnt_salen = *nfs_salen;
	} else if (!nfs_string_to_sockaddr(option, mnt_saddr, mnt_salen))
		return 0;

	return 1;
}