]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - utils/mount/network.c
nfs-utils: Remove all uses of AI_ADDRCONFIG
[nfs-utils.git] / utils / mount / network.c
index f020933dfe87d6ed1d55e6e04b401943d5d768a2..21a7a2cc11fd8ed2faa5fa064c7a68bf5b5e3026 100644 (file)
 #include "parse_opt.h"
 #include "network.h"
 #include "conffile.h"
+#include "nfslib.h"
 
 #define PMAP_TIMEOUT   (10)
 #define CONNECT_TIMEOUT        (20)
 #define MOUNT_TIMEOUT  (30)
 
+#define SAFE_SOCKADDR(x)       (struct sockaddr *)(char *)(x)
+
 extern int nfs_mount_data_version;
 extern char *progname;
 extern int verbose;
@@ -82,6 +85,7 @@ static const char *nfs_nfs_pgmtbl[] = {
 static const char *nfs_transport_opttbl[] = {
        "udp",
        "tcp",
+       "rdma",
        "proto",
        NULL,
 };
@@ -206,9 +210,6 @@ int nfs_lookup(const char *hostname, const sa_family_t family,
 {
        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;
@@ -426,12 +427,12 @@ static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
                if (bindresvport(so, &laddr) < 0)
                        goto err_bindresvport;
        } else {
-               cc = bind(so, (struct sockaddr *)&laddr, namelen);
+               cc = bind(so, SAFE_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,
+               cc = connect_to(so, SAFE_SOCKADDR(saddr), namelen,
                                timeout);
                if (cc < 0)
                        goto err_connect;
@@ -754,11 +755,12 @@ int nfs_probe_bothports(const struct sockaddr *mnt_saddr,
  */
 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),
+       struct sockaddr *mnt_addr = SAFE_SOCKADDR(&mnt_server->saddr);
+       struct sockaddr *nfs_addr = SAFE_SOCKADDR(&nfs_server->saddr);
+
+       return nfs_probe_bothports(mnt_addr, sizeof(mnt_server->saddr),
                                        &mnt_server->pmap,
-                                       (struct sockaddr *)&nfs_server->saddr,
-                                       sizeof(nfs_server->saddr),
+                                       nfs_addr, sizeof(nfs_server->saddr),
                                        &nfs_server->pmap);
 }
 
@@ -770,7 +772,7 @@ static int nfs_probe_statd(void)
        };
        rpcprog_t program = nfs_getrpcbyname(NSMPROG, nfs_ns_pgmtbl);
 
-       return nfs_getport_ping((struct sockaddr *)&addr, sizeof(addr),
+       return nfs_getport_ping(SAFE_SOCKADDR(&addr), sizeof(addr),
                                program, (rpcvers_t)1, IPPROTO_UDP);
 }
 
@@ -857,7 +859,14 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
                return 0;
        }
 
-       client->cl_auth = authunix_create_default();
+       client->cl_auth = nfs_authsys_create();
+       if (client->cl_auth == NULL) {
+               if (verbose)
+                       nfs_error(_("%s: Failed to create RPC auth handle"),
+                               progname);
+               CLNT_DESTROY(client);
+               return 0;
+       }
 
        res = CLNT_CALL(client, MOUNTPROC_UMNT,
                        (xdrproc_t)xdr_dirpath, (caddr_t)argp,
@@ -892,7 +901,7 @@ int nfs_advise_umount(const struct sockaddr *sap, const socklen_t salen,
  */
 int nfs_call_umount(clnt_addr_t *mnt_server, dirpath *argp)
 {
-       struct sockaddr *sap = (struct sockaddr *)&mnt_server->saddr;
+       struct sockaddr *sap = SAFE_SOCKADDR(&mnt_server->saddr);
        socklen_t salen = sizeof(mnt_server->saddr);
        struct pmap *pmap = &mnt_server->pmap;
        CLIENT *clnt;
@@ -957,8 +966,10 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
        }
        if (clnt) {
                /* try to mount hostname:dirname */
-               clnt->cl_auth = authunix_create_default();
-               return clnt;
+               clnt->cl_auth = nfs_authsys_create();
+               if (clnt->cl_auth)
+                       return clnt;
+               CLNT_DESTROY(clnt);
        }
        return NULL;
 }
@@ -1000,11 +1011,11 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
                struct sockaddr_in *caddr)
 {
        CLIENT *clnt = NULL;
-       int sock, stat;
+       int sock, status;
        static char clnt_res;
        struct sockaddr dissolve;
 
-       rpc_createerr.cf_stat = stat = 0;
+       rpc_createerr.cf_stat = status = 0;
        sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE);
        if (sock == RPC_ANYSOCK) {
                if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) {
@@ -1047,18 +1058,18 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned long prog,
                return 0;
        }
        memset(&clnt_res, 0, sizeof(clnt_res));
-       stat = clnt_call(clnt, NULLPROC,
+       status = clnt_call(clnt, NULLPROC,
                         (xdrproc_t)xdr_void, (caddr_t)NULL,
                         (xdrproc_t)xdr_void, (caddr_t)&clnt_res,
                         TIMEOUT);
-       if (stat) {
+       if (status) {
                clnt_geterr(clnt, &rpc_createerr.cf_error);
-               rpc_createerr.cf_stat = stat;
+               rpc_createerr.cf_stat = status;
        }
        clnt_destroy(clnt);
        close(sock);
 
-       if (stat == RPC_SUCCESS)
+       if (status == RPC_SUCCESS)
                return 1;
        else
                return 0;
@@ -1092,13 +1103,13 @@ static int nfs_ca_sockname(const struct sockaddr *sap, const socklen_t salen,
 
        switch (sap->sa_family) {
        case AF_INET:
-               if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+               if (bind(sock, SAFE_SOCKADDR(&sin), sizeof(sin)) < 0) {
                        close(sock);
                        return 0;
                }
                break;
        case AF_INET6:
-               if (bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)) < 0) {
+               if (bind(sock, SAFE_SOCKADDR(&sin6), sizeof(sin6)) < 0) {
                        close(sock);
                        return 0;
                }
@@ -1203,6 +1214,8 @@ nfs_nfs_program(struct mount_options *options, unsigned long *program)
                        return 1;
                }
        case PO_BAD_VALUE:
+               nfs_error(_("%s: invalid value for 'nfsprog=' option"),
+                               progname);
                return 0;
        }
 
@@ -1242,9 +1255,12 @@ nfs_nfs_version(struct mount_options *options, unsigned long *version)
                        }
                        return 0;
                case PO_NOT_FOUND:
-                       nfs_error(_("%s: option parsing error\n"),
+                       nfs_error(_("%s: parsing error on 'vers=' option\n"),
                                        progname);
+                       return 0;
                case PO_BAD_VALUE:
+                       nfs_error(_("%s: invalid value for 'vers=' option"),
+                                       progname);
                        return 0;
                }
        case 4: /* nfsvers */
@@ -1256,9 +1272,12 @@ nfs_nfs_version(struct mount_options *options, unsigned long *version)
                        }
                        return 0;
                case PO_NOT_FOUND:
