views:

1186

answers:

3

How do I create valid IP ranges given an IP address and Subnet mask in Perl? I understand the concept of generating the IP ranges but need help writing in Perl. For example, if I AND the IP address and subnet mask I get the subnet number. Adding 1 to this number should give me the first valid IP. If I invert the subnet mask and OR with the subnet number, I should get the broadcast address. Subtracting 1 from it should give the last valid IP address.

+3  A: 

See perldoc perlop for information about the bitwise operators (they are the same as in most other C-like languages):

  • & is bitwise AND
  • | is bitwise OR
  • ^ is bitwise XOR
  • >> is right-shift
  • << is left-shift

However, if you really want to do some work with network blocks and IP addresses (as opposed to simply answering a homework assignment - although I'm curious what course you'd be taking that used Perl), you can avoid reinventing the wheel by turning to CPAN:

Ether
A: 

Quick & dirty way to find the subnet mask:

use Socket;
my $subnet_mask = inet_ntoa(inet_aton($ip_str) & inet_aton($mask_str)):
IggShaman
I think what you were going for there was to get the network address from a client address and the netmask, but the code as written is wrong.
hobbs
This code gets your subnet's base ip address. Add 1 to get the first valid ip address.
IggShaman
A: 

If you want to play with bitwise operators yourself, it becomes this:

#!/usr/bin/perl
use strict;
use warnings;
use Socket;

my $ip_address = '192.168.0.15';
my $netmask = 28;

my $ip_address_binary = inet_aton( $ip_address );
my $netmask_binary    = ~pack("N", (2**(32-$netmask))-1);

my $network_address    = inet_ntoa( $ip_address_binary & $netmask_binary );
my $first_valid        = inet_ntoa( pack( 'N', unpack('N', $ip_address_binary & $netmask_binary ) + 1 ));
my $last_valid         = inet_ntoa( pack( 'N', unpack('N', $ip_address_binary | ~$netmask_binary ) - 1 ));
my $broadcast_address  = inet_ntoa( $ip_address_binary | ~$netmask_binary );

print $network_address, "\n";
print $first_valid, "\n";
print $last_valid, "\n";
print $broadcast_address, "\n";

exit;

With Net::Netmask it's easier to understand:

#!/usr/bin/perl
use strict;
use warnings;
use Net::Netmask;

my $ip_address = '192.168.0.15';
my $netmask = 28;

my $block = Net::Netmask->new( "$ip_address/$netmask" );

my $network_address    = $block->base();
my $first_valid        = $block->nth(1);
my $last_valid         = $block->nth( $block->size - 2 );
my $broadcast_address  = $block->broadcast();

print $network_address, "\n";
print $first_valid, "\n";
print $last_valid, "\n";
print $broadcast_address, "\n";

exit;
depesz