aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2014-10-28 18:14:29 +0100
committerTobias Brunner <tobias@strongswan.org>2014-10-30 12:32:45 +0100
commit82be444eb99b51f42e717bf883a981ae9cd7d77e (patch)
tree8049f39c02d2866b585d02914acf1efd3a443798 /src
parentbbe3070aa207afaa8c61867157fd097ef09b2ac4 (diff)
downloadstrongswan-82be444eb99b51f42e717bf883a981ae9cd7d77e.tar.bz2
strongswan-82be444eb99b51f42e717bf883a981ae9cd7d77e.tar.xz
host: Add function to create two hosts from a range definition
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/networking/host.c28
-rw-r--r--src/libstrongswan/networking/host.h13
-rw-r--r--src/libstrongswan/tests/suites/test_host.c83
3 files changed, 124 insertions, 0 deletions
diff --git a/src/libstrongswan/networking/host.c b/src/libstrongswan/networking/host.c
index 8d04a4ec9..95c7390a7 100644
--- a/src/libstrongswan/networking/host.c
+++ b/src/libstrongswan/networking/host.c
@@ -528,6 +528,34 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port)
/*
* Described in header.
*/
+bool host_create_from_range(char *string, host_t **from, host_t **to)
+{
+ char *pos;
+
+ pos = strchr(string, '-');
+ if (!pos)
+ {
+ return FALSE;
+ }
+ *to = host_create_from_string(pos + 1, 0);
+ if (!*to)
+ {
+ return FALSE;
+ }
+ pos = strndup(string, pos - string);
+ *from = host_create_from_string_and_family(pos, (*to)->get_family(*to), 0);
+ free(pos);
+ if (!*from)
+ {
+ (*to)->destroy(*to);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Described in header.
+ */
host_t *host_create_from_subnet(char *string, int *bits)
{
char *pos, buf[64];
diff --git a/src/libstrongswan/networking/host.h b/src/libstrongswan/networking/host.h
index 9c9b5035f..3670768c4 100644
--- a/src/libstrongswan/networking/host.h
+++ b/src/libstrongswan/networking/host.h
@@ -181,6 +181,19 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port);
host_t *host_create_from_sockaddr(sockaddr_t *sockaddr);
/**
+ * Parse a range definition (1.2.3.0-1.2.3.5), return the two hosts.
+ *
+ * The two hosts are not ordered, from is simply the first, to is the second,
+ * from is not necessarily smaller.
+ *
+ * @param string string to parse
+ * @param from returns the first address (out)
+ * @param to returns the second address (out)
+ * @return TRUE if parsed successfully, FALSE otherwise
+ */
+bool host_create_from_range(char *string, host_t **from, host_t **to);
+
+/**
* Create a host from a CIDR subnet definition (1.2.3.0/24), return bits.
*
* @param string string to parse
diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c
index 63442083a..1f97bff6e 100644
--- a/src/libstrongswan/tests/suites/test_host.c
+++ b/src/libstrongswan/tests/suites/test_host.c
@@ -400,6 +400,84 @@ START_TEST(test_create_from_subnet_v6)
END_TEST
/*******************************************************************************
+ * host_create_from_range
+ */
+
+static const chunk_t addr_v4_to = chunk_from_chars(0xc0, 0xa8, 0x00, 0x05);
+static const chunk_t addr_v6_to = chunk_from_chars(0xfe, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05);
+
+static void verify_range(char *str, int family, chunk_t from_addr,
+ chunk_t to_addr)
+{
+ host_t *from, *to;
+
+ if (!family)
+ {
+ ck_assert(!host_create_from_range(str, &from, &to));
+ }
+ else
+ {
+ ck_assert(host_create_from_range(str, &from, &to));
+ verify_address(from, from_addr, family, 0);
+ verify_address(to, to_addr, family, 0);
+ from->destroy(from);
+ to->destroy(to);
+ }
+}
+
+START_TEST(test_create_from_range_v4)
+{
+ host_t *from, *to;
+
+ ck_assert(host_create_from_range("0.0.0.0-0.0.0.0", &from, &to));
+ verify_any(from, AF_INET, 0);
+ verify_any(to, AF_INET, 0);
+ from->destroy(from);
+ to->destroy(to);
+
+ verify_range("192.168.0.1-192.168.0.1", AF_INET, addr_v4, addr_v4);
+ verify_range("192.168.0.1-192.168.0.5", AF_INET, addr_v4, addr_v4_to);
+ verify_range("192.168.0.5-192.168.0.1", AF_INET, addr_v4_to, addr_v4);
+
+ verify_range("192.168.0.1", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-192", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-192.168", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-192.168.0", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1 - 192.168.0.5", 0, chunk_empty, chunk_empty);
+ verify_range("foo.b.a.r", 0, chunk_empty, chunk_empty);
+ verify_range("foo.b.a.r-b.a.r.f", 0, chunk_empty, chunk_empty);
+}
+END_TEST
+
+START_TEST(test_create_from_range_v6)
+{
+ host_t *from, *to;
+
+ ck_assert(host_create_from_range("::-::", &from, &to));
+ verify_any(from, AF_INET6, 0);
+ verify_any(to, AF_INET6, 0);
+ from->destroy(from);
+ to->destroy(to);
+
+ verify_range("fec1::1-fec1::1", AF_INET6, addr_v6, addr_v6);
+ verify_range("fec1::1-fec1::5", AF_INET6, addr_v6, addr_v6_to);
+ verify_range("fec1::5-fec1::1", AF_INET6, addr_v6_to, addr_v6);
+
+ verify_range("fec1::1", 0, chunk_empty, chunk_empty);
+ verify_range("fec1::1-", 0, chunk_empty, chunk_empty);
+ verify_range("fec1::1-fec1", 0, chunk_empty, chunk_empty);
+ verify_range("fec1::1 - fec1::5", 0, chunk_empty, chunk_empty);
+ verify_range("foo::bar", 0, chunk_empty, chunk_empty);
+ verify_range("foo::bar-bar::foo", 0, chunk_empty, chunk_empty);
+
+ verify_range("fec1::1-192.168.0.1", 0, chunk_empty, chunk_empty);
+ verify_range("192.168.0.1-fec1::1", 0, chunk_empty, chunk_empty);
+}
+END_TEST
+
+/*******************************************************************************
* host_create_netmask
*/
@@ -627,6 +705,11 @@ Suite *host_suite_create()
tcase_add_test(tc, test_create_from_subnet_v6);
suite_add_tcase(s, tc);
+ tc = tcase_create("host_create_from_range");
+ tcase_add_test(tc, test_create_from_range_v4);
+ tcase_add_test(tc, test_create_from_range_v6);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("host_create_netmask");
tcase_add_test(tc, test_create_netmask_v4);
tcase_add_test(tc, test_create_netmask_v6);