summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@baturin.org>2013-06-02 05:53:13 -0700
committerDaniil Baturin <daniil@baturin.org>2013-06-02 05:53:13 -0700
commit83cf00e0117c4b41001a56f93cf4beae720cc6a0 (patch)
treef9be4ab75a0a7df11f1a35103987a83f218bb13a
parenta64770739a28b05f6c5a033a3f2085959662b447 (diff)
downloadipaddrcheck-83cf00e0117c4b41001a56f93cf4beae720cc6a0.tar.gz
ipaddrcheck-83cf00e0117c4b41001a56f93cf4beae720cc6a0.zip
Add interface address validation support.
Fix IPv4 CIDR regex to support one-digit mask properly.
-rw-r--r--src/ipaddrcheck.c21
-rw-r--r--src/ipaddrcheck_functions.c25
-rw-r--r--src/ipaddrcheck_functions.h7
-rw-r--r--tests/check_ipaddrcheck.c24
4 files changed, 72 insertions, 5 deletions
diff --git a/src/ipaddrcheck.c b/src/ipaddrcheck.c
index 8b99b23..cc0a26b 100644
--- a/src/ipaddrcheck.c
+++ b/src/ipaddrcheck.c
@@ -47,6 +47,8 @@
#define IS_VALID_INTF_ADDR 220
#define IS_ANY_CIDR 230
#define IS_ANY_SINGLE 240
+#define ALLOW_LOOPBACK 250
+#define NO_ACTION 500
static const struct option options[] =
{
@@ -71,7 +73,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' },
+ { "allow-loopback", no_argument, NULL, 'C' },
{ "version", no_argument, NULL, 'z' },
{ "help", no_argument, NULL, '?' },
{ NULL, no_argument, NULL, 0 }
@@ -91,6 +93,9 @@ int main(int argc, char* argv[])
int option_index = 0; /* Number of the current option for getopt call */
int optc; /* Option character for getopt call */
+ int allow_loopback = NO_LOOPBACK; /* Allow IPv4 loopback in --is-valid-intf-address */
+
+
/* Parse options, convert to action codes, store in array */
/* Try to allocate memory for the actions array, abort if fail */
@@ -101,7 +106,7 @@ int main(int argc, char* argv[])
return(EXIT_FAILURE);
}
- while( (optc = getopt_long(argc, argv, "acdefghijklmnoprstuzAB?", options, &option_index)) != -1 )
+ while( (optc = getopt_long(argc, argv, "acdefghijklmnoprstuzABC?", options, &option_index)) != -1 )
{
switch(optc)
{
@@ -169,6 +174,10 @@ int main(int argc, char* argv[])
case 'B':
action = IS_ANY_SINGLE;
break;
+ case 'C':
+ allow_loopback = LOOPBACK_ALLOWED;
+ action = NO_ACTION;
+ break;
case '?':
print_help();
return(0);
@@ -273,6 +282,14 @@ int main(int argc, char* argv[])
case IS_ANY_SINGLE:
result = is_any_single(address_str);
break;
+ case IS_VALID_INTF_ADDR:
+ printf("allow_loopback: %d\n", allow_loopback);
+ result = is_valid_intf_address(address, address_str, allow_loopback);
+ break;
+ case NO_ACTION:
+ break;
+ default:
+ break;
}
printf("action: %d\n", actions[action_count]);
action_count--;
diff --git a/src/ipaddrcheck_functions.c b/src/ipaddrcheck_functions.c
index dfcdcfb..0240914 100644
--- a/src/ipaddrcheck_functions.c
+++ b/src/ipaddrcheck_functions.c
@@ -48,7 +48,7 @@ int is_ipv4_cidr(char* address_str)
const char *error;
int erroffset;
- re = pcre_compile("^((([1-9]\\d{0,2}|0)\\.){3}([1-9]\\d{0,2}|0)(\\/([1-3][0-9]|0)))$",
+ re = pcre_compile("^((([1-9]\\d{0,2}|0)\\.){3}([1-9]\\d{0,2}|0)\\/([1-9]\\d*|0))$",
0, &error, &erroffset, NULL);
rc = pcre_exec(re, NULL, address_str, strlen(address_str), 0, 0, offsets, 1);
@@ -443,3 +443,26 @@ int is_ipv6_link_local(CIDR *address)
return(result);
}
+/* Is it an address that can belong an interface? */
+int is_valid_intf_address(CIDR *address, char* address_str, int allow_loopback)
+{
+ int result;
+
+ if( (is_ipv4_broadcast(address) == RESULT_FAILURE) &&
+ (is_ipv4_multicast(address) == RESULT_FAILURE) &&
+ (is_ipv6_multicast(address) == RESULT_FAILURE) &&
+ ((is_ipv4_loopback(address) == RESULT_FAILURE) || (allow_loopback == LOOPBACK_ALLOWED)) &&
+ (cidr_equals(address, cidr_from_str(IPV6_LOOPBACK)) != 0) &&
+ (cidr_equals(address, cidr_from_str(IPV4_UNSPECIFIED)) != 0) &&
+ (cidr_contains(cidr_from_str(IPV4_THIS), address) != 0) &&
+ (is_any_cidr(address_str) == RESULT_SUCCESS) )
+ {
+ result = RESULT_SUCCESS;
+ }
+ else
+ {
+ result = RESULT_FAILURE;
+ }
+
+ return(result);
+}
diff --git a/src/ipaddrcheck_functions.h b/src/ipaddrcheck_functions.h
index 34bb18e..67cc410 100644
--- a/src/ipaddrcheck_functions.h
+++ b/src/ipaddrcheck_functions.h
@@ -37,11 +37,17 @@
#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_UNSPECIFIED "0.0.0.0/0"
+#define IPV4_THIS "0.0.0.0/8"
#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"
+#define IPV6_LOOPBACK "::1/128"
+
+#define NO_LOOPBACK 0
+#define LOOPBACK_ALLOWED 1
int is_ipv4_cidr(char* address_str);
int is_ipv4_single(char* address_str);
@@ -63,3 +69,4 @@ 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);
+int is_valid_intf_address(CIDR *address, char* address_str, int allow_loopback);
diff --git a/tests/check_ipaddrcheck.c b/tests/check_ipaddrcheck.c
index ebf99b2..9315bec 100644
--- a/tests/check_ipaddrcheck.c
+++ b/tests/check_ipaddrcheck.c
@@ -43,8 +43,11 @@ END_TEST
START_TEST (test_is_ipv4_cidr)
{
- char* good_address_str = "192.0.2.1/21";
- ck_assert_int_eq(is_ipv4_cidr(good_address_str), RESULT_SUCCESS);
+ 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);
@@ -339,6 +342,22 @@ START_TEST (test_is_ipv6_link_local)
}
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
+
Suite *ipaddrcheck_suite(void)
{
@@ -366,6 +385,7 @@ Suite *ipaddrcheck_suite(void)
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);
suite_add_tcase(s, tc_core);