#!/usr/bin/perl # Script for listing the IP addresses contained in a CIDR netblock. # Originally written to help someone out at work. # Copyright Rayner Lucas 2005-2018. use Getopt::Long; use Net::CIDR qw(:all); use strict; use warnings; my $VERSION = 1.0; # Options my $number_opt = ''; my $range_opt = ''; my $list_opt = ''; my $help_opt = ''; my $version_opt = ''; GetOptions( 'number' => \$number_opt, 'range' => \$range_opt, 'list' => \$list_opt, 'help' => \$help_opt, 'version' => \$version_opt ); # If no options given, assume --range. if (!$number_opt && !$range_opt && !$list_opt && !$help_opt && !$version_opt) { $range_opt = 'true'; } my $help_text = < 255)) { fail_validation("Invalid address or netmask. Use cidr2range --help for help."); } } } if (!defined($mask) || $mask !~ /^\d+$/) { fail_validation("Invalid address or netmask. Use cidr2range --help for help."); } # Check that the address is valid. if (!cidrvalidate("$w.$x.$y.$z")) { fail_validation("Address specified was not valid. Use cidr2range --help for help."); } # Check netmask is within the limits of mathematical possibility. if ($mask < 0 || $mask > 32) { fail_validation("Netmask must be a number from 0 to 32. Use cidr2range --help for help."); } # Right, lets get to work. if ($number_opt) { my $num = 2**(32 - $mask); print "$num address" . ($num != 1 ? "es" : '') . ".\n"; } my @cidr_list = ("$w.$x.$y.$z/$mask"); my @range_list = cidr2range(@cidr_list); if ($range_opt) { print "Address range: " . $range_list[0] . "\n"; } if ($list_opt) { # Find the start address in the netblock and store it in $w, $x, $y, $z. my @addresses = split(/\-/, $range_list[0]); my @octets = split(/\./, $addresses[0]); $w = $octets[0]; $x = $octets[1]; $y = $octets[2]; $z = $octets[3]; # Count up through the addresses and print each one. for (my $count = 2**(32 - $mask); $count > 0; $count--) { # If the other error checks work properly, this error should # never happen. if ($w > 255) { fail_validation("Invalid address/mask specified: leftmost octet would be greater than 255. Use cidr2range --help for help."); } print "$w.$x.$y.$z\n"; $z++; if ($z > 255) { $y++; $z = 0; } if ($y > 255) { $x++; $y = 0; } if ($x > 255) { $w++; $x = 0; } } } exit(0); =head1 NAME cidr2range - convert CIDR notation to a range or list of IP addresses. =head1 SYNOPSIS B I<[OPTIONS]> I
BI =head1 DESCRIPTION This command converts an address block in CIDR notation (address/netmask) into a range, list, or number of IP addresses. Options are: =over 4 =item B<-l, --list> list all IP addresses in the given CIDR block, one per line. =item B<-n, --number> print the number of IP addresses in the given CIDR block. =item B<-r, --range> print the range of IP addresses for the given CIDR block. =item B<-h, --help> display help text and exit. =item B<-v, --version> display version information and exit. =back The B<--list>, B<--number>, and B<--range> options can be combined, so specifying all three will cause the command to print the number of addresses, the range of addresses, and all the individual IP addresses for the specified block. If no options are given, B<--range> is assumed. =head1 EXAMPLES =over 4 =item cidr2range -l 192.168.1.2/30 Prints the list of IP addresses from 192.168.1.0 to 192.168.1.3, one address per line. =back =head1 README Converts CIDR notation (e.g. 192.168.1.1/23) to a list or range of IP addresses. =head1 PREREQUISITES This script requires the C and C modules. It also uses the C and C pragmas. =head1 COPYRIGHT Copyright Rayner Lucas, 2005-2010. This program is free software. You may copy or redistribute it under the same terms as Perl itself. =pod OSNAMES any =pod SCRIPT CATEGORIES Networking =cut