summaryrefslogtreecommitdiff
path: root/src/libstrongswan/tests/suites
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2015-10-22 11:43:58 +0200
committerYves-Alexis Perez <corsac@debian.org>2015-10-22 11:43:58 +0200
commit5dca9ea0e2931f0e2a056c7964d311bcc30a01b8 (patch)
tree037f1ec5bb860846938ddcf29771c24e9c529be0 /src/libstrongswan/tests/suites
parentb238cf34df3fe4476ae6b7012e7cb3e9769d4d51 (diff)
downloadvyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.tar.gz
vyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.zip
Imported Upstream version 5.3.3
Diffstat (limited to 'src/libstrongswan/tests/suites')
-rw-r--r--src/libstrongswan/tests/suites/test_chunk.c2
-rw-r--r--src/libstrongswan/tests/suites/test_host.c6
-rw-r--r--src/libstrongswan/tests/suites/test_identification.c91
-rw-r--r--src/libstrongswan/tests/suites/test_settings.c172
-rw-r--r--src/libstrongswan/tests/suites/test_traffic_selector.c594
5 files changed, 838 insertions, 27 deletions
diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c
index 312a187ac..6272ca795 100644
--- a/src/libstrongswan/tests/suites/test_chunk.c
+++ b/src/libstrongswan/tests/suites/test_chunk.c
@@ -1020,7 +1020,7 @@ START_TEST(test_printf_hook)
int len;
/* %B should be the same as %b, which is what we check, comparing the
- * acutal result could be tricky as %b prints the chunk's memory address */
+ * actual result could be tricky as %b prints the chunk's memory address */
len = snprintf(buf, sizeof(buf), "%B", &printf_hook_data[_i].in);
ck_assert(len >= 0 && len < sizeof(buf));
len = snprintf(mem, sizeof(mem), "%b", printf_hook_data[_i].in.ptr,
diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c
index 7161b2c5b..5cb8013ff 100644
--- a/src/libstrongswan/tests/suites/test_host.c
+++ b/src/libstrongswan/tests/suites/test_host.c
@@ -104,6 +104,9 @@ START_TEST(test_create_from_string_v4)
{
host_t *host;
+ host = host_create_from_string(NULL, 500);
+ ck_assert(!host);
+
host = host_create_from_string("%any", 500);
verify_any(host, AF_INET, 500);
host->destroy(host);
@@ -196,6 +199,7 @@ static void test_create_from_string_and_family_addr(char *string, chunk_t addr,
START_TEST(test_create_from_string_and_family_v4)
{
+ test_create_from_string_and_family_any(NULL, AF_INET, AF_UNSPEC);
test_create_from_string_and_family_any("%any", AF_INET, AF_INET);
test_create_from_string_and_family_any("%any4", AF_INET, AF_INET);
test_create_from_string_and_family_any("0.0.0.0", AF_INET, AF_INET);
@@ -210,6 +214,7 @@ END_TEST
START_TEST(test_create_from_string_and_family_v6)
{
+ test_create_from_string_and_family_any(NULL, AF_INET6, AF_UNSPEC);
test_create_from_string_and_family_any("%any", AF_INET6, AF_INET6);
test_create_from_string_and_family_any("%any6", AF_INET6, AF_INET6);
test_create_from_string_and_family_any("::", AF_INET6, AF_INET6);
@@ -224,6 +229,7 @@ END_TEST
START_TEST(test_create_from_string_and_family_other)
{
+ test_create_from_string_and_family_any(NULL, AF_UNSPEC, AF_UNSPEC);
test_create_from_string_and_family_any("%any", AF_UNSPEC, AF_INET);
test_create_from_string_and_family_any("%any4", AF_UNSPEC, AF_INET);
test_create_from_string_and_family_any("0.0.0.0", AF_UNSPEC, AF_INET);
diff --git a/src/libstrongswan/tests/suites/test_identification.c b/src/libstrongswan/tests/suites/test_identification.c
index de00e4afd..ff14ba897 100644
--- a/src/libstrongswan/tests/suites/test_identification.c
+++ b/src/libstrongswan/tests/suites/test_identification.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2015 Tobias Brunner
* Copyright (C) 2009 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -727,6 +727,88 @@ START_TEST(test_matches_empty_reverse)
END_TEST
/*******************************************************************************
+ * identification hashing
+ */
+
+static bool id_hash_equals(char *str, char *b_str)
+{
+ identification_t *a, *b;
+ bool success = FALSE;
+
+ a = identification_create_from_string(str);
+ b = identification_create_from_string(b_str ?: str);
+ success = a->hash(a, 0) == b->hash(b, 0);
+ a->destroy(a);
+ b->destroy(b);
+ return success;
+}
+
+START_TEST(test_hash)
+{
+ ck_assert(id_hash_equals("moon@strongswan.org", NULL));
+ ck_assert(id_hash_equals("vpn.strongswan.org", NULL));
+ ck_assert(id_hash_equals("192.168.1.1", NULL));
+ ck_assert(id_hash_equals("C=CH", NULL));
+
+ ck_assert(!id_hash_equals("moon@strongswan.org", "sun@strongswan.org"));
+ ck_assert(!id_hash_equals("vpn.strongswan.org", "*.strongswan.org"));
+ ck_assert(!id_hash_equals("192.168.1.1", "192.168.1.2"));
+ ck_assert(!id_hash_equals("C=CH", "C=DE"));
+ ck_assert(!id_hash_equals("fqdn:strongswan.org", "keyid:strongswan.org"));
+}
+END_TEST
+
+START_TEST(test_hash_any)
+{
+ ck_assert(id_hash_equals("%any", NULL));
+ ck_assert(id_hash_equals("%any", "0.0.0.0"));
+ ck_assert(id_hash_equals("%any", "*"));
+ ck_assert(id_hash_equals("%any", ""));
+
+ ck_assert(!id_hash_equals("%any", "any"));
+}
+END_TEST
+
+START_TEST(test_hash_dn)
+{
+ identification_t *a, *b;
+
+ /* same DN (C=CH, O=strongSwan), different RDN type (PRINTABLESTRING vs.
+ * UTF8STRING) */
+ a = identification_create_from_data(chunk_from_chars(
+ 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48, 0x31,
+ 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x13, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
+ 0x53, 0x77, 0x61, 0x6e));
+ b = identification_create_from_data(chunk_from_chars(
+ 0x30, 0x22, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
+ 0x55, 0x04, 0x06, 0x0c, 0x02, 0x43, 0x48, 0x31,
+ 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
+ 0x0c, 0x0a, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67,
+ 0x53, 0x77, 0x61, 0x6e));
+ ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
+ ck_assert(a->equals(a, b));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_hash_inc)
+{
+ identification_t *a;
+
+ a = identification_create_from_string("vpn.strongswan.org");
+ ck_assert(a->hash(a, 0) != a->hash(a, 1));
+ a->destroy(a);
+
+ a = identification_create_from_string("C=CH, O=strongSwan");
+ ck_assert(a->hash(a, 0) != a->hash(a, 1));
+ a->destroy(a);
+}
+END_TEST
+
+/*******************************************************************************
* identification part enumeration
*/
@@ -851,6 +933,13 @@ Suite *identification_suite_create()
tcase_add_loop_test(tc, test_matches_empty_reverse, ID_ANY, ID_KEY_ID + 1);
suite_add_tcase(s, tc);
+ tc = tcase_create("hash");
+ tcase_add_test(tc, test_hash);
+ tcase_add_test(tc, test_hash_any);
+ tcase_add_test(tc, test_hash_dn);
+ tcase_add_test(tc, test_hash_inc);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("part enumeration");
tcase_add_test(tc, test_parts);
suite_add_tcase(s, tc);
diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c
index 9601a34a9..bead9d795 100644
--- a/src/libstrongswan/tests/suites/test_settings.c
+++ b/src/libstrongswan/tests/suites/test_settings.c
@@ -58,6 +58,10 @@ START_SETUP(setup_base_config)
" }\n"
" key2 = with space\n"
" key3 = \"string with\\nnewline\"\n"
+ " key4 = \"multi line\n"
+ "string\"\n"
+ " key5 = \"escaped \\\n"
+ "newline\"\n"
"}\n"
"out = side\n"
"other {\n"
@@ -88,6 +92,8 @@ START_TEST(test_get_str)
verify_string("", "main.empty");
verify_string("with space", "main.key2");
verify_string("string with\nnewline", "main.key3");
+ verify_string("multi line\nstring", "main.key4");
+ verify_string("escaped newline", "main.key5");
verify_string("value", "main.sub1.key");
verify_string("value2", "main.sub1.key2");
verify_string("bar", "main.sub1.subsub.foo");
@@ -97,7 +103,7 @@ START_TEST(test_get_str)
verify_string("other val", "other.key1");
verify_null("main.none");
- verify_null("main.key4");
+ verify_null("main.key6");
verify_null("other.sub");
}
END_TEST
@@ -131,7 +137,7 @@ START_TEST(test_get_str_printf)
* probably document it at least */
verify_null("main.%s%u.key%d", "sub", 1, 2);
- verify_null("%s.%s%d", "main", "key", 4);
+ verify_null("%s.%s%d", "main", "key", 6);
}
END_TEST
@@ -529,9 +535,7 @@ END_TEST
# define include2 "/tmp/strongswan-settings-test-include2"
#endif
-START_SETUP(setup_include_config)
-{
- chunk_t inc1 = chunk_from_str(
+static char *include_content1 =
"main {\n"
" key1 = n1\n"
" key2 = n2\n"
@@ -544,14 +548,17 @@ START_SETUP(setup_include_config)
" sub3 = val3\n"
" }\n"
" include " include2 "\n"
- "}");
- chunk_t inc2 = chunk_from_str(
+ "}";
+static char *include_content2 =
"key2 = v2\n"
"sub1 {\n"
" key = val\n"
- "}");
- ck_assert(chunk_write(inc1, include1, 0022, TRUE));
- ck_assert(chunk_write(inc2, include2, 0022, TRUE));
+ "}";
+
+START_SETUP(setup_include_config)
+{
+ ck_assert(chunk_write(chunk_from_str(include_content1), include1, 0022, TRUE));
+ ck_assert(chunk_write(chunk_from_str(include_content2), include2, 0022, TRUE));
}
END_SETUP
@@ -600,6 +607,27 @@ START_TEST(test_include)
}
END_TEST
+START_TEST(test_include_string)
+{
+ chunk_t contents = chunk_from_str(
+ "main {\n"
+ " key1 = val1\n"
+ " key2 = val2\n"
+ " none = x\n"
+ " sub1 {\n"
+ " include this/does/not/exist.conf\n"
+ " include = value\n"
+ " key2 = value2\n"
+ " include \"" include2 "\"\n"
+ " }\n"
+ "}\n"
+ "include \"" include1 "\"");
+
+ create_settings(contents);
+ verify_include();
+}
+END_TEST
+
START_TEST(test_load_files)
{
chunk_t contents = chunk_from_str(
@@ -784,6 +812,104 @@ START_TEST(test_order_section)
}
END_TEST
+
+START_TEST(test_load_string)
+{
+ char *content =
+ "main {\n"
+ " key1 = val1\n"
+ " key2 = val2\n"
+ " key3 = val3\n"
+ " none = x\n"
+ " sub1 {\n"
+ " include = value\n"
+ " key2 = v2\n"
+ " sub1 {\n"
+ " key = val\n"
+ " }\n"
+ " }\n"
+ "}";
+ char *val1, *val2, *val3;
+
+ settings = settings_create_string(content);
+
+ val1 = settings->get_str(settings, "main.key1", NULL);
+ val2 = settings->get_str(settings, "main.sub1.key2", NULL);
+ /* loading the same content twice should not change anything, with... */
+ ck_assert(settings->load_string(settings, content, TRUE));
+ ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
+ ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
+ /* ...or without merging */
+ ck_assert(settings->load_string(settings, content, FALSE));
+ ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
+ ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
+
+ val1 = settings->get_str(settings, "main.key2", NULL);
+ val2 = settings->get_str(settings, "main.key3", NULL);
+ val3 = settings->get_str(settings, "main.none", NULL);
+ /* only pointers for modified settings should change, but still be valid */
+ ck_assert(settings->load_string(settings, include_content1, FALSE));
+ ck_assert(val1 != settings->get_str(settings, "main.key2", NULL));
+ ck_assert_str_eq(val1, "val2");
+ ck_assert(val2 == settings->get_str(settings, "main.key3", NULL));
+ ck_assert(val3 != settings->get_str(settings, "main.none", NULL));
+ ck_assert_str_eq(val3, "x");
+
+ settings->destroy(settings);
+ settings = settings_create_string(content);
+ ck_assert(settings);
+
+ ck_assert(settings->load_string(settings, include_content1, TRUE));
+ verify_include();
+
+ ck_assert(settings->load_string(settings, include_content2, FALSE));
+ verify_null("main.key1");
+ verify_string("v2", "key2");
+ verify_string("val", "sub1.key");
+ verify_null("main.sub1.key3");
+}
+END_TEST
+
+
+START_TEST(test_load_string_section)
+{
+ char *content =
+ "main {\n"
+ " key1 = val1\n"
+ " key2 = val2\n"
+ " none = x\n"
+ " sub1 {\n"
+ " include = value\n"
+ " key2 = value2\n"
+ " }\n"
+ "}";
+
+ settings = settings_create_string(content);
+
+ ck_assert(settings->load_string_section(settings, include_content1, TRUE, ""));
+ ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub1"));
+ verify_include();
+
+ /* invalid strings are a failure */
+ ck_assert(!settings->load_string_section(settings, "conf {", TRUE, ""));
+ /* NULL or empty strings are OK though */
+ ck_assert(settings->load_string_section(settings, "", TRUE, ""));
+ ck_assert(settings->load_string_section(settings, NULL, TRUE, ""));
+ verify_include();
+
+ ck_assert(settings->load_string_section(settings, include_content2, FALSE, "main"));
+ verify_null("main.key1");
+ verify_string("v2", "main.key2");
+ verify_string("val", "main.sub1.key");
+ verify_null("main.sub1.key3");
+ verify_null("main.sub2.sub3");
+
+ ck_assert(settings->load_string_section(settings, include_content2, TRUE, "main.sub2"));
+ verify_string("v2", "main.sub2.key2");
+ verify_string("val", "main.sub2.sub1.key");
+}
+END_TEST
+
START_SETUP(setup_fallback_config)
{
create_settings(chunk_from_str(
@@ -904,11 +1030,10 @@ END_TEST
START_SETUP(setup_string_config)
{
create_settings(chunk_from_str(
- "string = \" with accurate\twhitespace\"\n"
+ "string = \" with accurate\twhite\\tspace\"\n"
"special = \"all { special } characters # can be used.\"\n"
- "unterminated = \"is fine\n"
- "but = produces a warning\n"
- "newlines = \"can either be encoded\\nor \\\n"
+ "newlines = \"can be encoded explicitly\\nor implicitly\n"
+ "or \\\n"
"escaped\"\n"
"quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n"
"multiple = \"strings\" are \"combined\"\n"
@@ -918,11 +1043,9 @@ END_SETUP
START_TEST(test_strings)
{
- verify_string(" with accurate\twhitespace", "string");
+ verify_string(" with accurate\twhite\tspace", "string");
verify_string("all { special } characters # can be used.", "special");
- verify_string("is fine", "unterminated");
- verify_string("produces a warning", "but");
- verify_string("can either be encoded\nor escaped", "newlines");
+ verify_string("can be encoded explicitly\nor implicitly\nor escaped", "newlines");
verify_string("\"and\" slashes \\ can \\ be", "quotes");
verify_string("strings are combined", "multiple");
}
@@ -990,6 +1113,12 @@ START_TEST(test_invalid)
ck_assert(!settings->load_files(settings, path, FALSE));
contents = chunk_from_str(
+ "unterminated {\n"
+ " strings = \"are invalid\n");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(!settings->load_files(settings, path, FALSE));
+
+ contents = chunk_from_str(
"spaces in name {}");
ck_assert(chunk_write(contents, path, 0022, TRUE));
ck_assert(!settings->load_files(settings, path, FALSE));
@@ -1054,12 +1183,19 @@ Suite *settings_suite_create()
tc = tcase_create("include/load_files[_section]");
tcase_add_checked_fixture(tc, setup_include_config, teardown_include_config);
tcase_add_test(tc, test_include);
+ tcase_add_test(tc, test_include_string);
tcase_add_test(tc, test_load_files);
tcase_add_test(tc, test_load_files_section);
tcase_add_test(tc, test_order_kv);
tcase_add_test(tc, test_order_section);
suite_add_tcase(s, tc);
+ tc = tcase_create("load_string[_section]");
+ tcase_add_checked_fixture(tc, setup_include_config, teardown_config);
+ tcase_add_test(tc, test_load_string);
+ tcase_add_test(tc, test_load_string_section);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("fallback");
tcase_add_checked_fixture(tc, setup_fallback_config, teardown_config);
tcase_add_test(tc, test_add_fallback);
diff --git a/src/libstrongswan/tests/suites/test_traffic_selector.c b/src/libstrongswan/tests/suites/test_traffic_selector.c
index 4312c6ce1..bec32d2d8 100644
--- a/src/libstrongswan/tests/suites/test_traffic_selector.c
+++ b/src/libstrongswan/tests/suites/test_traffic_selector.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2015 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2015 Martin Willi
* Copyright (C) 2015 revosec AG
*
@@ -22,10 +25,9 @@ static void verify(const char *str, const char *alt, traffic_selector_t *ts)
{
char buf[512];
- ck_assert(ts != NULL);
snprintf(buf, sizeof(buf), "%R", ts);
- ts->destroy(ts);
- if (!streq(buf, str) && !streq(buf, alt))
+ DESTROY_IF(ts);
+ if (!streq(buf, str) && (!alt || !streq(buf, alt)))
{
fail("%s != %s or %s", buf, str, alt);
}
@@ -43,6 +45,16 @@ START_TEST(test_create_from_string)
verify("fec1::/64", NULL,
traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE,
"fec1::", 0, "fec1::ffff:ffff:ffff:ffff", 65535));
+ verify("fec1::1..fec1::ffff:ffff:ffff:ffff", NULL,
+ traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE,
+ "fec1::1", 0, "fec1::ffff:ffff:ffff:ffff", 65535));
+
+ ck_assert(!traffic_selector_create_from_string(IPPROTO_TCP, 0,
+ "10.1.0.0", 80, "10.1.255.255", 80));
+ ck_assert(!traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
+ "a.b.c.d", 80, "10.1.255.255", 80));
+ ck_assert(!traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE,
+ "10.1.0.0", 80, "a.b.c.d", 80));
}
END_TEST
@@ -53,6 +65,10 @@ START_TEST(test_create_from_cidr)
verify("10.1.0.1/32[udp/1234-1235]", "10.1.0.1/32[17/1234-1235]",
traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP,
1234, 1235));
+ verify("10.1.0.0/16[OPAQUE]", NULL,
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 65535, 0));
+
+ ck_assert(!traffic_selector_create_from_cidr("a.b.c.d/16", 0, 0, 65535));
}
END_TEST
@@ -62,6 +78,16 @@ START_TEST(test_create_from_bytes)
traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
+
+ ck_assert(!traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE,
+ chunk_empty, 0,
+ chunk_empty, 65535));
+ ck_assert(!traffic_selector_create_from_bytes(0, TS_IPV6_ADDR_RANGE,
+ chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
+ chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
+ ck_assert(!traffic_selector_create_from_bytes(0, 0,
+ chunk_from_chars(0x0a,0x01,0x00,0x00), 0,
+ chunk_from_chars(0x0a,0x01,0xff,0xff), 65535));
}
END_TEST
@@ -73,6 +99,175 @@ START_TEST(test_create_from_subnet)
}
END_TEST
+struct {
+ char *net;
+ ts_type_t type;
+ chunk_t enc;
+} rfc3779_prefix_tests[] = {
+ /* some examples from RFC 3779, for addressPrefix elements we pass the same
+ * value twice to the constructor */
+ { "10.0.0.0/8", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a), },
+ { "10.0.32.0/20", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x00,0x20), },
+ { "10.0.64.0/24", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x00,0x40), },
+ { "10.1.0.0/16", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x01), },
+ { "10.5.0.1/32", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00,0x0a,0x05,0x00,0x01), },
+ { "10.5.0.0/23", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x01,0x0a,0x05,0x00), },
+ { "10.64.0.0/12", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x40), },
+ { "10.64.0.0/20", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x0a,0x40,0x00), },
+ { "128.0.0.0/4", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0x80), },
+ { "172.16.0.0/12", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x04,0xac,0x10), },
+ { "0.0.0.0/0", TS_IPV4_ADDR_RANGE, chunk_from_chars(0x00), },
+ /* FIXME: not a correct encoding, so we might want to fail here */
+ { "0.0.0.0/0", TS_IPV4_ADDR_RANGE, {NULL, 0}, },
+ { "2001:0:2::/48", TS_IPV6_ADDR_RANGE, chunk_from_chars(0x00,0x20,0x01,0x00,0x00,0x00,0x02),},
+ { "2001:0:200::/39",TS_IPV6_ADDR_RANGE, chunk_from_chars(0x01,0x20,0x01,0x00,0x00,0x02),},
+ { "::/0", TS_IPV6_ADDR_RANGE, chunk_from_chars(0x00), },
+ /* FIXME: not a correct encoding, so we might want to fail here */
+ { "::/0", TS_IPV6_ADDR_RANGE, {NULL, 0}, },
+};
+
+START_TEST(test_create_from_rfc3779_format_prefix)
+{
+ verify(rfc3779_prefix_tests[_i].net, NULL,
+ traffic_selector_create_from_rfc3779_format(rfc3779_prefix_tests[_i].type,
+ rfc3779_prefix_tests[_i].enc, rfc3779_prefix_tests[_i].enc));
+}
+END_TEST
+
+START_TEST(test_create_from_rfc3779_format_range)
+{
+ /* addressRange elements encode a from and to address, which may still
+ * represent prefixes */
+ verify("10.5.0.0/23", NULL,
+ traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
+ chunk_from_chars(0x00,0x0a,0x05),
+ chunk_from_chars(0x01,0x0a,0x05,0x00)));
+ verify("2001:0:200::/39", NULL,
+ traffic_selector_create_from_rfc3779_format(TS_IPV6_ADDR_RANGE,
+ chunk_from_chars(0x01,0x20,0x01,0x00,0x00,0x02),
+ chunk_from_chars(0x02,0x20,0x01,0x00,0x00,0x00)));
+ verify("10.2.48.0..10.2.64.255", NULL,
+ traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
+ chunk_from_chars(0x04,0x0a,0x02,0x30),
+ chunk_from_chars(0x00,0x0a,0x02,0x40)));
+ verify("129.64.0.0..143.255.255.255", NULL,
+ traffic_selector_create_from_rfc3779_format(TS_IPV4_ADDR_RANGE,
+ chunk_from_chars(0x06,0x81,0x40),
+ chunk_from_chars(0x04,0x80)));
+}
+END_TEST
+
+
+static void verify_address(char *addr_from, char *addr_to, traffic_selector_t *ts)
+{
+ host_t *from, *to;
+
+ from = host_create_from_string(addr_from, 0);
+ to = host_create_from_string(addr_to, 0);
+
+ ck_assert_chunk_eq(from->get_address(from), ts->get_from_address(ts));
+ ck_assert_chunk_eq(to->get_address(to), ts->get_to_address(ts));
+ from->destroy(from);
+ to->destroy(to);
+ ts->destroy(ts);
+}
+
+START_TEST(test_get_address_range)
+{
+ verify_address("10.1.0.1", "10.1.0.10",
+ traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
+ "10.1.0.1", 0, "10.1.0.10", 65535));
+ /* currently not reordered */
+ verify_address("10.1.0.10", "10.1.0.1",
+ traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
+ "10.1.0.10", 0, "10.1.0.1", 65535));
+}
+END_TEST
+
+START_TEST(test_get_address_cidr)
+{
+ verify_address("10.1.0.0", "10.1.255.255",
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535));
+ verify_address("fec1::", "fec1::ffff:ffff:ffff:ffff",
+ traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535));
+}
+END_TEST
+
+struct {
+ ts_type_t type;
+ char *from;
+ char *to;
+ char *net;
+ u_int8_t mask;
+ bool exact;
+} to_subnet_tests[] = {
+ { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.1", "10.0.0.1", 32, TRUE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.0", "10.255.255.255", "10.0.0.0", 8, TRUE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.255", "10.0.0.0", 24, FALSE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.0", "10.0.0.15", "10.0.0.0", 28, TRUE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.15", "10.0.0.0", 28, FALSE },
+ { TS_IPV4_ADDR_RANGE, "10.0.0.1", "10.0.0.16", "10.0.0.0", 27, FALSE },
+ { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::1", "fec1::1", 128, TRUE },
+ { TS_IPV6_ADDR_RANGE, "fec1::0", "fec1::ffff:ffff:ffff:ffff", "fec1::", 64, TRUE },
+ { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::ffff:ffff:ffff:ffff", "fec1::", 64, FALSE },
+ { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::7fff", "fec1::", 113, FALSE },
+ { TS_IPV6_ADDR_RANGE, "fec1::1", "fec1::efff", "fec1::", 112, FALSE },
+};
+
+START_TEST(test_to_subnet)
+{
+ traffic_selector_t *ts;
+ host_t *net, *exp_net;
+ u_int8_t mask;
+
+ ts = traffic_selector_create_from_string(0, to_subnet_tests[_i].type,
+ to_subnet_tests[_i].from, 0, to_subnet_tests[_i].to, 0);
+ ck_assert(ts->to_subnet(ts, &net, &mask) == to_subnet_tests[_i].exact);
+ exp_net = host_create_from_string(to_subnet_tests[_i].net, 0);
+ ck_assert(exp_net->ip_equals(exp_net, net));
+ ck_assert_int_eq(to_subnet_tests[_i].mask, mask);
+ exp_net->destroy(exp_net);
+ net->destroy(net);
+ ts->destroy(ts);
+}
+END_TEST
+
+struct {
+ char *cidr;
+ u_int16_t from_port;
+ u_int16_t to_port;
+ u_int16_t port;
+} to_subnet_port_tests[] = {
+ { "10.0.0.0/8", 0, 0, 0 },
+ { "10.0.0.1/32", 80, 80, 80 },
+ { "10.0.0.1/32", 123, 465, 0 },
+ { "0.0.0.0/0", 0, 65535, 0 },
+ { "fec1::/64", 0, 0, 0 },
+ { "fec1::1/128", 80, 80, 80 },
+ { "fec1::1/128", 123, 465, 0 },
+ { "::/0", 0, 65535, 0 },
+};
+
+START_TEST(test_to_subnet_port)
+{
+ traffic_selector_t *ts;
+ host_t *net, *exp_net;
+ u_int8_t mask;
+ int exp_mask;
+
+ ts = traffic_selector_create_from_cidr(to_subnet_port_tests[_i].cidr, 0,
+ to_subnet_port_tests[_i].from_port,
+ to_subnet_port_tests[_i].to_port);
+ ck_assert(ts->to_subnet(ts, &net, &mask));
+ exp_net = host_create_from_subnet(to_subnet_port_tests[_i].cidr, &exp_mask);
+ ck_assert(exp_net->ip_equals(exp_net, net));
+ ck_assert_int_eq(exp_mask, mask);
+ ck_assert_int_eq(to_subnet_port_tests[_i].port, net->get_port(net));
+ exp_net->destroy(exp_net);
+ net->destroy(net);
+ ts->destroy(ts);
+}
+END_TEST
START_TEST(test_subset)
{
@@ -81,6 +276,14 @@ START_TEST(test_subset)
a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
b = traffic_selector_create_from_cidr("10.1.5.0/24", 0, 0, 65535);
verify("10.1.5.0/24", NULL, a->get_subset(a, b));
+ verify("10.1.5.0/24", NULL, b->get_subset(b, a));
+ a->destroy(a);
+ b->destroy(b);
+
+ a = traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535);
+ b = traffic_selector_create_from_cidr("fec1::1/128", 0, 0, 65535);
+ verify("fec1::1/128", NULL, a->get_subset(a, b));
+ verify("fec1::1/128", NULL, b->get_subset(b, a));
a->destroy(a);
b->destroy(b);
}
@@ -117,7 +320,7 @@ START_TEST(test_subset_nonet)
a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
b = traffic_selector_create_from_cidr("10.2.0.0/16", 0, 0, 65535);
- ck_assert(a->get_subset(a, b) == NULL);
+ ck_assert(!a->get_subset(a, b));
a->destroy(a);
b->destroy(b);
}
@@ -129,7 +332,7 @@ START_TEST(test_subset_noport)
a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 9999);
b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 10000, 65535);
- ck_assert(a->get_subset(a, b) == NULL);
+ ck_assert(!a->get_subset(a, b));
a->destroy(a);
b->destroy(b);
}
@@ -141,7 +344,7 @@ START_TEST(test_subset_noproto)
a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 0, 65535);
b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_UDP, 0, 65535);
- ck_assert(a->get_subset(a, b) == NULL);
+ ck_assert(!a->get_subset(a, b));
a->destroy(a);
b->destroy(b);
}
@@ -153,7 +356,43 @@ START_TEST(test_subset_nofamily)
a = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535);
b = traffic_selector_create_from_cidr("::/0", 0, 0, 65535);
- ck_assert(a->get_subset(a, b) == NULL);
+ ck_assert(!a->get_subset(a, b));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_dynamic)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_dynamic(0, 0, 65535);
+ b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535);
+ ck_assert(!a->get_subset(a, b));
+ ck_assert(!b->get_subset(b, a));
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+START_TEST(test_subset_opaque)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr("10.0.0.0/8", 0, 65535, 0);
+ b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 80, 80);
+ ck_assert(!a->get_subset(a, b));
+ ck_assert(!b->get_subset(b, a));
+ b->destroy(b);
+
+ b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 65535, 0);
+ verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", a->get_subset(a, b));
+ verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", b->get_subset(b, a));
+ b->destroy(b);
+
+ b = traffic_selector_create_from_cidr("10.2.7.16/30", IPPROTO_TCP, 0, 65535);
+ verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", a->get_subset(a, b));
+ verify("10.2.7.16/30[tcp/OPAQUE]", "10.2.7.16/30[6/OPAQUE]", b->get_subset(b, a));
a->destroy(a);
b->destroy(b);
}
@@ -189,6 +428,130 @@ START_TEST(test_includes)
END_TEST
struct {
+ bool contained;
+ struct {
+ char *net;
+ u_int8_t proto;
+ u_int16_t from_port;
+ u_int16_t to_port;
+ } a, b;
+} is_contained_in_tests[] = {
+ { TRUE, { "10.0.0.0/16", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
+ { TRUE, { "10.0.1.0/24", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
+ { TRUE, { "10.0.1.0/24", 17, 123, 456 }, { "10.0.0.0/16", 0, 0, 65535 }, },
+ { TRUE, { "10.0.1.0/24", 17, 123, 456 }, { "10.0.0.0/16", 17, 123, 456 },},
+ { FALSE, { "10.0.0.0/8", 0, 0, 65535 }, { "10.0.0.0/16", 0, 0, 65535 }, },
+ { FALSE, { "10.0.1.0/24", 17, 0, 65535 }, { "10.0.0.0/16", 17, 123, 456 },},
+ { FALSE, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/16", 17, 123, 456 },},
+};
+
+START_TEST(test_is_contained_in)
+{
+ traffic_selector_t *a, *b;
+
+ a = traffic_selector_create_from_cidr(
+ is_contained_in_tests[_i].a.net, is_contained_in_tests[_i].a.proto,
+ is_contained_in_tests[_i].a.from_port, is_contained_in_tests[_i].a.to_port);
+ b = traffic_selector_create_from_cidr(
+ is_contained_in_tests[_i].b.net, is_contained_in_tests[_i].b.proto,
+ is_contained_in_tests[_i].b.from_port, is_contained_in_tests[_i].b.to_port);
+ ck_assert(a->is_contained_in(a, b) == is_contained_in_tests[_i].contained);
+ a->destroy(a);
+ b->destroy(b);
+}
+END_TEST
+
+struct {
+ char *net;
+ char *host;
+ bool is_host;
+ bool when_null;
+} is_host_tests[] = {
+ { "0.0.0.0/0", "192.168.1.2", FALSE, FALSE },
+ { "::/0", "fec2::1", FALSE, FALSE },
+ { "192.168.1.2/32", "192.168.1.2", TRUE, TRUE },
+ { "192.168.1.2/32", "192.168.1.1", FALSE, TRUE },
+ { "192.168.1.2/32", "fec2::1", FALSE, TRUE },
+ { "fec2::1/128", "fec2::1", TRUE, TRUE },
+ { "fec2::1/128", "fec2::2", FALSE, TRUE },
+ { "fec2::1/128", "192.168.1.2", FALSE, TRUE },
+};
+
+START_TEST(test_is_host)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ ts = traffic_selector_create_from_cidr(is_host_tests[_i].net, 0, 0, 65535);
+ h = host_create_from_string(is_host_tests[_i].host, 0);
+ ck_assert(ts->is_host(ts, h) == is_host_tests[_i].is_host);
+ ck_assert(ts->is_host(ts, NULL) == is_host_tests[_i].when_null);
+ ts->destroy(ts);
+ h->destroy(h);
+}
+END_TEST
+
+START_TEST(test_is_host_dynamic)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ ts = traffic_selector_create_dynamic(0, 0, 65535);
+ h = host_create_from_string(is_host_tests[_i].host, 0);
+ ck_assert(!ts->is_host(ts, h));
+ ck_assert(ts->is_host(ts, NULL));
+ ts->destroy(ts);
+ h->destroy(h);
+}
+END_TEST
+
+
+struct {
+ char *orig;
+ char *host;
+ char *after;
+} set_address_tests[] = {
+ { "0.0.0.0/0", "192.168.1.2", "0.0.0.0/0" },
+ { "::/0", "fec2::1", "::/0" },
+ { "192.168.1.2/32", "192.168.1.1", "192.168.1.1/32" },
+ { "192.168.1.2/32", "fec2::1", "fec2::1/128" },
+ { "192.168.1.2/32", "%any", "0.0.0.0/0" },
+ { "192.168.1.2/32", "%any6", "::/0" },
+ { "fec2::1/128", "192.168.1.1", "192.168.1.1/32" },
+ { "fec2::1/128", "fec2::2", "fec2::2/128" },
+ { "fec2::1/128", "%any", "0.0.0.0/0" },
+ { "fec2::1/128", "%any6", "::/0" },
+ { NULL, "192.168.1.1", "192.168.1.1/32" },
+ { NULL, "fec2::1", "fec2::1/128" },
+ { NULL, "%any", "0.0.0.0/0" },
+ { NULL, "%any6", "::/0" },
+};
+
+START_TEST(test_set_address)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ if (set_address_tests[_i].orig)
+ {
+ ts = traffic_selector_create_from_cidr(set_address_tests[_i].orig, 0, 0, 65535);
+ ck_assert(!ts->is_dynamic(ts));
+ }
+ else
+ {
+ ts = traffic_selector_create_dynamic(0, 0, 65535);
+ ck_assert(ts->is_dynamic(ts));
+ }
+ h = host_create_from_string(set_address_tests[_i].host, 0);
+ ts->set_address(ts, h);
+ ck_assert(!ts->is_dynamic(ts));
+ verify(set_address_tests[_i].after, NULL, ts);
+ h->destroy(h);
+}
+END_TEST
+
+
+struct {
int res;
struct {
char *net;
@@ -206,6 +569,10 @@ struct {
{ 1, { "2.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, },
{ -1, { "1.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/16", 0, 0, 65535 }, },
{ 1, { "1.0.0.0/16", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, },
+ { -1, { "fec1::/64", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
+ { 1, { "fec2::/64", 0, 0, 65535 }, { "fec1::/64", 0, 0, 65535 }, },
+ { -1, { "fec1::/48", 0, 0, 65535 }, { "fec1::/64", 0, 0, 65535 }, },
+ { 1, { "fec1::/64", 0, 0, 65535 }, { "fec1::/48", 0, 0, 65535 }, },
{ -1, { "10.0.0.0/8", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, },
{ 1, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, },
@@ -235,12 +602,15 @@ START_TEST(test_cmp)
{
case 0:
ck_assert(traffic_selector_cmp(a, b, NULL) == 0);
+ ck_assert(a->equals(a, b));
break;
case 1:
ck_assert(traffic_selector_cmp(a, b, NULL) > 0);
+ ck_assert(!a->equals(a, b));
break;
case -1:
ck_assert(traffic_selector_cmp(a, b, NULL) < 0);
+ ck_assert(!a->equals(a, b));
break;
}
a->destroy(a);
@@ -248,6 +618,172 @@ START_TEST(test_cmp)
}
END_TEST
+static void verify_clone(traffic_selector_t *ts)
+{
+ traffic_selector_t *clone;
+
+ clone = ts->clone(ts);
+ if (!ts->equals(ts, clone))
+ {
+ fail("%R != %R", ts, clone);
+ }
+ /* equals() already compares most of these but not all */
+ ck_assert(ts->get_type(ts) == clone->get_type(clone));
+ ck_assert(ts->get_protocol(ts) == clone->get_protocol(clone));
+ ck_assert(ts->get_from_port(ts) == clone->get_from_port(clone));
+ ck_assert(ts->get_to_port(ts) == clone->get_to_port(clone));
+ ck_assert_chunk_eq(ts->get_from_address(ts), clone->get_from_address(clone));
+ ck_assert_chunk_eq(ts->get_to_address(ts), clone->get_to_address(clone));
+ ck_assert(ts->is_host(ts, NULL) == clone->is_host(clone, NULL));
+ ck_assert(ts->is_dynamic(ts) == clone->is_dynamic(clone));
+ clone->destroy(clone);
+ ts->destroy(ts);
+}
+
+START_TEST(test_clone)
+{
+ traffic_selector_t *ts;
+ host_t *h;
+
+ ts = traffic_selector_create_dynamic(0, 0, 0);
+ verify_clone(ts);
+ ts = traffic_selector_create_dynamic(IPPROTO_UDP, 123, 456);
+ verify_clone(ts);
+ ts = traffic_selector_create_dynamic(IPPROTO_UDP, 0, 65535);
+ verify_clone(ts);
+
+ h = host_create_from_string("192.168.1.1", 0);
+ ts = traffic_selector_create_dynamic(0, 0, 0);
+ ts->set_address(ts, h);
+ verify_clone(ts);
+ ts = traffic_selector_create_dynamic(IPPROTO_UDP, 123, 456);
+ ts->set_address(ts, h);
+ verify_clone(ts);
+ h->destroy(h);
+
+ ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "10.0.0.1", 0, "10.0.0.16", 65535);
+ verify_clone(ts);
+ ts = traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV6_ADDR_RANGE, "fec1::1", 80, "fec1::1:0000", 80);
+ verify_clone(ts);
+ ts = traffic_selector_create_from_cidr("10.0.0.0/8", 0, 0, 65535);
+ verify_clone(ts);
+ ts = traffic_selector_create_from_cidr("fec1::/64", 0, 0, 65535);
+ verify_clone(ts);
+}
+END_TEST
+
+START_TEST(test_hash)
+{
+ traffic_selector_t *a, *b;
+ host_t *h;
+
+ a = traffic_selector_create_dynamic(0, 0, 0);
+ b = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 0);
+ ck_assert(a->hash(a, 0) != a->hash(a, 1));
+ ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
+ ck_assert_int_eq(a->hash(a, 1), b->hash(b, 1));
+
+ h = host_create_from_string("192.168.1.1", 0);
+ a->set_address(a, h);
+ ck_assert(a->hash(a, 0) != b->hash(b, 0));
+ h->destroy(h);
+
+ a->destroy(a);
+ a = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, "192.168.0.0", 0, "192.168.0.255", 65535);
+ ck_assert(a->hash(a, 0) != b->hash(b, 0));
+ b->destroy(b);
+ b = traffic_selector_create_from_cidr("192.168.0.0/24", 0, 0, 65535);
+ ck_assert_int_eq(a->hash(a, 0), b->hash(b, 0));
+ b->destroy(b);
+ b = traffic_selector_create_from_cidr("192.168.0.0/24", IPPROTO_TCP, 0, 65535);
+ ck_assert(a->hash(a, 0) != b->hash(b, 0));
+ b->destroy(b);
+ b = traffic_selector_create_from_cidr("192.168.0.0/24", 0, 123, 456);
+ ck_assert(a->hash(a, 0) != b->hash(b, 0));
+ b->destroy(b);
+ a->destroy(a);
+}
+END_TEST
+
+struct {
+ u_int8_t proto;
+ u_int16_t from_port;
+ u_int16_t to_port;
+ u_int8_t from_type;
+ u_int8_t from_code;
+ u_int8_t to_type;
+ u_int8_t to_code;
+ char *str;
+ char *str_alt;
+} icmp_tests[] = {
+ { IPPROTO_ICMP, 0, 0, 0, 0, 0, 0, "dynamic[icmp/0]", "dynamic[1/0]" },
+ { IPPROTO_ICMP, 3, 3, 3, 0, 3, 0, "dynamic[icmp/3]", "dynamic[1/3]" },
+ { IPPROTO_ICMP, 0x0307, 0x0307, 3, 7, 3, 7, "dynamic[icmp/3(7)]", "dynamic[1/3(7)]" },
+ { IPPROTO_ICMP, 0x0300, 0x040f, 3, 0, 4, 15, "dynamic[icmp/3-4(15)]", "dynamic[1/3-4(15)]" },
+ { IPPROTO_ICMP, 0x0301, 0x040f, 3, 1, 4, 15, "dynamic[icmp/3(1)-4(15)]", "dynamic[1/3(1)-4(15)]" },
+ { IPPROTO_ICMPV6, 0, 0, 0, 0, 0, 0, "dynamic[ipv6-icmp/0]", "dynamic[58/0]" },
+ { IPPROTO_ICMPV6, 1, 1, 1, 0, 1, 0, "dynamic[ipv6-icmp/1]", "dynamic[58/1]" },
+ { IPPROTO_ICMPV6, 0x0104, 0x0104, 1, 4, 1, 4, "dynamic[ipv6-icmp/1(4)]", "dynamic[58/1(4)]" },
+ { IPPROTO_ICMPV6, 0x0100, 0x040f, 1, 0, 4, 15, "dynamic[ipv6-icmp/1-4(15)]", "dynamic[58/1-4(15)]" },
+ { IPPROTO_ICMPV6, 0x0101, 0x040f, 1, 1, 4, 15, "dynamic[ipv6-icmp/1(1)-4(15)]", "dynamic[58/1(1)-4(15)]" },
+};
+
+START_TEST(test_icmp)
+{
+ traffic_selector_t *ts;
+ u_int16_t from, to;
+
+ ts = traffic_selector_create_dynamic(icmp_tests[_i].proto,
+ icmp_tests[_i].from_port, icmp_tests[_i].to_port);
+ from = ts->get_from_port(ts);
+ to = ts->get_to_port(ts);
+ ck_assert_int_eq(icmp_tests[_i].from_type, traffic_selector_icmp_type(from));
+ ck_assert_int_eq(icmp_tests[_i].from_code, traffic_selector_icmp_code(from));
+ ck_assert_int_eq(icmp_tests[_i].to_type, traffic_selector_icmp_type(to));
+ ck_assert_int_eq(icmp_tests[_i].to_code, traffic_selector_icmp_code(to));
+ verify(icmp_tests[_i].str, icmp_tests[_i].str_alt, ts);
+}
+END_TEST
+
+static void verify_list(const char *str, const char *alt, linked_list_t *list)
+{
+ char buf[512];
+
+ snprintf(buf, sizeof(buf), "%#R", list);
+ list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
+ if (!streq(buf, str) && !streq(buf, alt))
+ {
+ fail("%s != %s or %s", buf, str, alt);
+ }
+}
+
+START_TEST(test_printf_hook_null)
+{
+ verify("(null)", NULL, NULL);
+}
+END_TEST
+
+START_TEST(test_printf_hook_hash)
+{
+ linked_list_t *list;
+
+ list = linked_list_create_with_items(
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
+ NULL);
+ verify_list("10.1.0.0/16 ", NULL, list);
+ list = linked_list_create_with_items(
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
+ traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP, 1234, 1235),
+ NULL);
+ verify_list("10.1.0.0/16 10.1.0.1/32[udp/1234-1235] ", "10.1.0.0/16 10.1.0.1/32[17/1234-1235] ", list);
+ list = linked_list_create_with_items(
+ traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535),
+ traffic_selector_create_from_string(IPPROTO_UDP, TS_IPV4_ADDR_RANGE, "10.1.0.1", 1234, "10.1.0.99", 1235),
+ NULL);
+ verify_list("10.1.0.0/16 10.1.0.1..10.1.0.99[udp/1234-1235] ", "10.1.0.0/16 10.1.0.1..10.1.0.99[17/1234-1235] ", list);
+}
+END_TEST
+
Suite *traffic_selector_suite_create()
{
Suite *s;
@@ -260,6 +796,18 @@ Suite *traffic_selector_suite_create()
tcase_add_test(tc, test_create_from_cidr);
tcase_add_test(tc, test_create_from_bytes);
tcase_add_test(tc, test_create_from_subnet);
+ tcase_add_loop_test(tc, test_create_from_rfc3779_format_prefix, 0, countof(rfc3779_prefix_tests));
+ tcase_add_test(tc, test_create_from_rfc3779_format_range);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("addresses");
+ tcase_add_test(tc, test_get_address_range);
+ tcase_add_test(tc, test_get_address_cidr);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("to_subnet");
+ tcase_add_loop_test(tc, test_to_subnet, 0, countof(to_subnet_tests));
+ tcase_add_loop_test(tc, test_to_subnet_port, 0, countof(to_subnet_port_tests));
suite_add_tcase(s, tc);
tc = tcase_create("subset");
@@ -270,15 +818,47 @@ Suite *traffic_selector_suite_create()
tcase_add_test(tc, test_subset_noport);
tcase_add_test(tc, test_subset_noproto);
tcase_add_test(tc, test_subset_nofamily);
+ tcase_add_test(tc, test_subset_dynamic);
+ tcase_add_test(tc, test_subset_opaque);
suite_add_tcase(s, tc);
tc = tcase_create("includes");
tcase_add_loop_test(tc, test_includes, 0, countof(include_tests));
suite_add_tcase(s, tc);
+ tc = tcase_create("is_contained_in");
+ tcase_add_loop_test(tc, test_is_contained_in, 0, countof(is_contained_in_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("is_host");
+ tcase_add_loop_test(tc, test_is_host, 0, countof(is_host_tests));
+ tcase_add_loop_test(tc, test_is_host_dynamic, 0, countof(is_host_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("set_address");
+ tcase_add_loop_test(tc, test_set_address, 0, countof(is_host_tests));
+ suite_add_tcase(s, tc);
+
tc = tcase_create("cmp");
tcase_add_loop_test(tc, test_cmp, 0, countof(cmp_tests));
suite_add_tcase(s, tc);
+ tc = tcase_create("clone");
+ tcase_add_test(tc, test_clone);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("hash");
+ tcase_add_test(tc, test_hash);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("icmp");
+ tcase_add_loop_test(tc, test_icmp, 0, countof(icmp_tests));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("printf hook");
+ tcase_add_test(tc, test_printf_hook_null);
+ tcase_add_test(tc, test_printf_hook_hash);
+ suite_add_tcase(s, tc);
+
return s;
}