tags:

views:

289

answers:

5

I need to generate a list of IP-addresses (IPv4) in Perl. I have start and end addresses, for example 1.1.1.1 and 1.10.20.30. How can I print all the addresses inbetween?

+2  A: 

It's all in how you code it. This is the fastest way I know.

my $start = 0x010101; # 1.1.1
my $end   = 0x0a141e; # 10.20.30

for my $ip ( $start..$end ) { 
    my @ip = ( $ip >> 16 & 0xff
             , $ip >>  8 & 0xff
             , $ip       & 0xff
             );
    print join( '.', 1, @ip ), "\n";
}
Axeman
+3  A: 

Use Net::IP's looping feature:

The + operator is overloaded in order to allow looping though a whole range of IP addresses:

Sinan Ünür
+2  A: 

TMTOWTDI:

sub inc_ip { $_[0] = pack "N", 1 + unpack "N", $_[0] }
my $start = 1.1.1.1;
my $end = 1.10.20.30;
for ( $ip = $start; $ip le $end; inc_ip($ip) ) {
    printf "%vd\n", $ip;
}
ysth
For those too lazy to google it - "Theres More Than One Way To Do It"
Rob Cowell
Does this method prevent your numbers from exceeding 255? sorry i'm having a hard time reading it, I'm not familiar with unpack and well for some reason all search engines on my netwok seem to be down (can't get to bing, yahoo, or google, in no particular order)
onaclov2000
@onaclov2000 http://p3rl.org/pack
Brad Gilbert
@onaclov2000: perldoc -f pack, perldoc -f unpack, perldoc perlpacktutYes, it prevents them from exceeding 255.
ysth
@ysth I read that as "funpack" lol
Cyclone
+3  A: 

Use Net::IP. From the CPAN documentation:

my $ip = new Net::IP ('195.45.6.7 - 195.45.6.19') || die;
# Loop
do {
    print $ip->ip(), "\n";
} while (++$ip);

This approach is more flexible because Net::IP accepts CIDR notation e.g. 193.0.1/24 and also supports IPv6.

Edit: if you are working with netblocks specifically, you might investigate Net::Netmask.

rjh
I would prefer these URLs: http://search.cpan.org/perldoc/Net::IP and http://search.cpan.org/perldoc/Net::Netmask
Brad Gilbert
@Sinan I felt that my answer added enough additional information to be worth posting. The counter question: why -shouldn't- I provide helpful information to the OP? How does it harm anyone?
rjh
A: 

I am able to print the ip addresses using the following 2 methods, but I am not able to save the individual elemens into an array.

For eg I am not able to :

sub inc_ip { $[0] = pack "N", 1 + unpack "N", $[0] } my $start = 1.1.1.1; my $end = 1.10.20.30; for ( $ip = $start; $ip le $end; inc_ip($ip) ) { printf "%vd\n", $ip; ---- This works push (@array, $ip) ; ---does not . How can I do this ?

}

Similarly

my $ip = new Net::IP ('195.45.6.7 - 195.45.6.19') || die; -- this works my $ip = new Net::IP ('$start - $end') || die; -- This does not work

Loop

do { print $ip->ip(), "\n"; push (@array,$ip->ip()) ; ---This does not work . } while (++$ip);