#!/usr/bin/perl -w # addrand.pl - a simple utility to return a range of ip addresses, sequentially # or randomized, without any duplication. # # George Bakos alpinista@bigfoot.com # - Sept 2002 # # license terms - Use it, sell it, beat yourself over the head with it. I don't # care. My Perl is ugly; feel free to take credit for it. # # On a linux 2.4.18 K6-1.4G box w/512MB RAM & 256M swap, this script was able to # generate and randomize 98% of a /8 net block. I wouldn't recommend trying # a range as large as that if you expect to run any fat X apps at the same time. use Getopt::Std; use Socket; our ($opt_r, $opt_t) = (0,0); getopts('rt:'); $randomize = $opt_r; $addrspec = "$opt_t"; # expand any wildcards $addrspec =~ s/\*/0-255/g; # After converting asterisks, target spec can have address octets or octet # ranges, none greater than 255. if ($addrspec !~ /\b[0-9]{1,3}(-[0-9]{1,3})?\.[0-9]{1,3}(-[0-9]{1,3})?\.[0-9]{1,3}(-[0-9]{1,3})?\.[0-9]{1,3}(-[0-9]{1,3})?\b/) { usage() }; @pieces = split /[\.-]/, $addrspec; for $piece (@pieces) { if ($piece > 255) { usage() }; } # Do we have any ranges specified? Look for a hyphen. if ($addrspec =~ /-/) { @octets = split(/\./, $addrspec); my $num; # Examine each octet specified for a hyphen. When we find one, it's time to # build a list from the range specified for that octet. foreach $octet (@octets) { $num++; my $octnum = "octet$num"; if ($octet =~ /[0-9]{1,3}-[0-9{1,3}]/) { my (@range, $cnt); @range = split(/-/, $octet); for ($cnt = $range[0]; $cnt <= $range[1]; $cnt++) { push @$octnum, $cnt; } } else { push @$octnum, $octet; } } # Build new array of addresses from the lists of individual octet values. We use # inet_aton() to conserve precious RAM. @targets = (); foreach $octet1 (@octet1) { foreach $octet2 (@octet2) { foreach $octet3 (@octet3) { foreach $octet4 (@octet4) { #print join(".", $octet1, $octet2, $octet3, $octet4), "\n"; push @targets, inet_aton(join(".", $octet1, $octet2, $octet3, $octet4)); } } } } # If there is only one address specified, that is the entire array } else { @targets = ($addrspec); } # don't try to randomize unless there is more than one element if ($randomize && @targets > 1 ) { pullrand( \@targets ); } elsif (@targets > 1 ) { while ( $targets[0] ) { print STDOUT inet_ntoa(shift @targets), "\n"; } } else { print STDOUT "$addrspec\n"; } sub pullrand { my $array = shift; while ( @$array[0] ) { my $j = int rand ( @$array ); @$array[0,$j] = @$array[$j,0]; print STDOUT inet_ntoa(shift @$array), "\n"; } } sub usage { print STDERR "Usage: $0 [-r] -t
\n"; print STDERR "\t example: $0 -r -t 10.0.4-5.1-254\n\n"; exit }