summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rw-r--r--src/Makefile.am2
-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.h40
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/check_ipaddrcheck.c85
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);