/**
* 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..
* 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.
*
* 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,
if (netid == NULL)
return 0;
- addr = nfs_sockaddr2universal(sap, salen);
+ addr = nfs_sockaddr2universal(sap);
if (addr == NULL) {
free(netid);
return 0;
case RPC_SUCCESS:
if ((uaddr == NULL) || (uaddr[0] == '\0')) {
rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
- continue;
+ return 0;
}
port = nfs_universal2port(uaddr);
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,
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);
}
*/
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,
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:
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);
}
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;
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);
* @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
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,
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);
#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)
{
rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
return 0;