'\"
'\" 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 "February 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
User-based SNMP version 2 (SNMPv2U) as defined in RFC 1909 and RFC
1910. The Tcl commands described in this man page follow the
conventions defined in the SNMPv2/SNMPv3 standards. The differences
between SNMPv1 and SNMPv2/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 are usually 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 usually used in
combination with the Tnm::mib(n) command, which allows to retrieve
information from Management Information Base (MIB) definitions.

.SH SNMP DATA TYPES
The SNMP protocol uses a fixed set of primitive data types. These data
types are mapped to a primitive 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 octect (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
OBJECT IDENTIFIER are used to address information in a MIB. An OBJECT
IDENTIFIER is a sequence of positive numbers which defines a path
through from the root of the global 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 accepted and converted to the value 
"1.3.6.1.4.1.1575".
.TP
.B IpAddress
Values of type IpAddress are converted into 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 of unsigned
numbers. 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 into a signed integer number on 32
bit systems.
.TP
.B INTEGER, Integer32
INTEGER or Integer32 values are in the range -2^31 (-2147483648) to
2^31-1 (2147483647). Values of these types are converted into a string 
of signed numbers.
.TP
.B Counter64
Counter64 values are in the range 0 to 2^64-1 (18446744073709551615).
Note, arithmetics with Counter64 values is 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.
.PP
The Tnm extension returns values in the primitive string
representation if no other formatting rules apply. Formatting rules
extracted from MIB definitions 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 instances. 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 instance, the
data type of the MIB instance and the value of the MIB instance. 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 for MIB instances. 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 in dotted notation
with labels or names that resolve to an object identifier value. See
the Tnm::mib manual page for details about OID tree, labels and
names. This 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 a MIB instance, 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 to value of the sysContact.0 instance. Please note, that the
Tnm extension always returns fully specified varbind lists to avoid
ambiguities.

SNMPv2 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 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 are the same for all supported SNMP versions and SNMP
session types, while others are specific to a particular version. 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. 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 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.

.TP
.BI -version " number"
The \fB-version\fR option selects the SNMP version used by a SNMP
session. The currently supported version numbers are SNMPv1 (RFC 1157
style SNMP), SNMPv2C (RFC 1901 style SNMP) and SNMPv2U (RFC 1910 style
SNMP). The default SNMP version is SNMPv1.

.TP
.BI -community " string"
The \fB-community\fR option is specific for SNMPv1 and SNMPv2C sessions.
It defines the community string which is used to identify the sender of
SNMP messages. The default community string is "public".

.TP
.BI -writecommunity " string"
The \fB-writecommunity\fR option is specific for SNMPv1 and SNMPv2C 
sessions. It defines the community string which is used to identify
the sender of SNMP messages when invoking SNMP set operations. 
The default write community string is empty which means that the
community string defined by the \fB-community\fR option is used.

.TP
.BI -user " name"
The \fB-user\fR option is specific to SNMPv2U sessions. It is used to
define the SNMP user name. The default user name is "public".

.TP
.BI -password " password"
The \fB-password\fR option is specific to SNMPv2U 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 1910. 
The key is also automatically localized once the agentID of the SNMP
agent is known. Note that the application should take care to keep
the passwords safe from unauthorized access. An empty password turns
SNMPv2U authentication off. The default password is "".

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

.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.

.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.

.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.

.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 with asynchronous messages.
The \fBTnm\fR 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. The default window size
is 10 messages.

.TP
.BI -agent " interp"
The \fB-agent\fR option turns the SNMP session into an SNMP agent.
The \fIinterp\fR argument defines the Tcl interpreter which will be
used to evaluate bindings associated with MIB instances. It is
recommended to use a safe Tcl interpreter if you are evaluating
scripts or arguments received over the network. It is also possible to
use the current Tcl interpreter by using an empty interpreter name.

.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 \fBsnmp alias\fR command. It is
possible to refer to other \fB-alias\fR options within an \fB-alias\fR
option. See the description of the \fBsnmp alias\fR command below for
an example.

.SH SNMP CALLBACK SCRIPTS

Many SNMP commands described below allow to program 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.
.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
are get-request, get-next-request, response, snmpV1-trap, set-request,
get-bulk-request, inform-request, snmpV2-trap, report.

.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 session\fR [\fIoption\fR \fIvalue\fR ...]
The \fBsnmp session\fR command creates new SNMP sessions. It returns a
session handle which is used to invoke operations. It is possible to
add configuration options as described above to the \fBsnmp session\fR
command in order to configure the SNMP session.

.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 \fBsnmp alias\fR command can be substitued when configuring a
SNMP session by using the \fB-alias\fR session option as described above.  

The \fBsnmp alias\fR 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 \fBsnmp alias\fR 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. 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 "-community ncc1701"
.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 info
The \fBsnmp info\fR command returns a list of existing SNMP sessions. 

.TP
.B snmp watch \fItoggle\fR
The \fBsnmp watch\fR command turns hex printing of SNMP packets on or
off. This is mostly a debugging aid because you can't process the
output with a Tcl script.

.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.

.SH GENERAL SNMP 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 \fBsnmp# configure\fR
session command always returns the current settings of the configuration 
options. Note, invoking the \fBsnmp# configure\fR 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# 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.

.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).

