From: Tobias Brunner Date: Tue, 28 Oct 2014 17:14:29 +0000 (+0100) Subject: host: Add function to create two hosts from a range definition X-Git-Tag: 5.2.2dr1~46^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82be444eb99b51f42e717bf883a981ae9cd7d77e;p=thirdparty%2Fstrongswan.git host: Add function to create two hosts from a range definition --- diff --git a/src/libstrongswan/networking/host.c b/src/libstrongswan/networking/host.c index 8d04a4ec99..95c7390a75 100644 --- a/src/libstrongswan/networking/host.c +++ b/src/libstrongswan/networking/host.c @@ -525,6 +525,34 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port) return &this->public; } +/* + * 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. */ diff --git a/src/libstrongswan/networking/host.h b/src/libstrongswan/networking/host.h index 9c9b5035fb..3670768c49 100644 --- a/src/libstrongswan/networking/host.h +++ b/src/libstrongswan/networking/host.h @@ -180,6 +180,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. * diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c index 63442083a8..1f97bff6e6 100644 --- a/src/libstrongswan/tests/suites/test_host.c +++ b/src/libstrongswan/tests/suites/test_host.c @@ -399,6 +399,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);