Skip to content

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

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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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