+ if (ban->address.ss_family == address->ss_family) {
+ if (address->ss_family == AF_INET) {
+ uint32_t a1, a2, mask;
+ mask = (ban->mask == 32) ? UINT32_MAX : (1u << ban->mask) - 1;
+ a1 = (uint32_t)((struct sockaddr_in *)&ban->address)->sin_addr.s_addr & mask;
+ a2 = (uint32_t)((struct sockaddr_in *)address)->sin_addr.s_addr & mask;
+ if (a1 == a2)
+ return true;
+ } else {
+ uint64_t mask[2];
+ uint64_t *a1 = (uint64_t *) &((struct sockaddr_in6 *)&ban->address)->sin6_addr.s6_addr;
+ uint64_t *a2 = (uint64_t *) &((struct sockaddr_in6 *)address)->sin6_addr.s6_addr;
+
+ if (ban->mask == 128)
+ mask[0] = mask[1] = 0xffffffffffffffffULL;
+ else if (ban->mask > 64) {
+ mask[0] = 0xffffffffffffffffULL;
+ mask[1] = SWAPPED(~((1ULL << (128 - ban->mask)) - 1));
+ } else {
+ mask[0] = SWAPPED(~((1ULL << (64 - ban->mask)) - 1));
+ mask[1] = 0ULL;
+ }
+ if ((a1[0] & mask[0]) == (a2[0] & mask[0]) &&
+ (a1[1] & mask[1]) == (a2[1] & mask[1]))
+ return true;
+ }