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

Hi all!

Ive got a problem performing IP address operations using Net::IP.

Here is what i need: I have to translate an IP address (for example, 10.0.1.3) into an integer value (for example, 167772419), and translate an integer value to an ip (167772419 to 10.0.1.3). I did:

use Net::IP qw(:PROC); my $ipaddr = '10.0.1.3'; my $ip = new Net::IP($ipaddr) or die (Net::IP::Error()); my $int = $ip->intip(); print "Integer value of IP $ipaddr: $int\n";

And it prints:
Integer value of IP 10.0.1.3: 167772419

Which is correct. But the reverse operation:

use Net::IP qw(:PROC); + + my $intaddr = 167772419; my $binaddr; eval{ $binaddr = ip_inttobin($intaddr); }; die "Error: $@" if($@); !defined($binaddr) and print "Binary not defined\n"; print "Binary value of integer $intaddr: $binaddr\n";


Prints:

Binary not defined
Binary value of integer 167772419:

Thus, i dont know how to transform an integer into a binary, and a binary into an ip, which is the only way i currently know.

Any idea on how to deal with this?
Thank you

Replies are listed 'Best First'.
Re: IP operation trouble
by gellyfish (Monsignor) on Jan 12, 2005 at 14:07 UTC

    It's probably a lot easier than this:

    use Socket; + my $ip = '127.0.0.1'; + my $int = ip_to_int($ip); + print $int,"\n"; + print int_to_ip($int); + sub int_to_ip { my ($int) = @_; return inet_ntoa(pack('N', $int)); } + sub ip_to_int { my ($ip) = @_; return unpack('N', inet_aton($ip)); }
    Note the use of pack and unpack here.

    /J\

Re: IP operation trouble
by borisz (Canon) on Jan 12, 2005 at 14:16 UTC
    without testing, your my $binaddr inside the eval is out of scope. try:
    my $intaddr = 167772419; my $binaddr; eval{ $binaddr = ip_inttobin($intaddr); }; die "Error: $@" if($@);
    Boris
Re: IP operation trouble
by naChoZ (Curate) on Jan 12, 2005 at 14:08 UTC

    It's because $binaddr only lives within the eval block. Ditch the eval block and you should be ok.

    Update:
    I fiddled with it a little just because I've never really messed with binary operations.

    #!/usr/local/bin/perl -w use strict; use Net::IP qw/:PROC/; # # create your Net::IP object # my $ip_addr = Net::IP->new( "192.168.0.20" ); # # $ip_int becomes a Math::BigInt object # my $ip_int = ip_bintoint( $ip_addr->binip ); print "IP Address: ", $ip_addr->ip, "\nBin: ", $ip_addr->binip, "\nInt: ", $ip_int->numify(), "\n"; # # turn the Integer into a vanilla scalar # my $int_ip = $ip_int->numify(); # # Now start from the integer and go backwards # my $bin_from_int = sprintf( "%b", $int_ip); my $ip_from_bin = ip_bintoip( $bin_from_int, 4); print "\n\nInt: $int_ip\n", "Bin: $bin_from_int\n", "IP: ", $ip_from_bin, "\n";

    --
    "This alcoholism thing, I think it's just clever propaganda produced by people who want you to buy more bottled water." -- pedestrianwolf

      Hi there, The purpose of the eval block was to ensure there was not any error in the function, without it there happens the same. Thanks anyway
Re: IP operation trouble
by DrHyde (Prior) on Jan 13, 2005 at 10:14 UTC
    I'm not familiar with that module, so here's what I would have written:
    sub ipv4_to_int { my $int = 0; foreach (split(/\./, $_[0]) { $int <<= 8; $int += $_; } return $int; } sub int_to_ipv4 { my $ip = ''; my $int = shift; while($int) { $ip = ($int & 255).".$ip"; $int >>= 8; } chop($ip); return $ip; }
    Untested, season with error-checking to taste.

    You hardly ever see the >> and << bit-shifting operators in perl, and bitwise AND (&) is rare too, but they behave exactly the same as they do in C.

    And while I normally disapprove of "magic numbers" like the 8 and 255, I think that in this case their meaning is sufficiently obvious.