Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'instanceIndex=(0,)' caused exception SmiError as “ValueRangeConstraint(1, 2147483647) failed at: ”0“” at Integer32 #7

Open
harper1011 opened this issue May 29, 2016 · 4 comments

Comments

@harper1011
Copy link

harper1011 commented May 29, 2016

I am new for python and SNMP (as well as pysnmp). After two weeks study, I wrote a piece of python code which try to send a trap message.
The NotificationType was created by code: (pysnmp 4.3.2)

   notification = NotificationType(ObjectIdentity('MY_MIB_FILE','myAlarmCleared'),
                                    instanceIndex=(0,),  
                                    objects={
                                        ('MY_MIB_FILE', 'myAlarmId'):
                                            Integer32(111),
                                        ('MY_MIB_FILE', 'mySystemDN'):
                                            self.DisplayString(''),  # currently a null string
                                        ('MY_MIB_FILE', 'myAlarmNotificationSource'):
                                            ObjectIdentifier(
                                                (1, 3, 6, 1, 4)), # some dummy value
                                        ('MY_MIB_FILE', 'myNotiSequenceNum'):
                                            Integer32(222),
                                        ('MY_MIB_FILE', 'myAlarmManagedObjectInstance'):
                                            self.DisplayString('SubNetwork=nw1,ManagedElement=my-1'),
                                        ('MY_MIB_FILE', 'myAlarmType'):
                                            self.AlarmType(3),
                                        ('MY_MIB_FILE', 'myAlarmProbableCause'):
                                            self.ProbableCause(307),
                                        ('MY_MIB_FILE', 'myAlarmSpecificProblem'):
                                            self.DisplayString('test alarm'),
                                        ('MY_MIB_FILE', 'myAlarmPerceivedSeverity'):
                                            self.AlarmSeverity(6),
                                        ('MY_MIB_FILE', 'myAlarmTime'):
                                            self.DateAndTime(OctetString(self.get_current_date_and_time())),
                                        ('MY_MIB_FILE', 'myAlarmAdditionalText'):
                                            self.DisplayString('alarm testing'),
                                        ('MY_MIB_FILE', 'myAlarmName'):
                                            self.DisplayString('system_testing_alarm'),
                                        ('MY_MIB_FILE', 'myAlarmServiceUser'):
                                            self.DisplayString('Dapeng Jiao'),
                                        ('MY_MIB_FILE', 'myAlarmServiceProvider'):
                                            self.DisplayString('Unknown Service Provider'),
                                        ('MY_MIB_FILE', 'myAlarmSecurityAlarmDetector'):
                                            self.DisplayString('Unknown Alarm Detector'),
                                        ('MY_MIB_FILE', 'myAlarmADMC'):
                                            Integer(1)
                                    }
                                    )

when I execute this code, I got following SmiError:

  File "/vagrant_data/snmpAgent/SOURCES/snmp_notifier_v3.py", line 142, in notifier_start
    cbFun=cbfun
  File "/usr/lib/python2.7/site-packages/pysnmp/hlapi/asyncore/ntforg.py", line 145, in sendNotification
    vbProcessor.makeVarBinds(snmpEngine, varBinds),
  File "/usr/lib/python2.7/site-packages/pysnmp/hlapi/varbinds.py", line 51, in makeVarBinds
    varBinds.resolveWithMib(mibViewController)
  File "/usr/lib/python2.7/site-packages/pysnmp/smi/rfc1902.py", line 1143, in resolveWithMib
    objectIdentity = ObjectIdentity(*notificationObject+self.__instanceIndex).resolveWithMib(mibViewController)
  File "/usr/lib/python2.7/site-packages/pysnmp/smi/rfc1902.py", line 504, in resolveWithMib
    raise SmiError('Instance index %r to OID convertion failure at object %r: %s' % (self.__args[2:], mibNode.getLabel(), sys.exc_info()[1]))
pysnmp.smi.error.SmiError: Instance index (0,) to OID convertion failure at object 'myAlarmTime': ConstraintsIntersection(ConstraintsIntersection(ConstraintsIntersection(), ValueRangeConstraint(-2147483648, 2147483647)), ValueRangeConstraint(1, 2147483647)) failed at: "ValueRangeConstraint(1, 2147483647) failed at: "0"" at Integer32

It seems pysnmp doesn't like to add suffix .0 for the variable whose syntax is defined as:

Integer32().subtype(subtypeSpec=ValueRangeConstraint(1, 2147483647))).setMaxAccess("readwrite")

