The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Apache::WebSNMP - Allows for SNMP calls to be embedded in HTML

SYNOPSIS

 <html>
 <body>
 <snmp>
        host=zoom.google.org
        community=public
        connect
        interface=ifDescr
        extension(interface)=2
        mac=ifPhysAddress
        extension(mac)=2
        query
 </snmp>
 The interface <b>descriptor</b> for the ethernet card is <snmp> print(interface) </snmp> 
        and its <b>mac address</b> is <snmp> print(mac) </snmp>
 </body>
 </html>

DESCRIPTION

The WebSNMP module allows one to embed SNMP commands directly into HTML code.

REQUIRES

This module requires the perl SNMP module, available at the CPAN site.

USAGE

The module allows for three different kinds of statements, surrounded by <snmp> and </snmp> html tags. The three types of statements consist of configurations, variable assignments, and commands. A brief description of each type of statement follows:

Configuration

The configuration statements allow the user the set which host to poll for SNMP information, as well as the SNMP community that the get statements will draw from. This essentially takes the form of assigning values to the reserved variables host and community. All variables are assigned with the following syntax: varible_name=value

Note: there must not be any intervening whitespace between the '=' and the name and value. Thus to set the SNMP host to machine.domain.net, we would issue the configuration statement:

        <snmp>host=machine.domain.net</snmp>

If not specified, the default host is localhost, and the default community is public.

Variable Assignments

