netsnmp 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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