summaryrefslogtreecommitdiffstats
path: root/src/lib/test-net.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/test-net.c')
-rw-r--r--src/lib/test-net.c167
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();
+}