#!/usr/bin/perl # # Filename: /var/www/cgi-bin/passportarp.pl # # Purpose: Query Nortel Networks Passport 8600 switches for IP ARP table. # Help determine which ports should be placed in which VLANs # as we being to segment the hospital LAN into multiple VLANs. # # Author: Michael McNamara (mfm@michaelfmcnamara.com) # # Date: December 5, 2002 # # License: # Copyright (C) 2002 Michael McNamara (mfm@michaelfmcnamara.com) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see # # # Changes: # # Sep 10, 2007 (M.McNamara) # o added DBI code to build HTML form from database source # Feb 28, 2006 (M.McNamara) # o added logic to handle SMLT links # May 11, 2004 (M.McNamara) # o add the MAC address to the report output # Jul 11, 2003 (M.McNamara) # o add additional input validatation # # # Program Flow: # Check CGI Variables # Query switch for general information # Output general information # Query switch for VLAN information # Query switch for MLT information # Loop over VLANs to retreive FDB for each VLAN # Search for MAC address while retreiving FDB # Output and hits as the search progresses # End # Load Modules use strict; use SNMP; use CGI; use DBI; # MySQL Database Paramaters my $dbuser = "mysqluser"; my $dbpasswd = "mysqlpasswd"; my $database = "mysqldatabase"; my $table = "mysqltable"; my $dsn="DBI:mysql:mysqldatabase:localhost"; # Declare constants #use constant DEBUG => 0; # DEBUG settings use constant RETRIES => 3; # SNMP retries use constant TIMEOUT => 1000000; # SNMP timeout, in microseconds use constant SNMPVER => 1; # SNMP version # Declaration Variables my ($sess, @vals); my @devices; my ($card, $port); my $snmphost; my $comm = "public"; # SNMP Read-Only Community String my %array; my $switchfile = ""; my $datafile = ""; my $tempcard; my $tempport; my $intf; my ($sysDescr, $sysObjectID, $sysUpTime, $sysContact, $sysName, $sysLocation); my $numvlans; my $i; my (@vlanidtable, @vlannametable); my $tempf; my $date; my $ip; my $mlt; my $nummlts; my $x; my $specialcomm; my @mltname; my @mltindex; my @mltifindex; my @vlanidx; my $found = 0; my $count = 0; my ($days, $hrs, $mins, $tTime); my $DEBUG = 0; # DEBUG FLAG for troubleshooting # SNMP Settings $SNMP::verbose = $DEBUG; $SNMP::use_enums = 1; $SNMP::use_sprint_value = 0; &SNMP::initMib(); #&SNMP::loadModules('ALL'); &SNMP::loadModules('RAPID-CITY'); undef @devices; $| = 1; my $web = new CGI; $snmphost = $web->param('switch'); $ip = $web->param('ip'); $DEBUG = $web->param('debug'); $ip =~ tr/a-z/A-Z/; # Converting MAC address to uppercase ######################################################################### ######################################################################### ## M A I N P R O G R A M ######################################################################### ######################################################################### &html_header; if ($snmphost eq "") { &html_form(); } else { &runjob(); } &html_footer; exit 0; ######################################################################### ######################################################################### ### E N D P R O G R A M ######################################################################### ######################################################################### ########################################################################### # Subroutine html_header # # Purpose: perform all the initialization steps and procedures ########################################################################### sub html_header{ print $web->header; print $web->start_html('Nortel Passport 8600 Gigabit Switch IP ARP Table Search'); print ""; print $web->h3('Nortel Passport 8600 Gigabit Switch IP ARP Table Search'); } #end sub ########################################################################### # Subroutine html_footer # # Purpose: perform all the initialization steps and procedures ########################################################################### sub html_footer { print $web->end_html; } #end sub ########################################################################### # Subroutine html_form # # Purpose: perform all the initialization steps and procedures ########################################################################### sub html_form { # Declare Local Variables my $ers8610id="rcA8610"; my $ers8606id="rcA8606"; my $ers1648id="rcA1648"; my $table="devices"; my $method="POST"; my $action="http://webserver/cgi-bin/passportarp.pl"; my $encoding="application/x-www-form-urlencoded"; my $dbvalue; # Let's open a DBI connection to the MySQL database my $dbh = DBI->connect($dsn,$dbuser,$dbpasswd) or die "ERROR: cannot open database: $DBI::errstr\n"; # Let's truncate the test table #my $truncate_sth = $dbh->prepare("TRUNCATE $table"); #$truncate_sth->execute(); #$truncate_sth->finish(); my $query_sth = $dbh->prepare("SELECT DISTINCT hostname FROM $table WHERE (sysObjectID = '$ers8610id') OR (sysObjectID = '$ers8606id') OR (sysObjectID = '$ers1648id')"); #my $query_sth = $dbh->prepare("SELECT hostname FROM $table"); $query_sth->execute(); #print $web->startform($method,$action,$encoding) print <

