class SNMP::TrapListener
SNMP
Trap Listener¶ ↑
Listens to a socket and processes received traps and informs in a separate thread.
Example¶ ↑
require 'snmp' m = SNMP::TrapListener.new(:Port => 1062, :Community => 'public') do |manager| manager.on_trap_default { |trap| p trap } end m.join
Constants
- NULL_HANDLER
Attributes
Retrieves the current configuration of this TrapListener
.
Public Class Methods
Source
# File lib/snmp/manager.rb, line 620 def initialize(options={}, &block) config = Config.new(options) @transport = config.create_transport @community = config.community @max_bytes = config.max_recv_bytes @mib = MIB.new load_modules(config.mib_modules, config.mib_dir) @config = config.applied_config @handler_init = block @oid_handler = {} @v1_handler = nil @v2c_handler = nil @default_handler = nil @lock = Mutex.new @handler_thread = Thread.new(self) { |m| process_traps(m) } end
Start a trap handler thread. If a block is provided then the block is executed before trap handling begins. This block is typically used to define the trap handler blocks.
The trap handler blocks execute in the context of the trap handler thread.
The most specific trap handler is executed when a trap arrives. Only one handler is executed. The handlers are checked in the following order:
-
handler for a specific OID
-
handler for a specific
SNMP
version -
default handler
The default for the :community option is ‘nil’ allows traps with any community to be accepted. To only accept traps from a specific community, the community may also be set to a string (e.g. ‘public’) or a list of strings (e.g. [‘public’, ‘my_private_community’] ).
Public Instance Methods
Source
# File lib/snmp/manager.rb, line 692 def exit @handler_thread.exit @transport.close end
Stops the trap handler thread and releases the socket.
See also Thread#exit.
Source
# File lib/snmp/manager.rb, line 683 def join @handler_thread.join end
Joins the current thread to the trap handler thread.
See also Thread#join.
Source
# File lib/snmp/manager.rb, line 653 def on_trap(object_id, &block) raise ArgumentError, "a block must be provided" unless block @lock.synchronize { @oid_handler[ObjectId.new(object_id)] = block } end
Define a trap handler block for a specific trap ObjectId
. This handler only applies to SNMPv2 traps. Note that symbolic OIDs are not supported by this method (like in the SNMP.Manager class).
Source
# File lib/snmp/manager.rb, line 643 def on_trap_default(&block) raise ArgumentError, "a block must be provided" unless block @lock.synchronize { @default_handler = block } end
Define the default trap handler. The default trap handler block is executed only if no other block is applicable. This handler should expect to receive both SNMPv1_Trap
and SNMPv2_Trap
objects.
Source
# File lib/snmp/manager.rb, line 662 def on_trap_v1(&block) raise ArgumentError, "a block must be provided" unless block @lock.synchronize { @v1_handler = block } end
Define a trap handler block for all SNMPv1 traps. The trap yielded to the block will always be an SNMPv1_Trap
.
Source
# File lib/snmp/manager.rb, line 673 def on_trap_v2c(&block) raise ArgumentError, "a block must be provided" unless block @lock.synchronize { @v2c_handler = block } end
Define a trap handler block for all SNMPv2c traps. The trap yielded to the block will always be an SNMPv2_Trap
. Note that InformRequest
is a subclass of SNMPv2_Trap
, so inform PDUs are also received by this handler.
Private Instance Methods
Source
# File lib/snmp/manager.rb, line 729 def community_allowed?(msg_community) @community.nil? || @community == msg_community || !(Array(@community) & Array(msg_community)).empty? end
Source
# File lib/snmp/manager.rb, line 702 def load_modules(module_list, mib_dir) module_list.each { |m| @mib.load_module(m, mib_dir) } end
Source
# File lib/snmp/manager.rb, line 706 def process_traps(trap_listener) @handler_init.call(trap_listener) if @handler_init loop do data, source_ip, source_port = @transport.recvfrom(@max_bytes) begin message = Message.decode(data, @mib) if community_allowed? message.community trap = message.pdu if trap.kind_of?(InformRequest) @transport.send(message.response.encode, source_ip, source_port) end trap.source_ip = source_ip select_handler(trap).call(trap) end rescue => e puts "Error handling trap: #{e}" puts e.backtrace.join("\n") puts "Received data:" p data end end end
Source
# File lib/snmp/manager.rb, line 733 def select_handler(trap) @lock.synchronize do if trap.kind_of?(SNMPv2_Trap) oid = trap.trap_oid if @oid_handler[oid] return @oid_handler[oid] elsif @v2c_handler return @v2c_handler elsif @default_handler return @default_handler else return NULL_HANDLER end elsif trap.kind_of?(SNMPv1_Trap) if @v1_handler return @v1_handler elsif @default_handler return @default_handler else return NULL_HANDLER end else return NULL_HANDLER end end end