.SH GENERATOR SNMP SESSION COMMANDS

.TP
.B snmp# get \fIvarbindlist\fR [\fIscript\fR]
The \fBsnmp# get\fR session command retrieves the list of instances as
specified in the \fIvarbindlist\fR by using an SNMP get-request.  If
the \fBsnmp# get\fR 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 \fBsnmp# get\fR session command is processed synchronously if the
callback \fIscript\fR is missing. In this case, the received varbind
list is returned or the command fails if the agent does not respond or
if a protocol error happens.

Below is an example for a synchronous and an asynchronous get
request to retrieve variables of the system group:

.CS
$s get "SNMPv2-MIB!sysDescr.0 SNMPv2-MIB!sysName.0"

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

.TP
.B snmp# getnext \fIvarbindlist\fR [\fIscript\fR]
The \fBsnmp# getnext\fR session command retrieves the values of the
lexicographical successors to the objects named in \fIvarbindlist\fR.
If the \fBsnmp# getnext\fR 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 \fBsnmp# getnext\fR session command is processed synchronously if
the callback \fIscript\fR is missing. In this case, the received
varbind list is returned or the command fails 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 are two
examples that show a synchronous and an asynchronous version.

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

proc dump {s vbl err} {
    if {$err == "noError"} {
        puts $vbl
        $s getnext $vbl { dump "%S" "%V" "%E" }
    }
}
$s getnext 1.3 { dump "%S" "%V" "%E" }
.CE

.TP
.B snmp# getbulk \fInr\fR \fImr\fR \fIvarbindlist\fR [\fIscript\fR]
The \fBsnmp# getbulk\fR session command can be used to implement fast
MIB tree walks by using get-bulk-requests. The \fBsnmp# getbulk\fR
command performs a getnext on the first \fInr\fR elements given in the
\fIvarbindlist\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
\fBsnmp# getbulk\fR 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 \fBsnmp# getbulk\fR session command is processed synchronously if
the callback \fIscript\fR is missing. In this case, the received
varbind list is returned or the command fails if the agent does not
respond or if a protocol error happens.

A typical example of the \fBsnmp# getbulk\fR session command is shown
below. It will return sysUpTime.0 and the values for ifIndex.1,
ifDescr.1, ifIndex.2 and ifDescr.2 assuming the device has at least 2
interfaces and implements snmp version 2.

.CS
$s getbulk 1 2 "SNMPv2-MIB!sysUpTime IF-MIB!ifIndex IF-MIB!ifDescr"
.CE

.TP
.B snmp# set \fIvarbindlist\fR [\fIcallback\fR]
The \fBsnmp# set\fR session command can be used to create and alter
MIB instances. The varbind list for set-requests must contain at least
the object identifier and the new value as described above. If the
\fBsnmp# set\fR 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 \fBsnmp# set\fR session command is processed synchronously if the
callback \fIscript\fR is missing. In this case, the received varbind
list is returned or the command fails if the agent does not respond or
if a protocol error happens.

Below is an example which shows how you can change the sysContact.0
and sysLocation.0 variables of the system group. 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.

.CS
$s set [list \\
    [list SNMPv2-MIB!sysContact.0 "Bert Nase"] \\
    [list SNMPv2-MIB!sysLocation.0 "Hall6, Floor 5"] \\
]
.CE

.TP
.B snmp# trap \fIsnmpTrapOid\fR \fIvarbindlist\fR

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

SNMPv1 traps are defined by an enterprise object identifier and a
generic and specific trap number. It is possible to convert a SNMPv1
trap definition into a \fIsnmpTrapOid\fR object identifier by
appending the generic and specific trap number to the enterprise
object identifier (RFC1908). This conversion is done automatically if
the SNMPv1 trap is defined using a TRAP-TYPE macro (RFC 1212) in a MIB
module.

SNMP traps are usually received on UDP port 162. It is therefore
necessary to change the default settings of the SNMP session handle to
send a trap. Below is an example that changes the destination port,
sends a coldStart trap, and restores the destination port. It is also
possible to keep a special session around just for sending trap
messages.

.CS
set port [$s cget -port]
$s configure -port 162
$s trap coldStart [list [list SNMPv2-MIB!sysDescr.0 "Fridge"]]
$s configure -port $port
.CE

.TP
.B snmp# inform \fIsnmpTrapOid\fR \fIvarbindlist\fR [\fIscript\fR]

