I have my code pasted below.  My module, loaded with <Location> directive in 
Apache2, works well.  However, sometimes switches don't respond correctly to 
bulk queries of fdbPorts object.  What I want to do is to be able print the 
value of my variables either to the browser or a log file.  A regular print 
statement does not work for this.  The relevant variables are in a subroutine 
called from my sub handler.
 
Thanks in advance.
 

#!/usr/bin/perl -w

package Handlers::PortMapper;

use warnings;

use strict;

use HTML::Template;

use DBI;

use Socket qw(:DEFAULT :crlf);

use dec_hex;

use snmpSession;

use SNMP;

use Net::NBName;

use Net::Ping;

use Apache2::Request ();

use Apache2::Const -compile=>'OK';

 

# %seen_vlans --tracks those vlans which are seen as each ports vlan membership 
is looked at 

# %device --all results for each device found on a switch are placed here for 
dispatching to a web page

# @answer;

my @switch_row; #--hold results of db query for switch

my @router_row; #--hold results of db query for router whose arp cache you want

my %devices_ref;

my %hash;

my $time; # --gets time query began

my $chosen_switch; #--switch passed via http form data

my $chosen_router; #--switch passed via http form data

my $switch_ip; #--result one for initial query

my $switch_model; #--result two for initial query

my $devices_ref;

my $router_ip; # --result for query of router address

my $dbh; #--database handle

my $sql; #--database query

my @loop_data; #--hold hashes for my template

# $i = 0 --counters

# $j = 0 --counters

sub handler {

my $r = shift;

my $req = Apache2::Request->new( $r );

$r->content_type('text/html'); 

my %mac_data;

my @mac_array; #hold individual hex digits returned by ipNetToMediaPhysAddress

my @loop_data = (); #array of anonymous hashes which is dispatched to web page 
for display

my $template = HTML::Template->new( filename => 
'/home/mitch/www-dev/mod_perl/templates/portmapper.tmpl',

debug => 1,

die_on_bad_params => 0 );

my $time = localtime();

$chosen_switch = $req->param('chosen_switch');

$chosen_switch =~ s/(\s.*)//g;

$chosen_router = $req->param( 'chosen_router' );

$dbh = DBI->connect( 'dbi:ODBC:MRIServer2k', 'mriinventory', '[EMAIL 
PROTECTED]',

{ PrintError => 1, RaiseError => 0, AutoCommit => 1 } );

$sql = "SELECT address, chassis_description FROM tblLiveCisco WHERE 
name='$chosen_switch'";

@switch_row = $dbh->selectrow_array( $sql );

$switch_ip = $switch_row[0];

$switch_model = $switch_row[1];

@router_row = $dbh->selectrow_array("SELECT address FROM tblLiveCisco WHERE 
name='$chosen_router'" );

$router_ip = $router_row[0];

$devices_ref = getDevices( $router_ip, $switch_ip, 'public');

foreach $_ (@{$devices_ref}) {

%hash = %$_;

push @loop_data, \%hash ;

}

$template->param(CHOSEN_SWITCH => $chosen_switch );

$template->param(MODEL => $switch_model );

$template->param(TIME => $time );

$template->param(LOOP_DATA => [EMAIL PROTECTED] );

print "Content-Type: text/html\n\n";

print $template->output;

return Apache2::Const::OK;

}

