I am new to snmp. I am using pysnmp to program a snmp agent, I compiled the MIB with mibdump.py and got it running using this examples: http://www.nealc.com/blog/blog/2013/02/23/writing-an-snmp-agent-with-a-custom-mib-using-pysnmp/ http://www.cloud-rocket.com/2013/08/writing-custom-mib-for-pysnmp-agent/ and also some of the documentation from de pysnmp webpage. I can do a get, a set and a walk on my agent, with variables that do not belong to a table. I cant do a walk on the table, I can do a get on half the objects, and I cant do a set on any of them. This is what I get when I try a get or a set on some of the objects. I thought it was something related to the way I was querying the table, but there is no consistency between one object and another, even if they seem the exact same.
pysnmp$ snmpset -v2c -c private localhost 1.3.6.1.4.1.1206.4.2.3.3.2.1.3.0 i 1
Error in packet.
Reason: notWritable (That object does not support modification)
Failed object: iso.3.6.1.4.1.1206.4.2.3.3.2.1.3.0
This is an object defind by mibdump.py like
fontName = MibTableColumn((1, 3, 6, 1, 4, 1, 1206, 4, 2, 3, 3, 2, 1, 3), DisplayString().subtype(subtypeSpec=ValueSizeConstraint(0, 64))).setMaxAccess("readwrite")
if mibBuilder.loadTexts: fontName.setStatus('mandatory')
Now this is a get on another column
pysnmp$ snmpget -v2c -c public localhost 1.3.6.1.4.1.1206.4.2.3.3.2.1.5.0
iso.3.6.1.4.1.1206.4.2.3.3.2.1.5.0 = No Such Instance currently exists at this OID
defined like this
fontCharSpacing = MibTableColumn((1, 3, 6, 1, 4, 1, 1206, 4, 2, 3, 3, 2, 1, 5), Integer32().subtype(subtypeSpec=ValueRangeConstraint(0, 255))).setMaxAccess("readwrite")
if mibBuilder.loadTexts: fontCharSpacing.setStatus('mandatory')
This is the debugger feedback for a set on the same object to an i 4 which should be in range
ValueConstraintError: ConstraintsIntersection(ValueRangeConstraint(-2147483648, 2147483647), ValueRangeConstraint(1, 255)) failed at: ValueConstraintError('ValueRangeConstraint(1, 255) failed at: ValueConstraintError(0,)',) at Integer32
There are a couple more errors that I think are related, to me it all seems like the MIB.py file is not getting read correctly, probably because I am overriding some code when customizing the mib. With the next function
def createVariable(SuperClass, getValue, sValue, *args):
"""This is going to create a instance variable that we can export.
getValue is a function to call to retreive the value of the scalar
"""
class Var(SuperClass):
def readGet(self, name, *args):
print " Getting var..."
return name, self.syntax.clone(getValue())
def writeTest(self, name, *args ):
print " Testing var..."
def writeCommit(self, name, val, *args ):
print " Setting var..."
sValue(val)
return Var(*args)
I dont understand the structure of pysnmp so I cant traceback where things go wrong, so I can post the rest of the code if necessary, it is only a couple hundred lines long for this tests.
Thank you for any help provided
To implement a dynamic SNMP table (where you can create/delete rows via SNMP SET) you should set up a hierarchy of MibTable
, MibTableRow
and MibTableColumn
objects:
(MibTable,
MibTableRow,
MibTableColumn,
MibScalarInstance) = mibBuilder.importSymbols(
'SNMPv2-SMI',
'MibTable',
'MibTableRow',
'MibTableColumn',
'MibScalarInstance'
)
And register them with pysnmp under the OIDs that reflect objects hierarchy e.g.:
RowStatus, = mibBuilder.importSymbols('SNMPv2-TC', 'RowStatus')
mibBuilder.exportSymbols(
'__EXAMPLE-MIB',
# table object
exampleTable=MibTable((1, 3, 6, 6, 1)).setMaxAccess('readcreate'),
# table row object, also carries references to table indices
exampleTableEntry=MibTableRow((1, 3, 6, 6, 1, 5)).setMaxAccess('readcreate').setIndexNames((0, '__EXAMPLE-MIB', 'exampleTableColumn1')),
# table column: string index
exampleTableColumn1=MibTableColumn((1, 3, 6, 6, 1, 5, 1), v2c.OctetString()).setMaxAccess('readcreate'),
# table column: string value
exampleTableColumn2=MibTableColumn((1, 3, 6, 6, 1, 5, 2), v2c.OctetString()).setMaxAccess('readcreate'),
# table column: integer value with default
exampleTableColumn3=MibTableColumn((1, 3, 6, 6, 1, 5, 3), v2c.Integer32(123)).setMaxAccess('readcreate'),
# table column: row status
exampleTableStatus=MibTableColumn((1, 3, 6, 6, 1, 5, 4), RowStatus('notExists')).setMaxAccess('readcreate')
)
Make sure to state how table index should look like e.g. the trailing part of the OID that goes past MibTableColumn
OID. You do that by configuring one or more columns to the .setIndexNames()
.
If you want to be able to create/drop the whole row in one shot, you need to have a dedicated status column in your table with the value of type RowStatus
. You can read the details on how RowStatus
works in RFC2579 (search for RowStatus).
By this point you should be able to create new rows:
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.2.97.98.99 s “my value”
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.4.97.98.99 i 4
(the 97.98.99
part of the OID corresponds to the exampleTableColumn1
string value of abc
which is an example index value).
As well as destroy the whole row:
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.4.97.98.99 i 6
When you create/destroy columns this way, the .createTest()
/createCommit()
and destroyTest()
/destroyCommit()
methods get invoked on the MibTableColumn
objects. The writeTest()
/writeCommit()
methods are invoked on value modification.
These are the methods you may want to override to control something outside pysnmp.
Complete example script can be seen here.
Note that we did not generate any code from ASN.1 MIB with mibdump.py
so far.
If you need more hands-on help with the code, I'd advise moving to pysnmp issues at GutHub.
With SNMP, MIBs usage is two-fold. SNMP clients (e.g. managers) use MIBs as a "schema" to figure out the data they receive from the SNMP servers (e.g. agents). The latter actually implement concrete data structures based on the MIB schema (schema instance).
With pysnmp we use the same set of Python classes for both purposes.
MibTable
, MibTableRow
, MibTableColumn
and MibScalar
)MibScalarInstance
) possibly manipulated by the schema objects whenever you intend to manage the schema instance objects at run time.This hopefully explains why pysnmp MIB management code looks similar for manager/agent implementations.