'\"
'\" Copyright (c) 1994-1996 Technical University of Braunschweig.
'\" Copyright (c) 1996-1997 University of Twente.
'\" Copyright (c) 1997-1998 Technical University of Braunschweig.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.so man.macros
.TH Tnm::snmp n "September 1998" Tnm "Tnm Tcl Extension"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tnm::snmp \- Send SNMP messages to devices on the Internet.
.BE

.SH DESCRIPTION
The Tnm Tcl extension includes an implementation of the Simple Network
Management Protocol (SNMP) which is used to monitor and control
devices on the Internet. The Tnm extension supports SNMP version 1
(SNMPv1) as defined in RFC 1157, community based SNMP version 2
(SNMPv2c) as defined in RFC 1901, RFC 1905, RFC 1906 as well as SNMP
version 3 (SNMPv3) as defined in RFC 2272 and RFC 2274. The Tcl
commands described in this man page follow the conventions defined in
the SNMPv2/SNMPv3 standards. The differences between SNMPv1, SNMPv2c
and SNMPv3 are hidden as far as possible from the user of this
extension by applying automatic conversions where possible (RFC 2089).

All SNMP messages are send or received by using so called SNMP
sessions. SNMP sessions are lightweight objects that keep information
about the transport address of the SNMP peer entity, the
authentication mechanism and parameters in use as well as some
parameters that control the behaviour of the SNMP protocol engine
itself.

The Tnm extension supports four different SNMP session types that
correspond to SNMP applications as defined in the architecture for
describing SNMP management frameworks (RFC 2271). A "generator" SNMP
session is used to initiate SNMP get/getnext/getbulk or set requests
and a "listener" SNMP session is used to receive event notifications
(either unacknowledged traps or acknowledged informs). "Generator" and
"listener" SNMP sessions can be used to implement traditional SNMP
manager.

A "responder" SNMP session receives incoming get/getnext/getbulk or
set requests, processes them and returns response messages.  Finally,
"notifier" SNMP sessions allow to send notifications as either SNMP
traps or informs. The combination of "responder" and "notifier" SNMP
sessions is traditionally called an SNMP agent.

The SNMP commands described in this manual page are often used in
combination with the Tnm::mib(n) command, which allows to retrieve
information from Management Information Base (MIB) definitions. The
implementation of the SNMP protocol engine also makes internal calls
to the MIB module in order to resolve names or to apply conversions.

.SH SNMP DATA TYPES
The SNMP protocol is based on a fixed set of primitive data
types. These primitive data types are mapped to a string
representation in Tcl. Below is the list of primitive SNMP data types
with a short description of the corresponding primitive representation
in Tcl:

.TP
.B OCTET STRING
An OCTET STRING is a sequence of octets (bytes). The primitive Tcl
string representation for an OCTET STRING value is a string containing
hexadecimal numbers (from 00 to ff) separated by colons. For example,
the ASCII string "rose" is represented as "72:6f:73:65".
.TP
.B OBJECT IDENTIFIER
An OBJECT IDENTIFIER value is a sequence of positive numbers which
defines a path from the root of the global OID registration 
tree to a MIB object or MIB instance. The primitive Tcl string
representation is the dotted notation, where sub-identifier are
separated by dots. For example, the OBJECT IDENTIFIER for the MIB node
labelled mib-2 has the Tcl string representation "1.3.6.1.2.1". The
Tnm extension always returns sub-identifier as decimal
numbers. However, the Tnm extension accepts sub-identifier which
contain hexadecimal values. A hexadecimal sub-identifier is either
preceeded by a colon instead of a dot or by the sequence "0x". For
example, the OBJECT IDENTIFIER value "1.3.6.1:4:1.0x627" is
automatically converted to the value "1.3.6.1.4.1.1575".
.TP
.B IpAddress
The data type IpAddress represents IPv4 addresses. The Tcl string
representation is the usual dotted notation where each byte is
converted into a decimal value, which is separated from its
predecessor by a dot. A typical example is "134.169.34.15".
.TP
.B TimeTicks
TimeTicks are non-negative integer values which represent the time,
modulo 2^32 (4294967296 decimal), in hundredths of a second. Note, the
precision of Tcl expressions is platform dependent and Tcl expressions
do not support unsigned values. Care must be taken to avoid unwanted
conversions of a TimeTicks value into a signed integer number on 32
bit systems.
.TP
.B Counter32, Gauge32, Unsigned32
Values of these numeric types are converted into a string representing
an unsigned number. Counter32, Gauge32 and Unsigned32 values are in
the range 0 to 2^32-1 (4294967295). Note, the precision of Tcl
expressions is platform dependent and Tcl expressions do not support
unsigned values. Care must be taken to avoid unwanted conversions of a
Counter32, Gauge32 or Unsigned32 value into a signed integer number on
32 bit systems.
.TP
.B Integer32
Integer32 values are in the range -2^31 (-2147483648) to 2^31-1
(2147483647). Values of these types are represented by a string
containing a signed number.
.TP
.B Counter64
Counter64 values are in the range 0 to 2^64-1 (18446744073709551615).
Note, the precision of Tcl expressions is platform dependent and Tcl
expressions do not support unsigned values.  Arithmetics with
Counter64 values are frequently done by "converting" the Counter64
value to a floating point number. This conversion is likely to remove
the lower bits on systems that use the IEEE floating point format.
Care must therefore be taken when computing deltas between two
Counter64 values.
.TP
.B Opaque
Opaque values were used in early versions of SNMP to exchange
arbitrary ASN.1/BER encoded values. The SNMP engine of the Tnm
extension also uses the Opaque data type to pass values with an
unknown ASN.1/BER encoding to the script layer. This is especially
useful if new tagged types are added to SNMP and agents ship those new
types via an SNMP version that does not know about this type.  The
primitive Tcl string representation for an Opaque value is a string
containing hexadecimal numbers (from 00 to ff) separated by colons.
The hexadecimal number correspond to the ASN.1/BER encoded value.
Note, Opaque is only supported for backwards compatibility and it
should only be used in rare cases.

