MINOR: contrib: make the iprange tool grep for addresses

The iprange tool is handy for transforming network range formats, but
it's common to need a tool for running quick checks on the output.
The tool now supports a list of addresses on the command line, and it
will only output those which match. It's absolutely inefficient but is
handy for debugging.
This commit is contained in:
Willy Tarreau 2012-12-13 00:11:02 +01:00
parent 0cae4b3218
commit 04281bd1ad
1 changed files with 23 additions and 9 deletions

View File

@ -38,13 +38,13 @@ static const char *get_ipv4_addr(unsigned int addr)
/* print all networks present between address <low> and address <high> in /* print all networks present between address <low> and address <high> in
* cidr format, followed by <eol>. * cidr format, followed by <eol>.
*/ */
static void convert_range(unsigned int low, unsigned int high, const char *eol) static void convert_range(unsigned int low, unsigned int high, const char *eol, const char *pfx)
{ {
int bit; int bit;
if (low == high) { if (low == high) {
/* single value */ /* single value */
printf("%s%s\n", get_ipv4_addr(low), eol); printf("%s%s%s%s\n", pfx?pfx:"", pfx?" ":"", get_ipv4_addr(low), eol);
return; return;
} }
else if (low > high) { else if (low > high) {
@ -55,7 +55,7 @@ static void convert_range(unsigned int low, unsigned int high, const char *eol)
if (low == high + 1) { if (low == high + 1) {
/* full range */ /* full range */
printf("0.0.0.0/0%s\n", eol); printf("%s%s0.0.0.0/0%s\n", pfx?pfx:"", pfx?" ":"", eol);
return; return;
} }
//printf("low=%08x high=%08x\n", low, high); //printf("low=%08x high=%08x\n", low, high);
@ -65,7 +65,7 @@ static void convert_range(unsigned int low, unsigned int high, const char *eol)
/* enlarge mask */ /* enlarge mask */
if (low & (1 << bit)) { if (low & (1 << bit)) {
/* can't aggregate anymore, dump and retry from the same bit */ /* can't aggregate anymore, dump and retry from the same bit */
printf("%s/%d%s\n", get_ipv4_addr(low), 32-bit, eol); printf("%s%s%s/%d%s\n", pfx?pfx:"", pfx?" ":"", get_ipv4_addr(low), 32-bit, eol);
low += (1 << bit); low += (1 << bit);
} }
else { else {
@ -82,7 +82,7 @@ static void convert_range(unsigned int low, unsigned int high, const char *eol)
if ((high - low + 1) & (1 << bit)) { if ((high - low + 1) & (1 << bit)) {
/* large bit accepted, dump and go on from the same bit */ /* large bit accepted, dump and go on from the same bit */
//printf("max: %08x/%d\n", low, 32-bit); //printf("max: %08x/%d\n", low, 32-bit);
printf("%s/%d%s\n", get_ipv4_addr(low), 32-bit, eol); printf("%s%s%s/%d%s\n", pfx?pfx:"", pfx?" ":"", get_ipv4_addr(low), 32-bit, eol);
low += (1 << bit); low += (1 << bit);
} }
else { else {
@ -96,7 +96,7 @@ static void convert_range(unsigned int low, unsigned int high, const char *eol)
static void usage(const char *argv0) static void usage(const char *argv0)
{ {
fprintf(stderr, fprintf(stderr,
"Usage: %s < iplist.csv\n" "Usage: %s [<addr> ...] < iplist.csv\n"
"\n" "\n"
"This program reads lines starting by two IP addresses and outputs them with\n" "This program reads lines starting by two IP addresses and outputs them with\n"
"the two IP addresses replaced by a netmask covering the range between these\n" "the two IP addresses replaced by a netmask covering the range between these\n"
@ -105,6 +105,9 @@ static void usage(const char *argv0)
"stripped, and lines beginning with a sharp character ('#') are ignored. The\n" "stripped, and lines beginning with a sharp character ('#') are ignored. The\n"
"IP addresses may be either in the dotted format or represented as a 32-bit\n" "IP addresses may be either in the dotted format or represented as a 32-bit\n"
"integer value in network byte order.\n" "integer value in network byte order.\n"
"\n"
"For each optional <addr> specified, only the network it belongs to is returned,\n"
"prefixed with the <addr> value.\n"
"\n", argv0); "\n", argv0);
} }
@ -114,9 +117,9 @@ main(int argc, char **argv)
int l, lnum; int l, lnum;
char *lb, *le, *hb, *he, *err; char *lb, *le, *hb, *he, *err;
struct in_addr src_addr, dst_addr; struct in_addr src_addr, dst_addr;
unsigned int sa, da; unsigned int sa, da, ta;
if (argc > 1) { if (argc > 1 && *argv[1] == '-') {
usage(argv[0]); usage(argv[0]);
exit(1); exit(1);
} }
@ -182,6 +185,17 @@ main(int argc, char **argv)
sa = htonl(src_addr.s_addr); sa = htonl(src_addr.s_addr);
da = htonl(dst_addr.s_addr); da = htonl(dst_addr.s_addr);
convert_range(sa, da, he); if (argc > 1) {
for (l = 1; l < argc; l++) {
if (inet_pton(AF_INET, argv[l], &dst_addr) <= 0)
continue;
ta = htonl(dst_addr.s_addr);
if ((sa <= ta && ta <= da) || (da <= ta && ta <= sa))
convert_range(sa, da, he, argv[l]);
}
}
else {
convert_range(sa, da, he, NULL);
}
} }
} }