'\"
'\" Copyright (c) 1994-1996 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.
'\" 
'\" The definitions below are for supplemental macros used in Tcl/Tk
'\" manual entries.
'\"
'\" .AP type name in/out ?indent?
'\"	Start paragraph describing an argument to a library procedure.
'\"	type is type of argument (int, etc.), in/out is either "in", "out",
'\"	or "in/out" to describe whether procedure reads or modifies arg,
'\"	and indent is equivalent to second arg of .IP (shouldn't ever be
'\"	needed;  use .AS below instead)
'\"
'\" .AS ?type? ?name?
'\"	Give maximum sizes of arguments for setting tab stops.  Type and
'\"	name are examples of largest possible arguments that will be passed
'\"	to .AP later.  If args are omitted, default tab stops are used.
'\"
'\" .BS
'\"	Start box enclosure.  From here until next .BE, everything will be
'\"	enclosed in one large box.
'\"
'\" .BE
'\"	End of box enclosure.
'\"
'\" .CS
'\"	Begin code excerpt.
'\"
'\" .CE
'\"	End code excerpt.
'\"
'\" .VS ?br?
'\"	Begin vertical sidebar, for use in marking newly-changed parts
'\"	of man pages.  If an argument is present, then a line break is
'\"	forced before starting the sidebar.
'\"
'\" .VE
'\"	End of vertical sidebar.
'\"
'\" .DS
'\"	Begin an indented unfilled display.
'\"
'\" .DE
'\"	End of indented unfilled display.
'\"
'\" .SO
'\"	Start of list of standard options for a Tk widget.  The
'\"	options follow on successive lines, in four columns separated
'\"	by tabs.
'\"
'\" .SE
'\"	End of list of standard options for a Tk widget.
'\"
'\" .OP cmdName dbName dbClass
'\"	Start of description of a specific option.  cmdName gives the
'\"	option's name as specified in the class command, dbName gives
'\"	the option's name in the option database, and dbClass gives
'\"	the option's class in the option database.
'\"
'\" .UL arg1 arg2
'\"	Print arg1 underlined, then print arg2 normally.
'\"
'\" SCCS: @(#) man.macros 1.8 96/02/15 20:02:24
'\"
'\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
'\"	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ie !"\\$3"" \{\
.ta \\n()Au \\n()Bu
\&\\$1	\\fI\\$2\\fP	(\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
'\"	# define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
'\"	# BS - start boxed text
'\"	# ^y = starting y location
'\"	# ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
'\"	# BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
'\"	# VS - start vertical sidebar
'\"	# ^Y = starting y location
'\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
.de VS
.if !"\\$1"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
'\"	# VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
'\"	# Special macro to handle page bottom:  finish off current
'\"	# box/sidebar if in box/sidebar mode, then invoked standard
'\"	# page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
'\"	# DS - begin display
.de DS
.RS
.nf
.sp
..
'\"	# DE - end display
.de DE
.fi
.RE
.sp
..
'\"	# SO - start of list of standard options
.de SO
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 4c 8c 12c
.ft B
..
'\"	# SE - end of list of standard options
.de SE
.fi
.ft R
.LP
See the \\fBoptions\\fR manual entry for details on the standard options.
..
'\"	# OP - start of full description for a single option
.de OP
.LP
.nf
.ta 4c
Command-Line Name:	\\fB\\$1\\fR
Database Name:	\\fB\\$2\\fR
Database Class:	\\fB\\$3\\fR
.fi
.IP
..
'\"	# CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
'\"	# CE - end code excerpt
.de CE
.fi
.RE
..
.de UL
\\$1\l'|0\(ul'\\$2
..
.TH snmp n "" Tnm "Tnm Tcl Extension"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
snmp \- Send SNMP messages to devices on the Internet.
.BE

.SH DESCRIPTION

The \fBTnm\fR Tcl extension includes an implementation of the Simple
Network Management Protocol (SNMP) which is used to monitor and
control devices on the Internet. The \fBTnm\fR extension supports SNMP
version 1 (SNMPv1) as defined in RFC 1155 and RFC 1157, community
based SNMP version 2 (SNMPv2C) as defined in RFC 1901-1908 as well as
User-based SNMP version 2 (SNMPv2U) as defined in RFC1909-1910. The
Tcl commands described in this man page follow the conventions defined
in the SNMPv2 standard (RFC1902-1908). The differences between SNMPv1
and SNMPv2 are hidden as far as possible from the user of this
extension by applying automatic conversions where possible.

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

The programming interface described in this man page can be split in
four groups:
.IP [1]
Commands to create and control SNMP sessions.
.IP [2]
Commands to invoke simple SNMP operations on SNMP sessions.
.IP [3]
Commands to invoke complex SNMP operations on SNMP sessions.
.IP [4]
Commands to implement SNMP agents.
.PP

The SNMP commands described in this man page are usually used together
with the 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 SNMP data types with a short description of the
corresponding primitive representation in Tcl:

.TP 20
.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 \fBTnm\fR extension always returns
sub-identifier as decimal numbers. However, the \fBTnm\fR 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 values are used to represent time intervals. The resolution
of a TimeTicks values is a deci-second. TimeTicks values are converted
to a string of the form "nd hh:mm:ss.cc" where n is the number of
days, hh is the number hours, mm is the number of minutes, ss is the
number of seconds and cc is the number of hundreds of a seconds. A
typical primitive Tcl string representation of a TimeTicks value looks
like "48d 12:36:43.22". The \fBTnm\fR extension accepts TimeTicks values
where the number of days and/or the number of deci-seconds is missing,
e.g. "1164:36:43". The deci-seconds are set to 0 if they are missing.

.TP
.B INTEGER, Integer32, Counter, Counter32, Gauge, Gauge32, Unsigned32
Values of all these numeric types are converted into an integer
number. Counter, Counter32, Gauge, Gauge32 and Unsigned32 values are
always positive. INTEGER or Integer32 values can be negative. The
Counter32, Gauge32 and Integer32 types are limited to 32 bits.
.TP
.B Counter64
The Counter64 type allows to use 64 bit unsigned counters. A value
of the Counter64 type is mapped to an integer number on 64 bit machines
and to a floating point number on 32 bit machines.
.PP

The \fBTnm\fR extension returns values in the primitive string
representation if no other formatting rules apply. Other formatting
rules are extracted from MIB specifications (see the mib(n) command on
how to load MIB specifications) and applied automatically. 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 an ASCII string by applying the
"225a" DISPLAY-HINT and values of type TruthValue are represented as
"true" or "false" instead of 1 and 2 (RFC 1903). Explicit conversions
are possible using the \fBmib format\fR and \fBmib scan\fR commands
described in the mib(n) man page.

.SH SNMP VARBIND LISTS

The SNMP protocol always operates of 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
base 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 {0d  0:03:23.08}} 
  {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 often not necessary to use fully specified varbind lists. It is
possible to omit the type and value fields if you are retrieving
values of MIB instances. For example, to retrieve the fully specified
varbing list example 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 also allowed to use object type descriptors instead of object
identifier in dotted notation. (See the mib(n) man page for details
about object identifier names.) This further simplifies the varbind
list above to:

.CS
{ sysUpTime.0 ifType.1 ifDescr.1 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 found in a MIB module. This allows to use a list like

.CS
{ {sysContact.0 "schoenw@cs.utwente.nl"} }
.CE

to change to value of the sysContact.0 instance. Please note, that the
\fBTnm\fR extension always returns fully specified varbind list to
avoid ambiguities.

SNMPv2 varbind list 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 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.
The 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 while some
of them 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 first element of the varbind list
has the position 1.
.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 SIMPLE 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 of 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
the any change 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).

.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 "sysDescr.0 sysName.0 sysContact.0"

$s get "sysDescr.0 sysName.0 sysContact.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
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 { 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 "sysUpTime ifIndex 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 sysContact.0 "Bert Nase"] \\
    [list 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. 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 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 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.

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
foreach name [$s scalars "sysUpTime udp tcp" 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 tnmTclCmdCount.0 tnmTclCmdCount
$s bind 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 tnmHttpSource.0 tnmHttpSource
$s instance tnmHttpError.0 tnmHttpError

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

$s bind tnmHttpSource.0 rollback {
    set tnmHttpSource ""
}
$s bind 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.
.br
The complex SNMP session commands should support asynchronous operations.

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

.SH AUTHORS
Juergen Schoenwaelder <schoenw@cs.utwente.nl>
.br
Sven Schmidt <vschmidt@ibr.cs.tu-bs.de>
.br
