int acl_addr_matches_ipv4host(acl_options_t* acl, struct sockaddr_in* addr, unsigned int port) { if(acl->port != 0 && acl->port != port) return 0; switch(acl->rangetype) { case acl_range_mask: case acl_range_subnet: if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) return 0; break; case acl_range_minmax: if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) return 0; break; case acl_range_single: default: if(memcmp(&addr->sin_addr, &acl->addr.addr, sizeof(struct in_addr)) != 0) return 0; break; } return 1; }
int acl_addr_matches(acl_options_t* acl, struct query* q) { if(acl->is_ipv6) { #ifdef INET6 struct sockaddr_storage* addr_storage = (struct sockaddr_storage*)&q->addr; struct sockaddr_in6* addr = (struct sockaddr_in6*)&q->addr; if(addr_storage->ss_family != AF_INET6) return 0; if(acl->port != 0 && acl->port != ntohs(addr->sin6_port)) return 0; switch(acl->rangetype) { case acl_range_mask: case acl_range_subnet: if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr, (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr))) return 0; break; case acl_range_minmax: if(!acl_addr_match_range((uint32_t*)&acl->addr.addr6, (uint32_t*)&addr->sin6_addr, (uint32_t*)&acl->range_mask.addr6, sizeof(struct in6_addr))) return 0; break; case acl_range_single: default: if(memcmp(&addr->sin6_addr, &acl->addr.addr6, sizeof(struct in6_addr)) != 0) return 0; break; } return 1; #else return 0; /* no inet6, no match */ #endif } else { struct sockaddr_in* addr = (struct sockaddr_in*)&q->addr; if(addr->sin_family != AF_INET) return 0; if(acl->port != 0 && acl->port != ntohs(addr->sin_port)) return 0; switch(acl->rangetype) { case acl_range_mask: case acl_range_subnet: if(!acl_addr_match_mask((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) return 0; break; case acl_range_minmax: if(!acl_addr_match_range((uint32_t*)&acl->addr.addr, (uint32_t*)&addr->sin_addr, (uint32_t*)&acl->range_mask.addr, sizeof(struct in_addr))) return 0; break; case acl_range_single: default: if(memcmp(&addr->sin_addr, &acl->addr.addr, sizeof(struct in_addr)) != 0) return 0; break; } return 1; } /* ENOTREACH */ return 0; }