.PP
The Tnm extension returns values in the primitive string
representation if no other formatting rules apply. Formatting rules
defined in MIB modules are applied automatically (see the
documentation for the Tnm::mib command on how to load MIB
modules). This includes the interpretation if DISPLAY-HINTs as well as
the conversion of integer values to the corresponding enumeration. For
example, DisplayString values are automatically converted from the
primitive OCTET STRING representation into a human readable ASCII
string by applying the "225a" DISPLAY-HINT, and values of type
TruthValue are returned as "true" or "false" instead of 1 and 2 (RFC
1903). Explicit conversions are possible by using the Tnm::mib format
and Tnm::mib scan commands as described in the Tnm::mib manual page.

.SH SNMP VARBIND LISTS
The SNMP protocol always operates on a list of MIB variables. This
list is called a varbind list. A varbind list is represented as a Tcl
list. Each element of the varbind list is itself a Tcl list describing
one varbind element. A fully specified varbind list element has three
elements: an object identifier, which identifies the MIB variable, the
data type of the MIB variable and the value of the MIB variable. A
fully specified varbind list might look like:

.CS
{
    {1.3.6.1.2.1.1.3.0 TimeTicks 20308} 
    {1.3.6.1.2.1.2.2.1.3.1 INTEGER softwareLoopback} 
    {1.3.6.1.2.1.2.2.1.2.1 {OCTET STRING} lo0}
    {1.3.6.1.2.1.2.2.1.8.1 INTEGER up}
}
.CE

It is not necessary to use fully specified varbind lists when invoking
SNMP retrieval operations. It is possible to omit the type and value
fields when retrieving values from MIB variables. For example, to
retrieve the fully specified varbind list show above, the following
much shorter varbind list has been used:

.CS
{
    1.3.6.1.2.1.1.3.0
    1.3.6.1.2.1.2.2.1.3.1
    1.3.6.1.2.1.2.2.1.2.1
    1.3.6.1.2.1.2.2.1.8.1
}
.CE

It is possible to replace OBJECT IDENTIFIER values with labels or
names that resolve to an OBJECT IDENTIFIER value. (See the Tnm::mib
manual page for details about legal names.) This further simplifies
the varbind list above to:

.CS
{
    SNMPv2-MIB!sysUpTime.0
    IF-MIB!ifType.1
    IF-MIB!ifDescr.1
    IF-MIB!ifOperStatus.1
}
.CE

In order to change the value of a MIB variable, you have to include
the new value in the varbind list. It is however possible to omit the
type element if the type can be obtained from a MIB definition. This
allows to use a list like

.CS
{
    {SNMPv2-MIB!sysContact.0 "schoenw@ibr.cs.tu-bs.de"}
}
.CE

to change the value of the sysContact.0 MIB variable. Note, that the
Tnm extension always returns fully specified varbind lists to avoid
ambiguities.

SNMPv2c and SNMPv3 varbind lists may contain exceptions (noSuchObject,
noSuchInstance, endOfMibView). These exceptions are signalled in the
type element of a varbind list element. The value of the varbind is
set to a null value which conforms to the data type of the object type:

.CS
{
    {1.3.6.1.2.1.2.2.1.3.2 noSuchInstance 0}
    {1.3.6.1.2.1.2.2.1.2.2 noSuchInstance {}}
}
.CE

It is the responsibility of the application to check for exceptions.
An application will not necessarily crash if such a check is missing,
but it might get confused while interpreting null values.

.SH SNMP SESSION OPTIONS
SNMP sessions are configured by manipulating session options. Some of
these options apply for all supported SNMP versions and SNMP session
types, while others are specific to a particular version or a
particular session type. The options described below can be used with
any SNMP session unless stated otherwise.

.TP
.BI -address " address"
The \fB-address\fR option defines the network address of the SNMP peer
entity. The value of \fIaddress\fR may be an IP address in dotted
notation (e.g. 134.169.34.1) or a hostname that can be resolved to an
IP address. The default address is 127.0.0.1.

.TP
.BI -port " port"
The \fB-port\fR option defines the UDP port which is used by the SNMP
peer entity to receive SNMP messages. The value of \fIport\fR may be a
port number or a service name which can be resolved to a port
number. The default port number is 161 for generator and responder
sessions and 162 for notifier and listener sessions.

.TP
.BI -version " number"
The \fB-version\fR option selects the SNMP version used by an SNMP
session. The version numbers currently supported are SNMPv1 (RFC
1157), SNMPv2c (RFC 1901, RFC 1905, RFC 1906) and SNMPv3 (RFC 2272,
RFC 2274, RFC 1905, RFC 1906). The default SNMP version is SNMPv1.

.TP
.BI -community " community"
The \fB-read\fR option is specific for SNMPv1 and SNMPv2c generator,
responder or notifier sessions. It defines the community string which
is used when invoking SNMP operations. The default community string is
"public".

