/* program that prints IP address ranges */ #include "prips.h" #include #include #include #include #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] \n"\ " -c print range in CIDR notation\n"\ " -d set the delimeter 'x' where 0 =< x =< 255\n"\ " -f set the format of addresses (hex, dec, or dot)\n"\ " -i set the increment to 'x'\n"\ " -e 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); }