The \fBsnmp# inform\fR session command is only available for SNMPv2
sessions and sends an inform-request to a manager. In contrast to a
trap, an inform-request is confirmed by the manager with a response
message. The information request type is defined by the
\fIsnmpTrapOid\fR in the same way as described for the \fBsnmp#
trap\fR session command above. The \fIvarbindlist\fR contains
variables that provide additional information for the remote
manager. Note, the value of sysUpTime.0 is added to the
\fIvarbindlist\fR automatically.

If the \fBsnmp# inform\fR 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 \fBsnmp# inform\fR session command is processed synchronously if
the callback \fIscript\fR is missing. In this case, the received
varbind list is returned or the command fails if the agent does not
respond or if a protocol error happens.

.CS
set port [$s cget -port]
$s configure -port 162
$s inform tooHot [list [list SNMPv2-MIB!sysDescr.0 "Fridge"]]
$s configure -port $port
.CE

.TP
.B snmp# bind {} send \fR[\fIscript\fR]
.ns
.TP
.B snmp# bind {} recv \fR[\fIscript\fR]
.ns
.TP
.B snmp# bind {} trap \fR[\fIscript\fR]
.ns
.TP
.B snmp# bind {} inform \fR[\fIscript\fR]
.ns
.TP
.B snmp# bind {} report \fR[\fIscript\fR]
The \fBsnmp# bind\fR session command allows to bind scripts to events
processed inside of the SNMP protocol engine. The first argument of
the \fBsnmp# bind\fR session commands described here is always an
empty string. (See the description of the agent commands below for
additional bindings and the use of this parameter.) The seconds
argument of the \fBsnmp# bind\fR session command is the event type.
The \fBsnmp# bind\fR session command always returns the script
currently bound to the given event type. A script is bound to an event
type by providing the optional \fIscript\fR argument. A script is
removed from an event by binding an empty string to this event.

A \fIsend\fR event is created whenever a SNMP message is send to the
network. Note, that the \fIsend\fR event only triggers once for every
request and not for every retransmission of the same
message. Similarly, the \fIrecv\fR event is created whenever a SNMP
message is received from the network. These commands can be used to
analyze the SNMP traffic from/to the SNMP engine.

Notifications send by an agent or another manager can be received by
binding scripts to \fItrap\fR and \fIinform\fR events. Binding a
script to one of these two event types starts the straps(8) daemon
which listens for incoming notifications on UDP port 162 and forwards
them to all interested processes on the local machine. SNMPv1 traps
are mapped to SNMPv2 traps as described in RFC 1908 section 3.1.2.

A \fIreport\fR event is created when the protocol engine receives a
SNMPv2U report message. These messages are used internally to
implement clock synchronization and agent discovery.

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

.SH COMPLEX SNMP SESSION COMMANDS

This section describes complex SNMP commands which usually perform a
sequence of SNMP operations. The implementation of these complex SNMP
session comands does some automatic error handling in order to hide
some of the differences between the SNMP version.

.TP
.B snmp# walk \fIvarName\fR \fIvarbindlist\fR \fIbody\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 given by \fIvarbindlist\fR. For each
valid varbind list retrieved from the agent, the Tcl script \fIbody\fR
is evaluated. Before evaluation of \fIbody\fR starts, the variable
named \fIvarName\fR is set to contain the actual varbind list. Below
is a simple example to walk and print the interface table:

.CS
$s walk x "ifIndex ifDescr" { puts $x }
.CE

.TP
.B snmp# scalars \fIscalarlist\fR \fIarrayName\fR
The \fBsnmp# scalars\fR session command can be used to retrieve
potentially large lists of scalars. The values are extracted from the
varbindlist and stored in the Tcl array named \fIarrayName\fR. The
\fIscalarlist\fR may include names of simple scalar MIB instances or
names of SNMP groups which can be expanded to a list of MIB
scalars. The array \fIarrayName\fR is indexed by the names of scalars
successfully retrieved from the agent.  The list of indexes is
returned by the \fBsnmp# scalars\fR session command. Protocol errors
(e.g. tooBig) or SNMPv2 varbind exceptions are handled internally.

The example below retrieves and prints the system uptime and the all
the scalars in the udp and tcp groups:

.CS
set groups "SNMPv2-MIB!sysUpTime UDP-MIB!udp TCP-MIB!tcp"
foreach name [$s scalars $groups s] {
    puts "$name : $s($name)"
}
.CE

.SH SNMP AGENT COMMANDS

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. It is therefore
complicated to write portable scripts that work correctly with large
SNMP numbers.
.PP
The complex SNMP session commands should support asynchronous operations.
.PP
It is not possible to receive SNMP traps by more than one application
on the Windows platform.
.PP
This man page is not up-to-date with the recent changes in the API.

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

.SH AUTHORS
Juergen Schoenwaelder <schoenw@cs.utwente.nl>
.br
Sven Schmidt
.br