.TP
.BI -user " name"
The \fB-user\fR option is specific to SNMPv3 sessions. It is used to
define the SNMPv3 user name. The default user name is the value of
the global tnm(user) variable, which defaults to the login name of
the underlying operating system.

.TP
.BI -authPassWord " password"
The \fB-authpasswd\fR option is specific to SNMPv3 sessions. It is
used to specify the authentication password of the user. The password
is automatically converted into a key by applying the password2key
algorithm of RFC 2274.  The key is also automatically localized once
the engineID of the SNMP peer entity is known. Note that the
application should take care to keep the passwords safe from
unauthorized access.

.TP
.BI -privPassWord " password"
The \fB-privPassWord\fR option is specific to SNMPv3 sessions. It is
used to specify the password of the user. The password is
automatically converted into a key by applying the password2key
algorithm of RFC 2274.  The key is also automatically localized once
the engineID of the SNMP peer entity is known. Note that the
application should take care to keep the passwords safe from
unauthorized access.

.TP
.BI -readSecurity " level"
The \fB-readSecurity\fR option is specific to SNMPv3 sessions. It
allows to specify the security level for SNMP read operations. Legal
values are noAuth/noPriv, md5/noPriv, md5/des, sha/noPriv, and
sha/des. Note, not all values are fully supported in the current
implementation.

.TP
.BI -writeSecurity " level"
The \fB-writeSecurity\fR option is specific to SNMPv3 sessions. It
allows to specify the security level for SNMP write operations. Legal
values are noAuth/noPriv, md5/noPriv, md5/des, sha/noPriv, and
sha/des. Note, not all values are fully supported in the current
implementation.

.TP
.BI -notifySecurity " level"
The \fB-writeSecurity\fR option is specific to SNMPv3 sessions. It
allows to specify the security level for SNMP notifications. Legal
values are noAuth/noPriv, md5/noPriv, md5/des, sha/noPriv, and
sha/des. Note, not all values are fully supported in the current
implementation.

.TP
.BI -context " context"
The \fB-context\fR option is specific to SNMPv3 sessions. It allows
to select between multiple contexts. The default context is the empty
string "".

.TP
.BI -engineID " id"
The \fB-engineID\fR option is specific to SNMPv3 sessions. It is used
to get or set the SNMP engineID for SNMPv3 messages. The default
engineID is the empty string "". Note, the engineID value might
change during protocol operations when doing SNMPv3 auto-discovery.

.TP
.BI -timeout " time"
The \fB-timeout\fR option defines the time the session will 
wait for a response. The \fItime\fR is defined in seconds with a
default of 5 seconds. This option only applies for unreliable
transports like UDP.

.TP
.BI -retries " number"
The \fB-retries\fR option defines how many times a request is
retransmitted during the timeout interval. The default \fInumber\fR of
retries is 3. This option only applies for unreliable
transports like UDP.

.TP
.BI -delay " delay"
The \fB-delay\fR option can be used to define a delay in milliseconds
between two messages send by the SNMP protocol engine. This can be
used to avoid network congestion problems. The default \fIdelay\fR
is 0 milliseconds. This option only applies for transports without
congestion control like UDP.

.TP
.BI -window " size"
The \fB-window\fR option allows to define a window which limits the
number of active asynchronous requests. This can be used to prevent
fast scripts to flood an agent or an intermediate system with
asynchronous messages.  The Tnm extension queues requests internally
so that no more than \fIsize\fR asynchronous requests are on the
wire. Setting the size to 0 turns the windowing mechanism off. This
option only applies for transports without congestion control like
UDP.

.TP
.BI -alias " name"
The \fB-alias\fR option substitutes this option with the configuration
options contained in the alias identified by \fIname\fR. You can
define configuration option aliases with the snmp alias command. It is
possible to refer to other -alias options within an -alias option. See
the description of the snmp alias command below for an example.

.TP
.BI -tags " tagList"
The \fB-tags\fR option is used to tag SNMP sessions. Tags are a
convenient way to group SNMP sessions that perform a single task or
which belong a specific network element. Tags are also convenient to
relate SNMP sessions to network map objects and/or management
functions.

.SH SNMP CALLBACK SCRIPTS
Many SNMP commands described below allow to invoke asynchronous SNMP
operations. Asynchronous SNMP operations work by sending out a request
without waiting for a response. The SNMP protocol engine keeps track
of asynchronous requests and processes callback scripts once an answer
for an asynchronous request is received or the request times out. The
callback script is always evaluated at global level. Special % escape
sequences can be used in the callback script to access details
contained in the SNMP response. These % escape sequences are
substitued before the callback script is evaluated. The substitution
depends on the character following the %, as defined in the list
below.

