From 038dcd982d442d894c467bf0d91cdaf421e87185 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Mon, 27 May 2013 02:37:44 -0700 Subject: 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. --- src/ipaddrcheck_functions.c | 369 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 src/ipaddrcheck_functions.c (limited to 'src/ipaddrcheck_functions.c') diff --git a/src/ipaddrcheck_functions.c b/src/ipaddrcheck_functions.c new file mode 100644 index 0000000..1006383 --- /dev/null +++ b/src/ipaddrcheck_functions.c @@ -0,0 +1,369 @@ +/* + * ipaddrcheck_functions.c: functions for iptest IPv4/IPv6 validator + * + * Maintainer: Daniil Baturin + * + * Copyright (C) 2013 SO3Group + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + * + */ + +#include "ipaddrcheck_functions.h" + +/* + * Address string functions + * + * Note that they perform format check only + * and must not be used to deermine if it's + * a valid address, only what type of address + * format it is. + * + * The only reason they exist is that libcidr + * is very liberal on its input format and + * doesn't provide any information on what + * the format was. + */ + +/* Does it have mask? */ +int has_mask(char* address_str) +{ + int result; + char *hasslash = strchr(address_str, '/'); + + if( hasslash != NULL ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Does it look like IPv4 CIDR (e.g. 192.0.2.1/24)? */ +int is_ipv4_cidr(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}/\\d{1,2}$", + 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); +} + +/* 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 + */ + +/* Does it look like a valid address of any protocol? */ +int is_valid_address(CIDR *address) +{ + int result; + + if( cidr_get_proto(address) != INVALID_PROTO ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it a correct IPv4 host or subnet address + with or without net mask */ +int is_ipv4(CIDR *address) +{ + int result; + + if( cidr_get_proto(address) == CIDR_IPV4 ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it a correct IPv4 host (i.e. not network) address? */ +int is_ipv4_host(CIDR *address) +{ + int result; + + if( (cidr_get_proto(address) == CIDR_IPV4) && + ((cidr_equals(address, cidr_addr_network(address)) < 0) || + (cidr_get_pflen(address) == 32)) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it a correct IPv4 network address? */ +int is_ipv4_net(CIDR *address) +{ + int result; + + if( (cidr_get_proto(address) == CIDR_IPV4) && + (cidr_equals(address, cidr_addr_network(address)) == 0) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it an IPv4 broadcast address? */ +int is_ipv4_broadcast(CIDR *address) +{ + int result; + + if( cidr_equals(address, cidr_addr_broadcast(address)) == 0 ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it an IPv4 multicast address? */ +int is_ipv4_multicast(CIDR *address) +{ + int result; + + if( (cidr_get_proto(address) == CIDR_IPV4) && + (cidr_contains(cidr_from_str(IPV4_MULTICAST), address) == 0) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it an IPv4 loopback address? */ +int is_ipv4_loopback(CIDR *address) +{ + int result; + + if( (cidr_get_proto(address) == CIDR_IPV4) && + (cidr_contains(cidr_from_str(IPV4_LOOPBACK), address) == 0) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it an IPv4 link-local address? */ +int is_ipv4_link_local(CIDR *address) +{ + int result; + + if( (cidr_get_proto(address) == CIDR_IPV4) && + (cidr_contains(cidr_from_str(IPV4_LINKLOCAL), address) == 0) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* Is it an IPv4 RFC1918 address? */ +int is_ipv4_rfc1918(CIDR *address) +{ + int result; + + if( (cidr_get_proto(address) == CIDR_IPV4) && + ( (cidr_contains(cidr_from_str(IPV4_RFC1918_A), address) == 0) || + (cidr_contains(cidr_from_str(IPV4_RFC1918_B), address) == 0) || + (cidr_contains(cidr_from_str(IPV4_RFC1918_C), address) == 0) ) ) + { + result = RESULT_SUCCESS; + } + else + { + result = RESULT_FAILURE; + } + + return(result); +} + +/* is it a correct IPv6 host or subnet address, + with or withour mask */ +int is_ipv6(CIDR *address) +{ + 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) +{ + 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) +{ + 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); +} + -- cgit v1.2.3