in reply to calculate subnet help
That looks a whole lot harder than it has to be. For starters, I'm assuming that there's a reason you want to do this yourself, rather than just using one of the CPAN libraries, like NetAddr::IP.
If that's the case, the trick is just remembering that in the end, an IPv4 address or mask is really just a 32 bit int. Just use a little bit of shifting and splitting to roll your own inet_aton and inet_ntoa if you don't want to use the ones in Socket
sub my_inet_aton { my ($string) = @_; my ($a, $b, $c, $d) = split(/\./, $string); return ( ($a << 24) + ($b << 16) + ($c << 8) + ($d) ); } sub my_inet_ntoa { my ($ip) = @_; return ( (($ip & 0xFF000000) >> 24) . '.' . (($ip & 0xFF0000) >> 16) . '.' . (($ip & 0xFF00) >> 8) . '.' . ($ip & 0xFF) ); }
Then just use a bitwise AND between the mask and IP address to extract the subnet portion.
my $ipstring = '192.168.190.128'; my $maskstring = '255.255.255.0'; my $ip = my_inet_aton($ipstring); my $mask = my_inet_aton($maskstring); my $subnet = $ip & $mask; print "Subnet portion of ", $ipstring, "/", $maskstring, " is ", my_inet_ntoa($subnet), "\n";
The basic logic is the same for IPv6 addresses. However, a) parsing them is a little tricker with things like :: compact form, and b) they're 128 bits, so not all systems will be able to directly do bit masks on them. If there's any chance you need to handle v6 addresses, you're much better off using one of the pre-existing CPAN modules that will handles those cases for you automatically.
|
|---|