Index of /tcl/ftparchive/sorted/net/snmp

      Name                   Last modified     Size  Description

[DIR] Parent Directory 29-Jan-99 12:29 - [   ] README 16-Jul-96 12:32 10k


This directory contains a SNMPv1/v2 protocol stack that was written to
support a Tcl based programming interface. It was implemented by Sven
Schmidt (vschmidt@ibr.cs.tu-bs.de) during his master thesis at the
Technical University of Braunschweig, GERMANY. Some ideas for the Tcl
interface were inspired by previous work done by P.H. Kamp.

The current version depends on the C interface of the event scheduler
found in Tcl7.5. Although we use this SNMP package mainly with scotty,
you can also use this SNMP extension in wish since it is dynamic
loadable.

Below is a short description of the syntax of the new SNMP Tcl
commands. The SNMPv1/v2 interface is implemented with two new Tcl
commands.  The first command deals with the Management Information
Base (MIB) and is called mib. Its syntax is:

	mib name        ?-exact? <name or oid>
	mib oid         ?-exact? <name or oid>
	mib syntax      ?-exact? <name or oid>
	mib description ?-exact? <name or oid>
	mib successor   ?-exact? <name or oid>
	mib access	?-exact? <name or oid>
	mib macro	?-exact? <name or oid>
	mib module	?-exact? <name or oid>
	mib file	?-exact? <name or oid>
	mib tc		?-excat? <name or oid>

