diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:51:24 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:51:24 +0000 |
commit | f7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch) | |
tree | a3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /src/lib/test-net.c | |
parent | Initial commit. (diff) | |
download | dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.tar.xz dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.zip |
Adding upstream version 1:2.3.19.1+dfsg1.upstream/1%2.3.19.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/test-net.c')
-rw-r--r-- | src/lib/test-net.c | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/src/lib/test-net.c b/src/lib/test-net.c new file mode 100644 index 0000000..fb19d5b --- /dev/null +++ b/src/lib/test-net.c @@ -0,0 +1,167 @@ +/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "net.h" + +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 const 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 }, + { "255.255.255.255", "127.0.0.0", 1, FALSE }, + { "1234:5678::abcf", "1234:5678::abce", 127, TRUE }, + { "1234:5678::abcd", "1234:5678::abce", 127, FALSE }, + { "123e::ffff", "123e::0", 15, TRUE }, + { "::ffff:1.2.3.4", "1.2.3.4", 32, TRUE }, + { "::ffff:1.2.3.4", "1.2.3.3", 32, FALSE }, + { "::ffff:1.2.3.4", "::ffff:1.2.3.4", 0, FALSE } + }; + struct ip_addr ip, net_ip; + unsigned int i; + + test_begin("net_is_in_network()"); + for (i = 0; i < N_ELEMENTS(input); i++) { + test_assert(net_addr2ip(input[i].ip, &ip) == 0); + test_assert(net_addr2ip(input[i].net, &net_ip) == 0); + test_assert_idx(net_is_in_network(&ip, &net_ip, input[i].bits) == + input[i].ret, i); + } + /* make sure non-IPv4 and non-IPv6 ip_addrs fail */ + test_assert(net_addr2ip("127.0.0.1", &ip) == 0); + net_ip = ip; + net_ip.family = 0; + test_assert(!net_is_in_network(&ip, &net_ip, 0)); + test_assert(!net_is_in_network(&net_ip, &ip, 0)); + test_assert(net_addr2ip("::1", &ip) == 0); + net_ip = ip; + net_ip.family = 0; + test_assert(!net_is_in_network(&ip, &net_ip, 0)); + test_assert(!net_is_in_network(&net_ip, &ip, 0)); + test_end(); +} + +static void test_net_ip2addr(void) +{ + struct ip_addr ip; + + test_begin("net_ip2addr()"); + test_assert(net_addr2ip("127.0.0.1", &ip) == 0 && + ip.family == AF_INET && + ntohl(ip.u.ip4.s_addr) == (0x7f000001)); + test_assert(net_addr2ip("2130706433", &ip) == 0 && + ip.family == AF_INET && + ntohl(ip.u.ip4.s_addr) == (0x7f000001)); + test_assert(strcmp(net_ip2addr(&ip), "127.0.0.1") == 0); + test_assert(net_addr2ip("255.254.253.252", &ip) == 0 && + ip.family == AF_INET && + ntohl(ip.u.ip4.s_addr) == (0xfffefdfc)); + test_assert(strcmp(net_ip2addr(&ip), "255.254.253.252") == 0); + test_assert(net_addr2ip("::5", &ip) == 0 && + ip.family == AF_INET6 && + ip.u.ip6.s6_addr[15] == 5); + test_assert(strcmp(net_ip2addr(&ip), "::5") == 0); + test_assert(net_addr2ip("[::5]", &ip) == 0 && + ip.family == AF_INET6 && + ip.u.ip6.s6_addr[15] == 5); + test_assert(strcmp(net_ip2addr(&ip), "::5") == 0); + ip.family = 123; + test_assert(net_addr2ip("abc", &ip) < 0 && + ip.family == 123); + test_end(); +} + +static void test_net_str2hostport(void) +{ + const char *host; + in_port_t port; + + test_begin("net_str2hostport()"); + /* [IPv6] */ + test_assert(net_str2hostport("[1::4]", 0, &host, &port) == 0 && + strcmp(host, "1::4") == 0 && port == 0); + test_assert(net_str2hostport("[1::4]", 1234, &host, &port) == 0 && + strcmp(host, "1::4") == 0 && port == 1234); + test_assert(net_str2hostport("[1::4]:78", 1234, &host, &port) == 0 && + strcmp(host, "1::4") == 0 && port == 78); + host = NULL; + test_assert(net_str2hostport("[1::4]:", 1234, &host, &port) < 0 && host == NULL); + test_assert(net_str2hostport("[1::4]:0", 1234, &host, &port) < 0 && host == NULL); + test_assert(net_str2hostport("[1::4]:x", 1234, &host, &port) < 0 && host == NULL); + /* IPv6 */ + test_assert(net_str2hostport("1::4", 0, &host, &port) == 0 && + strcmp(host, "1::4") == 0 && port == 0); + test_assert(net_str2hostport("1::4", 1234, &host, &port) == 0 && + strcmp(host, "1::4") == 0 && port == 1234); + /* host */ + test_assert(net_str2hostport("foo", 0, &host, &port) == 0 && + strcmp(host, "foo") == 0 && port == 0); + test_assert(net_str2hostport("foo", 1234, &host, &port) == 0 && + strcmp(host, "foo") == 0 && port == 1234); + test_assert(net_str2hostport("foo:78", 1234, &host, &port) == 0 && + strcmp(host, "foo") == 0 && port == 78); + host = NULL; + test_assert(net_str2hostport("foo:", 1234, &host, &port) < 0 && host == NULL); + test_assert(net_str2hostport("foo:0", 1234, &host, &port) < 0 && host == NULL); + test_assert(net_str2hostport("foo:x", 1234, &host, &port) < 0 && host == NULL); + /* edge cases with multiple ':' - currently these don't return errors, + but perhaps they should. */ + test_assert(net_str2hostport("foo::78", 1234, &host, &port) == 0 && + strcmp(host, "foo::78") == 0 && port == 1234); + test_assert(net_str2hostport("::foo:78", 1234, &host, &port) == 0 && + strcmp(host, "::foo:78") == 0 && port == 1234); + test_assert(net_str2hostport("[::foo]:78", 1234, &host, &port) == 0 && + strcmp(host, "::foo") == 0 && port == 78); + test_assert(net_str2hostport("[::::]", 1234, &host, &port) == 0 && + strcmp(host, "::::") == 0 && port == 1234); + test_assert(net_str2hostport("[::::]:78", 1234, &host, &port) == 0 && + strcmp(host, "::::") == 0 && port == 78); + test_end(); +} + +static void test_net_unix_long_paths(void) +{ +#ifdef ENAMETOOLONG + int long_errno = ENAMETOOLONG; +#else + int long_errno = EOVERFLOW; +#endif + + test_begin("net_*_unix() - long paths"); + + char path[PATH_MAX]; + memset(path, 'x', sizeof(path)-1); + path[sizeof(path)-1] = '\0'; + + test_assert(net_listen_unix(path, 1) == -1); + test_assert(errno == long_errno); + + test_assert(net_connect_unix(path) == -1); + test_assert(errno == long_errno); + + test_end(); +} + +void test_net(void) +{ + test_net_is_in_network(); + test_net_ip2addr(); + test_net_str2hostport(); + test_net_unix_long_paths(); +} |