ruby-snmp icon indicating copy to clipboard operation
ruby-snmp copied to clipboard

walk returns nothing if the oid is a leaf node

Open rbur004 opened this issue 5 years ago • 5 comments

manager.get(["1.3.6.1.4.1.674.10892.5.4.600.60.1.7.1.1"]) works

manager.walk(["1.3.6.1.4.1.674.10892.5.4.600.60.1.7.1.1"]) has no results (same oid)

manager.walk(["1.3.6.1.4.1.674.10892.5.4.600.60.1.7.1"]) works too, giving one result. (oid less last .1)

I noticed this a while ago, and changed to using get for the leaf node oids. Then forgot all about it and spent hours yesterday trying to work out why my code wouldn't work, then remembered coming across this a long time ago.

rbur004 avatar Oct 02 '19 21:10 rbur004

That's the expected behavior. The walk() method uses get_next() not get() to retrieve data. I think this behavior is consistent with other tools.

hallidave avatar Oct 05 '19 00:10 hallidave

I had been expecting the same behaviour as the command line snmpwalk, which does return a single leaf oid.

% snmpwalk -v 1 -c public 10.30.20.99 1.3.6.1.4.1.674.10892.5.4.600.60.1.7.1.1 SNMPv2-SMI::enterprises.674.10892.5.4.600.60.1.7.1.1 = INTEGER: 4675038

I'll wrap the walk with my own code, as some devices I am querying have an extra arc at the end of some of their oids, and others don't. Hence I used walk, rather than get for these case, and have gotten into the habit of using walk everywhere.

There isn't much consistency in the use of oids across different manufacturers.

rbur004 avatar Oct 05 '19 19:10 rbur004

Looked into the net-snmp snmpwalk c code, There is a final GET request done, if no oids are returned. This can be turned off with -CI

% snmpwalk -v 1 -c public -CI 10.30.20.99 1.3.6.1.4.1.674.10892.5.4.600.60.1.7.1.1 %

-CI In fact, the given OID will be retrieved automatically if the main subtree walk returns no useable values. This allows a walk of a single instance to behave as generally expected, and return the specified instance value. This option turns off this final GET request, so a walk of a single instance will return nothing.

There is also a -Ci to do a get of the oid, before doing get next requests. This is turned off by default in the cli snmpwalk.

So your library is correct, it is just that the command line version has these extra options, which I wasn't aware of.

rbur004 avatar Oct 05 '19 19:10 rbur004

My hack to get the behaviour of the cli snmpwalk.

module SNMP #Manager class from snmp gem class Manager

alias real_walk walk

#Overrides walk in the SNMP gem manager.rb.
#Walks a list of ObjectId or VarBind objects using get_next until the response to the first OID in the list reaches the end of its MIB subtree.
# @param object_list [Array] List of oids we are looking up
# @param index_column The index_column identifies the column that will provide the index for each row. 
# @param options [Hash] :walk_include_requested same as cli snmpwalk -Ci  (Default is false. When true: does get(oid) before calling walk(oid) )
#                       :walk_dont_get_requested same as cli snmpwalk -CI (Default is false. When false: do get(oid) if walk returns no results)
#
def walk(object_list, index_column=0, options: {})
  @includeRequested = options[:walk_include_requested] != nil ? options[:walk_include_requested] : false
  @excludeRequested = options[:walk_dont_get_requested] != nil ? options[:walk_dont_get_requested] : false  
  object_list.each do |ol|
    if @includeRequested
      get([ol]).each_varbind { |vb| yield vb }
    end
    result = false
    real_walk([ol], index_column) do |row|
      result = true
      yield row
    end
    if !@includeRequested && !@excludeRequested && !result
      get([ol]).each_varbind { |vb| yield vb }
    end
  end
end

end
end

rbur004 avatar Oct 05 '19 22:10 rbur004

Thanks. I'll think about adding an option to the walk method. I can see how the inconsistency with the snmpwalk command would be confusing.

hallidave avatar Oct 06 '19 01:10 hallidave