#!/usr/bin/perl -w use strict; use IP; #snmpwalk flags reference (full version man snmpwalkcmd # #-Oq Removes the equal sign and type information: #-Os Deletes all but the last symbolic part of the OID: #-Ov Output only the variable value, not the OID: #-O0 Print leading zero before HEX data #id is het ip #0 = mac #1 = subnet #2 = member of node my %ipDB = (); #enable debugging my $debug_enable = 1; my $start_host= '172.16.1.161'; #dictionary variable my $unknown_node = "unknown_node"; my $remote_node = "remote_node"; #regular expressions my $ipv4_regexp = '(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})'; my $mac_regexp = '[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}:[a-f0-9]{2}'; #tmp variablen my $raw_string = ""; my @raw_array = (); my %raw_hash = (); #debugging sub sub debug { if( $debug_enable ) { print "$_[0] \n"; } }; #run snmp_command; sub snmp_command { my $flags = $_[0]; my $host = $_[1]; my $identifier = $_[2]; debug("host = $host"); my $command = "snmpwalk -v 1 -O$flags -c public $host $identifier"; debug("command =$command"); my $raw_output = `$command`; debug("Raw output = $raw_output"); $raw_output =~ s/\n.*$//; debug("Reniced output = $raw_output"); return($raw_output); }; #some hashes my %local_ips = (); my %remote_ips = (); my %ip2mac = (); my %ip2subnet = (); # ip's who are used for special purposes like, loopback or general # aliasss sub allowed_ip { my %deny_list = (); $deny_list{'127.0.0.1'} = 1; $deny_list{'172.31.255.1'} =1; if( exists $deny_list{$_[0]} ) { return(0); } else { return(1); }; }; #during this part there will be checked whether we could use a ip #address as neighboor ip or as local ip #This is written to enimilate the acess point's ip of the clients sub ip_remote_check { my $ip = $_[0]; foreach my $local_ip (keys %local_ips) { debug("checking if $ip is at $local_ip / $ip2subnet{$local_ip}"); if( IP::calcOnNetwork($local_ip, $ip, $ip2subnet{$local_ip}) ) { if( IP::getNetmask($ip2subnet{$local_ip}) > 28 ) { debug("$ip seems to be really remote of $local_ip"); return(1); }; }; }; return(0); }; #ipAdEntNetMask.172.16.1.166 255.255.255.252 -> #$ip2subnetPart{172.16.1.166} = 255.255.255.252 $raw_string = snmp_command("qs",$start_host,"ipAdEntNetMask"); @raw_array = split(/\n/, $raw_string); foreach my $line (@raw_array) { if( $line =~ /\S*\.($ipv4_regexp) ($ipv4_regexp)$/ ) { debug("ip $1 at $6"); $ip2subnet{$1} = $6; }; }; #ipNetToMediaPhysAddress.4.172.27.129.1 00:02:6f:34:3a:ed -> #$ipDB{172.27.129.1}[0] = 00:02:6f:34:3a:ed $raw_string = snmp_command("0qs", $start_host, "ipNetToMediaPhysAddress"); @raw_array = split(/\n/, $raw_string); foreach my $line (@raw_array) { if( $line =~ /\S*\.($ipv4_regexp) ($mac_regexp)/ ) { $ipDB{$1}[0] = $6; $ipDB{$1}[1] = $ip2subnet{$1}; $ipDB{$1}[2] = $unknown_node; debug("ip $1 has $6"); }; }; my $nodename = snmp_command("sqv", $start_host, "sysName"); #my $ifaces = snmp_command("qs", $start_host, "ifNumber"); #ipAdEntIfIndex.127.0.0.1 3 #$ipDB{'127.0.0.1'}[2] = 'nodename' #$local_ips{'127.0.0.1'} = subnet node $raw_string = `snmpwalk -v 1 -Osq -c public $start_host ipAdEntIfIndex`; @raw_array = split(/\n/, $raw_string); foreach my $line (@raw_array) { if( $line =~ /\S*\.($ipv4_regexp) (\d+)/ ) { if( allowed_ip($1) ) { debug("local $1 is member of $nodename"); $ipDB{$1}[2] = $nodename; $local_ips{$1} = $ipDB{$1}[1]; }; }; }; #atIfIndex.1.1.172.27.129.66 1 #als ip niet in local_ips voorkomt dan: $raw_string = snmp_command("qs", $start_host, "atIfIndex"); @raw_array = split(/\n/, $raw_string); foreach my $line (@raw_array) { if( $line =~ /\S*\.($ipv4_regexp) \S*/ ) { if( allowed_ip($1) ) { if( $ipDB{$1}[2] eq $unknown_node ) { debug("remote ip $1"); if( ip_remote_check($1) ) { debug("remote ip $1 has probely node attached"); $ipDB{$1}[2] = $remote_node; $remote_ips{$1} = $ipDB{$1}[0]; } else { debug("remote ip $1 seems to be a exception"); }; }; }; }; }; exit;