Skip to content

getBulk appears to have the worng 'next' behaviour - which breaks SNMP Tables #53

@dirkx

Description

@dirkx

Tables appear to not be quite working; given a trivial 1 entry EntityMIB table with one entry:

  snmp.addReadOnlyIntegerHandler(oidEntPhysicalIndex, 1);
  snmp.addReadOnlyIntegerHandler(entPhysicalContainedIn,0 /* top level item/container */);
  snmp.addReadOnlyIntegerHandler(oidEntPhysicalClass, 1 /* (other) */);

  snmp.addReadOnlyStaticStringHandler(oidEntPhysicalDesc, "a desc");
  snmp.addReadOnlyStaticStringHandler(oidEntPhysicalName, "a name");

  snprintf(buff, sizeof(buff), "ESP32-%016llx", ESP.getEfuseMac());
  snmp.addReadOnlyStaticStringHandler(oidEntPhysicalSerialNum, std::string(buff));

Will give the right results on an snmpwalk

  $ snmpwalk 10.11.0.181 entPhysicalTable
  ENTITY-MIB::entPhysicalIndex.1 = INTEGER: 1
  ENTITY-MIB::entPhysicalDescr.1 = STRING: a desc
  ENTITY-MIB::entPhysicalContainedIn.1 = INTEGER: 0
  ENTITY-MIB::entPhysicalClass.1 = INTEGER: other(1)
  ENTITY-MIB::entPhysicalName.1 = STRING: a name
  ENTITY-MIB::entPhysicalSerialNum.1 = STRING: ESP32-00004045651b5ae0
  $

But will give an empty/no table on an

  $ snmptable 10.11.0.181 entPhysicalTable
  ENTITY-MIB::entPhysicalTable: No entries
  $

The reason for this appears a wrong GetBulk response:

   00:00:00.000000 IP (tos 0x0, ttl 64, id 21691, offset 0, flags [none], proto UDP (17), length 74, bad cksum 0 (->102e)!)
       10.11.0.240.57576 > 10.11.0.181.161:  { SNMPv2c { GetBulk(31) R=1397163026  N=0 M=10 .1.3.6.1.2.1.47.1.1.1.1.0 } }

    00:00:00.002582 IP (tos 0x0, ttl 255, id 27, offset 0, flags [none], proto UDP (17), length 83)
       10.11.0.181.161 > 10.11.0.240.57576:  { SNMPv2c { GetResponse(37) R=1397163026  .1.3.6.1.2.1.47.1.1.1.1.0=[endOfMibView] } }

i.e. the ENTITY-MIB::entPhysicalEntry.0 does not give the right reply. If we add, as dirty workaround/hack:

   snmp.addReadOnlyIntegerHandler(oidEntPhysicalTable, 0);

to the above code; things do work:

    $ snmptable 10.11.0.181 entPhysicalTable
    SNMP table: ENTITY-MIB::entPhysicalTable

    entPhysicalDescr entPhysicalVendor ...
    a desc           ? .....
    $

With TCPDUMP showing the expected:

    10.11.0.240.60651 > 10.11.0.181.161:  { SNMPv2c { GetBulk(31) R=343496280  N=0 M=10 .1.3.6.1.2.1.47.1.1.1.1.0 } }
        00:00:00.005414 IP (tos 0x0, ttl 255, id 18, offset 0, flags [none], proto UDP (17), length 417)
    10.11.0.181.161 > 10.11.0.240.60651:  { SNMPv2c { GetResponse(367) R=343496280  .1.3.6.1.2.1.47.1.1.1.1.1.1=1 .1.3.6.1.2.1.47.1.1.1.1.2.1="Valve controller" .1.3.6.1.2.1.47.1.1.1.1.4.1=0 .1.3.6.1.2.1.47.1.1.1.1.5.1=1 .1.3.6.1.2.1.47.1.1.1.1.7.1="XXX" .1.3.6.1.2.1.47.1.1.1.1.8.1="XX" .1.3.6.1.2.1.47.1.1.1.1.9.1="XXX" .1.3.6.1.2.1.47.1.1.1.1.10.1="XXX" .1.3.6.1.2.1.47.1.1.1.1.11.1="ESP32-00004045651b5ae0" .1.3.6.1.2.1.47.1.1.1.1.12.1="XXX" } }

However - this breaks various SNMP tools - as now

     % snmpget 10.11.0.181 entPhysicalEntry.0
     ENTITY-MIB::entPhysicalEntry.0 = INTEGER: 0

instead of the expected

     ENTITY-MIB::entPhysicalEntry.0 = No Such Object available on this agent at this OID

i.e. it returns a value (0) - confusing most tools, crashing some or causing an empty table entry. So this work around is not ideal. It seems that the getBulk() handler does not do a 'getNext' enough of a search.

I suspect that ValueCallback::findCallback() is too much subtree focused; and somehow misses, on a getNext / walk=True that, for example, a get next on a nonexistent .1.3.6.1.2.1.1.9.1.0 should return, for example, .1.3.6.1.2.1.1.9.1.2.1 (i.e. the first SNMPv2-MIB::sysORID.1 of the fist SNMPv2-MIB::sysORTable).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions