Пример #1
0
Файл: acl.c Проект: jkadlec/knot
bool netblock_match(const struct sockaddr_storage *ss1,
                    const struct sockaddr_storage *ss2,
                    unsigned prefix)
{
	if (ss1 == NULL || ss2 == NULL) {
		return false;
	}

	if (ss1->ss_family != ss2->ss_family) {
		return false;
	}

	const uint8_t *addr1, *addr2;
	switch (ss1->ss_family) {
	case AF_INET:
		addr1 = ipv4_addr(ss1);
		addr2 = ipv4_addr(ss2);
		prefix = prefix > IPV4_PREFIXLEN ? IPV4_PREFIXLEN : prefix;
		break;
	case AF_INET6:
		addr1 = ipv6_addr(ss1);
		addr2 = ipv6_addr(ss2);
		prefix = prefix > IPV6_PREFIXLEN ? IPV6_PREFIXLEN : prefix;
		break;
	default:
		return false;
	}

	/* Compare full bytes address block. */
	uint8_t full_bytes = prefix / 8;
	for (int i = 0; i < full_bytes; i++) {
		if (addr1[i] != addr2[i]) {
			return false;
		}
	}

	/* Compare last partial byte address block. */
	uint8_t rest_bits = prefix % 8;
	if (rest_bits > 0) {
		uint8_t rest1 = addr1[full_bytes] >> (8 - rest_bits);
		uint8_t rest2 = addr2[full_bytes] >> (8 - rest_bits);
		if (rest1 != rest2) {
			return false;
		}
	}
    int port(struct sockaddr_storage *addr)
    {
        if (AF_INET == addr->ss_family)
        {
            return ntohs(ipv4_addr(addr)->sin_port);
        }
        else if (AF_INET6 == addr->ss_family)
        {
            return ntohs(ipv6_addr(addr)->sin6_port);
        }

        return 0;
    }
    const char *inet_ntop(struct sockaddr_storage *addr)
    {
        if (AF_INET == addr->ss_family)
        {
            return ::inet_ntop(AF_INET, &(ipv4_addr(addr)->sin_addr), m_buffer, sizeof(m_buffer));
        }
        else if (AF_INET6 == addr->ss_family)
        {
            return ::inet_ntop(AF_INET6, &(ipv6_addr(addr)->sin6_addr), m_buffer, sizeof(m_buffer));
        }

        return NULL;
    }