Mercurial > dovecot > core-2.2
changeset 7517:e0007da64cdc HEAD
Moved net_is_in_network() to lib/network.c.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 15 May 2008 07:43:13 +0300 |
parents | 7a7cf6662302 |
children | 45a4fe590389 |
files | src/auth/auth-request.c src/lib/network.c src/lib/network.h src/tests/test-lib.c |
diffstat | 4 files changed, 91 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/src/auth/auth-request.c Thu May 15 07:01:40 2008 +0300 +++ b/src/auth/auth-request.c Thu May 15 07:43:13 2008 +0300 @@ -870,11 +870,9 @@ static int is_ip_in_network(const char *network, const struct ip_addr *ip) { - const uint32_t *ip1, *ip2; struct ip_addr src_ip, net_ip; const char *p; - unsigned int max_bits, bits, pos, i; - uint32_t mask; + unsigned int max_bits, bits; if (net_ipv6_mapped_ipv4_convert(ip, &src_ip) == 0) ip = &src_ip; @@ -895,44 +893,7 @@ if (net_addr2ip(network, &net_ip) < 0) return -1; - if (IPADDR_IS_V4(ip) != IPADDR_IS_V4(&net_ip)) { - /* one is IPv6 and one is IPv4 */ - return 0; - } - i_assert(IPADDR_IS_V6(ip) == IPADDR_IS_V6(&net_ip)); - - if (IPADDR_IS_V4(ip)) { - ip1 = &ip->u.ip4.s_addr; - ip2 = &net_ip.u.ip4.s_addr; - } else { -#ifdef HAVE_IPV6 - ip1 = (const void *)&ip->u.ip6; - ip2 = (const void *)&net_ip.u.ip6; -#else - /* shouldn't get here */ - return -1; -#endif - } - - /* check first the full 32bit ints */ - for (pos = 0, i = 0; pos + 32 <= bits; pos += 32, i++) { - if (ip1[i] != ip2[i]) - return 0; - } - - /* check the last full bytes */ - for (mask = 0xff; pos + 8 <= bits; pos += 8, mask <<= 8) { - if ((ip1[i] & mask) != (ip2[i] & mask)) - return 0; - } - - /* check the last bits, they're reversed in bytes */ - bits -= pos; - for (mask = 0x80 << (pos % 32); bits > 0; bits--, mask >>= 1) { - if ((ip1[i] & mask) != (ip2[i] & mask)) - return 0; - } - return 1; + return net_is_in_network(ip, &net_ip, bits); } static void auth_request_validate_networks(struct auth_request *request,
--- a/src/lib/network.c Thu May 15 07:01:40 2008 +0300 +++ b/src/lib/network.c Thu May 15 07:43:13 2008 +0300 @@ -703,3 +703,50 @@ return TRUE; } + +bool net_is_in_network(const struct ip_addr *ip, + const struct ip_addr *net_ip, unsigned int bits) +{ + const uint32_t *ip1, *ip2; + uint32_t mask; + unsigned int pos, i; + + if (IPADDR_IS_V4(ip) != IPADDR_IS_V4(net_ip)) { + /* one is IPv6 and one is IPv4 */ + return FALSE; + } + i_assert(IPADDR_IS_V6(ip) == IPADDR_IS_V6(net_ip)); + + if (IPADDR_IS_V4(ip)) { + ip1 = &ip->u.ip4.s_addr; + ip2 = &net_ip->u.ip4.s_addr; + } else { +#ifdef HAVE_IPV6 + ip1 = (const void *)&ip->u.ip6; + ip2 = (const void *)&net_ip->u.ip6; +#else + /* shouldn't get here */ + return FALSE; +#endif + } + + /* check first the full 32bit ints */ + for (pos = 0, i = 0; pos + 32 <= bits; pos += 32, i++) { + if (ip1[i] != ip2[i]) + return FALSE; + } + + /* check the last full bytes */ + for (mask = 0xff; pos + 8 <= bits; pos += 8, mask <<= 8) { + if ((ip1[i] & mask) != (ip2[i] & mask)) + return FALSE; + } + + /* check the last bits, they're reversed in bytes */ + bits -= pos; + for (mask = 0x80 << (pos % 32); bits > 0; bits--, mask >>= 1) { + if ((ip1[i] & mask) != (ip2[i] & mask)) + return FALSE; + } + return TRUE; +}
--- a/src/lib/network.h Thu May 15 07:01:40 2008 +0300 +++ b/src/lib/network.h Thu May 15 07:43:13 2008 +0300 @@ -110,4 +110,8 @@ bool is_ipv4_address(const char *addr); bool is_ipv6_address(const char *addr); +/* Returns TRUE if ip is in net_ip/bits network. */ +bool net_is_in_network(const struct ip_addr *ip, + const struct ip_addr *net_ip, unsigned int bits); + #endif
--- a/src/tests/test-lib.c Thu May 15 07:01:40 2008 +0300 +++ b/src/tests/test-lib.c Thu May 15 07:43:13 2008 +0300 @@ -6,6 +6,7 @@ #include "base64.h" #include "bsearch-insert-pos.h" #include "aqueue.h" +#include "network.h" #include "priorityq.h" #include "seq-range-array.h" #include "str-sanitize.h" @@ -366,6 +367,42 @@ test_out("mempool_alloconly", success); } +struct test_net_is_in_network_input { + const char *ip; + const char *net; + unsigned int bits; + bool ret; +}; + +static void test_net_is_in_network(void) +{ + static struct test_net_is_in_network_input input[] = { + { "1.2.3.4", "1.2.3.4", 32, TRUE }, + { "1.2.3.4", "1.2.3.3", 32, FALSE }, + { "1.2.3.4", "1.2.3.5", 32, FALSE }, + { "1.2.3.4", "1.2.2.4", 32, FALSE }, + { "1.2.3.4", "1.1.3.4", 32, FALSE }, + { "1.2.3.4", "0.2.3.4", 32, FALSE }, + { "1.2.3.253", "1.2.3.254", 31, FALSE }, + { "1.2.3.254", "1.2.3.254", 31, TRUE }, + { "1.2.3.255", "1.2.3.254", 31, TRUE }, + { "1.2.3.255", "1.2.3.0", 24, TRUE }, + { "1.2.255.255", "1.2.254.0", 23, TRUE }, + { "255.255.255.255", "128.0.0.0", 1, TRUE } + }; + struct ip_addr ip, net_ip; + unsigned int i; + bool success; + + for (i = 0; i < N_ELEMENTS(input); i++) { + net_addr2ip(input[i].ip, &ip); + net_addr2ip(input[i].net, &net_ip); + success = net_is_in_network(&ip, &net_ip, input[i].bits) == + input[i].ret; + test_out(t_strdup_printf("net_is_in_network(%u)", i), success); + } +} + struct pq_test_item { struct priorityq_item item; int num; @@ -680,6 +717,7 @@ test_bsearch_insert_pos, test_buffer, test_mempool_alloconly, + test_net_is_in_network, test_priorityq, test_seq_range_array, test_str_sanitize,