.IP \fB%%\fR 5
Replaced with a single percent.
.IP \fB%V\fR 5
Replaced with the fully specified varbind list.
.IP \fB%R\fR 5
Replaced with the request id.
.IP \fB%S\fR 5
Replaced with the session name.
.IP \fB%E\fR 5
Replaced with the error status. Possible values for the error status
are noError, tooBig, noSuchName, badValue, readOnly, genErr, noAccess,
wrongType, wrongLength, wrongEncoding, wrongValue, noCreation,
inconsistentValue, resourceUnavailable, commitFailed, undoFailed,
authorizationError, notWritable, inconsistentName, noResponse, and
endOfWalk. The last two error codes are generated internally by the
protocol engine when a request times out or when the end of an
asynchronous walk has been reached.
.IP \fB%I\fR 5
Replaced with the error index. The error index identifies the element
in the varbind list which caused an error. The index uses the Tcl list
numbering scheme where 0 refers to the first element of the list.
This is different from the SNMP numbering scheme, where the first list
element has the index value 1. The %I escape sequence will be replaced
by -1 if the error status is noError.
.IP \fB%A\fR 5
Replaced with the IP address of the peer sending the packet.
.IP \fB%P\fR 5
Replaced with the port number of the peer sending the packet.
.IP \fB%T\fR 5
Replaced with the SNMP PDU type. Possible values for the PDU type
can be retrieved with the snmp info pdus command described below.
.IP \fB%C\fR 5
Replaced with the context value of a scoped PDU. The context is currently
only available for SNMPv3 sessions. It will be replaced with the community
string for all other SNMP sessions.
.IP \fB%G\fr 5
Replaced with the engine ID of a scoped PDU. The engine ID is currently
only available for SNMPv3 sessions. It will be replaced with an empty
string for all other SNMP sessions.

.SH SNMP COMMAND

This section describes SNMP commands that are used to create new SNMP
sessions, to define SNMP aliases and to do some houskeeping.

.TP
.B snmp alias\fR [\fIname\fR [\fIoptions\fR]]
The \fBsnmp alias\fR command allows to create aliases for a list of
configuration options. This can be used to define short names for
complex session configurations and it allows to share e.g. frequently
used community strings between a number of devices. An alias defined
by the snmp alias command can be substitued when configuring an
SNMP session by using the -alias session option as described above.  

The snmp alias command invoked without arguments returns the list of
all known alias names. If invoked with an alias \fIname\fR, the list
of configuration options associated with this alias is
returned. Invoking the snmp alias command with an alias \fIname\fR and
an \fIoptions\fR list associates the list of configuration options
contained in \fIoptions\fR with the alias \fIname\fR.

Below is an examples that creates an SNMPv1 alias private which
defines a SNMPv1 community string pair. The aliases hub1 and hub2
define configuration options used to access two hubs. The aliases
hub1/private and hub2/private combine these aliases. It is now
possible to update the private community string for both hubs by
changing the private alias. Nesting alias definitions as shown below
allows to build a flexible configuration scheme.

snmp alias private "-read guiness -write andechs"
.br
snmp alias hub1 "-address 1.2.3.4 -window 2 -delay 10"
.br
snmp alias hub2 "-address 1.2.3.5 -timeout 10"
.br
snmp alias hub1/private "-alias hub1 -alias private"
.br
snmp alias hub2/private "-alias hub1 -alias private"

.TP
.B snmp delta \fIvbl1 vbl2\fR

The \fBsnmp delta\fR command computes takes two varbind lists and
computes delta values for each corresponding element in the varbind
lists. The result is returned in a varbind list, which uses the pseudo
data types "Delta32" for Counter32 values, "Delta64" for Counter64
values and "DeltaTicks" for TimeTicks values. For example, 

.CS
set a {{1.3.6.1.2.1.1.3.0 TimeTicks 4285807796}}
set b {{1.3.6.1.2.1.1.3.0 TimeTicks 4285808344}}
snmp delta $a $b
.CE

.RS
will return {1.3.6.1.2.1.1.3.0 DeltaTicks 548}. The advantage of using
the snmp delta command instead of the Tcl expr command is that the
snmp delta does not depend on the word length of your computers hardware
and is therefore much more portable.
.RE

.TP
.B snmp find \fR[\fB-address \fIaddr\fR] \fR[\fB-port \fInum\fR] \fR[\fB-tags \fIpatternList\fR] \fR[\fB-type \fItype\fR] \fR[\fB-version \fIversion\fR]
The \fBsnmp find\fR command returns lists of session names. The list
will contain all existing SNMP sessions known by the Tcl interpreter
if no options are present. XXX

.TP
.B snmp generator\fR [\fIoption\fR \fIvalue\fR ...]
The \fBsnmp generator\fR command creates new SNMP generator
sessions. It returns a session handle which can be used to invoke SNMP
operations. It is possible to pass configuration options to the
snmp generator command in order to configure the SNMP session.

.TP
.B snmp info \fIsubject ?pattern?\fR
The \fBsnmp info\fR command returns information about a given
subject. The optional \fIpattern\fR is used to select a subset of
information. The \fIsubject\fR errors returns the list of error codes
generated by SNMP operations. The \fIpattern\fR is matched against the
error code names. The subject \fIexceptions\fR returns the list of
possible exceptions in varbind lists. The \fIpattern\fR is matched
against the exception names. The subject \fIpdus\fR returns the list
of supported SNMP PDUs. The \fIpattern\fR is matched against the PDU
names. The subject \fItypes\fR returns the list of primitive SNMP data
types. The \fIpattern\fR is matched against the data type name. The
subject \fIversions\fR returns the list of supported SNMP versions.
The \fIpattern\fR is matched against the version name.

.TP
.B snmp listener\fR [\fIoption\fR \fIvalue\fR ...]
The \fBsnmp listener\fR command creates new SNMP listener sessions
which listen for incoming notifications. The command returns a session
handle which can be used to bind scripts which are evaluated when a
notification has been received. It is possible to pass configuration
options to the snmp listener command in order to configure the
SNMP session.

.TP
.B snmp notifier\fR [\fIoption\fR \fIvalue\fR ...]
The \fBsnmp notifier\fR command creates new SNMP notification
originating sessions. It returns a session handle which can be used to
send SNMP notifications to other SNMP engines. It is possible to pass
configuration options to the snmp notifier command in order to
configure the SNMP session.