sub getDevices {

my $router = shift;

my $switch = shift;

my $community = shift;

my @mac_array = ();

my %seen_vlans = ();

my %ifnames; #holds the ifIndex number and names of ports

my %trunk; #holds all ports on a switch that are trunking

my %arpCache;

my @data;

my @vlans; #all vlans found using vmVlan object

my $arp_mib = 'ipNetToMediaPhysAddress';

my ( $mac_address,$ip, $dns_name, $device_type );

my $arp_session = snmpSession::openSession( $router , $community, 1 );

my $vb_arp = new SNMP::Varbind( [$arp_mib] );

for(my $var = $arp_session->getnext( $vb_arp );

( $vb_arp->tag eq $arp_mib ) and not ( $arp_session->{ErrorNum} );

$var = $arp_session->getnext( $vb_arp )

) {

my $ip_addr = ( $vb_arp->tag . $vb_arp->iid );

$ip_addr =~ s/$arp_mib\d+\.//g;

my @vars = split(/:/, $var );

for( my $x = 0; $x < scalar( @vars ); $x++ ) {

if( length( $vars[$x] ) < 2 )

{

$vars[$x] = "0"."$vars[$x]";

}

push( @mac_array, $vars[$x] );

}

my $arp_mac_address = join( "", @mac_array );

push( @{$arpCache{$arp_mac_address}}, $ip_addr );

@mac_array = ();

}

if( $arp_session->{ErrorNum} ){ print "Got $arp_session->{ErrorStr} for 
$router\n"; }

my $vlan_session = snmpSession::openSession ( $switch, $community, 1 );

my $vb_vlan = new SNMP::VarList( ['vmVlan'], ['ifName'], 
['vlanTrunkPortDynamicStatus'] );

my @answers1 = $vlan_session->bulkwalk(0, 100, $vb_vlan );

if( $vlan_session->{ErrorNum} ) {

print "Got ", $vlan_session->{ErrorStr}, "on", $vlan_session->{DestHost}, " 
during Bulkwalk\n";

}

my $vlan_answer = $answers1[0];

my $ifName_answer = $answers1[1];

my $trunk_ports = $answers1[2];

for( my $i = 0; $i < scalar(@$vlan_answer); $i++ )

{

my $vlan = $vlan_answer->[$i]->[ 2];

if ( !exists ($seen_vlans{$vlan} ) ) {

push( @vlans, $vlan );

$seen_vlans{$vlan} = 1;

}

}

for( my $j = 0; $j < scalar(@$ifName_answer); $j++ )

{

my $index = $ifName_answer->[$j]->[1];

my $interface_name = $ifName_answer->[$j]->[2];

push @{$ifnames{$index}}, $interface_name;

}

for ( my $p = 0; $p < scalar( @$trunk_ports ); $p++ ) {

my $port_index = $trunk_ports->[$p]->[1];

if( $trunk_ports->[$p]->[2] eq 'trunking' )

{

$trunk{$port_index} = 1;

}

}

my $vb_cam = new SNMP::VarList( ['dot1dTpFdbPort'], ['dot1dBasePortIfIndex'] );

foreach $_ ( @vlans ) {

$community = "public@"."$_";

my $cam_session = snmpSession::openSession ( $switch, $community, 1 );

my @answers2 = $cam_session->bulkwalk(0, 1000, $vb_cam );

my $fdbPorts = $answers2[0];

my $portIndexes = $answers2[1];

for ( my $q = 0; $q < scalar( @$fdbPorts ); $q++ ) {

for( my $r = 0; $r < scalar( @$portIndexes ); $r++ ) {

if( $fdbPorts->[$q]->[2] == $portIndexes->[$r]->[1] && !exists( $trunk{ 
$portIndexes->[$r]->[2] } ) )

{

$mac_address = lc(dec_hex::dec_to_hex( $fdbPorts->[$q]->[1] ) );

if( exists($arpCache{$mac_address} ) ) {

$ip = $arpCache{$mac_address}->[0];

$dns_name = getName( $ip );

$device_type = getDeviceType( $ip );

}

else { $ip = undef; }

if( !defined( $ip ) )

{

if( $mac_address =~ /000255/o )

{

$device_type = 'Register';

}

elsif( $mac_address =~ /000ff8/o )

{

$device_type = 'PSC handheld';

}

elsif( $mac_address =~ /00a0f8/g )

{

$device_type = 'Symbol RF device';

}

elsif( $mac_address =~ /001795/g )

{

$device_type = 'Cisco Systems AP';

}

}

my %device = (); 

$device{PORT} = "@{$ifnames{ $portIndexes->[$r]->[2]} }";

$device{MAC} = $mac_address;

$device{IP} = $ip;

$device{DEVICE} = $dns_name;

$device{TYPE} = $device_type;

push( @data, \%device );

}

}

}

}

return [EMAIL PROTECTED];

}

sub getName {

my $ip_address = shift(@_);

my( $nbQuery, $nbStatus, $DNS, $packed_binary_address );

$packed_binary_address = inet_aton( $ip_address);

$DNS = gethostbyaddr( $packed_binary_address, AF_INET );

if( !$DNS ) {

$nbQuery = Net::NBName->new;

$nbStatus = $nbQuery->node_status( $ip_address );

if( defined $nbStatus )

{

$DNS = $nbStatus->{names}->[0]->{name};

}

if( !$DNS ) { $DNS = 'unknown' }

}

return $DNS;

}

sub getDeviceType {

my $address = shift( @_ );

my ( $type, $rtt, $tcp_print, $addr, $host);

$tcp_print = Net::Ping->new("syn");

$tcp_print->{port_num} = "9100";

$tcp_print->service_check( 1 );

$tcp_print->ping( $address );

if( ( $host, $rtt, $addr ) = $tcp_print->ack )

{

$type = "Printer";

}

else{

$tcp_print = Net::Ping->new("syn");

$tcp_print->{port_num} = "4500";

$tcp_print->service_check( 1 );

$tcp_print->ping( $address );

if( ( $host, $rtt, $addr ) = $tcp_print->ack )

{

$type = "Controller"

}

}

return $type;

}

1;

Mitchell Raful MCSE CCNP 
MCB Quantico 
Personal and Family Readiness (MRI) 
3044 Catlin Avenue 
Quantico, VA 22134 
Com: 703-784-5991 
DSN: 278-5991 
Cell: 804-363-0731 

 

Reply via email to