gnms 2.1.0.rc1 → 2.1.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of gnms might be problematic. Click here for more details.
- data/gnms.gemspec +1 -1
- data/lib/cmd_parse.rb +31 -71
- data/lib/config_global.rb +7 -1
- data/lib/external/ping.rb +3 -0
- data/lib/external/ping/icmp.rb +180 -0
- data/lib/external/ping/ping.rb +89 -0
- data/lib/external/ping/tcp.rb +83 -0
- data/lib/external/ping/udp.rb +125 -0
- data/lib/gnms.rb +1 -0
- data/lib/gui/about_window.rb +1 -1
- data/lib/gui/base_window.rb +4 -2
- data/lib/gui/canvas_map.rb +37 -10
- data/lib/gui/config_window.rb +30 -32
- data/lib/gui/debug_window.rb +1 -1
- data/lib/gui/event_window.rb +7 -3
- data/lib/gui/help_window.rb +1 -1
- data/lib/gui/mib_browser.rb +1 -1
- data/lib/gui/node_host_property.rb +2 -2
- data/lib/gui/node_view.rb +6 -2
- data/lib/main.rb +4 -3
- data/lib/node_db.rb +4 -2
- data/lib/node_listener.rb +56 -54
- data/plugins/PgsqlPercentConnectionMonitor.rb +1 -1
- metadata +180 -171
- data/pixmap/logo.jpg +0 -0
- data/pixmap/type/home.png +0 -0
- data/plugins/Defaultme.rb +0 -7
data/gnms.gemspec
CHANGED
@@ -34,7 +34,7 @@ end
|
|
34
34
|
Gem::Specification.new do |s|
|
35
35
|
s.name = "gnms"
|
36
36
|
#s.version = GNMSVERSION
|
37
|
-
s.version = "#{GNMSVERSION}.
|
37
|
+
s.version = "#{GNMSVERSION}.rc2"
|
38
38
|
s.platform = Gem::Platform::RUBY
|
39
39
|
s.required_ruby_version = '>= 1.8.6'
|
40
40
|
s.authors = ["David Maciejak"]
|
data/lib/cmd_parse.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "#{GNMSLIB}"+'/ipcalc'
|
2
|
+
require "#{GNMSLIB}"+'/external/ping'
|
2
3
|
require 'net/http'
|
3
4
|
|
4
5
|
#
|
@@ -502,7 +503,8 @@ end
|
|
502
503
|
#
|
503
504
|
# verify if monitored ports are always open
|
504
505
|
# return -1 if ok
|
505
|
-
# or return the severity as constant
|
506
|
+
# or return the worst severity as constant
|
507
|
+
#
|
506
508
|
def test_monitored_ports(ip)
|
507
509
|
$log.debug "cmd_parse test_monitored_ports #{ip}"
|
508
510
|
#we assume here $host[ip].port is not nil
|
@@ -510,84 +512,38 @@ def test_monitored_ports(ip)
|
|
510
512
|
return -1
|
511
513
|
end
|
512
514
|
|
513
|
-
#
|
514
|
-
|
515
|
+
#setting bad sev to critical by default
|
516
|
+
bad_sev = $status.size
|
517
|
+
sev_spe = $status.size
|
518
|
+
failed = 0
|
519
|
+
failed_str = ""
|
520
|
+
|
515
521
|
$host[ip].service.each_value{|serv|
|
516
522
|
if serv.monitor.to_i() == 1
|
517
|
-
|
523
|
+
p1 = nil
|
518
524
|
if serv.protocol == "tcp"
|
519
|
-
|
520
|
-
end
|
521
|
-
ip_port+="#{proto}:#{serv.port},"
|
522
|
-
end
|
523
|
-
}
|
524
|
-
ip_port.chop!()
|
525
|
-
if ip_port == ""
|
526
|
-
#we dont monitor ports for this node
|
527
|
-
return -1
|
528
|
-
end
|
529
|
-
ports = ip_port.split(/,/).dup
|
530
|
-
lp=""
|
531
|
-
nmap_version = $config.nmap_vers.to_f()
|
532
|
-
|
533
|
-
if nmap_version >= 6.0
|
534
|
-
lp=`#{$config.nmap_path} -sT -sU #{ip} --host_timeout 60 -p #{ip_port} 2>/dev/null | grep "^[0-9]"`
|
535
|
-
else
|
536
|
-
lp=`#{$config.nmap_path} -sT -sU #{ip} --host_timeout 60000 -p #{ip_port} 2>/dev/null | grep "^[0-9]"`
|
537
|
-
end
|
538
|
-
|
539
|
-
$log.error("Issue running scan command: #{$config.nmap_path} -sT -sU #{ip} -p #{ip_port}") if lp == ""
|
540
|
-
llp=lp.split(/\n/)
|
541
|
-
for pt in llp
|
542
|
-
ptlign=pt.split(/\s+/)
|
543
|
-
portprotocol=ptlign[0]
|
544
|
-
portstate=ptlign[1]
|
545
|
-
if portstate.match("^open")
|
546
|
-
ptt = portprotocol.split(/\//)
|
547
|
-
if ptt[1] == "tcp"
|
548
|
-
pt="T:#{ptt[0]}"
|
525
|
+
p1 = Net::Ping::TCP.new(ip, serv.port)
|
549
526
|
else
|
550
|
-
|
551
|
-
end
|
552
|
-
i=0
|
553
|
-
for ptlo in ports
|
554
|
-
if ptlo == pt
|
555
|
-
ports.delete ptlo
|
556
|
-
break
|
557
|
-
end
|
558
|
-
i+=1
|
527
|
+
p1 = Net::Ping::UDP.new(ip, serv.port)
|
559
528
|
end
|
529
|
+
|
530
|
+
if !p1.ping?
|
531
|
+
sev_spe = $host[ip].get_service_sev(serv.protocol, serv.port)
|
532
|
+
bad_sev = sev_spe if sev_spe < bad_sev
|
533
|
+
failed_str += "#{serv.protocol}/#{serv.port} "
|
534
|
+
failed += 1
|
535
|
+
end
|
560
536
|
end
|
561
|
-
|
562
|
-
|
563
|
-
if ports.size != 0 #we have port which dont respond
|
564
|
-
|
565
|
-
#identify worst sev from down port(s)
|
566
|
-
bad_sev = $status.size
|
567
|
-
str_port = ports.join(" ")
|
568
|
-
ports.each {|str|
|
569
|
-
sev_spe = $status.size
|
570
|
-
if str.gsub!(/T:/,"")
|
571
|
-
sev_spe = $host[ip].get_service_sev("tcp", str)
|
572
|
-
else
|
573
|
-
sev_spe = $host[ip].get_service_sev("udp", str)
|
574
|
-
end
|
575
|
-
bad_sev = sev_spe if sev_spe < bad_sev
|
576
|
-
}
|
537
|
+
}
|
538
|
+
if failed > 0
|
577
539
|
if bad_sev == $status.size
|
578
540
|
$log.error("Service monitoring severity can't be found, setting critical")
|
579
541
|
bad_sev = 0
|
580
542
|
end
|
581
|
-
|
582
|
-
#nmap protocol/port syntax to human easy readable!
|
583
|
-
str_port.gsub!(/T:/,"tcp/")
|
584
|
-
str_port.gsub!(/U:/,"udp/")
|
585
|
-
$event_win.add_event(EventWindow::PORT_EVENT_TYPE, get_level_from_status($status[bad_sev]), $host[ip], "#{str_port} not responding")
|
586
|
-
|
543
|
+
$event_win.add_event(EventWindow::PORT_EVENT_TYPE, get_level_from_status($status[bad_sev]), $host[ip], "#{failed_str} not responding")
|
587
544
|
return $status_value[bad_sev]
|
588
545
|
end
|
589
|
-
|
590
|
-
return -1
|
546
|
+
return -1
|
591
547
|
end
|
592
548
|
|
593
549
|
#
|
@@ -697,11 +653,15 @@ def osfingerprint(ip)
|
|
697
653
|
end
|
698
654
|
|
699
655
|
#
|
700
|
-
# Return the service name associate to the port
|
656
|
+
# Return the service name associate to the port given in argument
|
701
657
|
# first is protocol, second is port
|
702
|
-
def service_name(protocol,port)
|
703
|
-
|
704
|
-
|
658
|
+
def service_name(protocol, port)
|
659
|
+
serv = ""
|
660
|
+
begin
|
661
|
+
serv = Socket.getservbyport(port.to_i, protocol)
|
662
|
+
rescue
|
663
|
+
end
|
664
|
+
return serv
|
705
665
|
end
|
706
666
|
|
707
667
|
#
|
data/lib/config_global.rb
CHANGED
@@ -358,7 +358,11 @@ def init_config_var()
|
|
358
358
|
end
|
359
359
|
|
360
360
|
def show()
|
361
|
-
|
361
|
+
@window.show()
|
362
|
+
end
|
363
|
+
|
364
|
+
def visible()
|
365
|
+
@window.visible()
|
362
366
|
end
|
363
367
|
|
364
368
|
def init_hash_conf_by_level(h)
|
@@ -375,12 +379,14 @@ def initialize ()
|
|
375
379
|
@image_path = "#{PIXMAP_PATH}/bg"
|
376
380
|
@bg_type = "color"
|
377
381
|
#set this for the first time we launch gnms
|
382
|
+
@port_mon = true
|
378
383
|
@port_mon_delay = "60"
|
379
384
|
@snmp_mon_delay = "60"
|
380
385
|
@wmi_mon_delay = "60"
|
381
386
|
@custom_mon_delay = "60"
|
382
387
|
@jmx_mon_delay = "60"
|
383
388
|
@broadcast_ping_delay = "300"
|
389
|
+
@node_resolving = true
|
384
390
|
@node_resolving_delay = "120"
|
385
391
|
@mac_delay = "60"
|
386
392
|
@syslog_port="514"
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'ping')
|
2
|
+
|
3
|
+
if File::ALT_SEPARATOR
|
4
|
+
require 'win32/security'
|
5
|
+
require 'windows/system_info'
|
6
|
+
include Windows::SystemInfo
|
7
|
+
end
|
8
|
+
|
9
|
+
# The Net module serves as a namespace only.
|
10
|
+
module Net
|
11
|
+
|
12
|
+
# The Net::Ping::ICMP class encapsulates an icmp ping.
|
13
|
+
class Ping::ICMP < Ping
|
14
|
+
ICMP_ECHOREPLY = 0 # Echo reply
|
15
|
+
ICMP_ECHO = 8 # Echo request
|
16
|
+
ICMP_SUBCODE = 0
|
17
|
+
|
18
|
+
# You cannot set or change the port value. A value of 0 is always
|
19
|
+
# used internally for ICMP pings.
|
20
|
+
#
|
21
|
+
undef_method :port=
|
22
|
+
|
23
|
+
# Returns the data size, i.e. number of bytes sent on the ping. The
|
24
|
+
# default size is 56.
|
25
|
+
#
|
26
|
+
attr_reader :data_size
|
27
|
+
|
28
|
+
# Creates and returns a new Ping::ICMP object. This is similar to its
|
29
|
+
# superclass constructor, but must be created with root privileges (on
|
30
|
+
# UNIX systems), and the port value is ignored.
|
31
|
+
#
|
32
|
+
def initialize(host=nil, port=nil, timeout=5)
|
33
|
+
raise 'requires root privileges' if Process.euid > 0
|
34
|
+
|
35
|
+
if File::ALT_SEPARATOR && windows_version >= 6
|
36
|
+
unless Win32::Security.elevated_security?
|
37
|
+
raise 'requires elevated security'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
@seq = 0
|
42
|
+
@bind_port = 0
|
43
|
+
@bind_host = nil
|
44
|
+
@data_size = 56
|
45
|
+
@data = ''
|
46
|
+
|
47
|
+
0.upto(@data_size){ |n| @data << (n % 256).chr }
|
48
|
+
|
49
|
+
@pid = Process.pid & 0xffff
|
50
|
+
|
51
|
+
super(host, port, timeout)
|
52
|
+
@port = nil # This value is not used in ICMP pings.
|
53
|
+
end
|
54
|
+
|
55
|
+
# Sets the number of bytes sent in the ping method.
|
56
|
+
#
|
57
|
+
def data_size=(size)
|
58
|
+
@data_size = size
|
59
|
+
@data = ''
|
60
|
+
0.upto(size){ |n| @data << (n % 256).chr }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Associates the local end of the socket connection with the given
|
64
|
+
# +host+ and +port+. The default port is 0.
|
65
|
+
#
|
66
|
+
def bind(host, port = 0)
|
67
|
+
@bind_host = host
|
68
|
+
@bind_port = port
|
69
|
+
end
|
70
|
+
|
71
|
+
# Pings the +host+ specified in this method or in the constructor. If a
|
72
|
+
# host was not specified either here or in the constructor, an
|
73
|
+
# ArgumentError is raised.
|
74
|
+
#
|
75
|
+
def ping(host = @host)
|
76
|
+
super(host)
|
77
|
+
bool = false
|
78
|
+
|
79
|
+
socket = Socket.new(
|
80
|
+
Socket::PF_INET,
|
81
|
+
Socket::SOCK_RAW,
|
82
|
+
Socket::IPPROTO_ICMP
|
83
|
+
)
|
84
|
+
|
85
|
+
if @bind_host
|
86
|
+
saddr = Socket.pack_sockaddr_in(@bind_port, @bind_host)
|
87
|
+
socket.bind(saddr)
|
88
|
+
end
|
89
|
+
|
90
|
+
@seq = (@seq + 1) % 65536
|
91
|
+
pstring = 'C2 n3 A' << @data_size.to_s
|
92
|
+
timeout = @timeout
|
93
|
+
|
94
|
+
checksum = 0
|
95
|
+
msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @pid, @seq, @data].pack(pstring)
|
96
|
+
|
97
|
+
checksum = checksum(msg)
|
98
|
+
msg = [ICMP_ECHO, ICMP_SUBCODE, checksum, @pid, @seq, @data].pack(pstring)
|
99
|
+
|
100
|
+
begin
|
101
|
+
saddr = Socket.pack_sockaddr_in(0, host)
|
102
|
+
rescue Exception
|
103
|
+
socket.close unless socket.closed?
|
104
|
+
return bool
|
105
|
+
end
|
106
|
+
|
107
|
+
start_time = Time.now
|
108
|
+
|
109
|
+
socket.send(msg, 0, saddr) # Send the message
|
110
|
+
|
111
|
+
begin
|
112
|
+
Timeout.timeout(@timeout){
|
113
|
+
while true
|
114
|
+
io_array = select([socket], nil, nil, timeout)
|
115
|
+
|
116
|
+
if io_array.nil? || io_array[0].empty?
|
117
|
+
return false
|
118
|
+
end
|
119
|
+
|
120
|
+
pid = nil
|
121
|
+
seq = nil
|
122
|
+
|
123
|
+
data = socket.recvfrom(1500).first
|
124
|
+
type = data[20, 2].unpack('C2').first
|
125
|
+
|
126
|
+
case type
|
127
|
+
when ICMP_ECHOREPLY
|
128
|
+
if data.length >= 28
|
129
|
+
pid, seq = data[24, 4].unpack('n3')
|
130
|
+
end
|
131
|
+
else
|
132
|
+
if data.length > 56
|
133
|
+
pid, seq = data[52, 4].unpack('n3')
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
if pid == @pid && seq == @seq && type == ICMP_ECHOREPLY
|
138
|
+
bool = true
|
139
|
+
break
|
140
|
+
end
|
141
|
+
end
|
142
|
+
}
|
143
|
+
rescue Exception => err
|
144
|
+
@exception = err
|
145
|
+
ensure
|
146
|
+
socket.close if socket
|
147
|
+
end
|
148
|
+
|
149
|
+
# There is no duration if the ping failed
|
150
|
+
@duration = Time.now - start_time if bool
|
151
|
+
|
152
|
+
return bool
|
153
|
+
end
|
154
|
+
|
155
|
+
alias ping? ping
|
156
|
+
alias pingecho ping
|
157
|
+
|
158
|
+
private
|
159
|
+
|
160
|
+
# Perform a checksum on the message. This is the sum of all the short
|
161
|
+
# words and it folds the high order bits into the low order bits.
|
162
|
+
#
|
163
|
+
def checksum(msg)
|
164
|
+
length = msg.length
|
165
|
+
num_short = length / 2
|
166
|
+
check = 0
|
167
|
+
|
168
|
+
msg.unpack("n#{num_short}").each do |short|
|
169
|
+
check += short
|
170
|
+
end
|
171
|
+
|
172
|
+
if length % 2 > 0
|
173
|
+
check += msg[length-1, 1].unpack('C').first << 8
|
174
|
+
end
|
175
|
+
|
176
|
+
check = (check >> 16) + (check & 0xffff)
|
177
|
+
return (~((check >> 16) + check) & 0xffff)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
# The Net module serves as a namespace only.
|
5
|
+
#
|
6
|
+
module Net
|
7
|
+
|
8
|
+
# The Ping class serves as an abstract base class for all other Ping class
|
9
|
+
# types. You should not instantiate this class directly.
|
10
|
+
#
|
11
|
+
class Ping
|
12
|
+
# The version of the net-ping library.
|
13
|
+
VERSION = '1.5.2'
|
14
|
+
|
15
|
+
# The host to ping. In the case of Ping::HTTP, this is the URI.
|
16
|
+
attr_accessor :host
|
17
|
+
|
18
|
+
# The port to ping. This is set to the echo port (7) by default. The
|
19
|
+
# Ping::HTTP class defaults to port 80.
|
20
|
+
#
|
21
|
+
attr_accessor :port
|
22
|
+
|
23
|
+
# The maximum time a ping attempt is made.
|
24
|
+
attr_accessor :timeout
|
25
|
+
|
26
|
+
# If a ping fails, this value is set to the error that occurred which
|
27
|
+
# caused it to fail.
|
28
|
+
#
|
29
|
+
attr_reader :exception
|
30
|
+
|
31
|
+
# This value is set if a ping succeeds, but some other condition arose
|
32
|
+
# during the ping attempt which merits warning, e.g a redirect in the
|
33
|
+
# case of Ping::HTTP#ping.
|
34
|
+
#
|
35
|
+
attr_reader :warning
|
36
|
+
|
37
|
+
# The number of seconds (returned as a Float) that it took to ping
|
38
|
+
# the host. This is not a precise value, but rather a good estimate
|
39
|
+
# since there is a small amount of internal calculation that is added
|
40
|
+
# to the overall time.
|
41
|
+
#
|
42
|
+
attr_reader :duration
|
43
|
+
|
44
|
+
# The default constructor for the Net::Ping class. Accepts an optional
|
45
|
+
# +host+, +port+ and +timeout+. The port defaults to your echo port, or
|
46
|
+
# 7 if that happens to be undefined. The default timeout is 5 seconds.
|
47
|
+
#
|
48
|
+
# The host, although optional in the constructor, must be specified at
|
49
|
+
# some point before the Net::Ping#ping method is called, or else an
|
50
|
+
# ArgumentError will be raised.
|
51
|
+
#
|
52
|
+
# Yields +self+ in block context.
|
53
|
+
#
|
54
|
+
# This class is not meant to be instantiated directly. It is strictly
|
55
|
+
# meant as an interface for subclasses.
|
56
|
+
#
|
57
|
+
def initialize(host=nil, port=nil, timeout=5)
|
58
|
+
@host = host
|
59
|
+
@port = port || Socket.getservbyname('echo') || 7
|
60
|
+
@timeout = timeout
|
61
|
+
@exception = nil
|
62
|
+
@warning = nil
|
63
|
+
@duration = nil
|
64
|
+
|
65
|
+
yield self if block_given?
|
66
|
+
end
|
67
|
+
|
68
|
+
# The default interface for the Net::Ping#ping method. Each subclass
|
69
|
+
# should call super() before continuing with their own implementation in
|
70
|
+
# order to ensure that the @exception and @warning instance variables
|
71
|
+
# are reset.
|
72
|
+
#
|
73
|
+
# If +host+ is nil here, then it will use the host specified in the
|
74
|
+
# constructor. If the +host+ is nil and there was no host specified
|
75
|
+
# in the constructor then an ArgumentError is raised.
|
76
|
+
#--
|
77
|
+
# The @duration should be set in the subclass' ping method.
|
78
|
+
#
|
79
|
+
def ping(host = @host)
|
80
|
+
raise ArgumentError, 'no host specified' unless host
|
81
|
+
@exception = nil
|
82
|
+
@warning = nil
|
83
|
+
@duration = nil
|
84
|
+
end
|
85
|
+
|
86
|
+
alias ping? ping
|
87
|
+
alias pingecho ping
|
88
|
+
end
|
89
|
+
end
|