.TP
.B snmp oid \fIvbl\fR [\fIindex\fR]
The \fBsnmp oid\fR command extracts object identifier values out of
the varbind list \fIvbl\fR. The object identifier which belongs to the
varbind with the given index is extracted, if the optional \fIindex\fR
value is present. Otherwise, the list of all object identifier values
in the varbind list \fIvbl\fR is returned.

.TP
.B snmp responder\fR [\fIoption\fR \fIvalue\fR ...]
The \fBsnmp responder\fR command creates new SNMP command responder
sessions. It returns a session handle which can be used to process
received SNMP commands. It is possible to pass configuration options
to the snmp responder command in order to configure the SNMP
session.

.TP
.B snmp type \fIvbl\fR [\fIindex\fR]
The \fBsnmp type\fR command extracts type names out of the varbind
list \fIvbl\fR. The type name which belongs to the varbind with the
given \fIindex\fR is extracted, if the optional \fIindex\fR parameter
is present. Otherwise, the list of all type names in the varbind list
\fIvbl\fR is returned.

.TP
.B snmp value \fIvbl\fR [\fIindex\fR]
.B \fBsnmp value\fR command extracts values out of the varbind list
\fIvbl\fR. The value which belongs to the varbind with the given
\fIindex\fR is extracted, if the optional \fIindex\fR parameter is
present. Otherwise, the list of all values in the varbind list
\fIvbl\fR is returned.

.TP
.B snmp wait
The \fBsnmp wait\fR command blocks until all asynchronous requests for
all SNMP sessions have been processed. Events are processed while
waiting for outstanding responses which can have arbitrary side
effects.

.TP
.B snmp watch \fIboolean\fR
The \fBsnmp watch\fR command turns hex printing of SNMP packets on or
off. This is mostly a debugging aid because the output is written
directly to the stderr channel.

.SH GENERAL SESSION COMMANDS

This sections describes simple SNMP session commands which correspond
directly to SNMP protocol operations. It also discusses some commands
to configure and control the SNMP protocol engine.

.TP
.B snmp# configure \fR[\fIoption value\fR ...]
The \fBsnmp# configure\fR session command can be used to query or
change the current configuration options. See the description of SNMP
session options above for more details. The configure session command
always returns the current settings of the configuration
options. Note, invoking the configure session command on a SNMP
session that has asynchronous requests pending can have arbitrary side
effects because it processes events until all pending requests for
this session have either timed out or returned a response.  This
behavior makes sure that pending request are not affected by changes
to a configuration option.

.TP
.B snmp# cget \fIoption\fR
The \fBsnmp# cget\fR session command allows to retrieve the value of
the SNMP session option given by \fIoption\fR. See the description of
SNMP session options above for more details.

.TP
.B snmp# destroy
The \fBsnmp# destroy\fR session command destroys the session. All data
associated with the SNMP session is removed (outstanding asynchronous
requests are cancelled).

.TP
.B snmp# wait \fR[\fIrequest\fR]
The \fBsnmp# wait\fR command blocks until all asynchronous requests
for this SNMP session have been processed. Events are processed while
waiting for outstanding responses which can have arbitrary side
effects.

.SH GENERATOR SESSION COMMANDS

.TP
.B snmp# bind \fIevent\fR [\fIscript\fR]
The \fBsnmp# bind\fR session command allows to bind scripts to events
generated inside of the SNMP protocol engine. The \Ievent\fR parameter
selects the event, which must be one of the events described
below. The optional \fIscript\fR parameter specifies the script which
is evaluated when the \fIeven\fR occurs. An empty string can be used
to remove an existing event binding. The command returns the script
bound to the event or an empty string if the script parameter is
missing.

A \fIsend\fR event is generated whenever an SNMP message is send to
the network. The \fIsend\fR event is only generated once for every
message and not for every retransmission of the same message. A
\fIrecv\fR event is generated whenever a SNMP message is received from
the network.

A script bound to an event is evaluated in the same way as callback
scripts. Substitutions of % escape sequences take place as described
above and scripts are always evaluated at global level.

.TP
.B snmp# get \fIvbl\fR [\fIscript\fR]

The \fBsnmp# get\fR session command retrieves the list of instances as
specified in the varbind list \fIvbl\fR by using an SNMP get-request.  If
the get session command contains a callback \fIscript\fR, then the
command sends the get-request and returns immediately. The result is
the request id for the asynchronous request. The get session command
is processed synchronously if the callback \fIscript\fR is absent. In
this case, the received varbind list is returned. The command fails
with a Tcl error if the agent does not respond or if a protocol error
happens.

Below is an example for a synchronous get request to retrieve some
variables of the system group. The Tcl catch command is used to handle
any errors:

.CS
set vbl {SNMPv2-MIB!sysDescr.0 SNMPv2-MIB!sysName.0}
set err [catch {$s get $vbl} vbl]
if {$err == 0} {
    puts $vbl
}
.CE

.RS
The code below implements the same get request with an asynchronous
get request:
.RE

.CS
set vbl {SNMPv2-MIB!sysDescr.0 SNMPv2-MIB!sysName.0}
$s get $vbl {
    if {"%E" == "noError"} { puts "%V" }
}
.CE

.TP
.B snmp# getnext \fIvbl\fR [\fIscript\fR]
The \fBsnmp# getnext\fR session command retrieves the values of the
lexicographical successors to the objects named in varbind list \fIvbl\fR.
If the getnext session command contains a callback \fIscript\fR, then
the command sends the get-next-request and returns immediately. The
result is the request id for the asynchronous request. The getnext
session command is processed synchronously if the callback
\fIscript\fR is absent. In this case, the received varbind list is
returned. The command fails with a Tcl error if the agent does not
respond or if a protocol error happens.

