#!/usr/bin/perl -w

# Syntax: find-net <NFS Server>

use strict;
use Socket;
use Data::Dumper;
#use ProjectBuilder::Base;

my $nfsip = inet_ntoa(scalar gethostbyname($ARGV[0] || 'localhost'));
print "NFS IP: $nfsip\n";

my %if;
my $if = \%if;

my $curdev = "";
open(IP,"ip addr |") || die "Unable to read IP config\n";
while(<IP>) {
	# Remove duplicate spaces
	$_ =~ s/\s+/ /g;
	#print "Line: $_\n";
	# Check for a new interface
	my $tmp;
	if (/^[0-9]+:/) {
		my $dev;
		my $rank;
		($rank,$dev,$tmp) = split(/:/);
		#print "$rank,$dev,$tmp";
		$dev =~ s/\s*//;
		$if->{$dev}->{'if'} = $dev;
		$curdev = $dev;
	}
	($tmp,$tmp,$if->{$curdev}->{'mac'},$tmp) = split(/ /) if (/^ link/);
	($tmp,$tmp,$if->{$curdev}->{'cidr'},$tmp) = split(/ /) if (/^ inet/);
}
close(IP);

# Ideas Taken from http://nixcraft.com/shell-scripting/11398-simple-ipcalc-perl-script.html
foreach my $dev (keys %if) {
	next if (not defined $if->{$dev}->{'cidr'});
	($if->{$dev}->{'ip'},my $cidr) = split(/\//,$if->{$dev}->{'cidr'});

	$if->{$dev}->{'nm'} = cvt_bits_mask($cidr);

	my ($ipaddress) = unpack("N",pack( "C4",split(/\./,$if->{$dev}->{'ip'})));
	my ($netmask) = unpack( "N", pack( "C4",split(/\./,$if->{$dev}->{'nm'})));

	# Calculate network address by logical AND operation of addr & netmask
	# and convert network address to IP address format
	$if->{$dev}->{'net'} = join(".",unpack("C4",pack("N",($ipaddress & $netmask))));

	# Calculate broadcase address by inverting the netmask
	# and do a logical or with network address
	$if->{$dev}->{'bcast'} = join(".",unpack("C4",pack("N",($ipaddress & $netmask)+(~ $netmask))));
}
print "IP: ".Dumper($if)."\n";

# From http://icmp.ru/man/cisco/cookbook/ciscockbk-CHP-5-SECT-3.htm
sub cvt_bits_mask() {

my ($bits) = @_;
my $a = 0;
my $b = 0;
my $c = 0;
my $d = 0;

if ($bits <= 8 ) {
	$a = bits_to_dec($bits);
} else {
	$a = 255;
	if ($bits <= 16 ) {
		$b = bits_to_dec($bits-8);
	} else {
		$b=255;
		if ($bits <= 24 ) {
			$c = bits_to_dec($bits-16);
		} else {
			$c=255;
			if ($bits <= 32 ) {
				$d = bits_to_dec($bits-24);
			} else {
				print "invalid bit count\n";
				exit();
			}
		}
	}
}
return ($a.".".$b.".".$c.".".$d);
}
   
sub bits_to_dec() {
my ($bits) = @_;
   
if ($bits == 0 ) { return 0; }
if ($bits == 1 ) { return 128; }
if ($bits == 2 ) { return 192; }
if ($bits == 3 ) { return 224; }
if ($bits == 4 ) { return 240; }
if ($bits == 5 ) { return 248; }
if ($bits == 6 ) { return 252; }
if ($bits == 7 ) { return 254; }
if ($bits == 8 ) { return 255; }
}
