/** * from_local - determine whether request comes from the local system * @sap: pointer to socket address to check * * With virtual hosting, each hardware network interface can have * multiple network addresses. On such machines the number of machine * addresses can be surprisingly large. * * We also expect the local network configuration to change over time, * so call getifaddrs(3) more than once, but not too often. * * Returns TRUE if the sockaddr contains an address of one of the local * network interfaces. Otherwise FALSE is returned. */ int from_local(const struct sockaddr *sap) { static struct ifaddrs *ifaddr = NULL; static time_t last_update = 0; struct ifaddrs *ifa; unsigned int count; time_t now; if (time(&now) == ((time_t)-1)) { xlog(L_ERROR, "%s: time(2): %m", __func__); /* If we don't know what time it is, use the * existing ifaddr list, if one exists */ now = last_update; if (ifaddr == NULL) now++; } if (now != last_update) { xlog(D_GENERAL, "%s: updating local if addr list", __func__); if (ifaddr) freeifaddrs(ifaddr); if (getifaddrs(&ifaddr) == -1) { xlog(L_ERROR, "%s: getifaddrs(3): %m", __func__); return FALSE; } last_update = now; } count = 0; for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) { if ((ifa->ifa_flags & IFF_UP) && nfs_compare_sockaddr(sap, ifa->ifa_addr)) { xlog(D_GENERAL, "%s: incoming address matches " "local interface address", __func__); return TRUE; } else count++; } xlog(D_GENERAL, "%s: checked %u local if addrs; " "incoming address not found", __func__, count); return FALSE; }
/* * Find a previously cached SVC xprt structure with the given bind address * and transport semantics. * * Returns pointer to a cached SVC xprt. * * If no matching SVC XPRT can be found, NULL is returned. */ static SVCXPRT * svc_create_find_xprt(const struct sockaddr *bindaddr, const struct netconfig *nconf) { unsigned int i; for (i = 0; i < SVC_CREATE_XPRT_CACHE_SIZE; i++) { SVCXPRT *xprt = svc_create_xprt_cache[i]; struct sockaddr *sap; if (xprt == NULL) continue; if (strcmp(nconf->nc_netid, xprt->xp_netid) != 0) continue; sap = (struct sockaddr *)xprt->xp_ltaddr.buf; if (!nfs_compare_sockaddr(bindaddr, sap)) continue; return xprt; } return NULL; }
static int matchhostname(const char *hostname1, const char *hostname2) { struct addrinfo *results1 = NULL, *results2 = NULL; struct addrinfo *ai1, *ai2; int result = 0; if (strcasecmp(hostname1, hostname2) == 0) return 1; /* * Don't pass export wildcards or netgroup names to DNS */ if (!is_hostname(hostname1) || !is_hostname(hostname2)) return 0; results1 = address_list(hostname1); if (results1 == NULL) goto out; results2 = address_list(hostname2); if (results2 == NULL) goto out; if (strcasecmp(results1->ai_canonname, results2->ai_canonname) == 0) { result = 1; goto out; } for (ai1 = results1; ai1 != NULL; ai1 = ai1->ai_next) for (ai2 = results2; ai2 != NULL; ai2 = ai2->ai_next) if (nfs_compare_sockaddr(ai1->ai_addr, ai2->ai_addr)) { result = 1; break; } out: freeaddrinfo(results1); freeaddrinfo(results2); return result; }