To retrieve the whole MIB tree, you can use the result of a getnext
command as an argument for the next getnext command. Below is a
synchronous version which walks a complete MIB tree:

.CS
set vbl 1.3
while {! [catch {$s getnext $vbl} vbl]} {
    puts $vbl
}
.CE

.RS
The asynchronous version of this script requires to define a procedure
which calls itself asynchronously:
.RE

.CS
proc walk {s vbl err} {
    if {$err == "noError"} {
        puts $vbl
        $s getnext $vbl { walk "%S" "%V" "%E" }
    }
}

$s getnext 1.3 { walk "%S" "%V" "%E" }
.CE

.TP
.B snmp# getbulk \fInr\fR \fImr\fR \fIvbl\fR [\fIscript\fR]
The \fBsnmp# getbulk\fR session command can be used to implement
faster MIB tree walks by using get-bulk-requests. The getbulk session
command performs a getnext on the first \fInr\fR elements given in the
varbind list \fIvbl\fR. For the remaining elements, the agent is asked to
repeat the getnext operation mostly \fImr\fR times. SNMPv1 sessions
automatically map get-bulk-requests to get-next-requests.  If the
getbulk session command contains a callback \fIscript\fR, then the
command sends the get-bulk-request and returns immediately. The result
is the request id for the asynchronous request. The \getbulk session
command is processed synchronously if the callback \fIscript\fR is
absent. In this case, the received varbind list is returned. The
command fails with a Tcl error if the agent does not respond or if a
protocol error happens.

The following synchronous example show how to retrieve the value of
ifNumber.0 and how to use it to read columns of the ifTable in a
single getbulk operation.

.CS
set err [catch {$s get ifNumber.0} vbl]
if {$err == 1} { exit 1 }
set m [snmp value $vbl 0]
set vbl {SNMPv2-MIB!sysUpTime IF-MIB!ifDescr IF-MIB!ifLastChange}
set err [catch {$s getbulk 1 $m $vbl} vbl]
if {$err == 1} { exit 2 }
puts $vbl
.CE

.RS
The example below does the same thing asynchronously. Note, both
examples are simplifications because the getbulk does not guarantee
that all \fImr\fR repetitions are actually made. You therefore have to
ask ifNumber.0 + 1 repetitions so that you are able to detect whether
you got the whole table or just parts of it.
.RE

.CS
proc getit {s m} {
    set vbl {SNMPv2-MIB!sysUpTime IF-MIB!ifDescr IF-MIB!ifLastChange}
    $s getbulk 1 $m $vbl {
        if {"%E" == "noError"} {
            puts "%V"
        }
    }
}

$s get ifNumber.0 {
    if {"%E" == "noError"} {
        getit %S [snmp value "%V" 0]
    }
}
.CE

.TP
.B snmp# set \fIvbl\fR [\fIscript\fR]
The \fBsnmp# set\fR session command can be used to create and modify
MIB instances. The varbind list \fIvbl\fR for set-requests must
contain at least the object identifier and the new value as described
above. If the set session command contains a callback \fIscript\fR,
then the command sends the set-request and returns immediately. The
result is the request id for the asynchronous request. The set session
command is processed synchronously if the callback \fIscript\fR is
absent. In this case, the received varbind list is returned. The
command fails with a Tcl error if the agent does not respond or if a
protocol error happens.

Below is a synchronous example which shows how you can change the
sysContact.0 and sysLocation.0 variables of the system group.

.CS
set vbl [list \\
    [list SNMPv2-MIB!sysContact.0 "Bert Nase"] \\
    [list SNMPv2-MIB!sysLocation.0 "Hall6, Floor 5"] \\
]
set err [catch {$s set $vbl} vbl]
if {$err == 1} {
    exit 1
}
.CE

.RS
Note that it is always recommended to use the Tcl list command to
build the varbind list. This makes sure that quoting is done in the
correct way. The asynchronous version of the command looks as follows:
.RE

.CS
set vbl [list \\
    [list SNMPv2-MIB!sysContact.0 "Bert Nase"] \\
    [list SNMPv2-MIB!sysLocation.0 "Hall6, Floor 5"] \\
]
$s set $vbl {
    if {"%E" != "noError"} {
        exit 1
    }
}
.CE

.TP
.B snmp# walk \fIvarName\fR \fIvbl\fR \fIbody\fR
.ns
.TP
.B snmp# walk \fIvbl\fR \fIscript\fR
The \fBsnmp# walk\fR session command walks a whole MIB subtree. The
command repeats sending getbulk requests until the returned varbind
list is outside of the subtree rooted at the varbind list
\fIvbl\fR.

The first version of the walk command is synchronous. For each valid
varbind list retrieved from the agent, the Tcl script \fIbody\fR is
evaluated. Before evaluation of \fIbody\fR starts, the actual varbind
list is assigned to the variable named \fIvarName\fR. Below is a
simple example which prints the two columns ifDescr and ifType of the
interface table:

.CS
$s walk x "IF-MIB!ifDescr IF-MIB!ifType" { 
   puts "[snmp value $x 0] ([snmp value $x 1])"
}
.CE

