X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=support%2Fnfs%2Fgetport.c;h=aa9c154386d4cc14c004616e9ce64e679684f561;hp=9d85e897090f97e5a26bcd2dbd21783209f306e8;hb=c7fa61e76f072d97a9bdb4a551aa2ba28e5818cc;hpb=2fcfd397bc555a6c31082c09e6fee7750e41fdb0 diff --git a/support/nfs/getport.c b/support/nfs/getport.c index 9d85e89..aa9c154 100644 --- a/support/nfs/getport.c +++ b/support/nfs/getport.c @@ -321,7 +321,6 @@ int nfs_universal2port(const char *uaddr) /** * nfs_sockaddr2universal - convert a sockaddr to a "universal address" * @sap: pointer to a socket address - * @salen: length of socket address * * Universal addresses (defined in RFC 1833) are used when calling an * rpcbind daemon via protocol versions 3 or 4.. @@ -330,81 +329,56 @@ int nfs_universal2port(const char *uaddr) * the returned string. Otherwise NULL is returned and * rpc_createerr.cf_stat is set to reflect the error. * + * inet_ntop(3) is used here, since getnameinfo(3) is not available + * in some earlier glibc releases, and we don't require support for + * scope IDs for universal addresses. */ -#ifdef HAVE_GETNAMEINFO - -char *nfs_sockaddr2universal(const struct sockaddr *sap, - const socklen_t salen) +char *nfs_sockaddr2universal(const struct sockaddr *sap) { - struct sockaddr_un *sun = (struct sockaddr_un *)sap; - char buf[NI_MAXHOST]; + const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap; + const struct sockaddr_un *sun = (const struct sockaddr_un *)sap; + const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; + char buf[INET6_ADDRSTRLEN + 8 /* for port information */]; uint16_t port; + size_t count; + char *result; + int len; switch (sap->sa_family) { case AF_LOCAL: return strndup(sun->sun_path, sizeof(sun->sun_path)); case AF_INET: - if (getnameinfo(sap, salen, buf, (socklen_t)sizeof(buf), - NULL, 0, NI_NUMERICHOST) != 0) + if (inet_ntop(AF_INET, (const void *)&sin->sin_addr.s_addr, + buf, (socklen_t)sizeof(buf)) == NULL) goto out_err; - port = ntohs(((struct sockaddr_in *)sap)->sin_port); + port = ntohs(sin->sin_port); break; case AF_INET6: - if (getnameinfo(sap, salen, buf, (socklen_t)sizeof(buf), - NULL, 0, NI_NUMERICHOST) != 0) + if (inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr, + buf, (socklen_t)sizeof(buf)) == NULL) goto out_err; - port = ntohs(((struct sockaddr_in6 *)sap)->sin6_port); + port = ntohs(sin6->sin6_port); break; default: goto out_err; } - (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ".%u.%u", + count = sizeof(buf) - strlen(buf); + len = snprintf(buf + strlen(buf), count, ".%u.%u", (unsigned)(port >> 8), (unsigned)(port & 0xff)); - - return strdup(buf); - -out_err: - rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; - return NULL; -} - -#else /* HAVE_GETNAMEINFO */ - -char *nfs_sockaddr2universal(const struct sockaddr *sap, - const socklen_t salen) -{ - struct sockaddr_un *sun = (struct sockaddr_un *)sap; - char buf[NI_MAXHOST]; - uint16_t port; - char *addr; - - switch (sap->sa_family) { - case AF_LOCAL: - return strndup(sun->sun_path, sizeof(sun->sun_path)); - case AF_INET: - addr = inet_ntoa(((struct sockaddr_in *)sap)->sin_addr); - if (addr != NULL && strlen(addr) > sizeof(buf)) - goto out_err; - strcpy(buf, addr); - port = ntohs(((struct sockaddr_in *)sap)->sin_port); - break; - default: + /* before glibc 2.0.6, snprintf(3) could return -1 */ + if (len < 0 || (size_t)len > count) goto out_err; - } - - (void)snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ".%u.%u", - (unsigned)(port >> 8), (unsigned)(port & 0xff)); - return strdup(buf); + result = strdup(buf); + if (result != NULL) + return result; out_err: rpc_createerr.cf_stat = RPC_N2AXLATEFAILURE; return NULL; } -#endif /* HAVE_GETNAMEINFO */ - /* * Send a NULL request to the indicated RPC service. * @@ -431,7 +405,6 @@ static int nfs_gp_ping(CLIENT *client, struct timeval timeout) * to by r_netid and r_addr; otherwise 0. */ static int nfs_gp_init_rpcb_parms(const struct sockaddr *sap, - const socklen_t salen, const rpcprog_t program, const rpcvers_t version, const unsigned short protocol, @@ -443,7 +416,7 @@ static int nfs_gp_init_rpcb_parms(const struct sockaddr *sap, if (netid == NULL) return 0; - addr = nfs_sockaddr2universal(sap, salen); + addr = nfs_sockaddr2universal(sap); if (addr == NULL) { free(netid); return 0; @@ -496,7 +469,7 @@ static unsigned short nfs_gp_rpcb_getaddr(CLIENT *client, case RPC_SUCCESS: if ((uaddr == NULL) || (uaddr[0] == '\0')) { rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; - continue; + return 0; } port = nfs_universal2port(uaddr); @@ -564,7 +537,6 @@ static unsigned long nfs_gp_pmap_getport(CLIENT *client, static unsigned short nfs_gp_getport_rpcb(CLIENT *client, const struct sockaddr *sap, - const socklen_t salen, const rpcprog_t program, const rpcvers_t version, const unsigned short protocol, @@ -573,8 +545,8 @@ static unsigned short nfs_gp_getport_rpcb(CLIENT *client, unsigned short port = 0; struct rpcb parms; - if (nfs_gp_init_rpcb_parms(sap, salen, program, - version, protocol, &parms) != 0) { + if (nfs_gp_init_rpcb_parms(sap, program, version, + protocol, &parms) != 0) { port = nfs_gp_rpcb_getaddr(client, &parms, timeout); nfs_gp_free_rpcb_parms(&parms); } @@ -610,7 +582,6 @@ static unsigned long nfs_gp_getport_pmap(CLIENT *client, */ static unsigned short nfs_gp_getport(CLIENT *client, const struct sockaddr *sap, - const socklen_t salen, const rpcprog_t program, const rpcvers_t version, const unsigned short protocol, @@ -619,7 +590,7 @@ static unsigned short nfs_gp_getport(CLIENT *client, switch (sap->sa_family) { #ifdef HAVE_LIBTIRPC case AF_INET6: - return nfs_gp_getport_rpcb(client, sap, salen, program, + return nfs_gp_getport_rpcb(client, sap, program, version, protocol, timeout); #endif /* HAVE_LIBTIRPC */ case AF_INET: @@ -656,6 +627,8 @@ int nfs_rpc_ping(const struct sockaddr *sap, const socklen_t salen, if (timeout != NULL) tout = *timeout; + nfs_clear_rpc_createerr(); + memcpy(saddr, sap, (size_t)salen); client = nfs_get_rpcclient(saddr, salen, protocol, program, version, &tout); @@ -719,11 +692,13 @@ unsigned short nfs_getport(const struct sockaddr *sap, unsigned short port = 0; CLIENT *client; + nfs_clear_rpc_createerr(); + memcpy(saddr, sap, (size_t)salen); client = nfs_gp_get_rpcbclient(saddr, salen, protocol, default_rpcb_version, &timeout); if (client != NULL) { - port = nfs_gp_getport(client, saddr, salen, program, + port = nfs_gp_getport(client, saddr, program, version, protocol, timeout); CLNT_DESTROY(client); } @@ -758,10 +733,12 @@ int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen, CLIENT *client; int result = 0; + nfs_clear_rpc_createerr(); + client = nfs_gp_get_rpcbclient(sap, salen, protocol, default_rpcb_version, &timeout); if (client != NULL) { - port = nfs_gp_getport(client, sap, salen, program, + port = nfs_gp_getport(client, sap, program, version, protocol, timeout); CLNT_DESTROY(client); client = NULL; @@ -774,6 +751,8 @@ int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen, memcpy(saddr, sap, (size_t)salen); nfs_gp_set_port(saddr, htons(port)); + nfs_clear_rpc_createerr(); + client = nfs_get_rpcclient(saddr, salen, protocol, program, version, &timeout); if (client != NULL) { @@ -832,11 +811,13 @@ unsigned short nfs_getlocalport(const rpcprot_t program, CLIENT *client; struct timeval timeout = { -1, 0 }; + nfs_clear_rpc_createerr(); + client = nfs_gp_get_rpcbclient(sap, salen, 0, RPCBVERS_4, &timeout); if (client != NULL) { struct rpcb parms; - if (nfs_gp_init_rpcb_parms(sap, salen, program, version, + if (nfs_gp_init_rpcb_parms(sap, program, version, protocol, &parms) != 0) { port = nfs_gp_rpcb_getaddr(client, &parms, timeout); nfs_gp_free_rpcb_parms(&parms); @@ -846,6 +827,8 @@ unsigned short nfs_getlocalport(const rpcprot_t program, #endif /* NFS_GP_LOCAL */ if (port == 0) { + nfs_clear_rpc_createerr(); + if (nfs_gp_loopback_address(lb_addr, &lb_len)) { port = nfs_getport(lb_addr, lb_len, program, version, protocol); @@ -862,7 +845,6 @@ unsigned short nfs_getlocalport(const rpcprot_t program, * @salen: length of server address * @transport: transport protocol to use for the query * @addr: pointer to r_addr address - * @addrlen: length of address * @program: requested RPC program number * @version: requested RPC version number * @protocol: requested IPPROTO_ value of transport protocol @@ -893,7 +875,6 @@ unsigned short nfs_rpcb_getaddr(const struct sockaddr *sap, const socklen_t salen, const unsigned short transport, const struct sockaddr *addr, - const socklen_t addrlen, const rpcprog_t program, const rpcvers_t version, const unsigned short protocol, @@ -909,11 +890,13 @@ unsigned short nfs_rpcb_getaddr(const struct sockaddr *sap, if (timeout != NULL) tout = *timeout; + nfs_clear_rpc_createerr(); + memcpy(saddr, sap, (size_t)salen); client = nfs_gp_get_rpcbclient(saddr, salen, transport, RPCBVERS_4, &tout); if (client != NULL) { - if (nfs_gp_init_rpcb_parms(addr, addrlen, program, version, + if (nfs_gp_init_rpcb_parms(addr, program, version, protocol, &parms) != 0) { port = nfs_gp_rpcb_getaddr(client, &parms, tout); nfs_gp_free_rpcb_parms(&parms); @@ -926,16 +909,17 @@ unsigned short nfs_rpcb_getaddr(const struct sockaddr *sap, #else /* !HAVE_LIBTIRPC */ -unsigned short nfs_rpcb_getaddr(const struct sockaddr *sap, - const socklen_t salen, - const unsigned short transport, - const struct sockaddr *addr, - const socklen_t addrlen, - const rpcprog_t program, - const rpcvers_t version, - const unsigned short protocol, - const struct timeval *timeout) +unsigned short nfs_rpcb_getaddr(__attribute__((unused)) const struct sockaddr *sap, + __attribute__((unused)) const socklen_t salen, + __attribute__((unused)) const unsigned short transport, + __attribute__((unused)) const struct sockaddr *addr, + __attribute__((unused)) const rpcprog_t program, + __attribute__((unused)) const rpcvers_t version, + __attribute__((unused)) const unsigned short protocol, + __attribute__((unused)) const struct timeval *timeout) { + nfs_clear_rpc_createerr(); + rpc_createerr.cf_stat = RPC_UNKNOWNADDR; return 0; } @@ -991,6 +975,8 @@ unsigned long nfs_pmap_getport(const struct sockaddr_in *sin, if (timeout != NULL) tout = *timeout; + nfs_clear_rpc_createerr(); + memcpy(saddr, sin, sizeof(address)); client = nfs_gp_get_rpcbclient(saddr, (socklen_t)sizeof(*sin), transport, PMAPVERS, &tout);