/* program that prints IP address ranges */
#include "prips.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "except.h"
typedef enum {
FORMAT_HEX = 0,
FORMAT_DEC = 1,
FORMAT_DOT = 2
} AddrFormat;
#define FORMATS "hex", "dec", "dot"
const char *MAINTAINER = "dan@vertekcorp.com";
const char *VERSION =
"\rprips 0.9.4\n"\
" \rThis program comes with NO WARRANTY,\n"\
" \rto the extent permitted by law.\n"\
" \rYou may redistribute copies under\n"\
" \rthe terms of the GNU General Public License.\n";
void usage(char *prog);
AddrFormat get_format(char *format);
int main(int argc, char *argv[])
{
char ch, *argstr = "d:f:i:e:cv";
unsigned long start = 0, end = 0, current;
int octet[4][256]; /* Holds all of the exceptions if -e is used */
int format = FORMAT_DOT; /* Dotted decimal by default */
int delimiter = 10; /* New line by default */
int increment = 1; /* Standard incrementer is one */
char *prefix, *offset;
/* flags */
int exception_flag = 0; /* If one, check for exclusions */
int print_as_cidr_flag= 0; /* If one, print range as addr/offset */
opterr = 0;
while ((ch = getopt(argc, argv, argstr)) != EOF) {
switch (ch) {
case 'c':
print_as_cidr_flag = 1;
break;
case 'd':
delimiter = atoi(optarg);
if(delimiter < 0 || delimiter > 255)
{
fprintf(stderr, "%s: delimiter must be between 0 and 255\n",
argv[0]);
exit(1);
}
break;
case 'f':
format = get_format(optarg);
break;
case 'i':
if((increment = atoi(optarg)) < 1)
{
fprintf(stderr, "%s: increment must be a positive integer\n",
argv[0]);
exit(1);
}
break;
case 'e':
set_exceptions(optarg, octet);
exception_flag = 1;
break;
case 'v':
printf("%s", VERSION);
exit(0);
case '?':
usage(argv[0]);
exit(1);
}
}
/*************************************************************/
/* Figure out what we have to work with. argc - optind is */
/* the number of arguments we have. If there is one argu- */
/* ment, we are dealing with CIDR, or a mistake. If ther */
/* are two arguments, we are dealing with start address and */
/* end address. We also make sure to test if the CIDR nota- */
/* tion is proper. */
/*************************************************************/
switch(argc - optind)
{
case 1: /* CIDR? */
prefix = strtok(argv[optind], "/");
if((offset = strtok(NULL, "/"))) /* CIDR */
{
start = numberize(prefix);
if(start == -1)
{
fprintf(stderr, "%s: bad IP address\n", argv[0]);
exit(1);
}
end = add_offset(prefix, atoi(offset));
}
else
{
usage(argv[0]);
exit(1);
}
break;
case 2: /* start address, end address */
start = numberize(argv[optind]);
end = numberize(argv[optind+1]);
if(start == -1 || end == -1)
{
fprintf(stderr, "%s: bad IP address\n", argv[0]);
exit(1);
}
break;
default:
usage(argv[0]);
exit(1);
}
/***************************************************************/
/* OK- at this point we have the start and end address. If */
/* the start is greater than the end, we exit with an error. */
/* Otherwise, we start printing addresses that are not part of */
/* the exception list, if one exists. */
/***************************************************************/
if(start > end)
{
fprintf(stderr,
"%s: start address must be smaller than end address\n",
argv[0]);
exit(1);
}
if(print_as_cidr_flag) /* print start - end as start/offset */
printf("%s%c", cidrize(start, end), delimiter);
else
{
for(current = start; current <= end; current += increment)
{ if(!exception_flag || !except(¤t, octet))
{
switch(format)
{
case FORMAT_HEX:
printf("%lx%c", current, delimiter);
break;
case FORMAT_DEC:
printf("%lu%c", current, delimiter);
break;
default:
printf("%s%c", denumberize(current),
delimiter);
break;
}
}
}
}
return(0);
} /* end main */
void usage(char *prog)
{
fprintf(stderr, "usage: %s [options] <start end | CIDR block>\n"\
" -c print range in CIDR notation\n"\
" -d <x> set the delimeter 'x' where 0 =< x =< 255\n"\
" -f <x> set the format of addresses (hex, dec, or dot)\n"\
" -i <x> set the increment to 'x'\n"\
" -e <x.x.x,x.x> e.g. -e ..4. will not print 192.168.4.[0-255]\n\n"\
" \rReport bugs to %s\n",
prog, MAINTAINER);
}
AddrFormat get_format(char *format)
{
char *list[] = {FORMATS};
int i;
for (i = 0; i < 3; i++)
if( strcmp(format, list[i]) == 0)
break;
return(i);
}
syntax highlighted by Code2HTML, v. 0.9.1