Variables are used as temporary holding locations for information returned from SNMP calls. The decision to use variables was made to obviate the necessity of making a different SNMP get call for each separate piece of information. Variable assignments follow the simple format listed above, where the variable and the value, this time the symbolic name of a SNMP object identifier, are separated only by an equals sign (no whitespace). For example: description=ifDescr The OIDs currently implemented are a subset of the IETF Management MIB. Support is available for the system, interface, ip, tcp, udp, icmp, and at modules. A list of the currently supported OIDs, and their symbolic equivalents, is given below:

                # system

                'sysDescr'      => "1.3.6.1.2.1.1.1",
                'sysObjectID'   => "1.3.6.1.2.1.1.2",
                'sysUpTime'     => "1.3.6.1.2.1.1.3",
                'sysContact'    => "1.3.6.1.2.1.1.4",
                'sysName'       => "1.3.6.1.2.1.1.5",
                'sysLocation'   => "1.3.6.1.2.1.1.6",
                'sysServices'   => "1.3.6.1.2.1.1.7",
                # interface
                'ifIndex'       => "1.3.6.1.2.1.2.2.1.1",
                'ifDescr'       => "1.3.6.1.2.1.2.2.1.2",
                'ifType'        => "1.3.6.1.2.1.2.2.1.3",
                'ifMtu'         => "1.3.6.1.2.1.2.2.1.4",
                'ifSpeed'       => "1.3.6.1.2.1.2.2.1.5",
                'ifPhysAddress' => "1.3.6.1.2.1.2.2.1.6",
                'ifAdminStatus' => "1.3.6.1.2.1.2.2.1.7",
                'ifOperStatus'  => "1.3.6.1.2.1.2.2.1.8",
                'ifLastChange'  => "1.3.6.1.2.1.2.2.1.9",
                'ifInOctets'    => "1.3.6.1.2.1.2.2.1.10",
                'ifInUcastPkts' => "1.3.6.1.2.1.2.2.1.11",
                'ifInNUcastPkts'=> "1.3.6.1.2.1.2.2.1.12",
                'ifInDiscards'  => "1.3.6.1.2.1.2.2.1.13",
                'ifInErrors'    => "1.3.6.1.2.1.2.2.1.14",
                'ifInUnknownProtos' => "1.3.6.1.2.1.2.2.1.15",
                'ifOutOctets'   => "1.3.6.1.2.1.2.2.1.16",
                'ifOutUcastPkts' => "1.3.6.1.2.1.2.2.1.17",
                'ifOutNUcastPkts' => "1.3.6.1.2.1.2.2.1.18",
                'ifOutDiscards' => "1.3.6.1.2.1.2.2.1.19",
                'ifOutErrors'   => "1.3.6.1.2.1.2.2.1.20",
                'ifOutQLen'     => "1.3.6.1.2.1.2.2.1.21",
                'ifSpecific'    => "1.3.6.1.2.1.2.2.1.22",
                # ip
                'ipForwarding'  => "1.3.6.1.2.4.1",
                'ipDefaultTTL'  => "1.3.6.1.2.4.2",
                'ipInReceives'  => "1.3.6.1.2.4.3",
                'ipInHdrErrors' => "1.3.6.1.2.4.4",
                'ipInAddrErrors' => "1.3.6.1.2.4.5",
                'ipForwDatagrams' => "1.3.6.1.2.4.6",
                'ipInUnknownProtos' => "1.3.6.1.2.4.7",
                'ipInDiscards'  => "1.3.6.1.2.4.8",
                'ipInDelivers'  => "1.3.6.1.2.4.9",
                'ipOutRequests' => "1.3.6.1.2.4.10",
                'ipOutDiscards' => "1.3.6.1.2.4.11",
                'ipOutNoRoutes' => "1.3.6.1.2.4.12",
                'ipReasmTimeout' => "1.3.6.1.2.4.13",
                'ipReasmReqds'  => "1.3.6.1.2.4.14",
                'ipReasmOKs'    => "1.3.6.1.2.4.15",
                'ipReasmFails'  => "1.3.6.1.2.4.16",
                'ipFragOKs'     => "1.3.6.1.2.4.17",
                'ipFragFails'   => "1.3.6.1.2.4.18",
                'ipFragCreates' => "1.3.6.1.2.4.19",
                'ipAdEntAddr'   => "1.3.6.1.2.4.20.1.1",
                'ipAdEntIfIndex' => "1.3.6.1.2.4.20.1.2",
                'ipAdEntNetMask' => "1.3.6.1.2.4.20.1.3",
                'ipAdEntBcastAddr' => "1.3.6.1.2.4.20.1.4",
                'ipAdEntEntReasmMaxSize' => "1.3.6.1.2.4.20.1.5",
                'ipRouteDest'   => "1.3.6.1.2.4.21.1.1",
                'ipRouteIfIndex' => "1.3.6.1.2.4.21.1.2",
                'ipRouteMetric1' => "1.3.6.1.2.4.21.1.3",
                'ipRouteMetric2' => "1.3.6.1.2.4.21.1.4",
                'ipRouteMetric3' => "1.3.6.1.2.4.21.1.5",
                'ipRouteMetric4' => "1.3.6.1.2.4.21.1.6",
                'ipRouteNextHop' => "1.3.6.1.2.4.21.1.7",
                'ipRouteType'   => "1.3.6.1.2.4.21.1.8",
                'ipRouteProto'  => "1.3.6.1.2.4.21.1.9",
                'ipRouteAge'    => "1.3.6.1.2.4.21.1.10",
                'ipRouteMask'   => "1.3.6.1.2.4.21.1.11",
                'ipRouteMetric5' => "1.3.6.1.2.4.21.1.12",
                'ipRouteInfo'   => "1.3.6.1.2.4.21.1.13",
                'ipNetToMediaIfIndex' => "1.3.6.1.2.1.4.22.1.1",
                'ipNetToMediaPhysAddress' => "1.3.6.1.2.1.4.22.1.2",
                'ipNetToMediaNetAddress' => "1.3.6.1.2.1.4.22.1.3",
                'ipNetToMediaType' => "1.3.6.1.2.1.4.22.1.4",
                'ipRoutingDiscards' => "1.3.6.1.2.4.23",
                # tcp
                'tcpRtoAlgorithm' => '1.3.6.1.2.1.6.1',
                'tcpRtoMin'     => '1.3.6.1.2.1.6.2',
                'tcpRtoMax'     => '1.3.6.1.2.1.6.3',
                'tcpMaxConn'    => '1.3.6.1.2.1.6.4',
                'tcpActiveOpens' => '1.3.6.1.2.1.6.5',
                'tcpPassiveOpens' => '1.3.6.1.2.1.6.6',
                'tcpAttemptFails' => '1.3.6.1.2.1.6.7',
                'tcpEstabResets' => '1.3.6.1.2.1.6.8',
                'tcpCurrEstab'  => '1.3.6.1.2.1.6.9',
                'tcpInSegs'     => '1.3.6.1.2.1.6.10',
                'tcpOutSegs'    => '1.3.6.1.2.1.6.11',
                'tcpRetransSets' => '1.3.6.1.2.1.6.12',
                'tcpConnState'  => '1.3.6.1.2.1.6.13.1.1',
                'tcpConnLocalAddress' => '1.3.6.1.2.1.6.13.1.2',
                'tcpConnLocalPort' => '1.3.6.1.2.1.6.13.1.3',
                'tcpConnRemAddress' => '1.3.6.1.2.1.6.13.1.4',
                'tcpConnRemPort' => '1.3.6.1.2.1.6.13.1.5',
                'tcpInErrs'     => '1.3.6.1.2.1.6.14',
                'tcpOutRsts'    => '1.3.6.1.2.1.6.15',
                # udp
                'udpInDatagrams' => '1.3.6.1.2.1.7.1',
                'udpNoPorts'    => '1.3.6.1.2.1.7.2',
                'udpInErrors'   => '1.3.6.1.2.1.7.3',
                'udpOutDatagrams' => '1.3.6.1.2.1.7.4',
                'udpLocalAddress' => '1.3.6.1.2.1.7.5.1.1',
                'udpLocalPort'  => '1.3.6.1.2.1.7.5.1.2',
                # at
                'atIfIndex'     => '1.3.6.1.2.1.3.1.1.1',
                'atPhysAddressIfIndex' => '1.3.6.1.2.1.3.1.1.2',
                'atNetAddress'  => '1.3.6.1.2.1.3.1.1.3',
                # icmp
                'icmpInMsgs'    => '1.3.6.1.2.1.5.1',   
                'icmpInErrors'  => '1.3.6.1.2.1.5.2',
                'icmpInDestUnreachs' => '1.3.6.1.2.1.5.3',
                'icmpInTimeExcds' => '1.3.6.1.2.1.5.4',
                'icmpInParmProbs' => '1.3.6.1.2.1.5.5',
                'icmpInSrcQuenchs' => '1.3.6.1.2.1.5.6',
                'icmpInRedirects' => '1.3.6.1.2.1.5.7',
                'icmpInEchos'   => '1.3.6.1.2.1.5.8',
                'icmpInEchoReps' => '1.3.6.1.2.1.5.9',
                'icmpInTimestamps' => '1.3.6.1.2.1.5.10',
                'icmpInTimestampsReps' => '1.3.6.1.2.1.5.11',
                'icmpInAddrMasks' => '1.3.6.1.2.1.5.12',
                'icmpInAddrMaskReps' => '1.3.6.1.2.1.5.13',
                'icmpOutMsgs'   => '1.3.6.1.2.1.5.14',
                'icmpOutErrors' => '1.3.6.1.2.1.5.15',
                'icmpOutDestUnreachs' => '1.3.6.1.2.1.5.16',
                'icmpOutTimeExcds' => '1.3.6.1.2.1.5.17',
                'icmpOutParmProbs' => '1.3.6.1.2.1.5.18',
                'icmpOutSrcQuenchs' => '1.3.6.1.2.1.5.19',
                'icmpOutRedirects' => '1.3.6.1.2.1.5.20',
                'icmpOutEchos'  => '1.3.6.1.2.1.5.21',
                'icmpOutEchoReps' => '1.3.6.1.2.1.5.22',
                'icmpOutTimestampsReps' => '1.3.6.1.2.1.5.23',
                'icmpOutTimestampsReps' => '1.3.6.1.2.1.5.24',
                'icmpOutAddrMasks' => '1.3.6.1.2.1.5.25',
                'icmpOutAddrMaskReps' => '1.3.6.1.2.1.5.26',

