Google+

SNMP Simulator Project Logo
SNMP Simulator introduction
Producing SNMP snapshots
Simulating SNMP Agents
Transport-based variation
Sharing snapshots
MIB-based simiulation
Simulation based on captured traffic
Simulation with variation modules
Recording with variation modules
Managing data files
Large scale simulation
Tips and tricks
Download & Install
License
Changelog
Github repo
Adding features
Simulation Service
Contact
Get SNMP Simulator at SourceForge.net. Fast, secure and Free Open Source software downloads

Using variation modules

Features described in this chapter are only applicable to Simulator version 0.2.0.

Without variation modules, simulated SNMP Agents are always static in terms of data returned to SNMP Managers. They are also read-only. By configuring particular OIDs or whole subtrees to be gatewayed to variation modules allows you to make returned data changing in time.

Another way of using variation modules is to gather data from some external source such as an SQL database or executed process or distant web-service.

It's also possible to modify simulated values through SNMP SET operation and store modified values in a database so they will persist over Simulator restarts.

Variation modules may be used for triggering events at other systems. For instance stock "notification" module will send SNMP TRAP/IMFORM messages to pre-configured SNMP Managers on SNMP SET request arrival to Simulator.

Finally, variation module API let you develop your own code in Python to fulfill your special needs and use your variation module with stock Simulator.

    Here's the current list of variation modules supplied with Simulator:

  • counter - produces a non-decreasing sequence of integers over time
  • gauge - produces a random number in specified range
  • notification - sends SNMP TRAP/INFORM messages to disitant SNMP entity
  • volatilecache - accepts and stores (in memory) SNMP var-binds through SNMP SET
  • involatilecache - accepts and stores (in file) SNMP var-binds through SNMP SET
  • sql - reads/writes var-binds from/to a SQL database
  • delay - delays SNMP response by specified number of miliseconds.
  • error - flag errors in SNMP response PDU
  • subprocess - executes external process and puts its stdout values into response

To make use of a variation module you will have to *edit* existing or create a new data file adding reference to a variation module into the "tag" field.

Consider .snmprec file format is a sequence of lines in the following format:

OID|TAG|VALUE

whereas TAG field complies to its own format:

TAG-ID[:MODULE-ID]

For example, the following .snmprec file contents will invoke the "volatilecache" module:

1.3.6.1.2.1.1.1.0|4:volatilecache|I'm a string, please modify me
1.3.6.1.2.1.1.3.0|2:volatilecache|42

and cast its returned values into ASN.1 OCTET STRING (4) and INTEGER (2) respectively.

Whenever a subtree is gatewayed to a variation module, TAG-ID part is left out as there might be no single type for all values within a subtree. Thus the empty TAG-ID sub-field serves as an indicator of a subtree.

For example, the following data file will serve all OIDs under 1.3.6.1.2.1.1 prefix to the "sql" variation module:

1.3.6.1.2.1.1|:sql|system

The value part is passed to variation module as-is. It is typically holds some module-specific configuration or initialization values.

For example, the following .snmprec line invokes the "notification" variation module instructing it to send SNMP INFORM message to SNMP Manager at 127.0.01:162 over SNMPv3 with specific SNMP params:

1.3.6.1.2.1.1.3.0|67:notification|3,usr-md5-des,md5,authkey1,des,
privkey1,udp,127.0.0.1,162,inform,1.3.6.1.6.3.1.1.5.2,

A small (but growing) collection of variation modules are shipped along with Simulator and normally installed into the Python site-packages directory. User can pass Simulator an alternative modules directory through its command line.

Simulator will load and bootstrap all variation modules it finds. Some modules can accept initialization parameters (like database connection credentials) through Simulator's --variation-module-options command-line parameter.

For example, the following Simulator invocation will configure its "sql" variation module to use sqlite database (sqlite3 Python module) and /var/tmp/system.db database file:

$ snmpsimd.py --variation-module-options=sql:sqlite3:/var/tmp/system.db

In case you are using multiple database connections or database types all through the sql variation module, you could refer to each module instance in .snmprec files through a so-called variation module alias.

The following command-line runs Simulator with two instances of the "involatilecache" variation module (dbA & dbB) each instance using distinct database file for storing their persistent values:

$ snmpsimd.py --variation-module-options=involatilecache=dbA:/var/tmp/fileA.db
--variation-module-options=involatilecache=dbB:/var/tmp/fileB.db

What follows is a brief description of some of the variation modules included into the distribution.

Counter module

