示例#1
0
/**
 * 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;
}
示例#2
0
/*
 * 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;
}
示例#3
0
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;
}