Paranoid
view release on metacpan or search on metacpan
lib/Paranoid/Network/IPv4.pm view on Meta::CPAN
use 5.008;
use strict;
use warnings;
use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS);
use base qw(Exporter);
use Paranoid;
use Paranoid::Debug qw(:all);
use Paranoid::Network::Socket;
my @base = qw(ipv4NetConvert ipv4NetIntersect);
my @constants = qw(MAXIPV4CIDR IPV4REGEX IPV4CIDRRGX IPV4BASE IPV4BRDCST
IPV4MASK);
my @ipv4sort = qw(ipv4NumSort ipv4StrSort ipv4PackedSort);
($VERSION) = ( q$Revision: 2.10 $ =~ /(\d+(?:\.\d+)+)/sm );
@EXPORT = @base;
@EXPORT_OK = ( @base, @constants, @ipv4sort );
%EXPORT_TAGS = (
all => [@EXPORT_OK],
base => [@base],
constants => [@constants],
ipv4Sort => [@ipv4sort],
);
use constant MAXIPV4CIDR => 32;
use constant IPV4REGEX =>
qr/(?:(?:25[0-5]|2[0-4][0-9]|1?\d\d?)\.){3}(?:25[0-5]|2[0-4][0-9]|1?\d\d?)/s;
use constant IPV4CIDRRGX =>
qr#@{[ IPV4REGEX ]}/(?:(?:3[0-2]|[12]?\d)|@{[ IPV4REGEX ]})#s;
use constant FULLMASK => 0xffffffff;
use constant IPV4BASE => 0;
use constant IPV4BRDCST => 1;
use constant IPV4MASK => 2;
#####################################################################
#
# Module code follows
#
#####################################################################
sub ipv4NetConvert {
# Purpose: Takes a string representation of an IPv4 network
# address and returns a list containing the binary
# network address, broadcast address, and netmask.
# Also allows for a plain IP being passed, in which
# case it only returns the binary IP.
# Returns: Array, empty on errors
# Usage: @network = ipv4NetConvert($netAddr);
my $netAddr = shift;
my ( $bnet, $bmask, $t, @rv );
subPreamble( PDLEVEL1, '$', $netAddr );
# Extract net address, mask
if ( defined $netAddr ) {
($t) = ( $netAddr =~ m#^(@{[ IPV4CIDRRGX ]}|@{[ IPV4REGEX ]})$#s )[0];
( $bnet, $bmask ) = split m#/#s, $t if defined $t;
}
if ( defined $bnet and length $bnet ) {
# First, convert $bnet to see if we have a valid IP address
$bnet = unpack 'N', inet_aton($bnet);
if ( defined $bnet and length $bnet ) {
# Save our network address
push @rv, $bnet;
if ( defined $bmask and length $bmask ) {
# Convert netmask
$bmask =
$bmask !~ /^\d+$/s ? unpack 'N', inet_aton($bmask)
: $bmask <= MAXIPV4CIDR
? FULLMASK - ( ( 2**( MAXIPV4CIDR - $bmask ) ) - 1 )
: undef;
if ( defined $bmask and length $bmask ) {
# Apply the mask to the base address
$rv[IPV4BASE] = $rv[IPV4BASE] & $bmask;
# Calculate and save our broadcast address
push @rv, $bnet | ( $bmask ^ FULLMASK );
# Save our mask
push @rv, $bmask;
} else {
pdebug( 'invalid netmask passed', PDLEVEL1 );
}
}
} else {
pdebug( 'failed to convert IPv4 address', PDLEVEL1 );
}
} else {
pdebug( 'failed to extract an IPv4 address', PDLEVEL1 );
}
subPostamble( PDLEVEL1, '@', @rv );
return @rv;
}
sub ipv4NetIntersect {
# Purpose: Tests whether network address ranges intersect
# Returns: Integer, denoting whether an intersection exists, and what
# kind:
#
# -1: destination range encompasses target range
# 0: both ranges do not intersect at all
# 1: target range encompasses destination range
#
# Usage: $rv = ipv4NetIntersect($net1, $net2);
( run in 0.510 second using v1.01-cache-2.11-cpan-71847e10f99 )