cjaar has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, Am new to perl, am trying some scaling test for static nat on a router. Given max static nat supported, i want to generate ip address (w/o using cpan modules). eg: 2000 max(static nats) want to hv 1 to 1 static nat, starting from 1.1.1.1-255, 2.1-255 .... till max. for simplicity i dont want to use 0 ip address, otherwise is also fine. i got the logic something like 1.1.n3.n4 max =2000( divide this by 255 to get how many times n3 hs to loop, if not exaclty divisible, mod to get the extra numbers to loop for n4) loop n4 from 1 to 255, reset to 1 and increment n3++ till i reach max... tried some code..but am not getting it right. a quick code would be apperciated. thx, cjaar

Replies are listed 'Best First'.
Re: generate range of IP address
by Fletch (Bishop) on May 21, 2007 at 13:24 UTC

    *sigh*. Fish.

    use constant NUM_TO_MAKE => 2000; my @addrs; my $made = 0; OUTER: for my $i ( 1 .. 254 ) { for my $j ( 1 .. 254 ) { for my $k ( 1 .. 254 ) { for my $l ( 1 .. 254 ) { push @addrs, "$i.$j.$k.$l"; last OUTER if ++$made >= NUM_TO_MAKE; } } } }

    And yes, the 254s are intentional. I don't think you want to be generating probable broadcast addresses; if you do, season to taste.

      hmm thx, just to understand ur code OUTER: is to comeout of all the for loops ? i tried something like "last if() " i missed the made also, to keep the how many i made :(

        OUTER is a label, as shown in the documentation for last and in perlsyn (see the section "Compound Statements").

Re: generate range of IP address
by Zaxo (Archbishop) on May 21, 2007 at 14:27 UTC

    I hope you're permitted to use modules that ship with perl. Socket has what you need.

    You should use numeric addresses instead of dotted quads for range calculations. That will save you fooling around with nested loops. Socket::inet_aton() and Socket::inet_ntoa() will convert between the two.

    Update: Here is a shorty that prints the quads in a range of 2000 above a base address, omitting network addresses.

    use Socket qw/inet_aton inet_ntoa/; my $base = '1.1.1.1'; my $nbase = unpack 'N',inet_aton($base); my @quads = map { inet_ntoa(pack('N', $_)) } grep { $_ % 256 } $nbase .. 2000 + $nbase; { local $, = ' '; print @quads, $/; }
    To omit broadcast, too, you just need to and the grep condition with  ($_ % 256) != 255. Added unpack/pack to fix byte order for arithmetic. The numeric representation for inet_* is in network order.

    After Compline,
    Zaxo

      I suggested as much in the CB but the OP persisted in wanting nested loops (hence the fish). Skipping network and/or broadcast addresses is a little trickier when you do it that way, though. Of course the simplest thing is to just install something like Net::Netmask and be done with it (or to just copy the guts into your source if you have to be moduleinstallaphobic for whatever reason; that also was suggested in the CB).

Re: generate range of IP address
by cengineer (Pilgrim) on May 21, 2007 at 13:27 UTC
    Can you post the code that you tried? Your question is a little fuzzy...