netsnmp 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'coveralls/rake/task'
4
+
5
+ desc "runs the tests and sends to coveralls server"
6
+ Coveralls::RakeTask.new
7
+
8
+ desc "runs the tests"
9
+ RSpec::Core::RakeTask.new
10
+
11
+ task default: [:spec]
12
+
13
+
14
+
15
+ namespace :spec do
16
+ desc "runs the tests in coverage mode"
17
+ task :coverage do
18
+ ENV['COVERAGE'] = "true"
19
+ Rake::Task["spec"].execute
20
+ end
21
+
22
+ desc "runs tests, check coverage, pushes to coverage server"
23
+ task :ci => ['spec:coverage', 'coveralls:push']
24
+ end
25
+
26
+
@@ -0,0 +1,16 @@
1
+ require 'netsnmp/version'
2
+
3
+ # core structures
4
+ require 'netsnmp/core'
5
+
6
+ module NETSNMP
7
+ # @return [String] the version of the netsnmp C library
8
+ def self.version ; Core.version ; end
9
+ end
10
+
11
+ require 'netsnmp/errors'
12
+ require 'netsnmp/varbind'
13
+ require 'netsnmp/oid'
14
+ require 'netsnmp/pdu'
15
+ require 'netsnmp/session'
16
+ require 'netsnmp/client'
@@ -0,0 +1,131 @@
1
+ module NETSNMP
2
+ # Main Entity, provides the user-facing API to communicate with SNMP Agents
3
+ #
4
+ # Under the hood it creates a "session" (analogous to the net-snmp C session), which will be used
5
+ # to proxy all the communication to the agent. the Client ensures that you only write pure ruby and
6
+ # read pure ruby, not concerning with snmp-speak like PDUs, varbinds and the like.
7
+ #
8
+ #
9
+ class Client
10
+
11
+ # @param [String] hostname the hostname of the agent
12
+ # @param [Hash] options the set of options to open the session.
13
+ #
14
+ # @see Session#initialize
15
+ def initialize(hostname, options)
16
+ @session ||= Session.new(hostname, options)
17
+ end
18
+
19
+ # @see Session#close
20
+ def close
21
+ @session.close
22
+ end
23
+
24
+ # Performs an SNMP GET Request
25
+ #
26
+ # @param [OID, String] oid_code the oid to get
27
+ # @param [Hash] options the varbind options (see Varbind)
28
+ # @option options [true, false] :response_pdu if true, the method returns a PDU
29
+ #
30
+ # @return [String] the value for the oid
31
+ #
32
+ def get(oid_code, **options)
33
+ request_pdu = RequestPDU.build(:get)
34
+ oid = oid_code.is_a?(OID) ? oid_code : OID.new(oid_code)
35
+ request_pdu.add_varbind(oid, options)
36
+ yield request_pdu if block_given?
37
+ response_pdu = @session.send(request_pdu)
38
+ case options[:response_type]
39
+ when :pdu then response_pdu
40
+ else response_pdu.value
41
+ end
42
+ end
43
+
44
+ # Performs an SNMP GETNEXT Request
45
+ #
46
+ # @param [OID, String] oid_code the oid to get
47
+ # @param [Hash] options the varbind options (see Varbind)
48
+ # @option options [true, false] :response_pdu if true, the method returns a PDU
49
+ #
50
+ # @return [String] the value for the next oid
51
+ #
52
+ # @note this method is used as a sub-routine for the walk
53
+ #
54
+ def get_next(oid_code, **options)
55
+ request_pdu = RequestPDU.build(:getnext)
56
+ oid = oid_code.is_a?(OID) ? oid_code : OID.new(oid_code)
57
+ request_pdu.add_varbind(oid, options)
58
+ yield request_pdu if block_given?
59
+ response_pdu = @session.send(request_pdu)
60
+ case options[:response_type]
61
+ when :pdu then response_pdu
62
+ else response_pdu.value
63
+ end
64
+ end
65
+
66
+ # Perform a SNMP Walk (issues multiple subsequent GENEXT requests within the subtree rooted on an OID)
67
+ #
68
+ # @param [OID, String] oid_code the root oid from the subtree
69
+ # @param [Hash] options the varbind options
70
+ #
71
+ # @return [Enumerator] the enumerator-collection of the oid-value pairs
72
+ #
73
+ def walk(oid_code, **options)
74
+ options[:response_type] = :pdu
75
+ walkoid = oid_code.is_a?(OID) ? oid_code : OID.new(oid_code)
76
+ Enumerator.new do |y|
77
+ code = walkoid.code
78
+ catch(:walk) do
79
+ loop do
80
+ response_pdu = get_next(code, options)
81
+ response_pdu.varbinds.each do |varbind|
82
+ code = varbind.oid_code
83
+ if !walkoid.parent_of?(code) or varbind.value.eql?(:endofmibview)
84
+ throw(:walk)
85
+ else
86
+ y << [code, varbind.value]
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ # Perform a SNMP GETBULK Request (performs multiple GETNEXT)
95
+ #
96
+ # @param [OID, String] oid_code the first oid
97
+ # @param [Hash] options the varbind options
98
+ # @option options [Integer] :errstat sets the number of objects expected for the getnext instance
99
+ # @option options [Integer] :errindex number of objects repeating for all the repeating IODs.
100
+ #
101
+ # @return [Enumerator] the enumerator-collection of the oid-value pairs
102
+ #
103
+ def get_bulk(oid_code, **options)
104
+ request_pdu = RequestPDU.build(:getbulk)
105
+ request_pdu[:errstat] = options.delete(:non_repeaters) || 0
106
+ request_pdu[:errindex] = options.delete(:max_repetitions) || 10
107
+ request_pdu.add_varbind(OID.new(oid_code), options)
108
+ yield request_pdu if block_given?
109
+ response_pdu = @session.send(request_pdu)
110
+ Enumerator.new do |y|
111
+ response_pdu.varbinds.each do |varbind|
112
+ y << [ varbind.oid_code, varbind.value ]
113
+ end
114
+ end
115
+ end
116
+
117
+ # Perform a SNMP SET Request
118
+ #
119
+ # @param [OID, String] oid_code the oid to update
120
+ # @param [Hash] options the varbind options
121
+ # @option options [Object] :value value to update the oid with.
122
+ #
123
+ def set(oid_code, **options)
124
+ request_pdu = PDU.build(:set)
125
+ request_pdu.add_varbind(OID.new(oid_code), options)
126
+ yield request_pdu if block_given?
127
+ response_pdu = @session.send(request_pdu)
128
+ response_pdu.value
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,12 @@
1
+ require 'ffi'
2
+
3
+ require 'netsnmp/core/libc'
4
+ require 'netsnmp/core/constants'
5
+ require 'netsnmp/core/structures'
6
+ require 'netsnmp/core/libsnmp'
7
+ require 'netsnmp/core/inline'
8
+ require 'netsnmp/core/utilities'
9
+
10
+ module NETSNMP::Core
11
+ LibSNMP.init_snmp("snmp")
12
+ end
@@ -0,0 +1,15 @@
1
+ require 'socket'
2
+ module SNMP
3
+ module Client
4
+ # RFC 2571
5
+
6
+ def bang(options={})
7
+ hostname, port = options.values_at(:hostname, :port)
8
+
9
+ sock = UDPSocket.new
10
+ sock.bind(hostname, port)
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,153 @@
1
+ module NETSNMP::Core
2
+ # Sets all the constants necessary to recognize from the structures
3
+ module Constants
4
+ MAX_OID_LEN = 128
5
+
6
+ # Return values of various send functions
7
+ STAT_SUCCESS = 0
8
+ STAT_ERROR = 1
9
+ STAT_TIMEOUT = 2
10
+
11
+ SNMP_VERSION_1 = 0
12
+ SNMP_VERSION_2c = 1
13
+ SNMP_VERSION_3 = 3
14
+
15
+
16
+ USM_AUTH_KU_LEN = 32
17
+ USM_PRIV_KU_LEN = 32
18
+
19
+ # SNMPv3 Security Levels
20
+ SNMP_SEC_LEVEL_NOAUTH = 1
21
+ SNMP_SEC_LEVEL_AUTHNOPRIV = 2
22
+ SNMP_SEC_LEVEL_AUTHPRIV = 3
23
+
24
+ # SNMP Errors
25
+ SNMPERR_SUCCESS = (0)
26
+ SNMPERR_GENERR = (-1)
27
+ SNMPERR_BAD_LOCPORT = (-2)
28
+ SNMPERR_BAD_ADDRESS = (-3)
29
+ SNMPERR_BAD_SESSION = (-4)
30
+ SNMPERR_TOO_LONG = (-5)
31
+ SNMPERR_NO_SOCKET = (-6)
32
+ SNMPERR_V2_IN_V1 = (-7)
33
+ SNMPERR_V1_IN_V2 = (-8)
34
+ SNMPERR_BAD_REPEATERS = (-9)
35
+ SNMPERR_BAD_REPETITIONS = (-10)
36
+ SNMPERR_BAD_ASN1_BUILD = (-11)
37
+ SNMPERR_BAD_SENDTO = (-12)
38
+ SNMPERR_BAD_PARSE = (-13)
39
+ SNMPERR_BAD_VERSION = (-14)
40
+ SNMPERR_BAD_SRC_PARTY = (-15)
41
+ SNMPERR_BAD_DST_PARTY = (-16)
42
+ SNMPERR_BAD_CONTEXT = (-17)
43
+ SNMPERR_BAD_COMMUNITY = (-18)
44
+ SNMPERR_NOAUTH_DESPRIV = (-19)
45
+ SNMPERR_BAD_ACL = (-20)
46
+ SNMPERR_BAD_PARTY = (-21)
47
+ SNMPERR_ABORT = (-22)
48
+ SNMPERR_UNKNOWN_PDU = (-23)
49
+ SNMPERR_TIMEOUT = (-24)
50
+ SNMPERR_BAD_RECVFROM = (-25)
51
+ SNMPERR_BAD_ENG_ID = (-26)
52
+ SNMPERR_BAD_SEC_NAME = (-27)
53
+ SNMPERR_BAD_SEC_LEVEL = (-28)
54
+ SNMPERR_ASN_PARSE_ERR = (-29)
55
+ SNMPERR_UNKNOWN_SEC_MODEL = (-30)
56
+ SNMPERR_INVALID_MSG = (-31)
57
+ SNMPERR_UNKNOWN_ENG_ID = (-32)
58
+ SNMPERR_UNKNOWN_USER_NAME = (-33)
59
+ SNMPERR_UNSUPPORTED_SEC_LEVEL = (-34)
60
+ SNMPERR_AUTHENTICATION_FAILURE = (-35)
61
+ SNMPERR_NOT_IN_TIME_WINDOW = (-36)
62
+ SNMPERR_DECRYPTION_ERR = (-37)
63
+ SNMPERR_SC_GENERAL_FAILURE = (-38)
64
+ SNMPERR_SC_NOT_CONFIGURED = (-39)
65
+ SNMPERR_KT_NOT_AVAILABLE = (-40)
66
+ SNMPERR_UNKNOWN_REPORT = (-41)
67
+ SNMPERR_USM_GENERICERROR = (-42)
68
+ SNMPERR_USM_UNKNOWNSECURITYNAME = (-43)
69
+ SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL = (-44)
70
+ SNMPERR_USM_ENCRYPTIONERROR = (-45)
71
+ SNMPERR_USM_AUTHENTICATIONFAILURE = (-46)
72
+ SNMPERR_USM_PARSEERROR = (-47)
73
+ SNMPERR_USM_UNKNOWNENGINEID = (-48)
74
+ SNMPERR_USM_NOTINTIMEWINDOW = (-49)
75
+ SNMPERR_USM_DECRYPTIONERROR = (-50)
76
+ SNMPERR_NOMIB = (-51)
77
+ SNMPERR_RANGE = (-52)
78
+ SNMPERR_MAX_SUBID = (-53)
79
+ SNMPERR_BAD_SUBID = (-54)
80
+ SNMPERR_LONG_OID = (-55)
81
+ SNMPERR_BAD_NAME = (-56)
82
+ SNMPERR_VALUE = (-57)
83
+ SNMPERR_UNKNOWN_OBJID = (-58)
84
+ SNMPERR_NULL_PDU = (-59)
85
+ SNMPERR_NO_VARS = (-60)
86
+ SNMPERR_VAR_TYPE = (-61)
87
+ SNMPERR_MALLOC = (-62)
88
+ SNMPERR_KRB5 = (-63)
89
+ SNMPERR_PROTOCOL = (-64)
90
+ SNMPERR_OID_NONINCREASING = (-65)
91
+ SNMPERR_MAX = (-65)
92
+
93
+ # PDU variable types
94
+ ASN_BOOLEAN = 0x01
95
+ ASN_INTEGER = 0x02
96
+ ASN_BIT_STR = 0x03
97
+ ASN_OCTET_STR = 0x04
98
+ ASN_NULL = 0x05
99
+ ASN_OBJECT_ID = 0x06
100
+ ASN_SEQUENCE = 0x10
101
+ ASN_SET = 0x11
102
+
103
+ ASN_UNIVERSAL = 0x00
104
+ ASN_APPLICATION = 0x40
105
+ ASN_CONTEXT = 0x80
106
+ ASN_PRIVATE = 0xC0
107
+
108
+ ASN_PRIMITIVE = 0x00
109
+ ASN_CONSTRUCTOR = 0x20
110
+
111
+ ASN_LONG_LEN = 0x80
112
+ ASN_EXTENSION_ID = 0x1F
113
+ ASN_BIT8 = 0x80
114
+
115
+
116
+ ASN_IPADDRESS = (ASN_APPLICATION | 0)
117
+ ASN_COUNTER = (ASN_APPLICATION | 1)
118
+ ASN_GAUGE = (ASN_APPLICATION | 2)
119
+ ASN_UNSIGNED = (ASN_APPLICATION | 2) # RFC 1902 - same as GAUGE
120
+ ASN_TIMETICKS = (ASN_APPLICATION | 3)
121
+ ASN_OPAQUE = (ASN_APPLICATION | 4)
122
+ ASN_NSAP = (ASN_APPLICATION | 5) # historic - don't use
123
+ ASN_COUNTER64 = (ASN_APPLICATION | 6)
124
+ ASN_UINTEGER = (ASN_APPLICATION | 7) # historic - don't use
125
+
126
+ # Exception types for SNMPv2 and SNMPv3 (no value needed)
127
+ SNMP_NOSUCHOBJECT = (ASN_CONTEXT | ASN_PRIMITIVE | 0x0)
128
+ SNMP_NOSUCHINSTANCE = (ASN_CONTEXT | ASN_PRIMITIVE | 0x1)
129
+ SNMP_ENDOFMIBVIEW = (ASN_CONTEXT | ASN_PRIMITIVE | 0x2)
130
+
131
+
132
+ # PDU types
133
+ SNMP_MSG_GET = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x0)
134
+ SNMP_MSG_GETNEXT = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x1)
135
+ SNMP_MSG_RESPONSE = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x2)
136
+ SNMP_MSG_SET = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x3)
137
+ SNMP_MSG_TRAP = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x4)
138
+ SNMP_MSG_GETBULK = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x5)
139
+ SNMP_MSG_INFORM = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x6)
140
+ SNMP_MSG_TRAP2 = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x7)
141
+ SNMP_MSG_REPORT = (ASN_CONTEXT | ASN_CONSTRUCTOR | 0x8)
142
+
143
+
144
+ # Callback status codes
145
+ NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE = 1
146
+ NETSNMP_CALLBACK_OP_TIMED_OUT = 2
147
+ NETSNMP_CALLBACK_OP_SEND_FAILED = 3
148
+ NETSNMP_CALLBACK_OP_CONNECT = 4
149
+ NETSNMP_CALLBACK_OP_DISCONNECT = 5
150
+
151
+ end
152
+ end
153
+
@@ -0,0 +1,20 @@
1
+ module NETSNMP::Core
2
+ module Inline
3
+ if RUBY_PLATFORM == "java"
4
+ def self.oid_size ; FFI::Pointer.size ; end
5
+ else
6
+ require 'inline'
7
+ inline do |builder|
8
+ # builder.include "sys/select.h"
9
+ builder.include "<net-snmp/net-snmp-config.h>"
10
+ builder.include "<net-snmp/types.h>"
11
+ #builder.include "stdio.h"
12
+ builder.c_singleton %q{
13
+ int oid_size() {
14
+ return sizeof(oid);
15
+ }
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,48 @@
1
+ module NETSNMP::Core
2
+ module C
3
+ extend FFI::Library
4
+ ffi_lib(FFI::Library::LIBC).first
5
+
6
+ typedef :pointer, :FILE
7
+ typedef :uint32, :in_addr_t
8
+ typedef :uint16, :in_port_t
9
+
10
+ unless FFI::Platform::IS_WINDOWS
11
+ attach_function :getdtablesize, [], :int
12
+ end
13
+
14
+ class Timeval < FFI::Struct
15
+ if FFI::Platform::IS_WINDOWS
16
+ layout(
17
+ :sec, :long,
18
+ :usec, :long
19
+ )
20
+ else
21
+ layout(
22
+ :tv_sec, :time_t,
23
+ :tv_usec, :suseconds_t
24
+ )
25
+ end
26
+ end
27
+
28
+ class FDSet < ::FFI::Struct
29
+ if FFI::Platform::IS_WINDOWS
30
+ layout(
31
+ :fd_count, :uint,
32
+ # TODO: Make it future proof by dynamically grabbing FD_SETSIZE.
33
+ :fd_array, [:uint, 2048]
34
+ )
35
+ def clear; self[:fd_count] = 0; end
36
+ else
37
+ # FD Set size.
38
+ FD_SETSIZE = C.getdtablesize
39
+ layout(
40
+ :fds_bits, [:long, FD_SETSIZE / FFI::Type::LONG.size]
41
+ )
42
+
43
+ # :nodoc:
44
+ def clear; super; end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,44 @@
1
+ module NETSNMP::Core
2
+ module LibSNMP
3
+ extend FFI::Library
4
+ ffi_lib ["libnetsnmp", "netsnmp"]
5
+
6
+ callback(:snmp_callback, [ :int, :pointer, :int, :pointer, :pointer ], :int)
7
+ callback(:netsnmp_callback, [ :int, :pointer, :int, :pointer, :pointer ], :int)
8
+
9
+ # checks whether the oid is supported
10
+ attach_function :read_objid, [:string, :pointer, :pointer], :int, blocking: true
11
+ # checks whether the mib is supported
12
+ attach_function :get_node, [:string, :pointer, :pointer], :int, blocking: true
13
+
14
+ # initializes internal stuff, loads mibs, etc etc etc...
15
+ attach_function :init_snmp, [ :string ], :void, blocking: true
16
+
17
+ # PDU API
18
+ attach_function :snmp_clone_pdu, [ :pointer ], :pointer
19
+ attach_function :snmp_pdu_type, [ :int ], :string
20
+ attach_function :snmp_pdu_add_variable, [ :pointer, :pointer, :uint, :u_char, :pointer, :size_t ], :pointer, blocking: true
21
+ attach_function :snmp_free_pdu, [ :pointer ], :void, blocking: true
22
+ attach_function :snmp_pdu_create, [:int], :pointer, blocking: true
23
+
24
+ # session handling
25
+ attach_function :generate_Ku, [:pointer, :int, :string, :int, :pointer, :pointer], :int, blocking: true
26
+ attach_function :snmp_sess_init, [ :pointer ], :void, blocking: true
27
+ attach_function :snmp_sess_open, [ :pointer ], :pointer, blocking: true
28
+ attach_function :snmp_sess_session, [ :pointer ], :pointer, blocking: true
29
+ attach_function :snmp_sess_close, [ :pointer ], :int, blocking: true
30
+
31
+ # send/receive API
32
+ attach_function :snmp_sess_send, [ :pointer, :pointer ], :int
33
+ attach_function :snmp_sess_async_send, [ :pointer, :pointer, :snmp_callback, :pointer ], :int, blocking: true
34
+ attach_function :snmp_sess_select_info, [ :pointer, :pointer, :pointer, :pointer, :pointer ], :int, blocking: true
35
+ attach_function :snmp_sess_read, [ :pointer, :pointer ], :int, blocking: true
36
+ attach_function :snmp_sess_timeout, [ :pointer ], :void
37
+ attach_function :snmp_sess_synch_response, [:pointer, :pointer, :pointer], :int, blocking: true
38
+
39
+
40
+ attach_function :snmp_perror, [ :string ], :void
41
+
42
+ attach_function :netsnmp_get_version, [], :string
43
+ end
44
+ end