mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
465 lines
12 KiB
C
465 lines
12 KiB
C
/* -*- coding: utf-8 -*-
|
|
* ----------------------------------------------------------------------
|
|
* Copyright © 2009-2012, RedJack, LLC.
|
|
* All rights reserved.
|
|
*
|
|
* Please see the LICENSE.txt file in this distribution for license
|
|
* details.
|
|
* ----------------------------------------------------------------------
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <check.h>
|
|
#include <libcork/core.h>
|
|
|
|
#include "ipset/ipset.h"
|
|
|
|
|
|
#define IPV4_BIT_SIZE 32
|
|
#define IPV6_BIT_SIZE 128
|
|
|
|
|
|
/*-----------------------------------------------------------------------
|
|
* Iterators
|
|
*/
|
|
|
|
START_TEST(test_iterate_empty)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
struct ipset_iterator *it = ipset_iterate(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
fail_unless(it->finished,
|
|
"IP set should be empty");
|
|
ipset_iterator_free(it);
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_ipv4_iterate_01)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "192.168.0.1");
|
|
|
|
fail_if(ipset_ip_add(&set, &ip1),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == IPV4_BIT_SIZE,
|
|
"IP CIDR prefix 0 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 1 element");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_ipv4_iterate_network_01)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "192.168.0.0");
|
|
|
|
fail_if(ipset_ip_add_network(&set, &ip1, 31),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate_networks(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == 31,
|
|
"IP CIDR prefix 0 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 1 elements");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_ipv4_iterate_network_02)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "192.168.0.0");
|
|
|
|
fail_if(ipset_ip_add_network(&set, &ip1, 16),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate_networks(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == 16,
|
|
"IP CIDR prefix 0 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 1 elements");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_ipv4_iterate_network_03)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
/*
|
|
* If we add all of the IP addresses in a network individually, we
|
|
* should still get the network as a whole from the iterator.
|
|
*/
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "192.168.0.0");
|
|
|
|
struct cork_ip ip2;
|
|
cork_ip_init(&ip2, "192.168.0.1");
|
|
|
|
fail_if(ipset_ip_add(&set, &ip1),
|
|
"Element should not be present");
|
|
|
|
fail_if(ipset_ip_add(&set, &ip2),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate_networks(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == 31,
|
|
"IP CIDR prefix 0 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 1 elements");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_ipv6_iterate_01)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "fe80::1");
|
|
|
|
fail_if(ipset_ip_add(&set, &ip1),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == IPV6_BIT_SIZE,
|
|
"IP CIDR prefix 0 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 1 element");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_ipv6_iterate_network_01)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "fe80::");
|
|
|
|
fail_if(ipset_ip_add_network(&set, &ip1, 127),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate_networks(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == 127,
|
|
"IP CIDR prefix 0 doesn't match (%u)", it->cidr_prefix);
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 1 element");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_ipv6_iterate_network_02)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "fe80::");
|
|
|
|
fail_if(ipset_ip_add_network(&set, &ip1, 16),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate_networks(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == 16,
|
|
"IP CIDR prefix 0 doesn't match (%u)", it->cidr_prefix);
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 1 element");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_ipv6_iterate_network_03)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
/*
|
|
* If we add all of the IP addresses in a network individually, we
|
|
* should still get the network as a whole from the iterator.
|
|
*/
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "fe80::");
|
|
|
|
struct cork_ip ip2;
|
|
cork_ip_init(&ip2, "fe80::1");
|
|
|
|
fail_if(ipset_ip_add(&set, &ip1),
|
|
"Element should not be present");
|
|
|
|
fail_if(ipset_ip_add(&set, &ip2),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate_networks(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == 127,
|
|
"IP CIDR prefix 0 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 1 elements");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_generic_ip_iterate_01)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "0.0.0.0");
|
|
|
|
struct cork_ip ip2;
|
|
cork_ip_init(&ip2, "::");
|
|
|
|
struct ipset_iterator *it = ipset_iterate_networks(&set, false);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == 0,
|
|
"IP CIDR prefix 0 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_if(it->finished,
|
|
"IP set should have more than 1 element");
|
|
fail_unless(cork_ip_equal(&ip2, &it->addr),
|
|
"IP address 1 doesn't match");
|
|
fail_unless(it->cidr_prefix == 0,
|
|
"IP CIDR prefix 1 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 2 elements");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
START_TEST(test_generic_ip_iterate_02)
|
|
{
|
|
struct ip_set set;
|
|
ipset_init(&set);
|
|
|
|
/*
|
|
* These addresses are carefully constructed so that the same BDD
|
|
* variable assignments are used to store both, apart from the
|
|
* IPv4/v6 discriminator variable. The goal is get a BDD that has
|
|
* EITHER in the assignment for variable 0, but isn't simply the
|
|
* empty or full set.
|
|
*/
|
|
|
|
struct cork_ip ip1;
|
|
cork_ip_init(&ip1, "192.168.0.1"); /* 0xc0a80001 */
|
|
|
|
struct cork_ip ip2;
|
|
cork_ip_init(&ip2, "c0a8:0001::");
|
|
|
|
fail_if(ipset_ip_add(&set, &ip1),
|
|
"Element should not be present");
|
|
fail_if(ipset_ip_add_network(&set, &ip2, 32),
|
|
"Element should not be present");
|
|
|
|
struct ipset_iterator *it = ipset_iterate_networks(&set, true);
|
|
fail_if(it == NULL,
|
|
"IP set iterator is NULL");
|
|
|
|
fail_if(it->finished,
|
|
"IP set shouldn't be empty");
|
|
fail_unless(cork_ip_equal(&ip1, &it->addr),
|
|
"IP address 0 doesn't match");
|
|
fail_unless(it->cidr_prefix == 32,
|
|
"IP CIDR prefix 0 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_if(it->finished,
|
|
"IP set should have more than 1 element");
|
|
fail_unless(cork_ip_equal(&ip2, &it->addr),
|
|
"IP address 1 doesn't match");
|
|
fail_unless(it->cidr_prefix == 32,
|
|
"IP CIDR prefix 1 doesn't match");
|
|
|
|
ipset_iterator_advance(it);
|
|
fail_unless(it->finished,
|
|
"IP set should contain 2 elements");
|
|
|
|
ipset_iterator_free(it);
|
|
|
|
ipset_done(&set);
|
|
}
|
|
END_TEST
|
|
|
|
|
|
/*-----------------------------------------------------------------------
|
|
* Testing harness
|
|
*/
|
|
|
|
Suite *
|
|
ipset_suite()
|
|
{
|
|
Suite *s = suite_create("ipset");
|
|
|
|
TCase *tc_iterator = tcase_create("iterator");
|
|
tcase_add_test(tc_iterator, test_iterate_empty);
|
|
tcase_add_test(tc_iterator, test_ipv4_iterate_01);
|
|
tcase_add_test(tc_iterator, test_ipv4_iterate_network_01);
|
|
tcase_add_test(tc_iterator, test_ipv4_iterate_network_02);
|
|
tcase_add_test(tc_iterator, test_ipv4_iterate_network_03);
|
|
tcase_add_test(tc_iterator, test_ipv6_iterate_01);
|
|
tcase_add_test(tc_iterator, test_ipv6_iterate_network_01);
|
|
tcase_add_test(tc_iterator, test_ipv6_iterate_network_02);
|
|
tcase_add_test(tc_iterator, test_ipv6_iterate_network_03);
|
|
tcase_add_test(tc_iterator, test_generic_ip_iterate_01);
|
|
tcase_add_test(tc_iterator, test_generic_ip_iterate_02);
|
|
suite_add_tcase(s, tc_iterator);
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
int
|
|
main(int argc, const char **argv)
|
|
{
|
|
int number_failed;
|
|
Suite *suite = ipset_suite();
|
|
SRunner *runner = srunner_create(suite);
|
|
|
|
ipset_init_library();
|
|
|
|
srunner_run_all(runner, CK_NORMAL);
|
|
number_failed = srunner_ntests_failed(runner);
|
|
srunner_free(runner);
|
|
|
|
return (number_failed == 0)? EXIT_SUCCESS: EXIT_FAILURE;
|
|
}
|