Does it a bug for pysnmp?
Or I should not add that .0 suffix?(at least after remove that '0,' from instanceIndex the code can be executed and trap message sent successfully.
But I was told that

A scalar variable has single instance and is identified by suffix .0 .
The object identifier (OID) with .0 suffix indicates a scalar variable (i.e., single instance) (eg, analogous/category of a “table” with only one column)
Each of the varbinds in the notification is scalar for this alarm notification.

Also there is a explanation about Scalar and Tabular Objects: https://www.webnms.com/cagent/help/technology_used/c_snmp_overview.html#scalar&tabular
Scalar and Tabular Objects

A managed object has both a type (defined in ASN.1) and a value. For example, the SNMP system group variable sysLocation ( this variable is defined in RFC1213-MIB ) has the type, DisplayString and may have the value, "WebNMS Velachery". So in our case, we can define noOfPapers or inkLevel of the printer as a scalar object in the MIB.

Managed objects, in SNMP, are of two types : scalar objects and tabular objects.

A managed object that always has a single instance is called a scalar object. Tabular objects, on the other hand, have multiple instances, such as the rows of a table. For example, the MIB II system group has seven "leaf" variables under it, as illustrated in Figure below. Each of these objects is a scalar object. For example, the value of sysUpTime is the duration of time since re-initialization of a system's network management software (SNMP agent), measured in hundredths of a second.

Tables in SNMP are two-dimensional objects defined as an ASN.1 type called SEQUENCE OF, which allows 0 or more members. Each element of the sequence is an entry (row) in the table, which itself is a sequence of scalar-valued objects. SNMP does not allow tables to be nested within tables.

For example, the MIB II at group contains simply one tabular object, the atTable, which contains one row for each of a system's physical interfaces. Each row in the table is an instance of the object atEntry. Each row contains instances of the scalar-valued leaf objects atIfIndex, atPhysAddress, and atNetAddress. The leaf objects are called columnar objects since the instances of each such object constitute one column in the table. Although these objects have scalar-valued instances, they are not scalar objects because they can have multiple instances.

So seems the .0 is anyway needed, right? (Since it should be a object has a single instance.)
Or there are some misunderstanding from us?

Thanks in advance.

Br,
-Dapeng Jiao

The original MIB defination for that variable is:

myAlarmCleared NOTIFICATION-TYPE
    OBJECTS {
        myAlarmId,
        cesSystemDN,
        myAlarmNotificationSource,
        cesNotiSequenceNum,
        myAlarmManagedObjectInstance,
        myAlarmType,
        myAlarmProbableCause,
        myAlarmSpecificProblem,
        myAlarmPerceivedSeverity,
        myAlarmTime,
        myAlarmAdditionalText,
        myAlarmName,
        myAlarmServiceUser,
        myAlarmServiceProvider,
        myAlarmSecurityAlarmDetector,
        myAlarmADMC
    }
    STATUS  current
    DESCRIPTION
        "This notification is generated when an alarm is cleared."
    ::=  {  myAlarmNotifications  3  }

myAlarmTime OBJECT-TYPE
    SYNTAX  DateAndTime
    MAX-ACCESS  read-only
    STATUS  current
    DESCRIPTION
        "This variable is the time of this Alarm object."
    ::=  {  myAlarmEntry  9  }

myAlarmEntry OBJECT-TYPE
    SYNTAX  myAlarmEntry
    MAX-ACCESS  not-accessible
    STATUS  current
    DESCRIPTION
        "A row containing one alarm."
    INDEX   { myAlarmId }
    ::= { myAlarmTable 1 }

and converted python format is:

myAlarmCleared = NotificationType((1, 3, 6, 1, 4, 1, xxxx, x, xx, x, xxx, x, 6, 3)).setObjects(*(
("MY-MIB-FILE", "myAlarmTime"), ("MY-MIB-FILE", "myAlarmName"),
("MY-MIB-FILE", "myAlarmServiceUser"), ("MY-MIB-FILE", "myAlarmSpecificProblem"),
("MY-MIB-FILE", "cesSystemDN"), ("MY-MIB-FILE", "myAlarmProbableCause"),
("MY-MIB-FILE", "myAlarmType"), ("MY-MIB-FILE", "myAlarmAdditionalText"),
("MY-MIB-FILE", "myAlarmNotificationSource"), ("MY-MIB-FILE", "myAlarmId"),
("MY-MIB-FILE", "myAlarmManagedObjectInstance"), ("MY-MIB-FILE", "myAlarmADMC"),
("MY-MIB-FILE", "myAlarmSecurityAlarmDetector"),
("MY-MIB-FILE", "myAlarmPerceivedSeverity"), ("MY-MIB-FILE", "cesNotiSequenceNum"),
("MY-MIB-FILE", "myAlarmServiceProvider"),))

myAlarmEntry = MibTableRow((1, 3, 6, 1, 4, 1, xxxx, x, xx, x, xxx, x, x, x, 1)).setIndexNames((0, "MY-MIB-FILE", "myAlarmId"))
if mibBuilder.loadTexts: myAlarmEntry.setDescription("A row containing one alarm.")

myAlarmTime = MibTableColumn((1, 3, 6, 1, 4, 1, xxxx, x, xx, x, xxx, x, x, 1, 1, 9), DateAndTime()).setMaxAccess("readonly")
if mibBuilder.loadTexts: myAlarmTime.setDescription("This variable is the time of this Alarm object.")

DateAndTime was imported from SNMPv2-TC.

One update for this:
Even the exception shows the problem is caused by 'myAlarmTime'

pysnmp.smi.error.SmiError: Instance index (0,) to OID convertion failure at object 'myAlarmTime': ConstraintsIntersection(ConstraintsIntersection(ConstraintsIntersection(), ValueRangeConstraint(-2147483648, 2147483647)), ValueRangeConstraint(1, 2147483647)) failed at: "ValueRangeConstraint(1, 2147483647) failed at: "0"" at Integer32

But after debug, it seems the real issue is 'myAlarmId' syntax definition. As that variable is the only one defined with Integer32 with range (1, 2147483647)

myAlarmId = MibTableColumn((1, 3, 6, 1, 4, 1, xxxx, x, xx, x, xxx, x, 4, 1, 1, 1),
                            Integer32().subtype(subtypeSpec=ValueRangeConstraint(1, 2147483647))).setMaxAccess("readonly")

And after I change its value range to (0, 2147483647), the
instanceIndex = (0,)
start to works.

But I should NOT change that right?
Then what should be the root cause for this issue?
Pysnmp bug?
or our misunderstanding for SNMP and MIB file?

BTW: the suffix .0 was working fine with a Java based SNMP cilent. But due to company's order and license issue, we need to re-implement it and we though python should be a good enough to do this.

Attach more MIB definition relate to this alarm event

myAlarmTable OBJECT-TYPE
    SYNTAX  SEQUENCE OF myAlarmEntry
    MAX-ACCESS  not-accessible
    STATUS  current
    DESCRIPTION
        "A table of all the active alarms on the system."
    ::= { myAlarmObjects 1 }

myAlarmEntry OBJECT-TYPE
    SYNTAX  myAlarmEntry
    MAX-ACCESS  not-accessible
    STATUS  current
    DESCRIPTION
        "A row containing one alarm."
    INDEX   { myAlarmId }
    ::= { myAlarmTable 1 }

myAlarmEntry ::=
    SEQUENCE {
        myAlarmId                   Integer32,
        mySystemDN                  DisplayString,
        myAlarmNotificationSource           OBJECT IDENTIFIER,
        myAlarmManagedObjectInstance        DisplayString,
        myAlarmType                 AlarmType,
        myAlarmProbableCause            ProbableCause,
        myAlarmSpecificProblem          DisplayString,
        myAlarmPerceivedSeverity            AlarmSeverity,
        myAlarmTime                 DateAndTime,
        myAlarmAdditionalText           DisplayString,
        myAlarmName                 DisplayString,
        myAlarmServiceUser              DisplayString,
        myAlarmServiceProvider          DisplayString,
        myAlarmSecurityAlarmDetector        DisplayString,
        myAlarmADMC         INTEGER
    }


myAlarmId OBJECT-TYPE
    SYNTAX  Integer32 (1..2147483647)
    MAX-ACCESS  read-only
    STATUS  current
    DESCRIPTION
        "This object uniquely identifies an entry in the
        Alarm Table. It increases every time a new alarm
        occurs. Due to cleared alarms the index will not be
        contiguous. When the maximum is reached of
        Integer32, the value of this object rolls over to 1."
    ::=  {  myAlarmEntry  1  }

Br,
-Dapeng Jiao

lextm referenced this issue in lextudio/pysnmp Nov 10, 2022
@lextm
Copy link

lextm commented Aug 24, 2024

You should use a non-zero instance index, for example instanceIndex=(1,),. You can find an example in examples/smi/manager/convert-between-pdu-varbinds-and-mib-objects.py

@jmichiel
Copy link

jmichiel commented Nov 6, 2024

I'm having an identical issue.

This is a very stripped down version of the MIB I'm trying to use:

BAD-MIB DEFINITIONS ::= BEGIN

IMPORTS
 OBJECT-TYPE
   FROM RFC-1212
 enterprises
   FROM RFC1155-SMI;

globalConfiguration OBJECT IDENTIFIER ::= { enterprises 99999 }

-- Module Table
globalModuleTable OBJECT-TYPE
SYNTAX SEQUENCE OF ModuleTableEntry
ACCESS not-accessible
STATUS mandatory
::= { globalConfiguration 3 }

moduleTableEntry OBJECT-TYPE
SYNTAX ModuleTableEntry
ACCESS not-accessible
STATUS mandatory
INDEX { moduleNumber }
::= { globalModuleTable 1 }


ModuleTableEntry ::= SEQUENCE {
	moduleNumber 		INTEGER,
	moduleDeviceNode 	OBJECT IDENTIFIER,
	moduleMake 		OCTET STRING,
	moduleModel 		OCTET STRING,
	moduleVersion 		OCTET STRING,
	moduleType 		INTEGER } 
	
-- Module Number Parameter
moduleNumber OBJECT-TYPE
SYNTAX INTEGER (1..255)
ACCESS read-only
STATUS mandatory
::= { moduleTableEntry 1 } 

-- Module Make Parameter
moduleMake OBJECT-TYPE
SYNTAX OCTET STRING
ACCESS read-only
STATUS mandatory
::= { moduleTableEntry 3 }

END -- BAD-MIB DEFINITIONS 

Trying to use this OID: ObjectIdentity('BAD-MIB', 'moduleMake', 0)
I get this error:
pysnmp.smi.error.SmiError: Instance index (0,) to OID conversion failure at object 'moduleMake': <ConstraintsIntersection object, consts <ValueRangeConstraint object, consts -2147483648, 2147483647>, <ConstraintsUnion object, consts <ValueRangeConstraint object, consts 1, 255>>> failed at: ValueConstraintError('<ConstraintsUnion object, consts <ValueRangeConstraint object, consts 1, 255>> failed at: ValueConstraintError(\'all of (<ValueRangeConstraint object, consts 1, 255>,) failed for "0"\')') at Integer32 caused by <class 'pyasn1.type.error.ValueConstraintError'>: <ConstraintsIntersection object, consts <ValueRangeConstraint object, consts -2147483648, 2147483647>, <ConstraintsUnion object, consts <ValueRangeConstraint object, consts 1, 255>>> failed at: ValueConstraintError('<ConstraintsUnion object, consts <ValueRangeConstraint object, consts 1, 255>> failed at: ValueConstraintError(\'all of (<ValueRangeConstraint object, consts 1, 255>,) failed for "0"\')') at Integer32

The first instance of an OID is always at index 0, so changing to 1 will result in an NoSuchObject error if there's only meant to be 1.

Changing the moduleNumberdefinition to INTEGER (0..255) makes the error go away, but that doens't seem to make any sense as they are unrelated in my opinion.
The error also disappears if I remove the ModuleTableEntry' SEQUENCE` definition.

This seems to be an error in the OID conversion code.

@lextm
Copy link

lextm commented Nov 6, 2024

@jmichiel Two tips:

  1. Please read Call for your help to revive the PySNMP ecosystem together #429 to learn why you shouldn't post anything more in this repo.
  2. ObjectIdentity('BAD-MIB', 'moduleMake', 0) is a common mistake, so the issue you hit is different from this thread. Since moduleMake is not a scalar object, you shouldn't use 0 as index. The error message is more than correct here to point out that mistake. You might grab an SNMP book to study further.

@jmichiel
Copy link

jmichiel commented Nov 8, 2024

Sorry about posting here, wasn't aware of the move... (I'll still answer here if anyone else finds this)

Oh, I start to (finally) understand! You can't actually see by looking at the OID definition itself (like for moduleMake here) if it is a table entry, you have to know that it was referenced elsewhere, which is why removing the ModuleTableEntry ::= SEQUENCE definition solved it for me. I thought you had a table AND separate scalar values...

So the fact that I can only access this it through the .0 index on the device I'm testing means the implementation on the device side is wrong!

Thanks for clearing that up! Now I'll go and read up on SNMP tables...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants