forked from logstash-plugins/logstash-input-snmp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient.rb
143 lines (117 loc) · 4.25 KB
/
client.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
require "java"
require "logstash-input-snmp_jars.rb"
java_import "org.snmp4j.CommunityTarget"
java_import "org.snmp4j.PDU"
java_import "org.snmp4j.Snmp"
java_import "org.snmp4j.Target"
java_import "org.snmp4j.TransportMapping"
java_import "org.snmp4j.event.ResponseEvent"
java_import "org.snmp4j.mp.SnmpConstants"
java_import "org.snmp4j.smi.Address"
java_import "org.snmp4j.smi.GenericAddress"
java_import "org.snmp4j.smi.OID"
java_import "org.snmp4j.smi.OctetString"
java_import "org.snmp4j.smi.VariableBinding"
java_import "org.snmp4j.transport.DefaultUdpTransportMapping"
java_import "org.snmp4j.transport.DefaultTcpTransportMapping"
java_import "org.snmp4j.util.TreeUtils"
java_import "org.snmp4j.util.DefaultPDUFactory"
java_import "org.snmp4j.asn1.BER"
module LogStash
class SnmpClientError < StandardError
end
class SnmpClient
def initialize(protocol, address, port, community, version, retries, timeout, mib)
transport = case protocol.to_s
when "udp"
DefaultUdpTransportMapping.new
when "tcp"
DefaultTcpTransportMapping.new
else
raise(SnmpClientError, "invalid transport protocol specified '#{protocol.to_s}', expecting 'udp' or 'tcp'")
end
@target = build_target("#{protocol}:#{address}/#{port}", community, version, retries, timeout)
@mib = mib
@snmp = Snmp.new(transport)
transport.listen()
end
def get(oids, strip_root = 0)
pdu = PDU.new
Array(oids).each { |oid| pdu.add(VariableBinding.new(OID.new(oid))) }
pdu.setType(PDU::GET)
response_event = @snmp.send(pdu, @target, nil)
return nil if response_event.nil?
e = response_event.getError
raise(SnmpClientError, "error sending snmp get request: #{e.inspect}, #{e.getMessage}") if e
result = {}
response_pdu = response_event.getResponse
raise(SnmpClientError, "timeout sending snmp get request") if response_pdu.nil?
size = response_pdu.size
(0..size - 1).each do |i|
variable_binding = response_pdu.get(i)
oid = variable_binding.getOid.toString
variable = variable_binding.getVariable
value = coerce(variable)
result[@mib.map_oid(oid, strip_root)] = value
end
result
end
def walk(oid, strip_root = 0)
result = {}
treeUtils = TreeUtils.new(@snmp, DefaultPDUFactory.new)
events = treeUtils.getSubtree(@target, OID.new(oid))
return nil if events.nil? || events.size == 0
events.each do |event|
next if event.nil?
if event.isError
# TODO: see if we can salvage non errored event here
raise(SnmpClientError, "error sending snmp walk request: #{event.getErrorMessage}")
end
var_bindings = event.getVariableBindings
next if var_bindings.nil? || var_bindings.size == 0
var_bindings.each do |var_binding|
next if var_binding.nil?
oid = var_binding.getOid.toString
variable = var_binding.getVariable
value = coerce(variable)
result[@mib.map_oid(oid, strip_root)] = value
end
end
result
end
private
def coerce(variable)
variable_syntax = variable.getSyntax
# puts("variable.getSyntaxString=#{variable.getSyntaxString}")
case variable_syntax
when BER::OCTETSTRING
variable.toString
when BER::TIMETICKS, BER::COUNTER, BER::COUNTER32
variable.toLong
when BER::INTEGER, BER::INTEGER32, BER::GAUGE, BER::GAUGE32
variable.toInt
when BER::IPADDRESS
variable.toString
when BER::OID
variable.toString
when BER::NOSUCHOBJECT
"Error: No Such Instance currently exists at this OID"
else
raise(SnmpClientError, "unknown variable syntax #{variable_syntax}, #{variable.getSyntaxString}")
end
end
def build_target(address, community, version, retries, timeout)
target = CommunityTarget.new
target.setCommunity(OctetString.new(community))
target.setAddress(GenericAddress.parse(address))
target.setRetries(retries)
target.setTimeout(timeout)
target.setVersion(parse_version(version))
target
end
def parse_version(version)
# TODO implement
SnmpConstants.version2c
end
end
end