The name, oid and syntax options retrieve the considered field of the
OBJECT-TYPE macro. The description can be retrieved using the
description command. The successor option returns all know direct
successors of a node and may be used by MIB browser programs. The
return values are implicitely defined by the argument. If you query
for successors providing an object identifier, you will get a list of
object identifiers as a result list. If you query by name, you will
get the names. Note, name are not unique and object identifier are
faster. So use object identifier internally and convert them to `nice'
names when you print them out.  The -exact switch request exact
matches only, that is a lookup as `mib -exact syntax sysDescr' is
legal while `mib -exact syntax sysDescr.0' will fail. The exact switch
has no meaning for the successor lookup since they are always done
using exact lookups.

The snmp command is used to create SNMP session handles. All
operations are later done using session handles.

	snmp session <options>
	snmp info

The snmp session command creates a new session handle and the snmp
info command returns a list of all handles currently available.  An
existing handle can be configured later. We assume that $s contains 
the name of a valid snmp handle:

	$s configure [<options>]

Called without any options, this command returns a keyed list of all
currently configured options. Options may be specified in one of the
following forms:

SNMPv1 (RFC 1157):
	-address	<ip address>
	-port		<port number>
	-community	<community string>
	-timeout	<seconds>
	-retries	<number>
	-version	SNMPv1

SNMPv2C (RFC 1901-1908):

	-address	<ip address>
	-port		<port number>
	-community	<community string>
	-timeout	<seconds>
	-retries	<number>
	-version	SNMPv2C

SNMPv2USEC (RFC 1909-1910):

	-user		<string>
	-password	<string>
	-context	<string>
	-timeout	<seconds>
	-retries	<number>
	-version	SNMPv2USEC

SNMP operations are invoked by using one of the following commands:

	$s get     <var list>  [<callback>]
	$s getnext <var list>  [<callback>]
	$s set     <var list>  [<callback>]
	$s getbulk nr max <var list> [<callback>]

The SNMP operation will be done synchronously if no callback is
defined. The command will return the result of the SNMP operation or
an error. Asynchronous operations happen if you define a callback
function. The callback will be called when a response is received or
if the protocol engine did not receive an answer after some retries.

The varbind will always contain the object identifier in the first
element of the varbind list. Use an explicit mib name lookup to
convert it to something more readable.

The <callback> script can contain format strings that can be used to
access parameters in the callback. An example:

	$s get "sysDescr.0 sysUpTime.0" { puts "Answer from %S (%R): %V" }

The format escapes are:

	%V default varbind rendering (a list containing name, syntax
	   and value for each varbind)

	%R the request id

	%S the session id

	%E error status

	%I error index

	%A the network address of the agent

	%P the port number of the agent

There is another small goodie which makes walks easier. The walk
subcommand just does a walk over a subtree and evaluates body foreach
object in the subtree, which can be found in the variable var.

	$s walk <var list> <var list> <body>

There is currently no asynchronous version of this one.

SNMP Traps are also supported. The syntax is quite simple:

	$s bind "" trap <callback>

The callback may contain the usual escapes described above. SNMPv1 traps
look like SNMPv2 traps as described in RFC 1452. The first element in the
varbind is the sysUpTime of the agent sending the trap and the second 
element is the snmpTrapOID. See 1452 how enterprise specific traps are
coded as an object identifier.

To send traps to another manager, you can use the trap session command:

	$s trap trapOid <var list>

Note: You have to make sure that the session handle is configured to
send traps to the correct port. The default port used when creating
session handles is the SNMP port 161. You have to switch it to
something useful in most cases, e.g.

	$s configure -port 162

The latest feature allows scotty to run as an SNMP agent. To initialize
scotty as an agent, you have to create a session and turn this session
into an agent:

	$s configure -agent "" -port 1701

The example above will create a listening socket on port 1701 and
answer SNMP request that are valid regarding the session handle $s
(that is setting the community string on $s to foobar will only allow
messages which also use the foobar community). The agent supports some
buildin variables: The MIB-2 system group and the SNMP statistics
group. You can define you own MIB variables by writing down some ASN.1
MIB definitions and loading them via the 'mib load' command. Now you
can create instances using the following command:

	$s instance <instance-oid> <varname> [<default>]

This command create an instance with the object identifier
instance-oid and links it to the Tcl variable <varname>. You can use
instance bindings to bind Tcl procedures to variables, which gives an
easy way to implement agents that translate between management
applications and real world hard- and software. The agents directory
contains some example agent code.

Below are some examples to see how to program with this Tcl SNMP interface:

1. Simple SNMPv1 operations:

    set s [snmp session -address 134.169.34.3]
    $s get sysDescr.0
    $s getnext [mib successor system]
    $s destroy

2. A set operation using a private community:

    set txt "greetings from [exec hostname]"
    set s [snmp session -address 134.169.34.3 -community private]
    $s set [list [list sysName.0 "OCTET STRING" $txt] ]
    $s destroy

3. An authenticated SNMPv2USEC session on port 1701 for user james:

    set s [snmp session -port 1701 -user james -password enterprise]
    $s get "sysDescr.0 sysUpTime.0"
    $s destroy

4. A simple table walk.

    set s [snmp session -address 134.169.34.3]
    puts "Index ifInOctets  ifOutOctets Description"
    $s walk x "ifIndex ifInOctets ifOutOctets ifDescr" {
	set Index       [lindex [lindex $x 0] 2]
	set ifInOctets  [lindex [lindex $x 1] 2]
	set ifOutOctets [lindex [lindex $x 2] 2]
	set ifDescr     [lindex [lindex $x 3] 2]
	puts [format "%3u %12u %12u %s" \
			$Index $ifInOctets $ifOutOctets $ifDescr]
    }
    $s destroy

5. A simple trap handler (SNMP version 1).

    proc traphandler {ip list} {
	set msg "SNMP trap from $ip:"
	foreach vb $list {
	   append msg " [mib name [lindex $vb 0]]=\"[lindex $vb 2]\""
	}
	puts stderr $msg
    }

    set s [snmp session -port 162]
    $s bind "" trap {traphandler %A "%V"}

6. Sending some well known traps.

   set s [snmp session -port 162]
   $s trap coldStart ""
   $s trap warmStart ""

7. A simple agent with a counter SNMP variable (abusing sysLocation):

   set s [snmp session -port 8161 -agent ""]

   # Create a counter binding for the sysLocation variable:

   $s bind sysLocation.0 get { 
       incr sysLocation
   }

   # Send a set request to yourself to initialize the sysLocation 
   # counter.

   $s set {{sysLocation.0 1}} {puts "%E %V"}

   # you can even send asynchronous requests to yourself :-)

   $s get sysLocation.0 {puts "%V"}

   # and you can add more bindings to the MIB tree

   $s bind system get "puts {GET request on session %S from %A}"

   $s get sysLocation.0 {puts "%V"}

   # and you can do special things when variables are set

   $s bind sysContact.0 set {
       set sysContact [string toupper "%v"]
       # a break makes sure that no other (default) bindings are invoked
       break
   }

   $s set {{sysContact.0 foobar}} {puts "%E %V"}

8. Another agent with a save Tcl interpreter using check/commit/rollback
   bindings. This needs some more work to simplify things a lot more.

   set i [interp create -safe]
   $i alias puts puts stderr

   set a [snmp session -agent $i -port 1701]
   $a bind "" begin {puts ""}

   $a bind sysContact set { puts {set %o.[%i] = %v} }
   $a bind sysContact get { puts {get %o.[%i]} }
   $a bind sysContact check {puts {check %o.[%i] = %v} }
   $a bind sysContact commit { puts {commit %o.[%i] = %v} }
   $a bind sysContact rollback { puts {rollback %o.[%i] = %v} }
 
   set m [snmp session -port 1701]
   $m set {{sysContact.0 "Bert Nase"}} {puts "%E@%I %V"}
   $m get sysContact.0 {puts "%E@%I %V"}
   $m set {{sysContact.0 ga} {sysDescr.0 no}} {puts "%E@%I %V"}
   $m get sysContact.0 {puts "%E@%I %V"}
   $m set {{sysContact.0 ga} {sysContact.0 gu} {sysDescr.0 no}} {puts "%E@%I %V"}
   $m get sysContact.0 {puts "%E@%I %V"}