NAME¶
Net::SNMP - Object oriented interface to SNMP
SYNOPSIS¶
The Net::SNMP module implements an object oriented interface to the Simple
Network Management Protocol. Perl applications can use the module to retrieve
or update information on a remote host using the SNMP protocol. The module
supports SNMP version-1, SNMP version-2c (Community-Based SNMPv2), and SNMP
version-3. The Net::SNMP module assumes that the user has a basic
understanding of the Simple Network Management Protocol and related network
management concepts.
DESCRIPTION¶
The Net::SNMP module abstracts the intricate details of the Simple Network
Management Protocol by providing a high level programming interface to the
protocol. Each Net::SNMP object provides a one-to-one mapping between a Perl
object and a remote SNMP agent or manager. Once an object is created, it can
be used to perform the basic protocol exchange actions defined by SNMP.
A Net::SNMP object can be created such that it has either "blocking"
or "non-blocking" properties. By default, the methods used to send
SNMP messages do not return until the protocol exchange has completed
successfully or a timeout period has expired. This behavior gives the object a
"blocking" property because the flow of the code is stopped until
the method returns.
The optional named argument
-nonblocking can be passed to the object
constructor with a true value to give the object "non-blocking"
behavior. A method invoked by a non-blocking object queues the SNMP message
and returns immediately, allowing the flow of the code to continue. The queued
SNMP messages are not sent until an event loop is entered by calling the
"snmp_dispatcher()" method. When the SNMP messages are sent, any
response to the messages invokes the subroutine defined by the user when the
message was originally queued. The event loop exits when all messages have
been removed from the queue by either receiving a response, or by exceeding
the number of retries at the Transport Layer.
Blocking Objects¶
The default behavior of the methods associated with a Net::SNMP object is to
block the code flow until the method completes. For methods that initiate a
SNMP protocol exchange requiring a response, a hash reference containing the
results of the query is returned. The undefined value is returned by all
methods when a failure has occurred. The "error()" method can be
used to determine the cause of the failure.
The hash reference returned by a SNMP protocol exchange points to a hash
constructed from the VarBindList contained in the SNMP response message. The
hash is created using the ObjectName and the ObjectSyntax pairs in the
VarBindList. The keys of the hash consist of the OBJECT IDENTIFIERs in dotted
notation corresponding to each ObjectName in the VarBindList. The value of
each hash entry is set equal to the value of the corresponding ObjectSyntax.
This hash reference can also be retrieved using the
"var_bind_list()" method.
Non-blocking Objects¶
When a Net::SNMP object is created having non-blocking behavior, the invocation
of a method associated with the object returns immediately, allowing the flow
of the code to continue. When a method is invoked that would initiate a SNMP
protocol exchange requiring a response, either a true value (i.e. 0x1) is
returned immediately or the undefined value is returned if there was a
failure. The "error()" method can be used to determine the cause of
the failure.
The contents of the VarBindList contained in the SNMP response message can be
retrieved by calling the "var_bind_list()" method using the object
reference passed as the first argument to the callback. The value returned by
the "var_bind_list()" method is a hash reference created using the
ObjectName and the ObjectSyntax pairs in the VarBindList. The keys of the hash
consist of the OBJECT IDENTIFIERs in dotted notation corresponding to each
ObjectName in the VarBindList. The value of each hash entry is set equal to
the value of the corresponding ObjectSyntax. The undefined value is returned
if there has been a failure and the "error()" method may be used to
determine the reason.
METHODS¶
When named arguments are expected by the methods, two different styles are
supported. All examples in this documentation use the dashed-option style:
$object->method(-argument => $value);
However, the IO:: style is also allowed:
$object->method(Argument => $value);
- Non-blocking Objects Arguments
- When a Net::SNMP object has been created with a
"non-blocking" property, most methods that generate a SNMP
message take additional arguments to support this property.
- Callback
- Most methods associated with a non-blocking object have an
optional named argument called -callback. The -callback
argument expects a reference to a subroutine or to an array whose first
element must be a reference to a subroutine. The subroutine defined by the
-callback option is executed when a response to a SNMP message is
received, an error condition has occurred, or the number of retries for
the message has been exceeded.
When the -callback argument only contains a subroutine reference, the
subroutine is evaluated passing a reference to the original Net::SNMP
object as the only parameter. If the -callback argument was defined
as an array reference, all elements in the array are passed to subroutine
after the reference to the Net::SNMP object. The first element, which is
required to be a reference to a subroutine, is removed before the
remaining arguments are passed to that subroutine.
Once one method is invoked with the -callback argument, this argument
stays with the object and is used by any further calls to methods using
the -callback option if the argument is absent. The undefined value
may be passed to the -callback argument to delete the callback.
NOTE: The subroutine being passed with the -callback named
argument should not cause blocking itself. This will cause all the actions
in the event loop to be stopped, defeating the non-blocking property of
the Net::SNMP module.
- Delay
- An optional argument -delay can also be passed to
non-blocking objects. The -delay argument instructs the object to
wait the number of seconds passed to the argument before executing the
SNMP protocol exchange. The delay period starts when the event loop is
entered. The -delay parameter is applied to all methods associated
with the object once it is specified. The delay value must be set back to
0 seconds to disable the delay parameter.
- SNMPv3 Arguments
- A SNMP context is a collection of management information
accessible by a SNMP entity. An item of management information may exist
in more than one context and a SNMP entity potentially has access to many
contexts. The combination of a contextEngineID and a contextName
unambiguously identifies a context within an administrative domain. In a
SNMPv3 message, the contextEngineID and contextName are included as part
of the scopedPDU. All methods that generate a SNMP message optionally take
a -contextengineid and -contextname argument to configure
these fields.
- Context Engine ID
- The -contextengineid argument expects a hexadecimal
string representing the desired contextEngineID. The string must be 10 to
64 characters (5 to 32 octets) long and can be prefixed with an optional
"0x". Once the -contextengineid is specified it stays
with the object until it is changed again or reset to default by passing
in the undefined value. By default, the contextEngineID is set to match
the authoritativeEngineID of the authoritative SNMP engine.
- Context Name
- The contextName is passed as a string which must be 0 to 32
octets in length using the -contextname argument. The contextName
stays with the object until it is changed. The contextName defaults to an
empty string which represents the "default" context.
session() - create a new Net::SNMP object¶
($session, $error) = Net::SNMP->session(
[-hostname => $hostname,]
[-port => $port,]
[-localaddr => $localaddr,]
[-localport => $localport,]
[-nonblocking => $boolean,]
[-version => $version,]
[-domain => $domain,]
[-timeout => $seconds,]
[-retries => $count,]
[-maxmsgsize => $octets,]
[-translate => $translate,]
[-debug => $bitmask,]
[-community => $community,] # v1/v2c
[-username => $username,] # v3
[-authkey => $authkey,] # v3
[-authpassword => $authpasswd,] # v3
[-authprotocol => $authproto,] # v3
[-privkey => $privkey,] # v3
[-privpassword => $privpasswd,] # v3
[-privprotocol => $privproto,] # v3
);
This is the constructor for Net::SNMP objects. In scalar context, a reference to
a new Net::SNMP object is returned if the creation of the object is
successful. In list context, a reference to a new Net::SNMP object and an
empty error message string is returned. If a failure occurs, the object
reference is returned as the undefined value. The error string may be used to
determine the cause of the error.
Most of the named arguments passed to the constructor define basic attributes
for the object and are not modifiable after the object has been created. The
-timeout,
-retries,
-maxmsgsize,
-translate, and
-debug arguments are modifiable using an accessor method. See their
corresponding method definitions for a complete description of their usage,
default values, and valid ranges.
- Transport Domain Arguments
- The Net::SNMP module uses UDP/IPv4 as the default Transport
Domain to exchange SNMP messages between the local and remote devices. The
module also supports UDP/IPv6, TCP/IPv4, and TCP/IPv6 as alternative
Transport Domains. The -domain argument can be used to change the
Transport Domain by setting the value to one of the following strings:
'udp6', 'udp/ipv6'; 'tcp', 'tcp4', 'tcp/ipv4'; 'tcp6', or 'tcp/ipv6'. The
-domain argument also accepts the strings 'udp', 'udp4', or
'udp/ipv4' which correspond to the default Transport Domain of UDP/IPv4.
The transport address of the destination SNMP device can be specified using
the -hostname argument. This argument is optional and defaults to
"localhost". The destination port number can be specified as
part of the transport address or by using the -port argument.
Either a numeric port number or a textual service name can be specified. A
numeric port number in parentheses can optionally follow the service name.
This port number will be used if the service name cannot be resolved. If
the destination port number is not specified, the well-known SNMP port
number 161 is used.
By default the source transport address and port number are assigned
dynamically by the local device on which the Net::SNMP module is being
used. This dynamic assignment can be overridden by using the
-localaddr and -localport arguments. These arguments accept
the same values as the -hostname and -port arguments
respectively. The resolved address must correspond to a valid address of
an interface on the local device.
When using an IPv4 Transport Domain, the transport address can be specified
as either an IP network hostname or an IPv4 address in standard dotted
notation. The port information can be optionally appended to the hostname
or address delimited by a colon. The accepted IPv4 transport address
formats are "address", "address:port",
"hostname", and "hostname:port".
When using an IPv6 Transport Domain, the transport address can be specified
as an IP hostname (which will be looked up as a DNS quad-A record) or an
IPv6 address in presentation format. The port information can optionally
be included following a colon after the hostname or address. When
including this information after an IPv6 address, the address must be
enclosed in square brackets. The scope zone index (described in RFC 4007)
can be specified after the address as a decimal value delimited by a
percent sign. The accepted transport address formats for IPv6 are
"address", "address%zone", "[address]:port",
"[address%zone]:port", "hostname", and
"hostname:port".
- Security Model Arguments
- The -version argument controls which other arguments
are expected or required by the "session()" constructor. The
Net::SNMP module supports SNMPv1, SNMPv2c, and SNMPv3. The module defaults
to SNMPv1 if no -version argument is specified. The -version
argument expects either a digit (i.e. '1', '2', or '3') or a string
specifying the version (i.e. 'snmpv1', 'snmpv2c', or 'snmpv3') to define
the SNMP version.
The Security Model used by the Net::SNMP object is based on the SNMP version
associated with the object. If the SNMP version is SNMPv1 or SNMPv2c a
Community-based Security Model will be used, while the User-based Security
Model (USM) will be used if the version is SNMPv3.
- Community-based Security Model Argument
- If the Security Model is Community-based, the only argument
available is the -community argument. This argument expects a
string that is to be used as the SNMP community name. By default the
community name is set to 'public' if the argument is not present.
- User-based Security Model Arguments
- The User-based Security Model (USM) used by SNMPv3 requires
that a securityName be specified using the -username argument. The
creation of a Net::SNMP object with the version set to SNMPv3 will fail if
the -username argument is not present. The -username
argument expects a string 1 to 32 octets in length.
Different levels of security are allowed by the User-based Security Model
which address authentication and privacy concerns. A SNMPv3 Net::SNMP
object will derive the security level (securityLevel) based on which of
the following arguments are specified.
By default a securityLevel of 'noAuthNoPriv' is assumed. If the
-authkey or -authpassword arguments are specified, the
securityLevel becomes 'authNoPriv'. The -authpassword argument
expects a string which is at least 1 octet in length. Optionally, the
-authkey argument can be used so that a plain text password does
not have to be specified in a script. The -authkey argument expects
a hexadecimal string produced by localizing the password with the
authoritativeEngineID for the specific destination device. The
"snmpkey" utility included with the distribution can be used to
create the hexadecimal string (see snmpkey).
Two different hash algorithms are defined by SNMPv3 which can be used by the
Security Model for authentication. These algorithms are HMAC-MD5-96
"MD5" (RFC 1321) and HMAC-SHA-96 "SHA-1" (NIST FIPS
PUB 180-1). The default algorithm used by the module is HMAC-MD5-96. This
behavior can be changed by using the -authprotocol argument. This
argument expects either the string 'md5' or 'sha' to be passed to modify
the hash algorithm.
By specifying the arguments -privkey or -privpassword the
securityLevel associated with the object becomes 'authPriv'. According to
SNMPv3, privacy requires the use of authentication. Therefore, if either
of these two arguments are present and the -authkey or
-authpassword arguments are missing, the creation of the object
fails. The -privkey and -privpassword arguments expect the
same input as the -authkey and -authpassword arguments
respectively.
The User-based Security Model described in RFC 3414 defines a single
encryption protocol to be used for privacy. This protocol, CBC-DES
"DES" (NIST FIPS PUB 46-1), is used by default or if the string
'des' is passed to the -privprotocol argument. The module also
supports RFC 3826 which describes the use of CFB128-AES-128
"AES" (NIST FIPS PUB 197) in the USM. The AES encryption
protocol can be selected by passing 'aes' or 'aes128' to the
-privprotocol argument. By working with the Extended Security
Options Consortium <http://www.snmp.com/protocol/eso.shtml>, the
module also supports CBC-3DES-EDE "Triple-DES" (NIST FIPS 46-3)
in the User-based Security Model. This is defined in the draft
http://www.snmp.com/eso/draft-reeder-snmpv3-usm-3desede-00.txt
<http://www.snmp.com/eso/draft-reeder-snmpv3-usm-3desede-00.txt>.
The Triple-DES encryption protocol can be selected using the
-privprotocol argument with the string '3des' or '3desede'.
close() - clear the Transport Domain associated with the
object¶
$session->close();
This method clears the Transport Domain and any errors associated with the
object. Once closed, the Net::SNMP object can no longer be used to send or
receive SNMP messages.
snmp_dispatcher() - enter the non-blocking object event
loop¶
$session->snmp_dispatcher();
This method enters the event loop associated with non-blocking Net::SNMP
objects. The method exits when all queued SNMP messages have received a
response or have timed out at the Transport Layer. This method is also
exported as the stand alone function "snmp_dispatcher()" by default
(see "EXPORTS").
get_request() - send a SNMP get-request to the remote
agent¶
$result = $session->get_request(
[-callback => sub {},] # non-blocking
[-delay => $seconds,] # non-blocking
[-contextengineid => $engine_id,] # v3
[-contextname => $name,] # v3
-varbindlist => \@oids,
);
This method performs a SNMP get-request query to gather data from the remote
agent on the host associated with the Net::SNMP object. The message is built
using the list of OBJECT IDENTIFIERs in dotted notation passed to the method
as an array reference using the
-varbindlist argument. Each OBJECT
IDENTIFIER is placed into a single SNMP GetRequest-PDU in the same order that
it held in the original list.
A reference to a hash is returned in blocking mode which contains the contents
of the VarBindList. In non-blocking mode, a true value is returned when no
error has occurred. In either mode, the undefined value is returned when an
error has occurred. The "error()" method may be used to determine
the cause of the failure.
get_next_request() - send a SNMP get-next-request to the
remote agent¶
$result = $session->get_next_request(
[-callback => sub {},] # non-blocking
[-delay => $seconds,] # non-blocking
[-contextengineid => $engine_id,] # v3
[-contextname => $name,] # v3
-varbindlist => \@oids,
);
This method performs a SNMP get-next-request query to gather data from the
remote agent on the host associated with the Net::SNMP object. The message is
built using the list of OBJECT IDENTIFIERs in dotted notation passed to the
method as an array reference using the
-varbindlist argument. Each
OBJECT IDENTIFER is placed into a single SNMP GetNextRequest-PDU in the same
order that it held in the original list.
A reference to a hash is returned in blocking mode which contains the contents
of the VarBindList. In non-blocking mode, a true value is returned when no
error has occurred. In either mode, the undefined value is returned when an
error has occurred. The "error()" method may be used to determine
the cause of the failure.
set_request() - send a SNMP set-request to the remote
agent¶
$result = $session->set_request(
[-callback => sub {},] # non-blocking
[-delay => $seconds,] # non-blocking
[-contextengineid => $engine_id,] # v3
[-contextname => $name,] # v3
-varbindlist => \@oid_value,
);
This method is used to modify data on the remote agent that is associated with
the Net::SNMP object using a SNMP set-request. The message is built using a
list of values consisting of groups of an OBJECT IDENTIFIER, an object type,
and the actual value to be set. This list is passed to the method as an array
reference using the
-varbindlist argument. The OBJECT IDENTIFIERs in
each trio are to be in dotted notation. The object type is an octet
corresponding to the ASN.1 type of value that is to be set. Each of the
supported ASN.1 types have been defined and are exported by the package by
default (see "EXPORTS").
A reference to a hash is returned in blocking mode which contains the contents
of the VarBindList. In non-blocking mode, a true value is returned when no
error has occurred. In either mode, the undefined value is returned when an
error has occurred. The "error()" method may be used to determine
the cause of the failure.
trap() - send a SNMP trap to the remote manager¶
$result = $session->trap(
[-delay => $seconds,] # non-blocking
[-enterprise => $oid,]
[-agentaddr => $ipaddress,]
[-generictrap => $generic,]
[-specifictrap => $specific,]
[-timestamp => $timeticks,]
-varbindlist => \@oid_value,
);
This method sends a SNMP trap to the remote manager associated with the
Net::SNMP object. All arguments are optional and will be given the following
defaults in the absence of a corresponding named argument:
- •
- The default value for the trap -enterprise is
"1.3.6.1.4.1", which corresponds to
"iso.org.dod.internet.private.enterprises". The enterprise value
is expected to be an OBJECT IDENTIFER in dotted notation.
- •
- When the Transport Domain is UDP/IPv4 or TCP/IPv4, the
default value for the trap -agentaddr is the IP address associated
with the interface on which the trap will be transmitted. For other
Transport Domains the -agentaddr is defaulted to
"0.0.0.0". When specified, the agent-addr is expected to be an
IpAddress in dotted notation.
- •
- The default value for the -generictrap type is 6
which corresponds to "enterpriseSpecific". The generic-trap
types are defined and can be exported upon request (see
"EXPORTS").
- •
- The default value for the -specifictrap type is 0.
No pre-defined values are available for specific-trap types.
- •
- The default value for the trap -timestamp is the
"uptime" of the script. The "uptime" of the script is
the number of hundredths of seconds that have elapsed since the script
began running. The time-stamp is expected to be a TimeTicks number in
hundredths of seconds.
- •
- The default value for the trap -varbindlist is an
empty array reference. The variable-bindings are expected to be in an
array format consisting of groups of an OBJECT IDENTIFIER, an object type,
and the actual value of the object. This is identical to the list expected
by the "set_request()" method. The OBJECT IDENTIFIERs in each
trio are to be in dotted notation. The object type is an octet
corresponding to the ASN.1 type for the value. Each of the supported types
have been defined and are exported by default (see
"EXPORTS").
A true value is returned when the method is successful. The undefined value is
returned when a failure has occurred. The "error()" method can be
used to determine the cause of the failure. Since there are no
acknowledgements for Trap-PDUs, there is no way to determine if the remote
host actually received the trap.
NOTE: When the object is in non-blocking mode, the trap is not sent until
the event loop is entered and no callback is ever executed.
NOTE: This method can only be used when the version of the object is set
to SNMPv1.
get_bulk_request() - send a SNMP get-bulk-request to the
remote agent¶
$result = $session->get_bulk_request(
[-callback => sub {},] # non-blocking
[-delay => $seconds,] # non-blocking
[-contextengineid => $engine_id,] # v3
[-contextname => $name,] # v3
[-nonrepeaters => $non_reps,]
[-maxrepetitions => $max_reps,]
-varbindlist => \@oids,
);
This method performs a SNMP get-bulk-request query to gather data from the
remote agent on the host associated with the Net::SNMP object. All arguments
are optional except
-varbindlist and will be given the following
defaults in the absence of a corresponding named argument:
- •
- The default value for the get-bulk-request
-nonrepeaters is 0. The non-repeaters value specifies the number of
variables in the variable-bindings list for which a single successor is to
be returned.
- •
- The default value for the get-bulk-request
-maxrepetitions is 0. The max-repetitions value specifies the
number of successors to be returned for the remaining variables in the
variable-bindings list.
- •
- The -varbindlist argument expects an array reference
consisting of a list of OBJECT IDENTIFIERs in dotted notation. Each OBJECT
IDENTIFER is placed into a single SNMP GetBulkRequest-PDU in the same
order that it held in the original list.
A reference to a hash is returned in blocking mode which contains the contents
of the VarBindList. In non-blocking mode, a true value is returned when no
error has occurred. In either mode, the undefined value is returned when an
error has occurred. The "error()" method may be used to determine
the cause of the failure.
NOTE: This method can only be used when the version of the object is set
to SNMPv2c or SNMPv3.
$result = $session->inform_request(
[-callback => sub {},] # non-blocking
[-delay => $seconds,] # non-blocking
[-contextengineid => $engine_id,] # v3
[-contextname => $name,] # v3
-varbindlist => \@oid_value,
);
This method is used to provide management information to the remote manager
associated with the Net::SNMP object using an inform-request. The message is
built using a list of values consisting of groups of an OBJECT IDENTIFIER, an
object type, and the actual value to be identified. This list is passed to the
method as an array reference using the
-varbindlist argument. The
OBJECT IDENTIFIERs in each trio are to be in dotted notation. The object type
is an octet corresponding to the ASN.1 type of value that is to be identified.
Each of the supported ASN.1 types have been defined and are exported by the
package by default (see "EXPORTS").
The first two variable-bindings fields in the inform-request are specified by
SNMPv2 and should be:
- •
- sysUpTime.0 - ('1.3.6.1.2.1.1.3.0', TIMETICKS,
$timeticks)
- •
- snmpTrapOID.0 - ('1.3.6.1.6.3.1.1.4.1.0',
OBJECT_IDENTIFIER, $oid)
A reference to a hash is returned in blocking mode which contains the contents
of the VarBindList. In non-blocking mode, a true value is returned when no
error has occurred. In either mode, the undefined value is returned when an
error has occurred. The "error()" method may be used to determine
the cause of the failure.
NOTE: This method can only be used when the version of the object is set
to SNMPv2c or SNMPv3.
snmpv2_trap() - send a SNMP snmpV2-trap to the remote
manager¶
$result = $session->snmpv2_trap(
[-delay => $seconds,] # non-blocking
-varbindlist => \@oid_value,
);
This method sends a snmpV2-trap to the remote manager associated with the
Net::SNMP object. The message is built using a list of values consisting of
groups of an OBJECT IDENTIFIER, an object type, and the actual value to be
identified. This list is passed to the method as an array reference using the
-varbindlist argument. The OBJECT IDENTIFIERs in each trio are to be in
dotted notation. The object type is an octet corresponding to the ASN.1 type
of value that is to be identified. Each of the supported ASN.1 types have been
defined and are exported by the package by default (see "EXPORTS").
The first two variable-bindings fields in the snmpV2-trap are specified by
SNMPv2 and should be:
- •
- sysUpTime.0 - ('1.3.6.1.2.1.1.3.0', TIMETICKS,
$timeticks)
- •
- snmpTrapOID.0 - ('1.3.6.1.6.3.1.1.4.1.0',
OBJECT_IDENTIFIER, $oid)
A true value is returned when the method is successful. The undefined value is
returned when a failure has occurred. The "error()" method can be
used to determine the cause of the failure. Since there are no
acknowledgements for SNMPv2-Trap-PDUs, there is no way to determine if the
remote host actually received the snmpV2-trap.
NOTE: When the object is in non-blocking mode, the snmpV2-trap is not
sent until the event loop is entered and no callback is ever executed.
NOTE: This method can only be used when the version of the object is set
to SNMPv2c. SNMPv2-Trap-PDUs are supported by SNMPv3, but require the sender
of the message to be an authoritative SNMP engine which is not currently
supported by the Net::SNMP module.
get_table() - retrieve a table from the remote agent¶
$result = $session->get_table(
[-callback => sub {},] # non-blocking
[-delay => $seconds,] # non-blocking
[-contextengineid => $engine_id,] # v3
[-contextname => $name,] # v3
-baseoid => $oid,
[-maxrepetitions => $max_reps,] # v2c/v3
);
This method performs repeated SNMP get-next-request or get-bulk-request (when
using SNMPv2c or SNMPv3) queries to gather data from the remote agent on the
host associated with the Net::SNMP object. The first message sent is built
using the OBJECT IDENTIFIER in dotted notation passed to the method by the
-baseoid argument. Repeated SNMP requests are issued until the OBJECT
IDENTIFIER in the response is no longer a child of the base OBJECT IDENTIFIER.
The
-maxrepetitions argument can be used to specify the max-repetitions
value that is passed to the get-bulk-requests when using SNMPv2c or SNMPv3. If
this argument is not present, a value is calculated based on the maximum
message size for the Net::SNMP object. If the value is set to 1 or less,
get-next-requests will be used for the queries instead of get-bulk-requests.
A reference to a hash is returned in blocking mode which contains the contents
of the VarBindList. In non-blocking mode, a true value is returned when no
error has occurred. In either mode, the undefined value is returned when an
error has occurred. The "error()" method may be used to determine
the cause of the failure.
WARNING: Results from this method can become very large if the base
OBJECT IDENTIFIER is close to the root of the SNMP MIB tree.
get_entries() - retrieve table entries from the remote
agent¶
$result = $session->get_entries(
[-callback => sub {},] # non-blocking
[-delay => $seconds,] # non-blocking
[-contextengineid => $engine_id,] # v3
[-contextname => $name,] # v3
-columns => \@columns,
[-startindex => $start,]
[-endindex => $end,]
[-maxrepetitions => $max_reps,] # v2c/v3
);
This method performs repeated SNMP get-next-request or get-bulk-request (when
using SNMPv2c or SNMPv3) queries to gather data from the remote agent on the
host associated with the Net::SNMP object. Each message specifically requests
data for each OBJECT IDENTIFIER specified in the
-columns array. The
OBJECT IDENTIFIERs must correspond to column entries for a conceptual row in a
table. They may however be columns in different tables as long as each table
is indexed the same way. The optional
-startindex and
-endindex
arguments may be specified to limit the query to specific rows in the
table(s).
The
-startindex can be specified as a single decimal value or in dotted
notation if the index associated with the entry so requires. If the
-startindex is specified, it will be include as part of the query
results. If no
-startindex is specified, the first request message will
be sent without an index. To insure that the
-startindex is included,
the last sub-identifier in the index is decremented by one. If the last
sub-identifier has a value of zero, the sub-identifier is removed from the
index.
The optional
-endindex argument can be specified as a single decimal
value or in dotted notation. If the
-endindex is specified, it will be
included as part of the query results. If no
-endindex is specified,
repeated SNMP requests are issued until the response no longer returns entries
matching any of the columns specified in the
-columns array.
The
-maxrepetitions argument can be used to specify the max-repetitions
value that is passed to the get-bulk-requests when using SNMPv2c or SNMPv3. If
this argument is not present, a value is calculated based on the maximum
message size of the object and the number of columns specified in the
-columns array. If the value is set to 1 or less, get-next-requests
will be used for the queries instead of get-bulk-requests.
A reference to a hash is returned in blocking mode which contains the contents
of the VarBindList. In non-blocking mode, a true value is returned when no
error has occurred. In either mode, the undefined value is returned when an
error has occurred. The "error()" method may be used to determine
the cause of the failure.
version() - get the SNMP version from the object¶
$rfc_version = $session->version();
This method returns the current value for the SNMP version associated with the
object. The returned value is the corresponding version number defined by the
RFCs for the protocol version field (i.e. SNMPv1 == 0, SNMPv2c == 1, and
SNMPv3 == 3). The RFC versions are defined as constant by the module and can
be exported by request (see "EXPORTS").
error() - get the current error message from the
object¶
$error_message = $session->error();
This method returns a text string explaining the reason for the last error. An
empty string is returned if no error has occurred.
hostname() - get the hostname associated with the
object¶
$hostname = $session->hostname();
This method returns the parsed hostname string that is associated with the
object. Any port information and formatting that can be included with the
corresponding "session()" constructor argument will be stripped and
not included as part of the returned string.
error_status() - get the current SNMP error-status from
the object¶
$error_status = $session->error_status();
This method returns the numeric value of the error-status contained in the last
SNMP message received by the object.
error_index() - get the current SNMP error-index from the
object¶
$error_index = $session->error_index();
This method returns the numeric value of the error-index contained in the last
SNMP message received by the object.
var_bind_list() - get the hash reference for the
VarBindList values¶
$values = $session->var_bind_list();
This method returns a hash reference created using the ObjectName and the
ObjectSyntax pairs in the VarBindList of the last SNMP message received by the
object. The keys of the hash consist of the OBJECT IDENTIFIERs in dotted
notation corresponding to each ObjectName in the VarBindList. If any of the
OBJECT IDENTIFIERs passed to the request method began with a leading dot, all
of the OBJECT IDENTIFIER hash keys will be prefixed with a leading dot. If
duplicate OBJECT IDENTIFIERs are present in the VarBindList they will be
padded with spaces to make them an unique hash key. The value of each hash
entry is set equal to the value of the corresponding ObjectSyntax. The
undefined value is returned if there has been a failure.
var_bind_names() - get the array of the ObjectNames in the
VarBindList¶
@names = $session->var_bind_names();
This method returns an array containing the OBJECT IDENTIFIERs corresponding to
the ObjectNames in the VarBindList in the order that they were received in the
last SNMP message. The entries in the array will map directly to the keys in
the hash reference returned by the methods that perform SNMP message exchanges
and by the "var_bind_list()" and "var_bind_types()"
methods. The array returned for the convenience methods
"get_table()" and "get_entries()" will be in
lexicographical order. An empty array is returned if there has been a failure.
var_bind_types() - get the hash reference for the
VarBindList ASN.1 types¶
$types = $session->var_bind_types();
This method returns a hash reference created using the ObjectName and the ASN.1
type of the ObjectSyntax in the VarBindList of the last SNMP message received
by the object. The keys of the hash consist of the OBJECT IDENTIFIERs in
dotted notation corresponding to each ObjectName in the VarBindList. The value
of each hash entry is set equal to the ASN.1 type of the corresponding
ObjectSyntax. Constants for the supported ASN.1 types have been defined and
are exported by the package by default (see "EXPORTS"). The
undefined value is returned if there has been a failure.
timeout() - set or get the current timeout period for the
object¶
$seconds = $session->timeout([$seconds]);
This method returns the current value for the Transport Layer timeout for the
Net::SNMP object. This value is the number of seconds that the object will
wait for a response from the agent on the remote host. The default timeout is
5.0 seconds.
If a parameter is specified, the timeout for the object is set to the provided
value if it falls within the range 1.0 to 60.0 seconds. The undefined value is
returned upon an error and the "error()" method may be used to
determine the cause.
retries() - set or get the current retry count for the
object¶
$count = $session->retries([$count]);
This method returns the current value for the number of times to retry sending a
SNMP message to the remote host. The default number of retries is 1.
If a parameter is specified, the number of retries for the object is set to the
provided value if it falls within the range 0 to 20. The undefined value is
returned upon an error and the "error()" method may be used to
determine the cause.
max_msg_size() - set or get the current maxMsgSize for the
object¶
$octets = $session->max_msg_size([$octets]);
This method returns the current value for the maximum message size (maxMsgSize)
for the Net::SNMP object. This value is the largest message size in octets
that can be prepared or processed by the object. The default maxMsgSize is
1472 octets for UDP/IPv4, 1452 octets for UDP/IPv6, 1460 octets for TCP/IPv4,
and 1440 octets for TCP/IPv6.
If a parameter is specified, the maxMsgSize is set to the provided value if it
falls within the range 484 to 65535 octets. The undefined value is returned
upon an error and the "error()" method may be used to determine the
cause.
NOTE: When using SNMPv3, the maxMsgSize is actually contained in the SNMP
message (as msgMaxSize). If the value received from a remote device is less
than the current maxMsgSize, the size is automatically adjusted to be the
lower value.
translate() - enable or disable the translation mode for
the object¶
$mask = $session->translate([
$mode |
[ # Perl anonymous ARRAY reference
['-all' => $mode0,]
['-octetstring' => $mode1,]
['-null' => $mode2,]
['-timeticks' => $mode3,]
['-opaque' => $mode4,]
['-nosuchobject' => $mode5,]
['-nosuchinstance' => $mode6,]
['-endofmibview' => $mode7,]
['-unsigned' => $mode8]
]
]);
When the object decodes the GetResponse-PDU that is returned in response to a
SNMP message, certain values are translated into a more "human
readable" form. By default the following translations occur:
- •
- OCTET STRINGs and Opaques containing any octet which is not
part of the character set defined as a DisplayString in RFC 2679 are
converted into a hexadecimal representation prefixed with "0x".
The control codes NUL(0x00), BEL(0x07), BS(0x08), HT(0x09), LF(0x0A),
VT(0x0b), FF(0x0C), and CR(0x0D) are part of the character set and will
not trigger translation. The sequence 'CR x' for any x other than LF or
NUL is illegal and will trigger translation.
- •
- TimeTicks integer values are converted to a time
format.
- •
- NULL values return the string "NULL" instead of
an empty string.
- •
- noSuchObject exception values return the string
"noSuchObject" instead of an empty string.
- •
- noSuchInstance exception values return the string
"noSuchInstance" instead of an empty string.
- •
- endOfMibView exception values return the string
"endOfMibView" instead of an empty string.
- •
- Counter64, Counter, Gauge, and TimeTick values that have
been incorrectly encoded as signed negative values are returned as
unsigned values.
The "translate()" method can be invoked with two different types of
arguments.
If the argument passed is any Perl variable type except an array reference, the
translation mode for all ASN.1 types is set to either enabled or disabled,
depending on the value of the passed parameter. Any value that Perl would
treat as a true value will set the mode to be enabled for all types, while a
false value will disable translation for all types.
A reference to an array can be passed to the "translate()" method in
order to define the translation mode on a per ASN.1 type basis. The array is
expected to contain a list of named argument pairs for each ASN.1 type that is
to be modified. The arguments in the list are applied in the order that they
are passed in via the array. Arguments at the end of the list supercede those
passed earlier in the list. The argument "-all" can be used to
specify that the mode is to apply to all ASN.1 types. Only the arguments for
the ASN.1 types that are to be modified need to be included in the list.
The "translate()" method returns a bit mask indicating which ASN.1
types are to be translated. Definitions of the bit to ASN.1 type mappings can
be exported using the
:translate tag (see "EXPORTS"). The
undefined value is returned upon an error and the "error()" method
may be used to determine the cause.
debug() - set or get the debug mode for the module¶
$mask = $session->debug([$mask]);
This method is used to enable or disable debugging for the Net::SNMP module.
Debugging can be enabled on a per component level as defined by a bit mask
passed to the "debug()" method. The bit mask is broken up as
follows:
- •
- 0x02 - Message or PDU encoding and decoding
- •
- 0x04 - Transport Layer
- •
- 0x08 - Dispatcher
- •
- 0x10 - Message Processing
- •
- 0x20 - Security
Symbols representing these bit mask values are defined by the module and can be
exported using the
:debug tag (see "EXPORTS"). If a
non-numeric value is passed to the "debug()" method, it is evaluated
in boolean context. Debugging for all of the components is then enabled or
disabled based on the resulting truth value.
The current debugging mask is returned by the method. Debugging can also be
enabled using the stand alone function "snmp_debug()". This function
can be exported by request (see "EXPORTS").
SUBROUTINES¶
oid_base_match() - determine if an OID has a specified OID
base¶
$value = oid_base_match($base_oid, $oid);
This function takes two OBJECT IDENTIFIERs in dotted notation and returns a true
value (i.e. 0x1) if the second OBJECT IDENTIFIER is equal to or is a child of
the first OBJECT IDENTIFIER in the SNMP Management Information Base (MIB).
This function can be used in conjunction with the
"get-next-request()" or "get-bulk-request()" methods to
determine when a OBJECT IDENTIFIER in the GetResponse-PDU is no longer in the
desired MIB tree branch.
oid_lex_cmp() - compare two OBJECT IDENTIFIERs
lexicographically¶
$cmp = oid_lex_cmp($oid1, $oid2);
This function takes two OBJECT IDENTIFIERs in dotted notation and returns one of
the values 1, 0, -1 if $oid1 is respectively lexicographically greater, equal,
or less than $oid2.
oid_lex_sort() - sort a list of OBJECT IDENTIFIERs
lexicographically¶
@sorted_oids = oid_lex_sort(@oids);
This function takes a list of OBJECT IDENTIFIERs in dotted notation and returns
the listed sorted in lexicographical order.
$text = snmp_type_ntop($type);
This function takes an ASN.1 type octet and returns a text string suitable for
presentation. Some ASN.1 type definitions map to the same octet value when
encoded. This method cannot distinguish between these multiple mappings and
the most basic type name will be returned.
$time = ticks_to_time($timeticks);
This function takes an ASN.1 TimeTicks value and returns a string representing
the time defined by the value. The TimeTicks value is expected to be a
non-negative integer value representing the time in hundredths of a second
since some epoch. The returned string will display the time in days, hours,
and seconds format according to the value of the TimeTicks argument.
EXPORTS¶
The Net::SNMP module uses the
Exporter module to export useful constants
and subroutines. These exportable symbols are defined below and follow the
rules and conventions of the
Exporter module (see Exporter).
- Default
- &snmp_dispatcher, INTEGER, INTEGER32, OCTET_STRING,
OBJECT_IDENTIFIER, IPADDRESS, COUNTER, COUNTER32, GAUGE, GAUGE32,
UNSIGNED32, TIMETICKS, OPAQUE, COUNTER64, NOSUCHOBJECT, NOSUCHINSTANCE,
ENDOFMIBVIEW
- Exportable
- &snmp_debug, &snmp_dispatcher, &snmp_type_ntop,
&oid_base_match, &oid_lex_cmp,
&oid_lex_sort,&ticks_to_time, INTEGER, INTEGER32, OCTET_STRING,
NULL, OBJECT_IDENTIFIER, SEQUENCE, IPADDRESS, COUNTER, COUNTER32, GAUGE,
GAUGE32, UNSIGNED32, TIMETICKS, OPAQUE, COUNTER64, NOSUCHOBJECT,
NOSUCHINSTANCE, ENDOFMIBVIEW, GET_REQUEST, GET_NEXT_REQUEST, GET_RESPONSE,
SET_REQUEST, TRAP, GET_BULK_REQUEST, INFORM_REQUEST, SNMPV2_TRAP, REPORT,
DEBUG_ALL, DEBUG_NONE, DEBUG_MESSAGE, DEBUG_TRANSPORT,
DEBUG_DISPATCHER,DEBUG_PROCESSING, DEBUG_SECURITY, COLD_START, WARM_START,
LINK_DOWN, LINK_UP, AUTHENTICATION_FAILURE, EGP_NEIGHBOR_LOSS,
ENTERPRISE_SPECIFIC, SNMP_VERSION_1, SNMP_VERSION_2C, SNMP_VERSION_3,
SNMP_PORT, SNMP_TRAP_PORT, TRANSLATE_NONE,TRANSLATE_OCTET_STRING,
TRANSLATE_NULL, TRANSLATE_TIMETICKS,
TRANSLATE_OPAQUE,TRANSLATE_NOSUCHOBJECT, TRANSLATE_NOSUCHINSTANCE,
TRANSLATE_ENDOFMIBVIEW, TRANSLATE_UNSIGNED, TRANSLATE_ALL
- Tags
- :asn1
- INTEGER, INTEGER32, OCTET_STRING, NULL, OBJECT_IDENTIFIER,
SEQUENCE, IPADDRESS, COUNTER, COUNTER32, GAUGE, GAUGE32, UNSIGNED32,
TIMETICKS, OPAQUE, COUNTER64, NOSUCHOBJECT, NOSUCHINSTANCE, ENDOFMIBVIEW,
GET_REQUEST, GET_NEXT_REQUEST, GET_RESPONSE, SET_REQUEST, TRAP,
GET_BULK_REQUEST, INFORM_REQUEST, SNMPV2_TRAP, REPORT
- :debug
- &snmp_debug, DEBUG_ALL, DEBUG_NONE, DEBUG_MESSAGE,
DEBUG_TRANSPORT, DEBUG_DISPATCHER, DEBUG_PROCESSING, DEBUG_SECURITY
- :generictrap
- COLD_START, WARM_START, LINK_DOWN, LINK_UP,
AUTHENTICATION_FAILURE, EGP_NEIGHBOR_LOSS, ENTERPRISE_SPECIFIC
- :snmp
- &snmp_debug, &snmp_dispatcher, &snmp_type_ntop,
&oid_base_match, &oid_lex_cmp, &oid_lex_sort,
&ticks_to_time, SNMP_VERSION_1, SNMP_VERSION_2C, SNMP_VERSION_3,
SNMP_PORT, SNMP_TRAP_PORT
- :translate
- TRANSLATE_NONE, TRANSLATE_OCTET_STRING, TRANSLATE_NULL,
TRANSLATE_TIMETICKS, TRANSLATE_OPAQUE, TRANSLATE_NOSUCHOBJECT,
TRANSLATE_NOSUCHINSTANCE, TRANSLATE_ENDOFMIBVIEW, TRANSLATE_UNSIGNED,
TRANSLATE_ALL
- :ALL
- All of the above exportable items.
EXAMPLES¶
1. Blocking SNMPv1 get-request for sysUpTime¶
This example gets the sysUpTime from a remote host.
#! /usr/local/bin/perl
use strict;
use warnings;
use Net::SNMP;
my $OID_sysUpTime = '1.3.6.1.2.1.1.3.0';
my ($session, $error) = Net::SNMP->session(
-hostname => shift || 'localhost',
-community => shift || 'public',
);
if (!defined $session) {
printf "ERROR: %s.\n", $error;
exit 1;
}
my $result = $session->get_request(-varbindlist => [ $OID_sysUpTime ],);
if (!defined $result) {
printf "ERROR: %s.\n", $session->error();
$session->close();
exit 1;
}
printf "The sysUpTime for host '%s' is %s.\n",
$session->hostname(), $result->{$OID_sysUpTime};
$session->close();
exit 0;
This example sets the sysContact information on the remote host to "Help
Desk x911". The named arguments passed to the "session()"
constructor are for the demonstration of syntax only. These parameters will
need to be set according to the SNMPv3 parameters of the remote host. The
"snmpkey" utility included with the distribution can be used to
create the key values.
#! /usr/local/bin/perl
use strict;
use warnings;
use Net::SNMP;
my $OID_sysContact = '1.3.6.1.2.1.1.4.0';
my ($session, $error) = Net::SNMP->session(
-hostname => 'myv3host.example.com',
-version => 'snmpv3',
-username => 'myv3Username',
-authprotocol => 'sha1',
-authkey => '0x6695febc9288e36282235fc7151f128497b38f3f',
-privprotocol => 'des',
-privkey => '0x6695febc9288e36282235fc7151f1284',
);
if (!defined $session) {
printf "ERROR: %s.\n", $error;
exit 1;
}
my $result = $session->set_request(
-varbindlist => [ $OID_sysContact, OCTET_STRING, 'Help Desk x911' ],
);
if (!defined $result) {
printf "ERROR: %s.\n", $session->error();
$session->close();
exit 1;
}
printf "The sysContact for host '%s' was set to '%s'.\n",
$session->hostname(), $result->{$OID_sysContact};
$session->close();
exit 0;
3. Non-blocking SNMPv2c get-bulk-request for ifTable¶
This example gets the contents of the ifTable by sending get-bulk-requests until
the responses are no longer part of the ifTable. The ifTable can also be
retrieved using the "get_table()" method. The ifPhysAddress object
in the table has a syntax of an OCTET STRING. By default, translation is
enabled and non-printable OCTET STRINGs are translated into a hexadecimal
format. Sometimes the OCTET STRING contains all printable characters and this
produces unexpected output when it is not translated. The example turns off
translation for OCTET STRINGs and specifically formats the output for the
ifPhysAddress objects.
#! /usr/local/bin/perl
use strict;
use warnings;
use Net::SNMP qw(:snmp);
my $OID_ifTable = '1.3.6.1.2.1.2.2';
my $OID_ifPhysAddress = '1.3.6.1.2.1.2.2.1.6';
my ($session, $error) = Net::SNMP->session(
-hostname => shift || 'localhost',
-community => shift || 'public',
-nonblocking => 1,
-translate => [-octetstring => 0],
-version => 'snmpv2c',
);
if (!defined $session) {
printf "ERROR: %s.\n", $error;
exit 1;
}
my %table; # Hash to store the results
my $result = $session->get_bulk_request(
-varbindlist => [ $OID_ifTable ],
-callback => [ \&table_callback, \%table ],
-maxrepetitions => 10,
);
if (!defined $result) {
printf "ERROR: %s\n", $session->error();
$session->close();
exit 1;
}
# Now initiate the SNMP message exchange.
snmp_dispatcher();
$session->close();
# Print the results, specifically formatting ifPhysAddress.
for my $oid (oid_lex_sort(keys %table)) {
if (!oid_base_match($OID_ifPhysAddress, $oid)) {
printf "%s = %s\n", $oid, $table{$oid};
} else {
printf "%s = %s\n", $oid, unpack 'H*', $table{$oid};
}
}
exit 0;
sub table_callback
{
my ($session, $table) = @_;
my $list = $session->var_bind_list();
if (!defined $list) {
printf "ERROR: %s\n", $session->error();
return;
}
# Loop through each of the OIDs in the response and assign
# the key/value pairs to the reference that was passed with
# the callback. Make sure that we are still in the table
# before assigning the key/values.
my @names = $session->var_bind_names();
my $next = undef;
while (@names) {
$next = shift @names;
if (!oid_base_match($OID_ifTable, $next)) {
return; # Table is done.
}
$table->{$next} = $list->{$next};
}
# Table is not done, send another request, starting at the last
# OBJECT IDENTIFIER in the response. No need to include the
# calback argument, the same callback that was specified for the
# original request will be used.
my $result = $session->get_bulk_request(
-varbindlist => [ $next ],
-maxrepetitions => 10,
);
if (!defined $result) {
printf "ERROR: %s.\n", $session->error();
}
return;
}
4. Non-blocking SNMPv1 get-request and set-request on multiple
hosts¶
This example first polls several hosts for their sysUpTime. If the poll of the
host is successful, the sysContact and sysLocation information is set on the
host. The sysContact information is hardcoded to "Help Desk x911"
while the sysLocation information is passed as an argument to the callback.
#! /usr/local/bin/perl
use strict;
use warnings;
use Net::SNMP;
my $OID_sysUpTime = '1.3.6.1.2.1.1.3.0';
my $OID_sysContact = '1.3.6.1.2.1.1.4.0';
my $OID_sysLocation = '1.3.6.1.2.1.1.6.0';
# Hash of hosts and location data.
my %host_data = (
'10.1.1.2' => 'Building 1, Second Floor',
'10.2.1.1' => 'Building 2, First Floor',
'localhost' => 'Right here!',
);
# Create a session for each host and queue a get-request for sysUpTime.
for my $host (keys %host_data) {
my ($session, $error) = Net::SNMP->session(
-hostname => $host,
-community => 'private',
-nonblocking => 1,
);
if (!defined $session) {
printf "ERROR: Failed to create session for host '%s': %s.\n",
$host, $error;
next;
}
my $result = $session->get_request(
-varbindlist => [ $OID_sysUpTime ],
-callback => [ \&get_callback, $host_data{$host} ],
);
if (!defined $result) {
printf "ERROR: Failed to queue get request for host '%s': %s.\n",
$session->hostname(), $session->error();
}
}
# Now initiate the SNMP message exchange.
snmp_dispatcher();
exit 0;
sub get_callback
{
my ($session, $location) = @_;
my $result = $session->var_bind_list();
if (!defined $result) {
printf "ERROR: Get request failed for host '%s': %s.\n",
$session->hostname(), $session->error();
return;
}
printf "The sysUpTime for host '%s' is %s.\n",
$session->hostname(), $result->{$OID_sysUpTime};
# Now set the sysContact and sysLocation for the host.
$result = $session->set_request(
-varbindlist =>
[
$OID_sysContact, OCTET_STRING, 'Help Desk x911',
$OID_sysLocation, OCTET_STRING, $location,
],
-callback => \&set_callback,
);
if (!defined $result) {
printf "ERROR: Failed to queue set request for host '%s': %s.\n",
$session->hostname(), $session->error();
}
return;
}
sub set_callback
{
my ($session) = @_;
my $result = $session->var_bind_list();
if (defined $result) {
printf "The sysContact for host '%s' was set to '%s'.\n",
$session->hostname(), $result->{$OID_sysContact};
printf "The sysLocation for host '%s' was set to '%s'.\n",
$session->hostname(), $result->{$OID_sysLocation};
} else {
printf "ERROR: Set request failed for host '%s': %s.\n",
$session->hostname(), $session->error();
}
return;
}
REQUIREMENTS¶
- •
- The Net::SNMP module uses syntax that is not supported in
versions of Perl earlier than v5.6.0.
- •
- The non-core modules Crypt::DES, Digest::MD5,
and Digest::HMAC are required to support SNMPv3.
- •
- In order to support the AES Cipher Algorithm as a SNMPv3
privacy protocol, the non-core module Crypt::Rijndael is
needed.
- •
- To use UDP/IPv6 or TCP/IPv6 as a Transport Domain, the
non-core module Socket6 is needed.
AUTHOR¶
David M. Town <dtown@cpan.org>
ACKNOWLEDGMENTS¶
The original concept for this module was based on
SNMP_Session.pm written
by Simon Leinen <simon@switch.ch>.
The Abstract Syntax Notation One (ASN.1) encode and decode methods were
originally derived by example from the CMU SNMP package whose copyright
follows: Copyright (c) 1988, 1989, 1991, 1992 by Carnegie Mellon University.
All rights reserved.
LICENSE AND COPYRIGHT¶
Copyright (c) 1998-2010 David M. Town. All rights reserved.
This program is free software; you may redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.