diff options
author | Daniil Baturin <daniil@baturin.org> | 2013-05-27 02:37:44 -0700 |
---|---|---|
committer | Daniil Baturin <daniil@baturin.org> | 2013-05-27 02:37:44 -0700 |
commit | 038dcd982d442d894c467bf0d91cdaf421e87185 (patch) | |
tree | a5bf6eb9cf498dc7088819682bd6fad5aa0a0170 | |
parent | 069e78d6788b0e10272747f5d773ce9a167e90bc (diff) | |
download | ipaddrcheck-038dcd982d442d894c467bf0d91cdaf421e87185.tar.gz ipaddrcheck-038dcd982d442d894c467bf0d91cdaf421e87185.zip |
Again, multiple enhancements.
* IPv6 feature set nearly complete.
* Test suite expanded to cover all but a few functions.
* Source files renamed according to the new project name,
.h is now .h, implementations are moved to .c
* Something else.
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/ipaddrcheck.c (renamed from src/iptest.c) | 46 | ||||
-rw-r--r-- | src/ipaddrcheck_functions.c (renamed from src/iptest.h) | 153 | ||||
-rw-r--r-- | src/ipaddrcheck_functions.h | 40 | ||||
-rw-r--r-- | tests/Makefile.am | 2 | ||||
-rw-r--r-- | tests/check_ipaddrcheck.c | 85 |
7 files changed, 272 insertions, 59 deletions
diff --git a/configure.ac b/configure.ac index 8cc478c..595491b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,7 @@ AC_INIT([iptest], [0.1], [daniil@baturin.org]) -AC_PROG_CC +#AC_PROG_CC +AM_PROG_CC_C_O AC_CHECK_HEADER(pcre.h) AC_CHECK_HEADER(libcidr.h) diff --git a/src/Makefile.am b/src/Makefile.am index f30438f..6612d3e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ AM_CFLAGS = --pedantic -Wall -Werror -std=c99 -O2 AM_LDFLAGS = -ipaddrcheck_SOURCES = iptest.c iptest.h +ipaddrcheck_SOURCES = ipaddrcheck.c ipaddrcheck_functions.c ipaddrcheck_LDFLAGS = -lcidr -lpcre bin_PROGRAMS = ipaddrcheck diff --git a/src/iptest.c b/src/ipaddrcheck.c index c618b20..929da6b 100644 --- a/src/iptest.c +++ b/src/ipaddrcheck.c @@ -21,7 +21,31 @@ #include <errno.h> #include "config.h" -#include "iptest.h" +#include "ipaddrcheck_functions.h" + +/* Option codes */ +#define IS_VALID 10 +#define IS_IPV4 20 +#define IS_IPV4_CIDR 30 +#define IS_IPV4_SINGLE 40 +#define IS_IPV4_HOST 50 +#define IS_IPV4_NET 60 +#define IS_IPV4_BROADCAST 70 +#define IS_IPV4_UNICAST 80 +#define IS_IPV4_MULTICAST 90 +#define IS_IPV4_RFC1918 100 +#define IS_IPV4_LOOPBACK 110 +#define IS_IPV4_LINKLOCAL 120 +#define IS_IPV6 130 +#define IS_IPV6_CIDR 140 +#define IS_IPV6_SINGLE 150 +#define IS_IPV6_HOST 160 +#define IS_IPV6_NET 170 +#define IS_IPV6_UNICAST 180 +#define IS_IPV6_MULTICAST 190 +#define IS_IPV6_LINKLOCAL 200 +#define HAS_MASK 210 +#define IS_VALID_INTF_ADDR 220 static const struct option options[] = { @@ -45,6 +69,7 @@ static const struct option options[] = { "is-ipv6-multicast", no_argument, NULL, 's' }, { "is-ipv6-link-local", no_argument, NULL, 't' }, { "is-valid-intf-address", no_argument, NULL, 'u' }, + { "legacy", no_argument, NULL, 'w' }, { "version", no_argument, NULL, 'z' }, { NULL, no_argument, NULL, 0 } }; @@ -73,7 +98,7 @@ int main(int argc, char* argv[]) return(EXIT_FAILURE); } - while( (optc = getopt_long(argc, argv, "abcdv?", options, &option_index)) != -1 ) + while( (optc = getopt_long(argc, argv, "abcdefghijklmnoprstuz?", options, &option_index)) != -1 ) { switch(optc) { @@ -155,7 +180,6 @@ int main(int argc, char* argv[]) if( (argc - optind) == 1 ) { address_str = argv[optind]; - printf("%s\n", address_str); } else { @@ -193,11 +217,7 @@ int main(int argc, char* argv[]) result = is_ipv4_cidr(address_str); break; case IS_IPV4_SINGLE: - if( !(is_ipv4(address) && has_mask(address_str)) ) - { - result = RESULT_FAILURE; - } - /* No need to change it in case of success */ + result = is_ipv4_single(address_str); break; case IS_IPV4_HOST: result = is_ipv4_host(address); @@ -224,12 +244,22 @@ int main(int argc, char* argv[]) case IS_IPV6: result = is_ipv6(address); break; + case IS_IPV6_CIDR: + break; + case IS_IPV6_SINGLE: + break; case IS_IPV6_HOST: result = is_ipv6_host(address); break; case IS_IPV6_NET: result = is_ipv6_net(address); break; + case IS_IPV6_MULTICAST: + result = is_ipv6_multicast(address); + break; + case IS_IPV6_LINKLOCAL: + result = is_ipv6_link_local(address); + break; } printf("action: %d\n", actions[action_count]); action_count--; diff --git a/src/iptest.h b/src/ipaddrcheck_functions.c index f025911..1006383 100644 --- a/src/iptest.h +++ b/src/ipaddrcheck_functions.c @@ -1,5 +1,5 @@ /* - * ipaddrcheck.h: macros and functions for iptest IPv4/IPv6 validator + * ipaddrcheck_functions.c: functions for iptest IPv4/IPv6 validator * * Maintainer: Daniil Baturin <daniil at baturin dot org> * @@ -21,49 +21,7 @@ * */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <getopt.h> -#include <pcre.h> -#include <libcidr.h> - -#define INVALID_PROTO -1 - -/* Option codes */ -#define IS_VALID 10 -#define IS_IPV4 20 -#define IS_IPV4_CIDR 30 -#define IS_IPV4_SINGLE 40 -#define IS_IPV4_HOST 50 -#define IS_IPV4_NET 60 -#define IS_IPV4_BROADCAST 70 -#define IS_IPV4_UNICAST 80 -#define IS_IPV4_MULTICAST 90 -#define IS_IPV4_RFC1918 100 -#define IS_IPV4_LOOPBACK 110 -#define IS_IPV4_LINKLOCAL 120 -#define IS_IPV6 130 -#define IS_IPV6_CIDR 140 -#define IS_IPV6_SINGLE 150 -#define IS_IPV6_HOST 160 -#define IS_IPV6_NET 170 -#define IS_IPV6_UNICAST 180 -#define IS_IPV6_MULTICAST 190 -#define IS_IPV6_LINKLOCAL 200 -#define HAS_MASK 210 -#define IS_VALID_INTF_ADDR 220 - -#define RESULT_SUCCESS 1 -#define RESULT_FAILURE 0 - -#define IPV4_MULTICAST "224.0.0.0/4" -#define IPV4_LOOPBACK "127.0.0.0/8" -#define IPV4_LINKLOCAL "169.254.0.0/16" -#define IPV4_RFC1918_A "10.0.0.0/8" -#define IPV4_RFC1918_B "172.16.0.0/12" -#define IPV4_RFC1918_C "192.168.0.0/16" +#include "ipaddrcheck_functions.h" /* * Address string functions @@ -124,6 +82,32 @@ int is_ipv4_cidr(char* address_str) return(result); } +/* Is it a single dotted decimal address? */ +int is_ipv4_single(char* address_str) +{ + int result; + + int offsets[1]; + pcre *re; + int rc; + const char *error; + int erroffset; + + re = pcre_compile("^\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}$", + 0, &error, &erroffset, NULL); + rc = pcre_exec(re, NULL, address_str, strlen(address_str), 0, 0, offsets, 1); + + if( rc < 0 ) + { + result = RESULT_FAILURE; + } + else + { + result = RESULT_SUCCESS; + } + + return(result); +} /* * Address checking functions that rely on libcidr @@ -296,15 +280,90 @@ int is_ipv4_rfc1918(CIDR *address) with or withour mask */ int is_ipv6(CIDR *address) { - return RESULT_FAILURE; + int result; + + if( cidr_get_proto(address) == CIDR_IPV6 ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); } +/* Is it a correct IPv6 host address? */ int is_ipv6_host(CIDR *address) { - return RESULT_FAILURE; + int result; + + if( (cidr_get_proto(address) == CIDR_IPV6) && + ((cidr_equals(address, cidr_addr_network(address)) < 0) || + (cidr_get_pflen(address) == 128)) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); } +/* Is it a correct IPv6 network address? */ int is_ipv6_net(CIDR *address) { - return RESULT_FAILURE; + int result; + + if( (cidr_get_proto(address) == CIDR_IPV6) && + (cidr_equals(address, cidr_addr_network(address)) == 0) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it an IPv6 multicast address? */ +int is_ipv6_multicast(CIDR *address) +{ + int result; + + if( (cidr_get_proto(address) == CIDR_IPV6) && + (cidr_contains(cidr_from_str(IPV6_MULTICAST), address) == 0) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it an IPv6 link-local address? */ +int is_ipv6_link_local(CIDR *address) +{ + int result; + + if( (cidr_get_proto(address) == CIDR_IPV6) && + (cidr_contains(cidr_from_str(IPV6_LINKLOCAL), address) == 0) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); } + diff --git a/src/ipaddrcheck_functions.h b/src/ipaddrcheck_functions.h new file mode 100644 index 0000000..756a8f3 --- /dev/null +++ b/src/ipaddrcheck_functions.h @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <pcre.h> +#include <libcidr.h> + +#define INVALID_PROTO -1 + +#define RESULT_SUCCESS 1 +#define RESULT_FAILURE 0 + +#define IPV4_MULTICAST "224.0.0.0/4" +#define IPV4_LOOPBACK "127.0.0.0/8" +#define IPV4_LINKLOCAL "169.254.0.0/16" +#define IPV4_RFC1918_A "10.0.0.0/8" +#define IPV4_RFC1918_B "172.16.0.0/12" +#define IPV4_RFC1918_C "192.168.0.0/16" +#define IPV6_MULTICAST "ff00::/8" +#define IPV6_LINKLOCAL "fe80::/64" + +int has_mask(char* address_str); +int is_ipv4_cidr(char* address_str); +int is_ipv4_single(char* address_str); +int is_valid_address(CIDR *address); +int is_ipv4(CIDR *address); +int is_ipv4_host(CIDR *address); +int is_ipv4_net(CIDR *address); +int is_ipv4_broadcast(CIDR *address); +int is_ipv4_multicast(CIDR *address); +int is_ipv4_loopback(CIDR *address); +int is_ipv4_link_local(CIDR *address); +int is_ipv4_rfc1918(CIDR *address); +int is_ipv6(CIDR *address); +int is_ipv6_host(CIDR *address); +int is_ipv6_net(CIDR *address); +int is_ipv6_multicast(CIDR *address); +int is_ipv6_link_local(CIDR *address); + + diff --git a/tests/Makefile.am b/tests/Makefile.am index 0d76cc4..9b04635 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,5 +1,5 @@ TESTS = check_ipaddrcheck check_PROGRAMS = check_ipaddrcheck -check_ipaddrcheck_SOURCES = check_ipaddrcheck.c $(top_builddir)/src/iptest.h +check_ipaddrcheck_SOURCES = check_ipaddrcheck.c ../src/ipaddrcheck_functions.c check_ipaddrcheck_CFLAGS = @CHECK_CFLAGS@ check_ipaddrcheck_LDADD = -lcidr -lpcre @CHECK_LIBS@ diff --git a/tests/check_ipaddrcheck.c b/tests/check_ipaddrcheck.c index 246d445..60a64f9 100644 --- a/tests/check_ipaddrcheck.c +++ b/tests/check_ipaddrcheck.c @@ -1,5 +1,5 @@ #include <check.h> -#include "../src/iptest.h" +#include "../src/ipaddrcheck_functions.h" START_TEST (test_has_mask) { @@ -176,6 +176,84 @@ START_TEST (test_is_ipv4_rfc1918) } 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 + Suite *ipaddrcheck_suite(void) { @@ -194,6 +272,11 @@ Suite *ipaddrcheck_suite(void) 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); suite_add_tcase(s, tc_core); |