-                       nfs_error(_("%s: option parsing error\n"),
+                       nfs_error(_("%s: parsing error on 'nfsvers=' option\n"),
                                        progname);
+                       return 0;
                case PO_BAD_VALUE:
+                       nfs_error(_("%s: invalid value for 'nfsvers=' option"),
+                                       progname);
                        return 0;
                }
        }
@@ -1289,11 +1308,16 @@ nfs_nfs_protocol(struct mount_options *options, unsigned long *protocol)
        case 1: /* tcp */
                *protocol = IPPROTO_TCP;
                return 1;
-       case 2: /* proto */
+       case 2: /* rdma */
+               *protocol = NFSPROTO_RDMA;
+               return 1;
+       case 3: /* proto */
                option = po_get(options, "proto");
                if (option != NULL) {
                        if (!nfs_get_proto(option, &family, protocol)) {
                                errno = EPROTONOSUPPORT;
+                               nfs_error(_("%s: Failed to find '%s' protocol"), 
+                                       progname, option);
                                return 0;
                        }
                        return 1;
@@ -1327,6 +1351,8 @@ nfs_nfs_port(struct mount_options *options, unsigned long *port)
                        return 1;
                }
        case PO_BAD_VALUE:
+               nfs_error(_("%s: invalid value for 'port=' option"),
+                               progname);
                return 0;
        }
 