The second version of the walk command is asynchronous. For each valid
varbind list retrieved from the agents, the callback script
\fIscript\fR is evaluated. Substitutions of % escape sequences take
place as described above and scripts are always evaluated at global
level. The \fIscript\fR is called with an error status set to
endOfWalk and an empty varbind list when the walk terminates. Below is
the asynchronous version of the example which prints the two columns
ifType and ifDescr of the interface table:

.CS
$s walk "IF-MIB!ifDescr IF-MIB!ifType" {
    if {"%E" == "noError"} {
	puts [subst {[snmp value "%V" 0] ([snmp value "%V" 1])}]
    }
}

.SH LISTENER SESSION COMMANDS

.TP
.B snmp# bind \fIevent\fR [\fIscript\fR]
The \fBsnmp# bind\fR session command allows to bind scripts to events
generated inside of the SNMP protocol engine. The \Ievent\fR parameter
selects the event, which must be one of the events described
below. The optional \fIscript\fR parameter specifies the script which
is evaluated when the \fIeven\fR occurs. An empty string can be used
to remove an existing event binding. The command returns the script
bound to the event or an empty string if the script parameter is
missing.

A \fIsend\fR event is generated whenever an SNMP message is send to
the network. The \fIsend\fR event is only generated once for every
message and not for every retransmission of the same message. A
\fIrecv\fR event is generated whenever a SNMP message is received from
the network.

A \fItrap\fR event is generated whenever an SNMP trap is received
which matches the parameters of the session. A \fIinform\fR event is
generated whenever an SNMP inform request is received and processed
which matches the parameters of the session.

A script bound to an event is evaluated in the same way as callback
scripts. Substitutions of % escape sequences take place as described
above and scripts are always evaluated at global level.

.SH NOTIFIER SESSION COMMANDS

.TP
.B snmp# bind \fIevent\fR [\fIscript\fR]
The \fBsnmp# bind\fR session command allows to bind scripts to events
generated inside of the SNMP protocol engine. The \Ievent\fR parameter
selects the event, which must be one of the events described
below. The optional \fIscript\fR parameter specifies the script which
is evaluated when the \fIeven\fR occurs. An empty string can be used
to remove an existing event binding. The command returns the script
bound to the event or an empty string if the script parameter is
missing.

A \fIsend\fR event is generated whenever an SNMP message is send to
the network. The \fIsend\fR event is only generated once for every
message and not for every retransmission of the same message. A
\fIrecv\fR event is generated whenever a SNMP message is received from
the network.

A script bound to an event is evaluated in the same way as callback
scripts. Substitutions of % escape sequences take place as described
above and scripts are always evaluated at global level.

.TP
.B snmp# trap \fIsnmpTrapOid\fR \fIvbl\fR
The \fBsnmp# trap\fR command allows to notify a manager that a special
event has happened. The event type is defined by the \fIsnmpTrapOid\fR
object identifier. The standard notifications defined in RFC 1907 are
coldStart, warmStart and authenticationFailure. Additional
notification types are defined in other MIB modules. The varbind list
\fIvbl\fR contains variables that provide additional information for
the remote manager. Note, the value of sysUpTime.0 is added to the
varbind list automatically. However, it is up to the user to provide
any other required additional varbinds like the ifIndex for linkUp or
linkDown notifications.

SNMPv1 traps are defined by a TRAP-TYPE macro (RFC 1212) which defines
an enterprise object identifier and a generic and a specific trap
number. SNMPv1 TRAP-TYPE definitions are automatically converted into
an \fIsnmpTrapOid\fR object identifier by appending the generic and
specific trap number to the enterprise object identifier (RFC 1908).

.CS
$s trap coldStart [list [list SNMPv2-MIB!sysDescr.0 "Fridge"]]
.CE

.TP
.B snmp# inform \fIsnmpTrapOid\fR \fIvbl\fR [\fIscript\fR]
The \fBsnmp# inform\fR session allows to send an acknowledged
notification to a manager. An inform-request generated which is
confirmed by the manager with a response message. The event type is
defined by the \fIsnmpTrapOid\fR in the same way as described for the
trap session command above. The varbind list \fIvbl\fR contains
variables that provide additional information for the remote
manager. Note, the value of sysUpTime.0 is added to the varbind list
automatically. The inform session command will only send confirmed
notifications on SNMPv2c or SNMPv3 sessions. Invoking the inform
session command on an SNMPv1 session will result in an unacknowledged
trap.

If the inform session command contains a callback \fIscript\fR, then
the command sends the inform-request and returns immediately. The
result is the request id for the asynchronous request. The snmp#
inform session command is processed synchronously if the callback
\fIscript\fR is absent. In this case, the received varbind list is
returned. The command fails with a Tcl error if the manager does not
respond or if a protocol error happens.

.CS
$s inform coldStart [list [list SNMPv2-MIB!sysDescr.0 "Fridge"]]
.CE

.SH RESPONDER SESSION COMMANDS

XXX This is all outdated! XXX

This section describes the SNMP session commands used to implement
SNMP agents in Tcl. The SNMP agent maintains a tree of MIB instances
which are linked to Tcl variables. Whenever the value of a MIB
instance is required by the SNMP protocol engine, the corresponding
Tcl variable is read. This allows to update MIB instances easily from
Tcl. However, some MIB instances are designed to have arbitrary side
effects, especially if the value is changed. A binding mechanism
allows to bind Tcl scripts to events inside of the SNMP protocol
engine so that a Tcl script can control the behavior of MIB instances.