For example, to get the number of outbound and inbound errors on an ethernet interface, we would assign the ifOutErrors and ifInErrors OIDs to variables. Thus:

        <snmp> errorin=ifInErrors errorout=ifOutErrors </snmp>

Note that more than one command can be nested inside a single set of <snmp> tags, as long as they are separated by whitespace.

Commands

The following command statements are currently available:

connect initiates a connection with the SNMP host defined with the host configuration statement. This statement can be can be utilized multiple times in order to connect to several different machines, however any queries sent will be sent to the current connection.

query actually initiates the SNMP get for the information you have requested in your variables, contacting the host defined by the host configuration command, and storing the data in the proper variable.

extension(variable_name) adds an extension to the OID named by variable_name. Most OIDs require some form of extension (for example, the 'system' OIDs usually require an extension of 0, while interface OIDs require the interface number as an extension). The extension is merely appended to the OID value contained in the named variable.

print(variable_name) simply prints the information returned to a variable after a query command.

EXAMPLE

To put all this together, let us take a simple example: we wish to retrieve information concerning the ethernet interface on a host named 'host.domain.net'. Primarily we are concerned with the administrative status, mac address, and bytes transferred in and out of the interface. We would begin with the following block:

        <snmp>
                host=host.domain.net
                community=public
                connect
        </snmp>

This block defines the host and the SNMP community, and actually makes the connection to the host. This block can be placed anywhere within your HTML document, as long as it comes before your SNMP queries. Next, we must define the information that we wish to obtain:

        <snmp>
                description=ifDescr
                extension(description)=2
                mac=ifPhysAddress
                extension(mac)=2
                inbytes=ifInOctets
                extension(inbytes)
                outbytes=ifOutOctets
                extension(outbytes)
                query
        </snmp>

This block instantiates four variables: description, mac, inbytes, and outbytes, in which the information we wish to obtain will be stored. The extension commands tell the program that we are interested in interface 2. Finally, the query statement performs the SNMP get on the connected host. All that remains is to print out our data. Let us put it in tabular format:

        <table>
                <tr>
                        <td>
                                Description
                        </td>
                        <td>    
                                Mac Address     
                        </td>
                        <td>
                                Bytes In
                        </td>
                        <td>
                                Bytes Out
                        </td>
                </tr>
                <tr>
                        <td>
                                print(description)
                        </td>
                        <td>    
                                print(mac)     
                        </td>
                        <td>
                                print(inbytes)
                        </td>
                        <td>
                                print(outbytes)
                        </td>
                </tr>
        </table> 
This block merely prints out our information as an HTML table.  Mission accomplished.

AUTHOR

Chris Rigby