package Cpanel::BitConvert; # cpanel - Cpanel/BitConvert.pm Copyright(c) 2011 cPanel, Inc. # All rights Reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited # This module is in the public domain. use strict; sub convert_number_ipbits { my $n = shift; return ( split //, unpack 'B*', pack 'N', $n ); } sub convert_bits_number { my $bits = shift; my $n = join '', @$bits; return unpack 'N', pack 'B*', '0' x ( 32 - length $n ) . $n; } sub convert_number_ip { my $n = shift; return join '.', unpack 'C*', pack 'N', $n; } sub convert_ip_number { my $ip = shift; return unpack "N", pack "C*", split /\./, $ip; } sub do_chunk { my ( $chunks, $fbits, $lbits ) = @_; my ( @prefix, $idx1, $idx2, $size ); $idx1 = 0; $idx1++ while ( $idx1 <= $#$fbits and $$fbits[$idx1] eq $$lbits[$idx1] ); @prefix = @$fbits[ 0 .. $idx1 - 1 ]; $idx2 = $#$fbits; $idx2-- while ( $idx2 >= $idx1 and $$fbits[$idx2] eq '0' and $$lbits[$idx2] eq '1' ); if ( $idx2 >= $idx1 ) { $size = $#$fbits - $idx1; do_chunk( $chunks, $fbits, [ @prefix, ( split //, '0' . '1' x $size ) ] ); do_chunk( $chunks, [ @prefix, ( split //, '1' . '0' x $size ) ], $lbits ); } else { $size = $#$fbits - $idx2; push @$chunks, [ ( convert_bits_number [ @prefix, ( split //, '0' x $size ) ] ), @$fbits - $size ]; } } sub convert_iprange_cidrs { my $ip0 = shift; my $ip1 = shift; my ( @chunks, @fbits, @lbits ); my $ip0_number = convert_ip_number $ip0; my $ip1_number = convert_ip_number $ip1; return if ( $ip0_number > $ip1_number ); @fbits = convert_number_ipbits $ip0_number; @lbits = convert_number_ipbits $ip1_number; do_chunk( \@chunks, \@fbits, \@lbits ); my @ipl; for (@chunks) { my ( $n, $m ) = @$_; push( @ipl, convert_number_ip($n) . "/$m" ); } return @ipl; } sub mask2cidr { my ($mask) = @_; my ( @d, $n, $bits ); if ( $mask eq '0.0.0.0' ) { return '0'; } @d = split /\./, $mask; $n = ( ( ( ( ( $d[0] * 256 ) + $d[1] ) * 256 ) + $d[2] ) * 256 ) + $d[3]; $bits = 32; while ( ( $n % 2 ) == 0 ) { $n >>= 1; $bits -= 1; } return $bits; } 1;