--- /dev/null
+=head1 NAME
+
+B<check_interfaces> - spong-network module to check for down intefaces via SNMP
+
+=head1 DESCRIPTION
+
+This is a plugin module for the Spong L<spong-network> program. It is a core
+Spong module. The B<check_interfaces> module checks for down network interfaces
+on a host by polling via SNMP. It reports any interfaces that are
+administratively up but operationally not up.
+
+=cut
+
+# Register the routine with the plugin registry
+$PLUGINS{'interfaces'} = \&check_interfaces;
+
+use BER "0.57"; # should be in eval
+use SNMP_Session "0.59"; # should be in eval
+use SNMP_util "0.57"; # should be in eval
+use Socket;
+
+# This check will connect to a unit and ask it to return the system group
+# If it can do that, then we assume it is ok - if it can't then something is wrong.
+
+sub check_interfaces {
+ my ($host ) = @_;
+ my ($color, $summary, $message ) = ( "green", "", "" );
+ my $snmp_session;
+ my ($community) = $HOSTS{$host}->{'snmp_community'} || 'public';
+
+ $snmp_session = SNMP_Session->open ($host, $community, 161);
+
+ if (! $snmp_session ) {
+ $color = 'red';
+ $summary = "Error creating session to $host";
+ $message = $SNMP_Session::errmsg . "\n";;
+ return ( $color, $summary, $message );
+ }
+
+ snmpmapOID('sysObjectID' => '1.3.6.1.2.1.1.2.0');
+
+ $SNMP_Session::suppress_warnings = 2;
+ my ($ifNumber) =
+ snmpget("$community\@$host",
+ 'ifNumber');
+
+ if ( $SNMP_Session::errmsg ) {
+ $color = 'red';
+ $summary = 'Error retreiving ifNumber';
+ $message = $SNMP_Session::errmsg . "\n";
+ return ( $color, $summary, $message );
+ }
+
+ debug ("interfaces - $ifNumber",8 );
+ if ($ifNumber == 0) {
+ $color = "yellow";
+ $summary = "$host has no interfaces";
+ $message = "$host has no interfaces\n";
+ debug ("interfaces - $host - $color, $summary", 4 );
+ return ($color, $summary, $message );
+ }
+
+ my (%sifdesc, %siftype, %sifadminstatus, %sifoperstatus);
+
+ $snmp_session->map_table ([
+ [1,3,6,1,2,1,2,2,1,1], # ifIndex
+ [1,3,6,1,2,1,2,2,1,2], # ifDescr
+ [1,3,6,1,2,1,2,2,1,3], # ifType
+ [1,3,6,1,2,1,2,2,1,7], # ifAdminStatus
+ [1,3,6,1,2,1,2,2,1,8] # ifOperStatus
+ ],
+ sub ($@) {
+ my ($rowindex,$index,$ifdescr,$iftype,$ifadminstatus,$ifoperstatus) = @_;
+
+ grep (defined $_ && ($_=pretty_print $_), ($index,$ifdescr,$iftype,$ifadminstatus,$ifoperstatus));
+ debug("interfaces - seen $ifdescr",8);
+ $sifdesc{$index} = $ifdescr;
+ $siftype{$index} = $iftype;
+ $sifadminstatus{$index} = $ifadminstatus;
+ $sifoperstatus{$index} = $ifoperstatus;
+ });
+
+ if ( $SNMP_Session::errmsg ) {
+ $color = 'red';
+ $summary = 'Error retreiving ifNumber';
+ $message = $SNMP_Session::errmsg . "\n";
+ return ( $color, $summary, $message );
+ }
+
+ my $index;
+ foreach $index ( sort { $a <=> $b } keys %sifdesc) {
+ $message .= "interface $index status:\n";
+ $message .= "\tifDescr: $sifdesc{$index}\n";
+ $message .= "\tifType: $siftype{$index}\n";
+ $message .= "\tifAdminStatus: $sifadminstatus{$index}\n";
+ $message .= "\tifOperStatus: $sifoperstatus{$index}\n";
+ # If interface is not up and is admin up, we got a problem
+ if ($sifoperstatus{$index} != 1 && $sifadminstatus{$index} != 1) {
+ $color = "red";
+ }
+ }
+
+ if ($color eq "red") {
+ $summary = "some interfaces are down";
+ } else {
+ $summary = "all interfaces up";
+ }
+
+ debug ("interfaces - $host - $color, $summary", 4 );
+ return ($color, $summary, $message );
+}
+
+__END__
+
+=head2 Output Returned
+
+=over 4
+
+=item Status
+
+If all interfaces are operationally up, a 'green' status is returned. If a host
+is found to have no interfaces a 'yellow' status is returned. Any interfaces
+that are operationally down and administratively up, a 'red' status is
+returned. Any SNMP session problems will also result in a 'red' status being
+returned.
+
+=item Summary Field
+
+In normal operation, the status field will show "all interfaces up". If one or
+more network interfaces are down, it will show "some interfaces are down".
+Otherwise the summary field will have a description of what the problem or
+anamoly is.
+
+=item Detail Message Field
+
+In normal opereration the detail message field will have a list of all of the
+network interfaces in the I<MIBII ifTable> table along with the interface
+description (I<ifDesc>), type (I<ifType>), administrative status
+(I<ifAdminStatus>) and operational status (I<ifOperStatus>). Otherwise this
+field will have a detailed description of the cause of an error.
+
+=back
+
+=head2 Configuration
+
+=over 4
+
+=item SNMP Community Name
+
+The default SNMP Community name is I<public>. To override the default name
+specify a C<snmp_community> attribute in a host's entry in the I<%HOSTS>
+variabile of the L<spong.conf> configuration file. See the
+L<Examples|"EXAMPLES") section for a detailed example.
+
+=back
+
+=head1 EXAMPLES
+
+ %HOSTS = ( 'hostname.my-inc.com' => { 'services' => 'interfaces',
+ 'ip_addr' => ['192.168.13.123'],
+ 'snmp_community' => 'local-read',
+ },
+ );
+
+
+=head1 SEE ALSO
+
+L<spong-network>, L<check_snmp>,
+L<spong-network Modules Template|spong-network-mod-template>,
+L<Spong Developer Guide|develop-guide>
+
+=head1 NOTES
+
+The B<check_interfaces> module use SNMP to poll a host. It retrieves the
+B<ifIndex>, B<ifDesc>, B<ifType>, B<ifAdminStatus>, and B<ifOperStatus> fields
+for every entry in the B<ifTable> table. The module then scans all of all of
+the network interfaces inretrieved from the table. Any interface that is
+administratively up and is not operationally up will result in an critical
+status (red) being return.
+
+=head1 RESTRICTIONS
+
+B<check_interfaces> uses the C<SNMP_Session>, C<SNMP_utils> and C<BER> modules
+from the B<SNMP_Session> package. The B<SNMP_Session> package must be installed
+in order for this module to work.
+
+The latest version of B<SNMP_Session> package can be obtained from:
+
+ http://www.switch.ch/misc/leinen/snmp/perl/index.html
+
+=head1 AUTHOR
+
+The original author is Mike Bayliss <F<mbayliss@datax.be>>. Extra debug code
+and enhancements added by Stephen L Johnson <F<sjohnson@monsters.org>>.
+
--- /dev/null
+=head1 NAME
+
+B<check_snmp> - spong-network module to check for proper SNMP agent operation
+
+=head1 DESCRIPTION
+
+This is a plugin module for the Spong L<spong-network> program. It is a core
+Spong module. The B<check_snmp> module checks for the SNMP agent running
+in the host for proper operation.
+
+The module check SNMP by issuing an I<snmpget> operation for the I<systemGroup>
+table of the host. If the operation is sucessfully, snmp service is deemed
+OK. The module also has an option check for the I<sysObjectId>. An expected
+I<sysObjectId> value can be specified to be checked against the I<sysObjectId>
+value retrieved in the snmpget operation. If the values don't agree, a
+critical (red) status is reported
+
+=cut
+
+# Register the routine with the plugin registry
+$PLUGINS{'snmp'} = \&check_snmp;
+
+use BER "0.57"; # should be in eval
+use SNMP_Session "0.59"; # should be in eval
+use SNMP_util "0.57"; # should be in eval
+use Socket;
+
+# This check will connect to a unit and ask it to return the system group
+# If it can do that, then we assume it is ok - if it can't then something is wrong.
+
+sub check_snmp {
+ my ($host ) = @_;
+ my ($color, $summary, $message ) = ( "green", "", "" );
+ my $snmp_session;
+ my ($community) = $HOSTS{$host}->{'snmp_community'} || 'public';
+ my ($expect) = $HOSTS{$host}->{'expect_objid'};
+
+ $snmp_session = SNMP_Session->open ($host, $community, 161);
+
+ if (! $snmp_session ) {
+ $color = 'red';
+ $summary = "Error creating session to $host";
+ $message = $SNMP_Session::errmsg . "\n";;
+ return ( $color, $summary, $message );
+ }
+
+ snmpmapOID('sysObjectID' => '1.3.6.1.2.1.1.2.0');
+
+ $SNMP_Session::suppress_warnings = 2;
+ my ($sysDescr,$sysUpTime,$sysContact,$sysName,$sysLocation,$sysObjectID) =
+ snmpget("$community\@$host",
+ 'sysDescr',
+ 'sysUpTime',
+ 'sysContact',
+ 'sysName',
+ 'sysLocation',
+ 'sysObjectID');
+
+ if ( $SNMP_Session::errmsg ) {
+ $color = 'red';
+ $summary = 'Error retreiving System Group information';
+ $message = $SNMP_Session::errmsg . "\n";
+ return ( $color, $summary, $message );
+ }
+
+ debug ("snmp - $sysObjectID", 4 );
+
+ if ($sysObjectID) {
+ $message = "retrieved system group from $host\n\n";
+ $message .= "sysDescr: $sysDescr\n";
+ $message .= "sysUpTime: $sysUpTime\n";
+ $message .= "sysContact: $sysContact\n";
+ $message .= "sysName: $sysName\n";
+ $message .= "sysLocation: $sysLocation\n";
+ $message .= "sysObjectID: $sysObjectID\n";
+ if ( $expect && "$sysObjectID" ne "$expect") {
+ $color = "red";
+ $summary = "wrong equipment type";
+ $message .= "sysObjectID should have been $expect\n";
+ } else {
+ $summary = "snmp ok";
+ }
+ } else {
+ $color = "red";
+ $summary = "can't retreive system group from $host";
+ $message = "can't retreive system group from $host\n";
+ }
+
+ $snmp_session->close();
+ debug ("snmp - $host - $color, $summary" );
+ return ($color, $summary, $message );
+}
+
+1;
+
+__END__
+
+=head2 Output Returned
+
+=over 4
+
+=item Status
+
+If the I<snmpget> operation is successfully, 'green' status is return. If an
+SNMP error occurs a 'red' status is returned.
+
+If an C<expect_objid> is specified for the host, a 'green' status is returned
+if the I<snmpget> operation is successful and the I<sysObjectId> value matches
+the C<expect_objid>. If the values don't match, a 'red' status is returned.
+
+=item Summary Field
+
+If there are no problems, "snmp ok" is returned. Otherwise the summary field
+will have a short description of that the problem or anamoly is.
+
+=item Detail Message Field
+
+If normal operation the detail message will have the values of the system
+description (B<sysDesc>), uptime (B<sysUpTime>), contact (B<sysContact>), name
+(B<sysName>), location (B<sysLocation>), and object id (B<sysObjectID>) fields
+from the System Group. If an C<expect_objid) was specified for the host and the
+retrived object id doesn't match, the expected value will also be listed.
+Otherwise this field will have a detailed description of the cause of an error.
+
+=back
+
+=head2 Configuration
+
+=over 4
+
+=item SNMP Community Name
+
+The default SNMP Community name is I<public>. To override the default name
+specify a C<snmp_community> attribute in a host's entry in the I<%HOSTS)
+variable in the L<spong.conf> configuration file. See the L<Examples|"EXAMPLES"
+section for a detailed example.
+
+=item Expected System Object ID
+
+You can specify an expected I<sysObjectID> value to be checked against the
+retrieved. Specify a C<expect_objid> attribute in a host's entry in the
+I<%HOSTS> variable in the L<spong.conf> configuration file. See the
+L<Examples|"EXAMPLES"> section for a detailed example.
+
+=back
+
+=head1 EXAMPLES
+
+ %HOSTS = ( 'hostname.my-inc.com' => { 'services' => 'snmp',
+ 'ip_addr' => ['192.168.13.123'],
+ 'snmp_community' => 'local-read',
+ 'expect_objid' =>
+ '1.3.6.1.4.1.2021.250.10',
+ );
+
+=head1 SEE ALSO
+
+L<spong-network>, L<check_interfaces>,
+L<spong-network Modules Template|spong-network-mod-template>,
+L<Spong Developer's Guide|developer-guide>
+
+=head1 NOTES
+
+The B<check_snmp> module uses an SNMP I<snmpget> operation to poll a host.
+It retrieves the values of the system description (B<sysDesc>), uptime
+(B<sysUpTime>), contact (B<sysContact>), name (B<sysName>), location
+(B<sysLocation>), and object id (B<sysObjectID>) fields from the System Group.
+If the I<snmpget> operation was successful, the snmp service is deemed OK.
+
+If an optional C<expect_objid> value is specified for the host, it will be
+compared to the I<sysObjectID> value retrieved from the host. If the values
+don't match a critical ('red') status is generated.
+
+=head1 RESTRICTIONS
+
+B<check_interfaces> uses the C<SNMP_Session>, C<SNMP_utils> and C<BER> modules
+from the B<SNMP_Session> package. The B<SNMP_Session> package must be installed
+in order for this module to work.
+
+The latest version of B<SNMP_Session> package can be obtained from:
+
+ http://www.switch.ch/misc/leinen/snmp/perl/index.html
+
+=head1 AUTHOR
+
+The original author is Mike Bayliss <F<mbayliss@datax.be>>. Extra debug code
+and enhancements added by Stephen L Johnson <F<sjohnson@monsters.org>>.
+