#!/usr/bin/perl ###################################################################### ### Sample CGI script using the Perl 5 SNMP Module ### ### This script can be used as a CGI script with an HTTP Daemon, to ### allow asking SNMP queries from a World-Wide Web client. ### ###################################################################### ### When called with an empty QUERY_STRING environment variable, a ### form is generated that lets the user fill in a host and community ### name. When the filled-in form is submitted, the script will be ### called again, this time with parameters passed through ### $QUERY_STRING. It will make an SNMP query to the selected ### host/community and return the results as an HTML document ### containing an HTML 3 table which shows the names and values of ### some MIB variable instances. ###################################################################### require 5; use lib qw(/home/leinen/perl/SNMP_Session-0.96/lib /home/leinen/perl/SNMP_Session-0.96/blib/lib); use SNMP_Session; use BER; use CGI qw(:standard start_table end_table :debug); use strict; sub init_oids (); sub query_to_html_response ($$); sub snmp_get ($@); sub write_query_form (); sub html_error_message ($$); sub html_quote ($ ); my @allowed_hosts=qw(localhost ::1 127.0.0.1); my %allowed_hosts; my $community_file_name = "/home/leinen/snmp/.zxc"; my $ipv4_only_p = 0; my $home_url = "http://www.switch.ch/misc/leinen/snmp/perl/"; my (%ugly_oids, %pretty_oids); foreach (@allowed_hosts) { $allowed_hosts{$_} = 1; } my $q = new CGI; if (!defined ($q) || !defined $q->param ('hostname')) { write_query_form (); } else { init_oids (); if (! exists ($allowed_hosts{$q->param ('hostname')})) { print (header ()); html_error_message ("parsing the query", "Illegal hostname ".$q->param ('hostname')); } else { query_to_html_response ($q->param ('hostname'), $q->param ('community')); } } 1; sub init_oids () { %ugly_oids = qw(sysDescr.0 1.3.6.1.2.1.1.1.0 sysLocation.0 1.3.6.1.2.1.1.6.0 ); foreach (keys %ugly_oids) { $ugly_oids{$_} = encode_oid (split (/\./, $ugly_oids{$_})); $pretty_oids{$ugly_oids{$_}} = $_; } } sub query_to_html_response ($$) { my ($hostname, $community) = @_; my $session; if ($community eq 'public' && -r $community_file_name) { open (COMM, $community_file_name); $community = ; chomp $community; close COMM; } print (header (), start_html ("Perl SNMP Module Test"), h1 ("SNMP query to " .html_quote ($community) .'@' .html_quote ($hostname)), hr ()); srand(); eval { $session = SNMPv2c_Session->open ($hostname, $community, 161, undef, undef, undef, undef, $ipv4_only_p) }; html_error_message ("opening SNMP session", $SNMP_Session::errmsg), return 0 unless defined $session; html_error_message ("opening SNMP session", $@), return 0 if $@; eval { snmp_get ($session, qw(sysDescr.0 sysLocation.0)) }; html_error_message ("executing SNMP query", $@), return 0 if $@; $session->close (); print (end_html ()); 1; } sub snmp_get ($@) { my($session, @oids) = @_; my($response, $bindings, $binding, $value, $oid); grep ($_ = $ugly_oids{$_}, @oids); if ($session->get_request_response (@oids)) { $response = $session->pdu_buffer; ($bindings) = $session->decode_get_response ($response); print (start_table({border=>'1'})); while ($bindings ne '') { ($binding,$bindings) = decode_sequence ($bindings); ($oid,$value) = decode_by_template ($binding, "%O%@"); print Tr(th ({align=>'right'}, $pretty_oids{$oid}), td ({align=>'left'}, html_quote (pretty_print ($value)))); } print (end_table ()); 1; } else { die "No response received.\n"; } } sub write_query_form () { my $first_p = 1; my $options = join ("\n", map ({my $res = $q->option ({-selected=>$first_p, -value=>$_}, $_); $first_p = 0; $res;} @allowed_hosts)); print (header (), start_html ("Perl SNMP Module Test"), h1 ("Perl SNMP Module Test"), p ("This is a sample application of an ", a ({href => $home_url}, "SNMP Module"), "(version ${SNMP_Session::VERSION}) for Perl 5."), hr (), $q->start_form (-method=>'GET'), "Host name:\n", Select ({name => 'hostname'}, $options), "\n", "Community name:\n", Select ({name => 'community'}, option ({value => 'public'}, "public")), br (), "\n", input ({type => 'submit', value => "Send request"}), "\n", input ({type => 'reset', value => "Clear"}), "\n", $q->end_form (), hr (), "\n", address (a ({href=>"http://www.switch.ch/misc/leinen/"}, "Simon Leinen <simon\@switch.ch>")), "\n", end_html (), "\n"); } sub html_error_message ($$) { my($context, $errmsg) = @_; print ($q->h2 ("SNMP Error"), hr (), p ("While ",$context,", the following error occurred:"), pre (html_quote($errmsg)), end_html ()); } sub html_quote ($ ) { local ($_) = @_; return $_ unless /[<>&]/; s/&/&/g; s//>/g; $_; }