diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 00:53:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 00:53:35 +0000 |
commit | 69c6a41ffb878ef98c9378ed4b1634a404cfaa7f (patch) | |
tree | b2a4f704565d62fbb129ab9dc3b35977c50e6e7f /tests/contrib/test_sockaddr.c | |
parent | Initial commit. (diff) | |
download | knot-upstream.tar.xz knot-upstream.zip |
Adding upstream version 2.7.6.upstream/2.7.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/contrib/test_sockaddr.c')
-rw-r--r-- | tests/contrib/test_sockaddr.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/tests/contrib/test_sockaddr.c b/tests/contrib/test_sockaddr.c new file mode 100644 index 0000000..5f80507 --- /dev/null +++ b/tests/contrib/test_sockaddr.c @@ -0,0 +1,234 @@ +/* Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "contrib/sockaddr.h" +#include "libknot/errcode.h" + +struct sockaddr *SA(struct sockaddr_storage *ss) +{ + return (struct sockaddr *)ss; +} + +static void test_sockaddr_is_any(void) +{ + struct sockaddr_storage invalid = { 0 }; + ok(!sockaddr_is_any(SA(&invalid)), "sockaddr_is_any: invalid"); + + struct sockaddr_storage path = { 0 }; + path.ss_family = AF_UNIX; + ok(!sockaddr_is_any(SA(&path)), "sockaddr_is_any: unix"); + + struct sockaddr_storage ipv4_local = { 0 }; + sockaddr_set(&ipv4_local, AF_INET, "127.0.0.1", 0); + ok(!sockaddr_is_any(SA(&ipv4_local)), "sockaddr_is_any: IPv4 local"); + + struct sockaddr_storage ipv4_any = { 0 }; + sockaddr_set(&ipv4_any, AF_INET, "0.0.0.0", 0); + ok(sockaddr_is_any(SA(&ipv4_any)), "sockaddr_is_any: IPv4 any"); + + struct sockaddr_storage ipv6_local = { 0 }; + sockaddr_set(&ipv6_local, AF_INET6, "::1", 0); + ok(!sockaddr_is_any(SA(&ipv6_local)), "sockaddr_is_any: IPv6 local"); + + struct sockaddr_storage ipv6_any = { 0 }; + sockaddr_set(&ipv6_any, AF_INET6, "::", 0); + ok(sockaddr_is_any(SA(&ipv6_any)), "sockaddr_is_any: IPv6 any"); +} + +static void check_sockaddr_set(struct sockaddr_storage *ss, int family, + const char *straddr, int port) +{ + int ret = sockaddr_set(ss, family, straddr, port); + is_int(KNOT_EOK, ret, "set address '%s'", straddr); +} + +static void test_net_match(void) +{ + int ret; + struct sockaddr_storage t = { 0 }; + + // 127 dec ~ 01111111 bin + // 170 dec ~ 10101010 bin + struct sockaddr_storage ref4 = { 0 }; + check_sockaddr_set(&ref4, AF_INET, "127.170.170.127", 0); + + // 7F hex ~ 01111111 bin + // AA hex ~ 10101010 bin + struct sockaddr_storage ref6 = { 0 }; + check_sockaddr_set(&ref6, AF_INET6, "7FAA::AA7F", 0); + + ret = sockaddr_net_match(SA(&ref4), SA(&ref6), 32); + ok(ret == false, "match: family mismatch"); + + ret = sockaddr_net_match(NULL, SA(&ref4), 32); + ok(ret == false, "match: NULL first parameter"); + ret = sockaddr_net_match(SA(&ref4), NULL, 32); + ok(ret == false, "match: NULL second parameter"); + + ret = sockaddr_net_match(SA(&ref4), SA(&ref4), -1); + ok(ret == true, "match: ipv4 - identity, auto full prefix"); + ret = sockaddr_net_match(SA(&ref4), SA(&ref4), 31); + ok(ret == true, "match: ipv4 - identity, subnet"); + ret = sockaddr_net_match(SA(&ref4), SA(&ref4), 32); + ok(ret == true, "match: ipv4 - identity, full prefix"); + ret = sockaddr_net_match(SA(&ref4), SA(&ref4), 33); + ok(ret == true, "match: ipv4 - identity, prefix overflow"); + + ret = sockaddr_net_match(SA(&ref6), SA(&ref6), -1); + ok(ret == true, "match: ipv6 - identity, auto full prefix"); + ret = sockaddr_net_match(SA(&ref6), SA(&ref6), 127); + ok(ret == true, "match: ipv6 - identity, subnet"); + ret = sockaddr_net_match(SA(&ref6), SA(&ref6), 128); + ok(ret == true, "match: ipv6 - identity, full prefix"); + ret = sockaddr_net_match(SA(&ref6), SA(&ref6), 129); + ok(ret == true, "match: ipv6 - identity, prefix overflow"); + + // 124 dec ~ 01111100 bin + check_sockaddr_set(&t, AF_INET, "124.0.0.0", 0); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 5); + ok(ret == true, "match: ipv4 - first byte, shorter prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 6); + ok(ret == true, "match: ipv4 - first byte, precise prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 7); + ok(ret == false, "match: ipv4 - first byte, not match"); + + check_sockaddr_set(&t, AF_INET, "127.170.170.124", 0); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 29); + ok(ret == true, "match: ipv4 - last byte, shorter prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 30); + ok(ret == true, "match: ipv4 - last byte, precise prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref4), 31); + ok(ret == false, "match: ipv4 - last byte, not match"); + + // 7C hex ~ 01111100 bin + check_sockaddr_set(&t, AF_INET6, "7CAA::", 0); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 5); + ok(ret == true, "match: ipv6 - first byte, shorter prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 6); + ok(ret == true, "match: ipv6 - first byte, precise prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 7); + ok(ret == false, "match: ipv6 - first byte, not match"); + + check_sockaddr_set(&t, AF_INET6, "7FAA::AA7C", 0); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 125); + ok(ret == true, "match: ipv6 - last byte, shorter prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 126); + ok(ret == true, "match: ipv6 - last byte, precise prefix"); + ret = sockaddr_net_match(SA(&t), SA(&ref6), 127); + ok(ret == false, "match: ipv6 - last byte, not match"); +} + +static void test_range_match(void) +{ + bool ret; + struct sockaddr_storage t = { 0 }; + struct sockaddr_storage min = { 0 }; + struct sockaddr_storage max = { 0 }; + + // IPv4 tests. + + check_sockaddr_set(&min, AF_INET, "0.0.0.0", 0); + check_sockaddr_set(&max, AF_INET, "255.255.255.255", 0); + + check_sockaddr_set(&t, AF_INET, "0.0.0.0", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 max range - minimum"); + check_sockaddr_set(&t, AF_INET, "255.255.255.255", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 max range - maximum"); + + check_sockaddr_set(&min, AF_INET, "1.13.113.213", 0); + check_sockaddr_set(&max, AF_INET, "2.24.124.224", 0); + + check_sockaddr_set(&t, AF_INET, "1.12.113.213", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv4 middle range - negative far min"); + check_sockaddr_set(&t, AF_INET, "1.13.113.212", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv4 middle range - negative close min"); + check_sockaddr_set(&t, AF_INET, "1.13.113.213", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 middle range - minimum"); + check_sockaddr_set(&t, AF_INET, "1.13.213.213", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 middle range - middle"); + check_sockaddr_set(&t, AF_INET, "2.24.124.224", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv4 middle range - max"); + check_sockaddr_set(&t, AF_INET, "2.24.124.225", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv4 middle range - negative close max"); + check_sockaddr_set(&t, AF_INET, "2.25.124.225", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv4 middle range - negative far max"); + + // IPv6 tests. + + check_sockaddr_set(&min, AF_INET6, "::0", 0); + check_sockaddr_set(&max, AF_INET6, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 0); + + check_sockaddr_set(&t, AF_INET6, "::0", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 max range - minimum"); + check_sockaddr_set(&t, AF_INET6, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 max range - maximum"); + + check_sockaddr_set(&min, AF_INET6, "1:13::ABCD:200B", 0); + check_sockaddr_set(&max, AF_INET6, "2:A24::124:224", 0); + + check_sockaddr_set(&t, AF_INET6, "1:12::BCD:2000", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv6 middle range - negative far min"); + check_sockaddr_set(&t, AF_INET6, "1:13::ABCD:200A", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv6 middle range - negative close min"); + check_sockaddr_set(&t, AF_INET6, "1:13::ABCD:200B", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 middle range - minimum"); + check_sockaddr_set(&t, AF_INET6, "1:13:0:12:34:0:ABCD:200B", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 middle range - middle"); + check_sockaddr_set(&t, AF_INET6, "2:A24::124:224", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == true, "match: ipv6 middle range - max"); + check_sockaddr_set(&t, AF_INET6, "2:A24::124:225", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv6 middle range - negative close max"); + check_sockaddr_set(&t, AF_INET6, "2:FA24::4:24", 0); + ret = sockaddr_range_match(SA(&t), SA(&min), SA(&max)); + ok(ret == false, "match: ipv6 middle range - negative far max"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("sockaddr_is_any"); + test_sockaddr_is_any(); + + diag("sockaddr_net_match"); + test_net_match(); + + diag("sockaddr_range_match"); + test_range_match(); + + return 0; +} |