@@ -1342,7 +1368,7 @@ nfs_nfs_port(struct mount_options *options, unsigned long *port)
 sa_family_t    config_default_family = AF_UNSPEC;
 
 static int
-nfs_verify_family(sa_family_t family)
+nfs_verify_family(sa_family_t UNUSED(family))
 {
        return 1;
 }
@@ -1373,14 +1399,21 @@ int nfs_nfs_proto_family(struct mount_options *options,
 
        switch (po_rightmost(options, nfs_transport_opttbl)) {
        case 0: /* udp */
-               return 1;
        case 1: /* tcp */
+       case 2: /* rdma */
+               /* for compatibility; these are always AF_INET */
+               *family = AF_INET;
                return 1;
-       case 2: /* proto */
+       case 3: /* proto */
                option = po_get(options, "proto");
                if (option != NULL &&
-                   !nfs_get_proto(option, &tmp_family, &protocol))
-                       goto out_err;
+                   !nfs_get_proto(option, &tmp_family, &protocol)) {
+
+                       nfs_error(_("%s: Failed to find '%s' protocol"), 
+                               progname, option);
+                       errno = EPROTONOSUPPORT;
+                       return 0;
+               }
        }
 
        if (!nfs_verify_family(tmp_family))
@@ -1413,6 +1446,8 @@ nfs_mount_program(struct mount_options *options, unsigned long *program)
                        return 1;
                }
        case PO_BAD_VALUE:
+               nfs_error(_("%s: invalid value for 'mountprog=' option"),
+                               progname);
                return 0;
        }
 
@@ -1442,6 +1477,8 @@ nfs_mount_version(struct mount_options *options, unsigned long *version)
                        return 1;
                }
        case PO_BAD_VALUE:
+               nfs_error(_("%s: invalid value for 'mountvers=' option"),
+                               progname);
                return 0;
        }
 
@@ -1468,6 +1505,8 @@ nfs_mount_protocol(struct mount_options *options, unsigned long *protocol)
        if (option != NULL) {
                if (!nfs_get_proto(option, &family, protocol)) {
                        errno = EPROTONOSUPPORT;
+                       nfs_error(_("%s: Failed to find '%s' protocol"), 
+                               progname, option);
                        return 0;
                }
                return 1;
@@ -1479,7 +1518,11 @@ nfs_mount_protocol(struct mount_options *options, unsigned long *protocol)
         * 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);
+       if (!nfs_nfs_protocol(options, protocol))
+               return 0;
+       if (*protocol == NFSPROTO_RDMA)
+               *protocol = IPPROTO_TCP;
+       return 1;
 }
 
 /*
@@ -1500,6 +1543,8 @@ nfs_mount_port(struct mount_options *options, unsigned long *port)
                        return 1;
                }
        case PO_BAD_VALUE:
+               nfs_error(_("%s: invalid value for 'mountport=' option"),
+                               progname);
                return 0;
        }
 
@@ -1525,8 +1570,12 @@ int nfs_mount_proto_family(struct mount_options *options,
 
        option = po_get(options, "mountproto");
        if (option != NULL) {
-               if (!nfs_get_proto(option, &tmp_family, &protocol))
+               if (!nfs_get_proto(option, &tmp_family, &protocol)) {
+                       nfs_error(_("%s: Failed to find '%s' protocol"), 
+                               progname, option);
+                       errno = EPROTONOSUPPORT;
                        goto out_err;
+               }
                if (!nfs_verify_family(tmp_family))
                        goto out_err;
                *family = tmp_family;