/*
* check_ipaddrcheck.c: ipaddrcheck unit tests
*
* Copyright (C) 2013 Daniil Baturin
* Copyright (C) 2018-2024 VyOS maintainers and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 or later as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include
#include "../src/ipaddrcheck_functions.h"
START_TEST (test_is_valid_address)
{
char* good_v4_address_str = "192.0.2.1";
CIDR* good_v4_address = cidr_from_str(good_v4_address_str);
ck_assert_int_eq(is_valid_address(good_v4_address), RESULT_SUCCESS);
cidr_free(good_v4_address);
char* good_v6_address_str = "2001:db8:dead::1/56";
CIDR* good_v6_address = cidr_from_str(good_v6_address_str);
ck_assert_int_eq(is_valid_address(good_v6_address), RESULT_SUCCESS);
cidr_free(good_v6_address);
char* bad_address_str = "192.0.299.563";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_valid_address(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv4_cidr)
{
char* good_address_str_1 = "192.0.2.1/8";
ck_assert_int_eq(is_ipv4_cidr(good_address_str_1), RESULT_SUCCESS);
char* good_address_str_2 = "192.0.2.1/21";
ck_assert_int_eq(is_ipv4_cidr(good_address_str_2), RESULT_SUCCESS);
char* address_str_no_mask = "192.0.2.1";
ck_assert_int_eq(is_ipv4_cidr(address_str_no_mask), RESULT_FAILURE);
/* libcidr allows it, but we don't want to support it */
char* address_str_decimal_mask = "192.0.2.1/255.255.255.0";
ck_assert_int_eq(is_ipv4_cidr(address_str_decimal_mask), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_ipv4_single)
{
char* good_address_str = "192.0.2.1";
ck_assert_int_eq(is_ipv4_single(good_address_str), RESULT_SUCCESS);
char* bad_address_str = "192.0.2.1/25";
ck_assert_int_eq(is_ipv4_single(bad_address_str), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_ipv6_cidr)
{
char* good_address_str = "2001:db8:abcd::/64";
ck_assert_int_eq(is_ipv6_cidr(good_address_str), RESULT_SUCCESS);
char* address_str_no_mask = "2001:db8::1";
ck_assert_int_eq(is_ipv6_cidr(address_str_no_mask), RESULT_FAILURE);
/* libcidr allows fully spellt hex masks, but we don't want to support it */
char* address_str_decimal_mask = "::/0:0:0:0:0:0:0:0";
ck_assert_int_eq(is_ipv6_cidr(address_str_decimal_mask), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_ipv6_single)
{
char* good_address_str = "2001:db8::10";
ck_assert_int_eq(is_ipv6_single(good_address_str), RESULT_SUCCESS);
char* bad_address_str = "2001:db8::/32";
ck_assert_int_eq(is_ipv6_single(bad_address_str), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_any_cidr)
{
char* good_address_str_v4 = "192.0.2.1/21";
ck_assert_int_eq(is_any_cidr(good_address_str_v4), RESULT_SUCCESS);
char* address_str_no_mask_v4 = "192.0.2.1";
ck_assert_int_eq(is_any_cidr(address_str_no_mask_v4), RESULT_FAILURE);
char* good_address_str_v6 = "2001:db8::a/56";
ck_assert_int_eq(is_any_cidr(good_address_str_v6), RESULT_SUCCESS);
char* address_str_no_mask_v6 = "2001:db8:a:b::c";
ck_assert_int_eq(is_any_cidr(address_str_no_mask_v6), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_any_single)
{
char* good_address_str_v4 = "192.0.2.1";
ck_assert_int_eq(is_any_single(good_address_str_v4), RESULT_SUCCESS);
char* bad_address_str_v4 = "192.0.2.1/25";
ck_assert_int_eq(is_any_single(bad_address_str_v4), RESULT_FAILURE);
char* good_address_str_v6 = "2001:db8::10";
ck_assert_int_eq(is_any_single(good_address_str_v6), RESULT_SUCCESS);
char* bad_address_str_v6 = "2001:db8::/32";
ck_assert_int_eq(is_any_single(bad_address_str_v6), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_ipv4)
{
char* good_address_str = "192.0.2.1";
CIDR* good_address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv4(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* bad_address_str = "2001:db8::1/64";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv4(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv4_host)
{
char* good_address_str_no_mask = "192.0.2.1";
CIDR* good_address = cidr_from_str(good_address_str_no_mask);
ck_assert_int_eq(is_ipv4_host(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* good_address_str_cidr = "192.0.2.55/24";
CIDR* good_address_cidr = cidr_from_str(good_address_str_cidr);
ck_assert_int_eq(is_ipv4_host(good_address_cidr), RESULT_SUCCESS);
cidr_free(good_address_cidr);
char* bad_address_str = "192.0.2.0/24";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv4_host(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv4_net)
{
char* good_address_str = "192.0.2.0/25";
CIDR* good_address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv4_net(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* bad_address_str = "192.0.2.55/24";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv4_net(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv4_broadcast)
{
char* good_address_str = "192.0.2.255/24";
CIDR* good_address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv4_broadcast(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* bad_address_str = "192.0.2.55/24";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv4_broadcast(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
char* bad_address_str_ptp = "192.0.2.1/31";
CIDR* bad_address_ptp = cidr_from_str(bad_address_str_ptp);
ck_assert_int_eq(is_ipv4_broadcast(bad_address_ptp), RESULT_FAILURE);
cidr_free(bad_address_ptp);
char* bad_address_str_v6 = "2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff/32";
CIDR* bad_address_v6 = cidr_from_str(bad_address_str_v6);
ck_assert_int_eq(is_ipv4_broadcast(bad_address_v6), RESULT_FAILURE);
cidr_free(bad_address_v6);
}
END_TEST
START_TEST (test_is_ipv4_multicast)
{
char* good_address_str = "224.0.0.5";
CIDR* good_address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv4_multicast(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* bad_address_str = "192.0.2.55";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv4_multicast(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv4_loopback)
{
char* good_address_str = "127.0.0.90";
CIDR* good_address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv4_loopback(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* bad_address_str = "192.0.2.55";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv4_loopback(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv4_link_local)
{
CIDR* address = NULL;
char* good_address_str = "169.254.23.32";
address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv4_link_local(address), RESULT_SUCCESS);
cidr_free(address);
char* bad_address_str = "192.0.2.55";
address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv4_link_local(address), RESULT_FAILURE);
cidr_free(address);
}
END_TEST
START_TEST (test_is_ipv4_rfc1918)
{
char* good_address_str_a = "10.0.0.1";
CIDR* good_address_a = cidr_from_str(good_address_str_a);
ck_assert_int_eq(is_ipv4_rfc1918(good_address_a), RESULT_SUCCESS);
cidr_free(good_address_a);
char* good_address_str_b = "172.16.25.100";
CIDR* good_address_b = cidr_from_str(good_address_str_b);
ck_assert_int_eq(is_ipv4_rfc1918(good_address_b), RESULT_SUCCESS);
cidr_free(good_address_b);
char* good_address_str_c = "192.168.1.67";
CIDR* good_address_c = cidr_from_str(good_address_str_c);
ck_assert_int_eq(is_ipv4_rfc1918(good_address_c), RESULT_SUCCESS);
cidr_free(good_address_c);
char* bad_address_str = "192.0.2.55";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv4_link_local(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv6)
{
char* good_address_str = "2001:db8:1fe::49";
CIDR* good_address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv6(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* bad_address_str = "192.0.2.44";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv6(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv6_host)
{
char* good_address_str_no_mask = "2001:db8:a::1";
CIDR* good_address = cidr_from_str(good_address_str_no_mask);
ck_assert_int_eq(is_ipv6_host(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* good_address_str_cidr = "2001:db8:b::100/64";
CIDR* good_address_cidr = cidr_from_str(good_address_str_cidr);
ck_assert_int_eq(is_ipv6_host(good_address_cidr), RESULT_SUCCESS);
cidr_free(good_address_cidr);
char* bad_address_str = "2001:db8:f::/48";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv6_host(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv6_net)
{
char* good_address_str = "2001:db8::/32";
CIDR* good_address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv6_net(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* bad_address_str = "2001:db8:34::1/64";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv6_net(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv6_multicast)
{
char* good_address_str = "ff02::6";
CIDR* good_address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv6_multicast(good_address), RESULT_SUCCESS);
cidr_free(good_address);
char* bad_address_str = "2001:db8::1";
CIDR* bad_address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv6_multicast(bad_address), RESULT_FAILURE);
cidr_free(bad_address);
}
END_TEST
START_TEST (test_is_ipv6_link_local)
{
CIDR* address = NULL;
char* good_address_str = "fe80::5ab0:35ff:fef2:9365";
address = cidr_from_str(good_address_str);
ck_assert_int_eq(is_ipv6_link_local(address), RESULT_SUCCESS);
cidr_free(address);
char* bad_address_str = "2001:db8::2";
address = cidr_from_str(bad_address_str);
ck_assert_int_eq(is_ipv6_link_local(address), RESULT_FAILURE);
cidr_free(address);
}
END_TEST
START_TEST (test_is_valid_intf_address)
{
char* good_address_str_v4 = "192.0.2.5/24";
CIDR* good_address_v4 = cidr_from_str(good_address_str_v4);
ck_assert_int_eq(is_valid_intf_address(good_address_v4, good_address_str_v4, NO_LOOPBACK), RESULT_SUCCESS);
cidr_free(good_address_v4);
char* good_address_str_v6 = "2001:db8:a:b::14/64";
CIDR* good_address_v6 = cidr_from_str(good_address_str_v6);
ck_assert_int_eq(is_valid_intf_address(good_address_v6, good_address_str_v6, NO_LOOPBACK), RESULT_SUCCESS);
cidr_free(good_address_v6);
}
END_TEST
START_TEST (test_is_any_host)
{
char* good_address_str_v4 = "192.0.2.1/25";
CIDR* good_address_v4 = cidr_from_str(good_address_str_v4);
ck_assert_int_eq(is_any_host(good_address_v4), RESULT_SUCCESS);
cidr_free(good_address_v4);
char* good_address_str_v6 = "2001:db8:aff::1/64";
CIDR* good_address_v6 = cidr_from_str(good_address_str_v6);
ck_assert_int_eq(is_any_host(good_address_v6), RESULT_SUCCESS);
cidr_free(good_address_v6);
char* bad_address_str_v4 = "192.0.2.0/24";
CIDR* bad_address_v4 = cidr_from_str(bad_address_str_v4);
ck_assert_int_eq(is_any_host(bad_address_v4), RESULT_FAILURE);
cidr_free(bad_address_v4);
char* bad_address_str_v6 = "2001:db8::/32";
CIDR* bad_address_v6 = cidr_from_str(bad_address_str_v6);
ck_assert_int_eq(is_any_host(bad_address_v6), RESULT_FAILURE);
cidr_free(bad_address_v6);
}
END_TEST
START_TEST (test_is_any_net)
{
char* good_address_str_v4 = "192.0.2.0/25";
CIDR* good_address_v4 = cidr_from_str(good_address_str_v4);
ck_assert_int_eq(is_any_net(good_address_v4), RESULT_SUCCESS);
cidr_free(good_address_v4);
char* good_address_str_v6 = "2001:db8:aff::/64";
CIDR* good_address_v6 = cidr_from_str(good_address_str_v6);
ck_assert_int_eq(is_any_net(good_address_v6), RESULT_SUCCESS);
cidr_free(good_address_v6);
char* bad_address_str_v4 = "192.0.2.33/24";
CIDR* bad_address_v4 = cidr_from_str(bad_address_str_v4);
ck_assert_int_eq(is_any_net(bad_address_v4), RESULT_FAILURE);
cidr_free(bad_address_v4);
char* bad_address_str_v6 = "2001:db8::1/32";
CIDR* bad_address_v6 = cidr_from_str(bad_address_str_v6);
ck_assert_int_eq(is_any_net(bad_address_v6), RESULT_FAILURE);
cidr_free(bad_address_v6);
}
END_TEST
START_TEST (test_is_ipv4_range)
{
ck_assert_int_eq(is_ipv4_range("192.0.2.0-192.0.2.10", 0, 1), RESULT_SUCCESS);
ck_assert_int_eq(is_ipv4_range("192.0.2.-", 0, 1), RESULT_FAILURE);
ck_assert_int_eq(is_ipv4_range("192.0.2.99-192.0.2.11", 0, 1), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_ipv4_range_prefix)
{
ck_assert_int_eq(is_ipv4_range("192.0.2.0-192.0.2.10", 24, 1), RESULT_SUCCESS);
ck_assert_int_eq(is_ipv4_range("10.0.1.1-10.0.2.1", 24, 1), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_ipv6_range)
{
ck_assert_int_eq(is_ipv6_range("2001:db8::1-2001:db8::20", 0, 1), RESULT_SUCCESS);
ck_assert_int_eq(is_ipv6_range("2001:-", 0, 1), RESULT_FAILURE);
ck_assert_int_eq(is_ipv6_range("2001:db8::99-2001:db8:1", 0, 1), RESULT_FAILURE);
}
END_TEST
START_TEST (test_is_ipv6_range_prefix)
{
ck_assert_int_eq(is_ipv6_range("2001:db8::1-2001:db8::20", 64, 1), RESULT_SUCCESS);
ck_assert_int_eq(is_ipv6_range("2001:db8:aaaa::1-2001:db8:bbbb::1", 64, 1), RESULT_FAILURE);
}
END_TEST
Suite *ipaddrcheck_suite(void)
{
Suite *s = suite_create("ipaddrcheck");
/* Core test case */
TCase *tc_core = tcase_create("Core");
tcase_add_test(tc_core, test_is_valid_address);
tcase_add_test(tc_core, test_is_ipv4_cidr);
tcase_add_test(tc_core, test_is_ipv4_single);
tcase_add_test(tc_core, test_is_ipv6_cidr);
tcase_add_test(tc_core, test_is_ipv6_single);
tcase_add_test(tc_core, test_is_any_cidr);
tcase_add_test(tc_core, test_is_any_single);
tcase_add_test(tc_core, test_is_ipv4);
tcase_add_test(tc_core, test_is_ipv4_host);
tcase_add_test(tc_core, test_is_ipv4_net);
tcase_add_test(tc_core, test_is_ipv4_broadcast);
tcase_add_test(tc_core, test_is_ipv4_multicast);
tcase_add_test(tc_core, test_is_ipv4_loopback);
tcase_add_test(tc_core, test_is_ipv4_link_local);
tcase_add_test(tc_core, test_is_ipv4_rfc1918);
tcase_add_test(tc_core, test_is_ipv6);
tcase_add_test(tc_core, test_is_ipv6_host);
tcase_add_test(tc_core, test_is_ipv6_net);
tcase_add_test(tc_core, test_is_ipv6_multicast);
tcase_add_test(tc_core, test_is_ipv6_link_local);
tcase_add_test(tc_core, test_is_valid_intf_address);
tcase_add_test(tc_core, test_is_any_host);
tcase_add_test(tc_core, test_is_any_net);
tcase_add_test(tc_core, test_is_ipv4_range);
suite_add_tcase(s, tc_core);
return(s);
}
int main (void)
{
int number_failed;
Suite *s = ipaddrcheck_suite();
SRunner *sr = srunner_create(s);
srunner_run_all(sr, CK_NORMAL);
number_failed = srunner_ntests_failed(sr);
srunner_free (sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}