The counter module maintains and returns a never decreasing integer value (except for the case of overflow) changing in time in accordance with user-defined rules. This module is per-OID stateful and configurable.

The counter module accepts the following comma-separated key=value parameters in .snmprec value field:

  • min - the minimum value ever stored and returned by this module. Default is 0.
  • max - the maximum value ever stored and returned by this module. Default is 2**32 (0xFFFFFFFF).
  • wrap - if zero, generated value will freeze when reaching 'max'. Otherwise generated value is reset to 'min'.
  • function - defines elapsed-time-to-generated-value relationship. Can be any of reasonably suitable mathematical function from the math module such as sin, log, pow etc. The only requirement is that used function accepts a single integer argument. Default is x = f(x).
  • rate - elapsed time scaler. Default is 1.0.
  • scale - function value scaler. Default is 1.0.
  • offset - constant value by which the return value increases on each invocation. Default is 0.
  • deviation - random deviation maximum. Default is 0.0 which means no deviation.

This module generates values by execution of the following formula:

v = abs(function(UPTIME * rate) * scale + offset + RAND(0, deviation)

Here's an example counter module use in a .snmprec file:

1.3.6.1.2.1.2.2.1.13.1|65:counter|max=100,scale=0.6,deviation=1,function=cos

Gauge module

The gauge module maintains and returns an integer value changing in time in accordance with user-defined rules. This module is per-OID stateful and configurable.

The gauge module accepts the following comma-separated key=value parameters in .snmprec value field:

  • min - the minimum value ever stored and returned by this module. Default is 0.
  • max - the maximum value ever stored and returned by this module. Default is 2**32 (0xFFFFFFFF).
  • function - defines elapsed-time-to-generated-value relationship. Can be any of reasonably suitable mathematical function from the math module such as sin, log, pow etc. The only requirement is that used function accepts a single integer argument. Default is x = f(x).
  • rate - elapsed time scaler. Default is 1.
  • scale - function value scaler. Default is 1.
  • offset - constant value by which the return value increases on each invocation. Default is 0.
  • deviation - random deviation minimum and maximum. Default is 0 which means no deviation.

This module generates values by execution of the following formula:

v = function(UPTIME * rate) * scale + offset + RAND(-deviation, deviation)

Here's an example gauge module use in a .snmprec file:

1.3.6.1.2.1.2.2.1.21.1|66:gauge|function=sin,scale=100,deviation=0.5

Delay module

The delay module postpones SNMP request processing for specified number of milliseconds.

Delay module accepts the following comma-separated key=value parameters in .snmprec value field:

  • value - holds the var-bind value to be included into SNMP response. In case of a string value containing commas, use 'hexvalue' instead.
  • hexvalue - holds the var-bind value as a sequence of ASCII codes in hex form. Before putting it into var-bind, hexvalue contents will be converted into ASCII text.
  • wait - specifies for how many milliseconds to delay SNMP response. Default is 500ms.
  • deviation - random delay deviation ranges. Default is 0 which means no deviation.

Here's an example delay module use in a .snmprec file:

1.3.6.1.2.1.2.2.1.3.1|2:delay|value=6,wait=100,deviation=200
1.3.6.1.2.1.2.2.1.4.1|2:delay|1500
1.3.6.1.2.1.2.2.1.6.1|4:delay|hexvalue=00127962f940,wait=800

The first entry makes Simulator responding with an integer value of 6 delayed by 0.1sec +- 0.2 sec. Negative delays are casted into zeros. The second entry is similar to the first one but uses delay module defaults. Finally, the last entry takes shape of an OCTET STRING value '0:12:79:62:f9:40' delayed by exactly 0.8 sec.

Keep in mind that since Simulator is a single-thread application, any delayed response will delay all concurrent requests processing as well.

Error module

The error module flags a configured error at SNMP response PDU.

Error module accepts the following comma-separated key=value parameters in .snmprec value field:

  • op - either of 'get', 'set' or o'any' values to indicate SNMP operation that would trigger error response. Here 'get' also enables GETNEXT and GETBULK operations. Default is 'any'.
  • value - holds the var-bind value to be included into SNMP response. In case of a string value containing commas, use 'hexvalue' instead.
  • hexvalue - holds the var-bind value as a sequence of ASCII codes in hex form. Before putting it into var-bind, hexvalue contents will be converted into ASCII text.
  • status - specifies error to be flagged. The following errors codes are supported:
    • 'genError'
    • 'noAccess'
    • 'wrongType'
    • 'wrongValue'
    • 'noCreation'
    • 'inconsistentValue'
    • 'resourceUnavailable'
    • 'commitFailed'
    • 'undoFailed'
    • 'authorizationError',
    • 'notWritable'
    • 'inconsistentName'
    • 'noSuchObject'
    • 'noSuchInstance'
    • 'endOfMib'

    The above constants are case-insensitive.

Here's an example error module use in a .snmprec file:

1.3.6.1.2.1.2.2.1.1.1|2:error|op=get,status=authorizationError,value=1
1.3.6.1.2.1.2.2.1.2.1|4:error|op=set,status=commitfailed,hexvalue=00127962f940
1.3.6.1.2.1.2.2.1.6.1|4:error|status=noaccess

The first entry flags 'authorizationError' on GET* and no error on SET. Second entry flags 'commitfailed' on SET but responds without errors to GET*. Finally, third entry always flags 'noaccess' error.

Volatile Cache module

The volatile cache module lets you make particular OID at a .snmprec file writable via SNMP SET operation. The new value will be stored in Simulator process's memory and communicated back on SNMP GET/GETNEXT/GETBULK operations. Stored data will be lost upon Simulator restart.

The .snmprec value will be used as an initial value by the volatilecache module.

Here's an example volatilecache module use in a .snmprec file:

1.3.6.1.2.1.1.3.0|2:volatilecache|42

In the above configuration, the initial value is 42 and can be modified by:

snmpset -v2c -c  localhost 1.3.6.1.2.1.1.3.0 i 24

command (assuming correct community name and Simulator is running locally).

Involatile cache module

The involatilecache module works similar to the volatilecache one, but the involatile vesion has an ability of storing current values in a persistent database.

Module invocation requires passing a name of a database file to be created if not already exists:

$ snmpsimd.py --variation-module-options=involatilecache:/tmp/shelves.db

All modifed values will be kept and then subsequently used on a per-OID basis in the specified file.

Subprocess module

The subprocess module can be used to execute an external program passing it request data and using its stdout output as a response value.

Value part of .snmprec line should contain space-separated path to external program executable followed by optional command-line parameters.

SNMP request parameters could be passed to the program to be executed by means of macro variables. With subprocess module, macro variables names always carry '@' sign at front and back (e.g. @MACRO@).

Full list of supported macros follows:

  • @DATAFILE@ - resolves into the .snmprec file selected by Simulator for serving current request
  • @OID@ - resolves into an OID of .snmprec line selected for serving current request
  • @TAG@ - resolves into the component of snmprec line selected for serving current request
  • @ORIGOID@ - resolves into currenty processed var-bind OID
  • @ORIGTAG@ - resolves into value type of currently processed var-bind
  • @ORIGVALUE@ - resolves into value of currently processed var-bind
  • @SETFLAG@ - resolves into '1' on SNMP SET, '0' otherwise
  • @NEXTFLAG@ - resolves into '1' on SNMP GETNEXT/GETBULK, '0' otherwise
  • @SUBTREEFLAG@ - resolves into '1' if the .snmprec file line selected for processing current request serves a subtree of OIDs rather than a single specific OID

Here's an example subprocess module use in a .snmprec file:

1.3.6.1.2.1.1.1.0|4:subprocess|echo SNMP Context is @DATAFILE@, received\
  request for @ORIGOID@, matched @OID@, received tag/value\
  "@ORIGTAG@"/"@ORIGVALUE@", would return value tagged @TAG@, SET request\ 
  flag is @SETFLAG@, next flag is @NEXTFLAG@, subtree flag is\
  @SUBTREEFLAG@
1.3.6.1.2.1.1.3.0|2:subprocess|date +%s

The first entry simply packs all current macro variables contents as a response string my printing them to stdout with echo, second entry invokes the UNIX date command instructing it to report elapsed UNIX epoch time.

Note .snmprec tag values -- executed program's stdout will be casted into appropriate type depending of tag indication.

Notification module

Beware: configuration syntax has changed since 0.2.0rc0

The notification module can send SNMP TRAP/INFORM notifications to distant SNMP engines by way of serving SNMP request sent to Simulator. In other words, SNMP message sent to Simulator can trigger sending TRAP/INFORM message to pre-configured targets.

No new process execution is involved in the operations of this module, it uses Simulator's SNMP engine for notification generation.

Notification module accepts the following comma-separated key=value parameters in .snmprec value field:

  • value - holds the var-bind value to be included into SNMP response message.
  • op - either of 'get', 'set' or 'any' values to indicate SNMP operation that would trigger notification. Here 'get' also enables GETNEXT and GETBULK operations. Default is 'set'.
  • version - SNMP version to use (1,2c,3).
  • ntftype - indicates notification type. Either 'trap' or 'inform'.
  • community - SNMP community name. For v1, v2c only. Default is 'public'.
  • trapoid - SNMP TRAP PDU element. Default is coldStart.
  • uptime - SNMP TRAP PDU element. Default is local SNMP engine uptime.
  • agentaddress - SNMP TRAP PDU element. For v1 only. Default is local SNMP engine address.
  • enterprise - SNMP TRAP PDU element. For v1 only.
  • user - USM username. For v3 only.
  • authproto - USM auth protocol. For v3 only. Either 'md5' or 'sha'. Default is 'md5'.
  • authkey - USM auth key. For v3 only.
  • privproto - USM encryption protocol. For v3 only. Either 'des' or 'aes'. Default is 'des'.
  • privkey - USM encryption key. For v3 only.
  • proto - transport protocol. Either 'udp' or 'udp6'. Default is 'udp'.
  • varbinds - a semicolon-separated list of OID:TAG:VALUE:OID:TAG:VALUE... of var-binds to add into SNMP TRAP PDU.
  • host - hostname or network address to send notification to.
  • port - UDP port to send notification to. Default is 162.

where <var-bind> has a syntax of:

<var-bind> = <oid>,<tag>,<value>

where <tag> is a single character of:

  • s: OctetString
  • i: Integer32
  • o: ObjectName
  • a: IpAddress
  • u: Unsigned32
  • g: Gauge32
  • t: TimeTicks
  • b: Bits
  • I: Counter64

For example, the following three .snmprec lines will send SNMP v1, v2c and v3 notifications whenever Simulator is processing GET* and/or SET request for configured OIDs:

1.3.6.1.2.1.1.1.0|4:notification|op=get,version=1,community=public,\
  proto=udp,host=127.0.0.1,port=162,ntftype=trap,\
  trapoid=1.3.6.1.4.1.20408.4.1.1.2.0.432,uptime=12345,agentaddress=127.0.0.1,\
  enterprise=1.3.6.1.4.1.20408.4.1.1.2,\
  varbinds=1.3.6.1.2.1.1.1.0:s:snmpsim agent:1.3.6.1.2.1.1.3.0:i:42,\
  value=SNMPv1 trap sender
1.3.6.1.2.1.1.2.0|6:notification|op=set,version=2c,community=public,\
  host=127.0.0.1,ntftype=trap,trapoid=1.3.6.1.6.3.1.1.5.1,\
  varbinds=1.3.6.1.2.1.1.1.0:s:snmpsim agent:1.3.6.1.2.1.1.3.0:i:42,\
  value=1.3.6.1.1.1
1.3.6.1.2.1.1.3.0|67:notification|version=3,user=usr-md5-des,authkey=authkey1,\
  privkey=privkey1,host=127.0.0.1,ntftype=inform,trapoid=1.3.6.1.6.3.1.1.5.2,\
  value=123456

Keep in mind that delivery status of INFORM notifications is not communicated back to SNMP Manager working with Simulator.

SQL module

The sql module lets you keep subtrees of OIDs and their values in a relational database. All SNMP operations are supported including transactional SET.

Module invocation requires passing database type (sqlite3, psycopg, MySQL and any other compliant to Python DB-API and importable as a Python module) and connect string which is database dependant:

$ snmpsimd.py --variation-module-options=sql:sqlite3:/tmp/sqlite.db

The .snmprec value is expected to hold database table name to keep all OID-value pairs served within selected .snmprec line. This table will not be created automatically and should exist for sql module to work. Table layout should be as follows:

  CREATE TABLE <tablename> (oid text primary key,
                            tag text,
                            value text,
                            maxaccess text default "read-only")

The most usual setup is to keep many OID-value pairs in a database table referred to by a .snmprec line serving a subtree of OIDs:

1.3.6.1.2.1.1|:sql|system

In the above case all OIDs under 1.3.6.1.2.1.1 prefix will be handled by a sql module using 'system' table.

Custom variation modules

Whenever you consider coding your own variation module, take a look at the existing ones. The API is very simple - it basically takes three Python functions (init, process, shutdown) where process() is expected to return a var-bind pair per each invocation.

Alternatively, we could help you with this task. Just let me know your requirements.


Need help? Open an issue at GitHub or ask question at Stack Overflow or try browsing snmpsim-users mailing list.