Passport 8600 Switch    (xxx.xxx.xxx.xxx)                DEBUG

Passport 8600 switches.

Let me know if you have questions, problems or suggestions.

Help


EOF $query_sth->finish(); $dbh->disconnect || die "Failed to disconnect\n"; } #end sub ########################################################################### # Subroutine runjob # # Purpose: perform all the initialization steps and procedures ########################################################################### sub runjob { print "
Initializing query for $snmphost for IP address $ip...
\n"; print "

\n"; if ($DEBUG) { print "DEBUG: snmphost = $snmphost
\n"; print "DEBUG: ipaddr = $ip
\n"; } if (($snmphost eq "") || ($snmphost eq "Select Passport Switch")) { print "ERROR: The switch parameter appears to be emtpy?
\n"; print "Please go back and enter a valid switch IP address of host name

\n"; exit 1; } elsif ($ip eq "") { print "ERROR: The ip address parameter appears to be emtpy?
\n"; print "Please go back and enter a valid IP address

\n"; exit 1; } elsif ( (length($ip) < 7) | (length($ip) > 15) ) { print "ERROR: The ip address shoud be greater than 6 characters and\n"; print "less than 15 characters long!?!
\n"; print "Please go back and enter a valid IP address

\n"; exit 1; }; $sess = new SNMP::Session ( DestHost => $snmphost, Community => $comm, Retry => RETRIES, Timeout => TIMEOUT, Version => SNMPVER ); if ( $sess->{ErrorStr} ) { print "DEBUG: sess->{ErrorStr} = $sess->{ErrorStr}\n"; } my $vars = new SNMP::VarList( ['sysDescr', 0], ['sysObjectID', 0], ['sysUpTime', 0], ['sysContact', 0], ['sysName', 0], ['sysLocation', 0] ); # ['rc2kChassisTemperature', 0] ); @vals = $sess->get($vars); # retreive SNMP information if ( $sess->{ErrorStr} ) { print "DEBUG: sess->{ErrorStr} = $sess->{ErrorStr}\n"; } if ($vals[0] eq "") { print "SNMP ERROR: Unable to poll the switch!!!
\n"; print "It is possible that the switch is down or you have
\n"; print "the wrong IP address or host name.

\n"; print "Please go back and check the switch name.
\n"; print "DEBUG: vals[0] = $vals[0]
\n"; print "DEBUG: vals[1] = $vals[1]
\n"; print "DEBUG: vals[2] = $vals[2]
\n"; print "DEBUG: vals[3] = $vals[3]
\n"; print "DEBUG: vals[4] = $vals[4]
\n"; print "DEBUG: vals[5] = $vals[5]
\n"; print "DEBUG: vals[6] = $vals[6]
\n"; exit 1; } $sysDescr = $vals[0]; $sysObjectID = $vals[1]; $sysUpTime = $vals[2]; $sysContact = $vals[3]; $sysName = $vals[4]; $sysLocation = $vals[5]; $tTime = $sysUpTime; $tTime /= 100; $days = int($tTime/(60*60*24)); $tTime -= $days * (60*60*24); $hrs = int($tTime/(60*60)); $tTime -= $hrs*(60*60); $mins = int($tTime/(60)); $tTime -= $mins*(60); print "sysDescr = $sysDescr
\n"; print "sysObjectID = $sysObjectID
\n"; print "sysUpTime = $days Days $hrs Hours $mins mins $tTime secs
\n"; print "sysContact = $sysContact
\n"; print "sysName = $sysName
\n"; print "sysLocation = $sysLocation
\n"; $tempf = ((9/5 * $vals[6]) + 32); if ($tempf < 100) { print "Chassis Temperature = ", ((9/5 * $vals[6]) + 32), " degrees
\n"; } else { print "Chassis Temperature = ", ((9/5 * $vals[6]) + 32), " degrees
\n"; }; print "

\n"; print "Please be patient it may take a while to complete the search...\n"; print "

