http://qs321.pair.com?node_id=164281

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


Hi Monks,

Is there any module for calculating ip addresses?
Something like:
  • given a start ip and end ip, output all the valid ip addresses in between.
  • given a ip range calculate the netmask, network and broadcast addresses (something like ipcalc).

    I right now need only the first function.
    I searched CPAN and found Net::IPv4Addr, but its not what i want.
    Hell. i even sat down to write the function, but it takes
    an amazing amount of time to output addresses between say 172.16.0.1 - 172.17.3.10
    And i'm too ashamed to post it here! :)
    --
    arc_of_descent

  • Replies are listed 'Best First'.
    Re: ip address calculations
    by lhoward (Vicar) on May 06, 2002 at 13:30 UTC
      Net::Netmask is what you need. Can do all the IP/network manipulations you want....
    Re: ip address calculations
    by tachyon (Chancellor) on May 06, 2002 at 11:57 UTC

      Socket the inet() functions and pack and unpack can do the first job. This takes under a second to run:

      use Socket; my $begin = "172.16.0.1"; my $end = "172.17.3.10"; my $ip = unpack N, inet_aton($begin); my $ip_end = unpack N, inet_aton($end); while ( $ip <= $ip_end ) { print inet_ntoa(pack N,$ip), "\n"; $ip++; }

      NetAddr::IP does the rest.

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print


        Yes! Very Interesting
        Thanx

        But i want to neglect ip addresses which are network or broadcast addresses.
        The above code prints out 172.16.2.0, 172.16.2.255, etc.
        I really want this functionality for users who are supposed
        to allocate ip addresses from a pool which they have defined
        using start and end ip addresses.
        I guess i'll have to put additional code to neglect
        the network and broadcast addresses.

        Thanx a lot!

        --
        arc_of_descent

    Re: ip address calculations
    by ariels (Curate) on May 06, 2002 at 11:45 UTC

      For your first code, Perl 5.6.1 lets you do this kind of niftiness:

      my ($s,$e) = unpack 'N2',1.2.3.4 . 1.2.4.2; printf("%vd\n",pack 'N',$_) for ($s..$e)
      If you use this code, though (complete with whitespace sensitivity that makes Python look like a Good Idea), you might well be shot. Replace the unpacks with a more direct translation of dotted quadruplets into ints, e.g.
      sub ip_to_num { my $ip = shift; my $n; $n = $n*256+$_ for (split /\./,$ip); $n }

      For the second question (and, indeed, for the first), it would be best to post some code, or at the very least some sample input/output.

        my ($s,$e) = unpack 'N2',172.16.0.1 . 172.17.0.0; printf("%vd\n",pack 'N',$_) for ($s..$e) __DATA__ Range iterator outside integer range at test.pl line 2.

        This will fail on "real" addresses (that exceed integer range) as shown.

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print