Reputation: 141
Is there a Perl function that, given an IP address and subnet mask, can return the CIDR notation of the subnet the IP belongs to?
For example, assuming I have the IP 192.168.1.23
with subnet mask 255.255.255.0
, I want to obtain the value 192.168.1.0/24
.
Or if I have 192.168.1.23
with subnet mask 255.255.255.224
I want 192.168.1.0/27
and so on.
I could eventually build a function that does so, but I find hard to believe there isn't something that does this already.
Upvotes: 2
Views: 2127
Reputation: 126732
I recommend that you use the NetAddr::IP
module. It's a simple matter of constructing an object with the required IP address and net mask and calling the network
method on it
It looks like this
use strict;
use warnings 'all';
use feature 'say';
use NetAddr::IP;
say make_cidr(qw/ 192.168.1.23 255.255.255.0 /);
say make_cidr(qw/ 192.168.1.23 255.255.255.224 /);
sub make_cidr {
my ($addr, $mask) = @_;
my $net = NetAddr::IP->new($addr, $mask);
$net->network;
}
192.168.1.0/24
192.168.1.0/27
Upvotes: 9
Reputation: 46187
If you want a prepackaged solution, you can use the addrandmask2cidr
function from Net::CIDR.
If you want to roll your own, the basic algorithm is to count the number of set bits in the mask to get the value after the slash (e.g., 255.255.255.0 is 11111111.11111111.11111111.00000000 in binary, 24 bits set, therefore CIDR /24) and do a logical-and (&
) of the address with the mask to get the network's base address.
Upvotes: 4