\n"; ################ BEGIN POLLING SPECIFIC SNMP PARAMETERS ###################### # rcMltNumMlts $nummlts = $sess->get("rcMltNumMlts.0"); print "DEBUG: Number of MultiLink Trunks = $nummlts
\n" if ($DEBUG); for ($i = 1; $i <= $nummlts; $i++) { # rcMltName $mltname[$i] = $sess->get("rcMltName.$i"); # rcMltId $mltindex[$i] = $sess->get("rcMltId.$i"); # rcMltIfIndex $mltifindex[$i] = $sess->get("rcMltIfIndex.$i"); print "DEBUG: MltId = $i and MltName = $mltname[$i] and MltIndex = $mltindex[$i] and MltIfIndex = $mltifindex[$i]
\n" if ($DEBUG); }; # rcVlanNumVlans $numvlans = $sess->get("rcVlanNumVlans.0"); $numvlans = $numvlans - 1; print "
DEBUG: Number of VLANs = $numvlans
\n" if ($DEBUG); my $vars = new SNMP::VarList( ['rcVlanId', 0], ['rcVlanName', 0] ); for ($i = 1; $i <= $numvlans; $i++) { ($vlanidtable[$i], $vlannametable[$i])= $sess->getnext($vars); print "DEBUG: VLANID = $vlanidtable[$i] with VLAN Name = $vlannametable[$i]
\n" if ($DEBUG); } #end for loop numvlans #sleep(10); #for ($x = 1; $x <= ($numvlans); $x++) { # $specialcomm = "$comm\@$vlanidtable[$x]"; # print "
DEBUG: Special Community String = $specialcomm
\n" if ($DEBUG); $sess = new SNMP::Session ( DestHost => $snmphost, Community => $comm, Retry => RETRIES, Timeoute => TIMEOUT, Version => SNMPVER ); my $vars = new SNMP::VarList( ['ipNetToMediaIfIndex', 0], ['ipNetToMediaPhysAddress', 0], ['ipNetToMediaNetAddress', 0], ['ipNetToMediaType', 0] ); do { @vals = $sess->getnext($vars); # retreive SNMP information #print "SNMP query against $snmphost just completed\n" if ($DEBUG); $vals[1] = unpack('H12', $vals[1]); $vals[1] =~ tr/a-z/A-Z/; $tempcard = (($vals[0] & 62914560) / 4194304); $tempport = (($vals[0] & 4128768) / 65536) + 1; print "DEBUG: $snmphost; $vals[0] ($tempcard/$tempport); $vals[1]; $vals[2]; $vals[3]
\n" if ($DEBUG); # if ($card != 0) { # # print "$snmphost, $vals[0], ($card/$port), $vals[1], $vals[2], $vals[3]\n" if ($DEBUG); # # $array{$snmphost}[$card][$port] = $vals[2]; # # } #end if $card $count++; if ($ip eq $vals[2]) { $found = 1; # SET FLAG $card = (($vals[0] & 62914560) / 4194304); $port = (($vals[0] & 4128768) / 65536) + 1; print "
\n"; print "DEVICE FOUND
\n"; # print "Card = $card, Port = $port
\n"; # print "VLAN = $vals[3]
\n"; print "
\n"; if ($card != 0) { #$card = int($vals[2]/64); #$port = ($vals[2] - ($card * 64) + 1); $intf = (((64 * $card) + $port) - 1); print "$ip ($vals[1]) address found on card $card port $port
\n"; } else { $mlt = 1; print "$ip ($vals[1]) address found on MLT $mltname[$port]
\n"; } # end else } # end if ip=val # } #end if fdbstatus = valid } until ($sess->{ErrorStr} | (($vals[3] ne "other") & ($vals[3] ne "invalid") & ($vals[3] ne "dynamic") & ($vals[3] ne "static") ) ); # } #end for if ($found == 0) { print "We were unable to find that MAC address in any of the "; print "VLAN forwarding tables.
The device may be shutoff or it "; print "may have aged out of the forwarding tables.
\n"; print "You may contact the Technology Infrastructure Team for "; print "further assistance.
\n"; } #if ($vals[11] == 1) { # print "DefaultVLAN = $vals[11]
\n"; #} else { # print "DefaultVLAN = $vals[11]
\n"; #} if (($found) & !($mlt)) { print "
\n"; print "Would you like to check the status of this port? "; print "Click Here!!!
\n"; print "

\n"; print "Would you like to check the utilization of this port? "; print "Click Here!!!
\n" } print "

We searched through $count forwarding records...

\n"; ##################### END HTML OUTPUT WITH FOOTER ####################### print "

\n"; $date = `date`; print "

\n"; print "$date\n"; print "

\n"; } #end sub