Example #1
0
isc_result_t
dns_peerlist_peerbyaddr(dns_peerlist_t *servers,
			isc_netaddr_t *addr, dns_peer_t **retval)
{
	dns_peer_t *server;
	isc_result_t res;

	REQUIRE(retval != NULL);
	REQUIRE(DNS_PEERLIST_VALID(servers));

	server = ISC_LIST_HEAD(servers->elements);
	while (server != NULL) {
		if (isc_netaddr_eqprefix(addr, &server->address,
					 server->prefixlen))
			break;

		server = ISC_LIST_NEXT(server, next);
	}

	if (server != NULL) {
		*retval = server;
		res = ISC_R_SUCCESS;
	} else {
		res = ISC_R_NOTFOUND;
	}

	return (res);
}
Example #2
0
isc_boolean_t
dns_aclelement_equal(dns_aclelement_t *ea, dns_aclelement_t *eb) {
	if (ea->type != eb->type)
		return (ISC_FALSE);
	switch (ea->type) {
	case dns_aclelementtype_ipprefix:
		if (ea->u.ip_prefix.prefixlen !=
		    eb->u.ip_prefix.prefixlen)
			return (ISC_FALSE);
		return (isc_netaddr_eqprefix(&ea->u.ip_prefix.address,
					     &eb->u.ip_prefix.address,
					     ea->u.ip_prefix.prefixlen));
	case dns_aclelementtype_keyname:
		return (dns_name_equal(&ea->u.keyname, &eb->u.keyname));
	case dns_aclelementtype_nestedacl:
		return (dns_acl_equal(ea->u.nestedacl, eb->u.nestedacl));
	case dns_aclelementtype_localhost:
	case dns_aclelementtype_localnets:
	case dns_aclelementtype_any:
		return (ISC_TRUE);
	default:
		INSIST(0);
		return (ISC_FALSE);
	}
}
Example #3
0
isc_boolean_t
isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
			  unsigned int prefixlen)
{
	isc_netaddr_t na, nb;
	isc_netaddr_fromsockaddr(&na, a);
	isc_netaddr_fromsockaddr(&nb, b);
	return (isc_netaddr_eqprefix(&na, &nb, prefixlen));
}
Example #4
0
static unsigned char
GAA_find_prefix(isc_interfaceiter_t *iter) {
	IP_ADAPTER_PREFIX *	ipap;
	IP_ADAPTER_PREFIX *	ipap_match;
	int			match_len;
	int			max_len;
	isc_netaddr_t		target;
	u_short			af;
	isc_netaddr_t		pfx;
	int			pfx_len;
	size_t			nbytes;
	unsigned char		nbits;
	unsigned char *		pbits;
	unsigned int		octets;

	match_len = 0;
	ipap_match = NULL;
	isc_netaddr_fromsockaddr(&target,
	    (isc_sockaddr_t *)iter->ipuaCur->Address.lpSockaddr);
	af = (u_short)target.family;
	INSIST(AF_INET == af || AF_INET6 == af);
	max_len = (AF_INET6 == af) ? 128 : 32;
	iter->current.netmask.family = af;
	for (ipap = iter->ipaaCur->FirstPrefix;
	     ipap != NULL;
	     ipap = ipap->Next) {
		if (ipap->Address.lpSockaddr->sa_family != af)
			continue;
		isc_netaddr_fromsockaddr(&pfx,
		    (isc_sockaddr_t *)ipap->Address.lpSockaddr);
		pfx_len = ipap->PrefixLength;
		INSIST(0 <= pfx_len && pfx_len <= max_len);
		if (pfx_len > match_len && pfx_len < max_len &&
		    isc_netaddr_eqprefix(&target, &pfx, pfx_len)) {
			ipap_match = ipap;
			match_len = pfx_len;
		}
	}
	if (NULL == ipap_match) {
		/* presume all-ones mask */
		if (AF_INET6 == af)
			octets = sizeof(iter->current.netmask.type.in6);
		else
			octets = sizeof(iter->current.netmask.type.in);
		memset(&iter->current.netmask.type, 0xFF, octets);
		return (8 * (unsigned char)octets);
	}
	nbytes = match_len / 8;
	nbits = match_len % 8;
	memset(&iter->current.netmask.type.in6, 0xFF, nbytes);
	pbits = (void *)&iter->current.netmask.type.in6;
	pbits += nbytes;
	*pbits |= 0xFF << (8 - nbits);
	return ((unsigned char)match_len);
}
Example #5
0
isc_boolean_t
dns_aclelement_match(isc_netaddr_t *reqaddr,
		     dns_name_t *reqsigner,
		     dns_aclelement_t *e,
		     dns_aclenv_t *env,
		     dns_aclelement_t **matchelt)
{
	dns_acl_t *inner = NULL;
	isc_netaddr_t *addr;
	isc_netaddr_t v4addr;
	int indirectmatch;
	isc_result_t result;

	switch (e->type) {
	case dns_aclelementtype_ipprefix:
		if (env == NULL ||
		    env->match_mapped == ISC_FALSE ||
		    reqaddr->family != AF_INET6 ||
		    !IN6_IS_ADDR_V4MAPPED(&reqaddr->type.in6))
			addr = reqaddr;
		else {
			isc_netaddr_fromv4mapped(&v4addr, reqaddr);
			addr = &v4addr;
		}

		if (isc_netaddr_eqprefix(addr,
					 &e->u.ip_prefix.address, 
					 e->u.ip_prefix.prefixlen))
			goto matched;
		break;
		
	case dns_aclelementtype_keyname:
		if (reqsigner != NULL &&
		    dns_name_equal(reqsigner, &e->u.keyname))
			goto matched;
		break;
		
	case dns_aclelementtype_nestedacl:
		inner = e->u.nestedacl;
	nested:
		result = dns_acl_match(reqaddr, reqsigner,
				       inner,
				       env,
				       &indirectmatch, matchelt);
		INSIST(result == ISC_R_SUCCESS);

		/*
		 * Treat negative matches in indirect ACLs as
		 * "no match".
		 * That way, a negated indirect ACL will never become 
		 * a surprise positive match through double negation.
		 * XXXDCL this should be documented.
		 */
		if (indirectmatch > 0)
			goto matchelt_set;
		
		/*
		 * A negative indirect match may have set *matchelt,
		 * but we don't want it set when we return.
		 */
		if (matchelt != NULL)
			*matchelt = NULL;
		break;
		
	case dns_aclelementtype_any:
	matched:
		if (matchelt != NULL)
			*matchelt = e;
	matchelt_set:
		return (ISC_TRUE);
			
	case dns_aclelementtype_localhost:
		if (env != NULL && env->localhost != NULL) {
			inner = env->localhost;
			goto nested;
		} else {
			break;
		}
		
	case dns_aclelementtype_localnets:
		if (env != NULL && env->localnets != NULL) {
			inner = env->localnets;
			goto nested;
		} else {
			break;
		}
		
	default:
		INSIST(0);
		break;
	}

	return (ISC_FALSE);
}