summaryrefslogtreecommitdiff
path: root/src/iptest.c
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@baturin.org>2013-05-25 21:58:25 -0700
committerDaniil Baturin <daniil@baturin.org>2013-05-25 21:58:25 -0700
commitaa7c28da716b15d8220c2af6b9448e033b176b98 (patch)
tree724b5d579b90390513e793c6549973cf2a061c9d /src/iptest.c
parenta95eae0bfe26c20be3fd84871ce14c861d505c19 (diff)
downloadipaddrcheck-aa7c28da716b15d8220c2af6b9448e033b176b98.tar.gz
ipaddrcheck-aa7c28da716b15d8220c2af6b9448e033b176b98.zip
Fix previous commit.
TODO: Get some sleep.
Diffstat (limited to 'src/iptest.c')
-rw-r--r--src/iptest.c264
1 files changed, 212 insertions, 52 deletions
diff --git a/src/iptest.c b/src/iptest.c
index 5087736..c2a7266 100644
--- a/src/iptest.c
+++ b/src/iptest.c
@@ -19,99 +19,259 @@
*
*/
+#include <errno.h>
#include "config.h"
#include "iptest.h"
static const struct option options[] =
{
- { "is-valid", required_argument, NULL, 'a' },
- { "is-ipv4", required_argument, NULL, 'b' },
- { "is-ipv4-host", required_argument, NULL, 'c'},
- { "is-ipv4-net", required_argument, NULL, 'd'},
- { "is-ipv6", required_argument, NULL, 'g' },
- { "is-ipv6-net", required_argument, NULL, 'G' },
- { NULL, no_argument, NULL, 0 }
+ { "is-valid", no_argument, NULL, 'a' },
+ { "has-mask", no_argument, NULL, 'b' },
+ { "is-ipv4", no_argument, NULL, 'c' },
+ { "is-ipv4-cidr", no_argument, NULL, 'd' },
+ { "is-ipv4-single", no_argument, NULL, 'e' },
+ { "is-ipv4-host", no_argument, NULL, 'f' },
+ { "is-ipv4-net", no_argument, NULL, 'g' },
+ { "is-ipv4-broadcast", no_argument, NULL, 'h' },
+ { "is-ipv4-multicast", no_argument, NULL, 'i' },
+ { "is-ipv4-loopback", no_argument, NULL, 'j' },
+ { "is-ipv4-link-local", no_argument, NULL, 'k' },
+ { "is-ipv4-rfc1918", no_argument, NULL, 'l' },
+ { "is-ipv6", no_argument, NULL, 'm' },
+ { "is-ipv6-cidr", no_argument, NULL, 'n' },
+ { "is-ipv6-single", no_argument, NULL, 'o' },
+ { "is-ipv6-host", no_argument, NULL, 'p' },
+ { "is-ipv6-net", no_argument, NULL, 'r' },
+ { "is-ipv6-multicast", no_argument, NULL, 's' },
+ { "is-ipv6-link-local", no_argument, NULL, 't' },
+ { "is-valid-intf-address", no_argument, NULL, 'u' },
+ { "version", no_argument, NULL, 'z' },
+ { NULL, no_argument, NULL, 0 }
};
-void help(void)
-{
- static char *message = \
-"--is-valid STR Check if STR is a valid IPv4 or IPv6 address\n\
- or subnet\n\
---is-ipv4 STR Check if STR is a valid IPv4 address with mask\n";
-
- printf("%s", message);
-}
+/* Auxillary functions */
+static void print_help(void);
+static void print_version(void);
int main(int argc, char* argv[])
{
- char *address_str = "";
- int action = 0;
+ char *address_str = ""; /* IP address string obtained from arguments */
+ int action = 0; /* Action associated with given check option */
+ int* actions; /* Array of all given actions */
+ int action_count = 0; /* Actions array size */
+
+ int option_index = 0; /* Number of the current option for getopt call */
+ int optc; /* Option character for getopt call */
+
+ /* Parse options, convert to action codes, store in array */
- int option_index = 0;
- char c;
- int option_count = 0;
+ /* Try to allocate memory for the actions array, abort if fail */
+ actions = (int*)calloc(argc, sizeof(int));
+ if( errno == ENOMEM )
+ {
+ fprintf(stderr, "Error: could not allocate memory!\n");
+ return(EXIT_FAILURE);
+ }
- while( (c = getopt_long(argc, argv, "abcd?", options, &option_index)) != -1 )
+ while( (optc = getopt_long(argc, argv, "abcdv?", options, &option_index)) != -1 )
{
- switch(c)
+ switch(optc)
{
case 'a':
action = IS_VALID;
- address_str = optarg;
break;
case 'b':
- action = IS_IPV4;
- address_str = optarg;
+ action = HAS_MASK;
break;
case 'c':
- action = IS_IPV4_HOST;
- address_str = optarg;
+ action = IS_IPV4;
break;
case 'd':
+ action = IS_IPV4_CIDR;
+ break;
+ case 'e':
+ action = IS_IPV4_SINGLE;
+ break;
+ case 'f':
+ action = IS_IPV4_HOST;
+ break;
+ case 'g':
action = IS_IPV4_NET;
- address_str = optarg;
+ case 'h':
+ action = IS_IPV4_BROADCAST;
break;
- case 'I':
+ case 'i':
+ action = IS_IPV4_MULTICAST;
+ break;
+ case 'j':
+ action = IS_IPV4_LOOPBACK;
+ break;
+ case 'k':
+ action = IS_IPV4_LINKLOCAL;
+ break;
+ case 'l':
+ action = IS_IPV4_RFC1918;
+ break;
+ case 'm':
action = IS_IPV6;
- address_str = optarg;
+ break;
+ case 'n':
+ action = IS_IPV6_CIDR;
+ break;
+ case 'o':
+ action = IS_IPV6_SINGLE;
+ break;
+ case 'p':
+ action = IS_IPV6_HOST;
+ break;
+ case 'r':
+ action = IS_IPV6_NET;
+ break;
+ case 's':
+ action = IS_IPV6_MULTICAST;
+ break;
+ case 't':
+ action = IS_IPV6_LINKLOCAL;
+ break;
+ case 'u':
+ action = IS_VALID_INTF_ADDR;
break;
case '?':
+ print_help();
+ return(0);
+ case 'z':
+ print_version();
+ return(0);
default:
- fprintf(stderr, "Invalid option\n");
+ fprintf(stderr, "Error: invalid option\n");
break;
}
- option_count++;
+
+ action_count = optind-2;
+ actions[action_count] = action;
}
- if( option_count != 1 )
+ /* Get non-option arguments */
+ if( (argc - optind) == 1 )
+ {
+ address_str = argv[optind];
+ printf("%s\n", address_str);
+ }
+ else
{
- fprintf(stderr, "Wrong options number, exactly one option expected!\n");
- help();
- return(1);
+ printf("Error: wrong number of arguments, one argument required!\n");
+ return(EXIT_FAILURE);
}
CIDR *address;
address = cidr_from_str(address_str);
- int result = EXIT_FAILURE;
+ int result = RESULT_SUCCESS;
+
+ /* Check if the address is valid at all,
+ if not there is no point in going further */
+ if( is_valid_address(address) != RESULT_SUCCESS )
+ {
+ return(EXIT_FAILURE);
+ }
- switch(action)
+ printf("action_count: %d\n", action_count);
+ while( (action_count >= 0) && (result == RESULT_SUCCESS) )
{
- case IS_VALID:
- result = is_valid_address(address);
- break;
- case IS_IPV4:
- result = is_ipv4(address);
- break;
- case IS_IPV4_HOST:
- result = is_ipv4_host(address);
- break;
- case IS_IPV4_NET:
- result = is_ipv4_net(address);
- break;
+ switch(actions[action_count])
+ {
+ case IS_VALID:
+ result = is_valid_address(address);
+ break;
+ case HAS_MASK:
+ result = has_mask(address_str);
+ break;
+ case IS_IPV4:
+ result = is_ipv4(address);
+ break;
+ case IS_IPV4_CIDR:
+ 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 */
+ break;
+ case IS_IPV4_HOST:
+ result = is_ipv4_host(address);
+ printf("rsult %d\n", result);
+ break;
+ case IS_IPV4_NET:
+ /* XXX: Should we fail this check for single addresses? */
+ result = is_ipv4_net(address);
+ break;
+ case IS_IPV4_BROADCAST:
+ result = is_ipv4_broadcast(address);
+ break;
+ case IS_IPV4_MULTICAST:
+ result = is_ipv4_multicast(address);
+ break;
+ case IS_IPV4_LOOPBACK:
+ result = is_ipv4_loopback(address);
+ break;
+ case IS_IPV4_LINKLOCAL:
+ result = is_ipv4_link_local(address);
+ break;
+ case IS_IPV4_RFC1918:
+ result = is_ipv4_rfc1918(address);
+ break;
+ case IS_IPV6:
+ result = is_ipv6(address);
+ break;
+ case IS_IPV6_HOST:
+ result = is_ipv6_host(address);
+ break;
+ case IS_IPV6_NET:
+ result = is_ipv6_net(address);
+ break;
+ }
+ printf("action: %d\n", actions[action_count]);
+ action_count--;
}
- return(result);
+ /* Clean up */
+ free(actions);
+ cidr_free(address);
+
+ if( result == RESULT_SUCCESS )
+ {
+ return(EXIT_SUCCESS);
+ }
+ else
+ {
+ return(EXIT_FAILURE);
+ }
+}
+
+/*
+ * Print help, no other side effects
+ */
+void print_help(void)
+{
+ static const char *message = \
+"--is-valid STR Check if STR is a valid IPv4 or IPv6 address\n\
+ or subnet\n\
+--is-ipv4 STR Check if STR is a valid IPv4 address with mask\n";
+
+ printf("%s", message);
+}
+
+/*
+ * Print version information, no other side effects
+ */
+void print_version(void)
+{
+ printf("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
+ printf("Copyright (C) Free Software Foundation, Inc.\n\
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
+This is free software: you are free to change and redistribute it.\n\
+There is NO WARRANTY, to the extent permitted by law.\n");
}