From a6e903164d1ac975dac03aa67bdf54502ac7f328 Mon Sep 17 00:00:00 2001 From: Othmar Gsenger Date: Sat, 15 Jan 2011 23:22:34 +0000 Subject: added netmask support --- local/netmask.pm | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 local/netmask.pm diff --git a/local/netmask.pm b/local/netmask.pm new file mode 100644 index 0000000..8a651b0 --- /dev/null +++ b/local/netmask.pm @@ -0,0 +1,63 @@ +package local::netmask; +require Exporter; +use strict; +use local::db; +use base "Exporter"; + +sub new +{ + my $invocant = shift; + my $class = ref($invocant) || $invocant; + # my $self = $class->SUPER::new(@_); + my $self=bless {}, $class; + return $self; +} + +sub check_ip_in_subnet +{ + my $self=shift; + my ($ip,$subnet_ip,$netmask) = @_; # example 192.168.1.1, 192.168.1.0, 24 -> returns true (1) + if ($ip =~ /\./ and $subnet_ip =~ /\./) + { + #ipv4 + + my $ip_int = $self->v4_array_to_int(split(/\./,$ip)); + my $subnet_ip_int = $self->v4_array_to_int(split(/\./,$subnet_ip)); + + my @netmask_ary; + for my $i (0..3) + { + my $bits = $netmask - $i*8; + $bits = 8 if $bits >8; + $bits = 0 if $bits <0; + my $unset = 8-$bits; + push @netmask_ary,256- (2** $unset ) ; + } + my $netmask_int = $self->v4_array_to_int(@netmask_ary); + return 1 if ( ($ip_int & $netmask_int) == ($subnet_ip_int & $netmask_int)); + return 0; + } elsif ($ip =~ /\:/ and $subnet_ip =~ /\:/) { + #ipv6 + die "Only Subnet lengths of a multiple of 16 are currently supported" if $netmask % 16; + my @ip = split(/\:/,$ip); + my @netmask = split(/\:/,$subnet_ip); + for my $i (1..$netmask /16) + { + my $ip_part = shift @ip; + $ip_part = 0 if not $ip_part; + my $netmask_part = shift @netmask; + $netmask_part = 0 if not $netmask_part; + return 0 if $netmask_part != $ip_part; + } + return 1; + } else { + return; # not matching or unknown + } +} + +sub v4_array_to_int +{ + my $self=shift; + my @array=@_; + return unpack( "N", pack( "C4",@array ) ); +} -- cgit v1.2.3