My HTML::Template output appears in the browser like so when in a mod_perl sub
handler subroutine. The other three modules work fine. This also works fine
as a CGI.
Content-Type: text/html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Management App</title>
<LINK rel="stylesheet" href="../css/yanmastyles.css" type="text/css">
<script type="text/javascript" >
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function' ) {
window.onload = func;
}
else {
window.onload = function() {
oldonload();
func();
}
}
}
function highlightRows() {
if( !document.getElementsByTagName ) return false;
var rows = document.getElementsByTagName( "tr" );
for( var i=0; i<rows.length; i++ ) {
rows[i].onmouseover = function() {
this.style.backgroundColor = "#d3d3d3";
}
rows[i].onmouseout = function() {
this.style.backgroundColor = "#fff";
}
}
}
addLoadEvent(highlightRows);
</script>
</head>
<body>
<div id="top">
<div id="banner">
<a href="index.html"><img src="../images/yanma-banner.jpg"
alt="Yanma"
width="900" height="172" border="0" /></a>
</div>
<div id="menubar">
<ul id="navigation">
<li><a href="/perl/choosemodel.pl"><span>Query</span></a></li>
<li><a
href="http://yanmadev.usmc-mccs.org/administration/update.html"><span>Update</span></a></li>
<li><a href="#"><span>Add</span></a></li>
<li><a href="choose_router.html"><span>NBAR Stats</span></a></li>
<li><a href="choosebase.pl"><span>Portmapper</span></a></li>
<li><a
href="http://yanmadev.usmc-mccs.org"><span>Home</span></a></li>
</ul>
</div>
<div id="border"></div>
</div>
<div id="content">
<h2>albasw02</h2>
<h3>Cisco Catalyst 3550 24 10/100 baseT ports + 2 Gig uplinks fixed
configuration Layer 2/3 Ethernet Switch</h3>
<h3>Fri Jan 11 16:16:52 2008</h3>
<table >
<thead>
<th>Interface</th>
<th>Mac Address</th>
<th>IP Address</th>
<th>Device</th>
<th>Controller/Printer</th>
</thead>
<tbody>
<tr>
<td>Fa0/13</td>
<td>001d0909cd0d</td>
<td>10.129.20.38</td>
<td>albxp02006.windows.usmc-mccs.org</td>
<td></td>
</tr>
<tr>
<td>Fa0/13</td>
<td>001d0909cd0d</td>
<td>10.129.20.38</td>
<td>albxp02006.windows.usmc-mccs.org</td>
<td></td>
</tr>
<tr>
<td>Fa0/13</td>
<td>001d0909cd0d</td>
<td>10.129.20.38</td>
<td>albxp02006.windows.usmc-mccs.org</td>
<td></td>
</tr>
</tbody>
</table>
All the info is there and is correct, just not rendered. All other modules
within the app work great, just not this one. Below is my Perl module.
#!/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/plain');
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;
Thanks,
Mitch
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
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Html-template-users mailing list
Html-template-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/html-template-users