.TP
.B snmp# instance \fIlabel\fR \fIvarName\fR [\fIdefault\fR]
The \fBsnmp# instance\fR session command creates a new MIB instance if
the session is configured as an SNMP agent. The MIB instance
identified by \fIlabel\fR is linked to the global Tcl variable
\fIvarName\fR. The SNMP protocol engine reads the value of
\fIvarName\fR and converts it into the required SNMP data type while
processing incoming requests. An agent script must ensure that
\fIvarName\fR contains an acceptable format (see above). The optional
argument \fIdefault\fR defines the initial value of \fIvarName\fR.
The lifetime of the MIB instance is bound to the Tcl variable
\fIvarName\fR.

.TP
.B snmp# bind \fIlabel\fR \fIevent\fR [\fIscript\fR]
The \fBsnmp# bind\fR session command binds a Tcl \fIscript\fR to the
MIB instance tree node identified by \fIlabel\fR and is only valid for
sessions in agent mode. The \fIevent\fR argument defines the SNMP
operation that triggers the evaluation of the \fIscript\fR. Supported
events types are get, set, create, check, commit, rollback, begin and
end. The \fBsnmp# bind\fR session command returns the currently
defined binding if the \fIscript\fR argument is missing.

The begin and end bindings are evaluated before PDU processing starts
and after PDU processing has finished. The \fIlabel\fR for begin and
end bindings must be empty. Get event bindings are evaluated, whenever
a MIB instance is read. They can be used to modify the contents of the
associated Tcl variable before the value is actually put into the
response message. 

Set, create, check, commit and rollback bindings are used to implement
writable MIB instances. The check, commit and rollback bindings are
needed to allow scripts to conform to the "as if simultaneously"
requirement (RFC 1157, RFC 1905). Set requests are processed in three
phases. In the first phase, set and create events are processed to
modify existing or create new MIB instances. The seconds phase is
processed only if no error occured in the first phase. The second
phase activates check bindings to allow scripts to check the
consistency of the new values. The final phase is the commit/rollback
phase which triggers the commit bindings if there has not been any
error in the earlier phases. An error in one of the earlier phases
triggers the rollback bindings. The protocol engine will also restore
the Tcl variables with previously saved values.

A Tcl script bound to an event can signal a SNMP specific error by
invoking the Tcl error command and returning one of the SNMP error
codes (tooBig, noSuchName, badValue, readOnly, genErr, noAccess,
wrongType, wrongLength, wrongEncoding, wrongValue, noCreation,
inconsistentValue, resourceUnavailable, commitFailed, undoFailed,
authorizationError, notWritable, inconsistentName).

All the % escapes sequences described in the section about callback
scripts will be expanded before the command is evaluated. In addition,
there are three more escapes defined for SNMP bindings:

.RS
.IP \fB%o\fR 5
Replaced with the object identifier of the MIB instance that triggered
the event.
.IP \fB%i\fR 5
Replaced with the instance identifier of the MIB instance that triggered
the event.
.IP \fB%v\fR
Replaced with the value for the MIB instance that triggered the event.
.IP \fB%p\fR
Replaced with the previous value for the MIB instance during SNMP set
operations and an empty string otherwise.
.RE

Below is an example that implements a MIB instance tnmTclCmdCount.0
which returns the actual number of Tcl commands processed by the Tcl
interpreter:

.CS
$s instance TUBS-IBR-TNM-MIB!tnmTclCmdCount.0 tnmTclCmdCount
$s bind TUBS-IBR-TNM-MIB!tnmTclCmdCount.0 get {
    set tnmTclCmdCount [info cmdcount]
}
.CE

The second example implements two MIB instances called tnmHttpSource.0
and tnmHttpError.0. The tnmHttpSource.0 instance shall retrieve a Tcl
file via HTTP and evaluate the contents. The second tnmHttpError.0
instance contains the error message of the last use of
tnmHttpSource.0:

.CS
$s instance TUBS-IBR-TNM-MIB!tnmHttpSource.0 tnmHttpSource
$s instance TUBS-IBR-TNM-MIB!tnmHttpError.0 tnmHttpError

$s bind TUBS-IBR-TNM-MIB!tnmHttpSource.0 set {
    set tnmHttpSource "%v"
    set msg [SNMP_HttpSource $tnmHttpSource]
    if {$msg != ""} {
        set tnmHttpError $msg
        error inconsistentValue
    }
}

$s bind TUBS-IBR-TNM-MIB!tnmHttpSource.0 rollback {
    set tnmHttpSource ""
}
$s bind TUBS-IBR-TNM-MIB!tnmHttpSource.0 commit {
    set tnmHttpError ""
}
.CE

It is sometimes useful to bind scripts to non-leaf nodes of the MIB
instance tree. All bindings starting from the leaf node up to the root
of the MIB instance tree are processed. You can use the Tcl break
command to disable further binding processing. For example, the
following binding will trigger on all get events in the enterprise MIB
subtree and can be used for debugging purposes:

.CS
$s bind 1.3.6.1.4.1 get {
    puts "%T from %A:%P object %o (instance %i)"
}
.CE

.SH BUGS
The Tcl arithmetic is not platform independent and does not support
unsigned numbers. It is therefore complicated to write portable
scripts that work correctly with large SNMP numbers.
.PP
It is not possible to receive SNMP traps by more than one application
on the Windows platform.
.PP
The SNMPv3 implementation currently only supports noAuth/noPriv
communication.

.SH SEE ALSO
scotty(1), Tnm(n), Tcl(n)

.SH AUTHORS
Juergen Schoenwaelder <schoenw@ibr.cs.tu-bs.de>
.br
