X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fmount%2Fnetwork.c;h=49d3c6b26d63c33c4b83ae6f497e1fb2a809f87f;hp=9f803a43e6c7e29561b0b62f07b47456765e8ffc;hb=bda03ca689ff8b410a778299e5c6f4a14fcc85f8;hpb=bd8cc33c7c089d5d36151732f4c00a836e7732e6 diff --git a/utils/mount/network.c b/utils/mount/network.c index 9f803a4..49d3c6b 100644 --- a/utils/mount/network.c +++ b/utils/mount/network.c @@ -139,6 +139,13 @@ static const unsigned long probe_mnt3_first[] = { 0, }; +/** + * nfs_gethostbyname - resolve a hostname to an IPv4 address + * @hostname: pointer to a C string containing a DNS hostname + * @saddr: returns an IPv4 address + * + * Returns 1 if successful, otherwise zero. + */ int nfs_gethostbyname(const char *hostname, struct sockaddr_in *saddr) { struct hostent *hp; @@ -457,6 +464,16 @@ static int probe_mntport(clnt_addr_t *mnt_server) return probe_port(mnt_server, probe_mnt1_first, probe_udp_only); } +/** + * 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 + * + * Returns 1 if successful, otherwise zero if some error occurred. + * Note that the arguments are both input and output arguments. + * + * A side effect of calling this function is that rpccreateerr is set. + */ int probe_bothports(clnt_addr_t *mnt_server, clnt_addr_t *nfs_server) { struct pmap *nfs_pmap = &nfs_server->pmap; @@ -524,8 +541,10 @@ static int probe_statd(void) return 1; } -/* - * Attempt to start rpc.statd +/** + * start_statd - attempt to start rpc.statd + * + * Returns 1 if statd is running; otherwise zero. */ int start_statd(void) { @@ -549,7 +568,7 @@ int start_statd(void) return 0; } -/* +/** * 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" @@ -593,6 +612,13 @@ int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp) 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; @@ -634,6 +660,12 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock) 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); @@ -641,11 +673,24 @@ void mnt_closeclnt(CLIENT *clnt, int msock) 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() doesn't actually check the version number. * In order to make sure that the server actually supports the service * we're requesting, we open and 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, @@ -715,3 +760,36 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog, else return 0; } + +/** + * get_client_address - acquire our local network address + * @saddr: server's address + * @caddr: filled in with our network address + * + * Discover a 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. + * + * Use a connected datagram socket so as not to leave a socket in TIME_WAIT. + * + * Returns one if successful, otherwise zero. + */ +int get_client_address(struct sockaddr_in *saddr, struct sockaddr_in *caddr) +{ + socklen_t len = sizeof(*caddr); + int socket, err; + + socket = get_socket(saddr, IPPROTO_UDP, CONNECT_TIMEOUT, FALSE, TRUE); + if (socket == RPC_ANYSOCK) + return 0; + + err = getsockname(socket, caddr, &len); + close(socket); + + if (err && verbose) { + nfs_error(_("%s: getsockname failed: %s"), + progname, strerror(errno)); + return 0; + } + return 1; +}