gnms 2.1.0 → 2.1.1
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/lib/cmd_parse.rb +9 -8
- data/lib/config_global.rb +19 -8
- data/lib/gui/config_window.rb +55 -21
- data/lib/gui/node_host_property.rb +277 -243
- data/lib/gui/node_host_view.rb +15 -11
- data/lib/main.rb +8 -3
- data/lib/monitor/client/snmp/snmp.rb +11 -5
- data/lib/monitor/server/snmp/snmptrap_server.rb +1 -1
- data/lib/node.rb +1 -1
- data/lib/node_listener.rb +182 -16
- data/lib/version.rb +1 -1
- metadata +3 -2
data/lib/gui/node_host_view.rb
CHANGED
@@ -131,8 +131,9 @@ class NodeHostView < NodeView
|
|
131
131
|
@notification_group.visibility = Goo::CanvasItem::VISIBLE
|
132
132
|
end
|
133
133
|
end
|
134
|
-
|
135
|
-
|
134
|
+
#
|
135
|
+
# define a tooltip
|
136
|
+
#
|
136
137
|
def show_tooltips()
|
137
138
|
if @tooltips==nil
|
138
139
|
@tooltips=Gtk::Window.new(Gtk::Window::POPUP)
|
@@ -162,15 +163,18 @@ gc = Gdk::GC.new(drawable)
|
|
162
163
|
end
|
163
164
|
vbox=Gtk::VBox.new
|
164
165
|
vbox.border_width=5
|
165
|
-
|
166
|
-
ttips_text+="\n<span weight=\"bold\" size=\"small\">
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
166
|
+
ttips_text="<span weight=\"bold\" size=\"small\">IPv4: </span>#{self.node.ipv4}"
|
167
|
+
ttips_text+="\n<span weight=\"bold\" size=\"small\">NetMask4: </span>#{self.node.netmask4}"
|
168
|
+
if !self.node.ipv6.nil?
|
169
|
+
ttips_text+="\n<span weight=\"bold\" size=\"small\">IPv6: </span>#{self.node.ipv6}"
|
170
|
+
ttips_text+="\n<span weight=\"bold\" size=\"small\">NetMask6: </span>#{self.node.netmask6}"
|
171
|
+
end
|
172
|
+
if self.node.dns_name?
|
173
|
+
ttips_text+="\n<span weight=\"bold\" size=\"small\">Dns name: </span>#{self.node.dns_name}"
|
174
|
+
end
|
175
|
+
if self.node.description?() &&( self.node.description != "")
|
176
|
+
ttips_text+="\n<span weight=\"bold\" size=\"small\">Description: </span>#{self.node.description}"
|
177
|
+
end
|
174
178
|
label = Gtk::Label.new.set_markup(ttips_text)
|
175
179
|
label.set_alignment(0,0.5)
|
176
180
|
vbox.add label
|
data/lib/main.rb
CHANGED
@@ -1031,13 +1031,17 @@ def set_map(mp=nil)
|
|
1031
1031
|
#thread to listen to monitored jmx cmd
|
1032
1032
|
add_monitoring_thread("JMX monitoring", tmonitorjmx())
|
1033
1033
|
end
|
1034
|
-
if $config.
|
1034
|
+
if $config.active_find_node_state
|
1035
1035
|
#thread to find new host in local network with broacast ping
|
1036
1036
|
add_monitoring_thread("Local ping", t_find_local_segment_pinging())
|
1037
|
+
#thread to find new host in remote network with nmap ping
|
1038
|
+
add_monitoring_thread("Remote ping", t_find_remote_new_host())
|
1039
|
+
end
|
1040
|
+
if $config.passive_find_node_state
|
1037
1041
|
#thread to find new host in local segment sniffing for arp/lldp/dhcp packets
|
1038
1042
|
add_monitoring_thread("Local sniffing", t_find_local_segment_sniffing())
|
1039
|
-
|
1040
|
-
|
1043
|
+
#thread which is sending SSDP query
|
1044
|
+
add_monitoring_thread("SSDP query", t_find_ssdp_discovery())
|
1041
1045
|
end
|
1042
1046
|
if $config.mac_state
|
1043
1047
|
#thread to find MAC address
|
@@ -1097,6 +1101,7 @@ def set_map(mp=nil)
|
|
1097
1101
|
# call all db method to save all the map in the db
|
1098
1102
|
#
|
1099
1103
|
def save_all_in_db()
|
1104
|
+
$log.info("Saving nodes")
|
1100
1105
|
#save nodes
|
1101
1106
|
set_busy()
|
1102
1107
|
|
@@ -165,20 +165,26 @@ end
|
|
165
165
|
def mac(ip)
|
166
166
|
#first try to solve it by the help of local arp table
|
167
167
|
temp=mac_tablelocal(ip)
|
168
|
-
|
168
|
+
|
169
169
|
if (temp!="")
|
170
170
|
return temp.chomp
|
171
171
|
end
|
172
172
|
if !$config.snmp_mon || $host[ip].status == CRITICAL
|
173
|
-
return
|
173
|
+
return
|
174
174
|
end
|
175
|
-
#puts "in map() 1 for #{ip}"
|
176
175
|
val=get_snmp_OID($host[ip], "ipAdEntIfIndex.#{ip}")
|
177
|
-
|
178
176
|
if !val || val == "Error"
|
179
177
|
return
|
180
178
|
end
|
181
179
|
result=get_snmp_OID($host[ip], "ifPhysAddress.#{val}")
|
182
|
-
#
|
180
|
+
#expecting the MAC address as a string
|
181
|
+
if !result.ascii_only?
|
182
|
+
#if binary, we tried to convert it
|
183
|
+
result = result.unpack("H2H2H2H2H2H2").join(":")
|
184
|
+
end
|
185
|
+
|
186
|
+
if !isValidMac(result)
|
187
|
+
return
|
188
|
+
end
|
183
189
|
return result
|
184
190
|
end
|
@@ -9,7 +9,7 @@ class SnmpTrapServer
|
|
9
9
|
#check if snmp lib support traps
|
10
10
|
def snmp_traps_supported?
|
11
11
|
begin
|
12
|
-
SNMP::UDPServerTransport.new('localhost', 9999)
|
12
|
+
SNMP::UDPServerTransport.new('localhost', 9999, Socket::AF_INET)
|
13
13
|
return true
|
14
14
|
rescue ArgumentError
|
15
15
|
return false
|
data/lib/node.rb
CHANGED
data/lib/node_listener.rb
CHANGED
@@ -107,7 +107,7 @@ end
|
|
107
107
|
def tmonitorjmx()
|
108
108
|
Thread.start {
|
109
109
|
while $config.jmx_mon
|
110
|
-
$log.
|
110
|
+
$log.debug("in tmonitorjmx every #{$config.jmx_mon_delay} second")
|
111
111
|
sleep($config.jmx_mon_delay.to_i)
|
112
112
|
ip_table=$host.keys
|
113
113
|
for ip in ip_table
|
@@ -119,7 +119,7 @@ def tmonitorjmx()
|
|
119
119
|
test_monitored_jmx(ip)
|
120
120
|
end
|
121
121
|
rescue Exception => msg
|
122
|
-
$log.error(msg)
|
122
|
+
$log.error("tmonitorjmx: #{msg}")
|
123
123
|
$event_win.add_event(EventWindow::JMX_EVENT_TYPE, "INFO", $host[ip], msg)
|
124
124
|
end
|
125
125
|
end
|
@@ -312,7 +312,7 @@ end
|
|
312
312
|
#
|
313
313
|
# snmp discovery
|
314
314
|
# read arp, route, interface from a snmp host
|
315
|
-
|
315
|
+
#
|
316
316
|
def tresolvesnmp()
|
317
317
|
Thread.start {
|
318
318
|
while $config.node_resolving
|
@@ -379,7 +379,7 @@ def tresolvesnmp()
|
|
379
379
|
new_node_array.push new_node.new(ip, mac_addr, netmask_addr, status)
|
380
380
|
}
|
381
381
|
#propagate the search if requested
|
382
|
-
if $config.
|
382
|
+
if $config.active_find_node_state
|
383
383
|
status = 4
|
384
384
|
manager.walk("1.3.6.1.2.1.4.22.1.2") { |vb|
|
385
385
|
#remove mib header and extract interface id and ip
|
@@ -403,7 +403,7 @@ def tresolvesnmp()
|
|
403
403
|
#node already exists, check the mac
|
404
404
|
if $host[nnode.ip].mac != Node::NOARP_PROPERTY
|
405
405
|
if $host[nnode.ip].mac != nnode.mac
|
406
|
-
$event_win.add_event(EventWindow::AVAIL_EVENT_TYPE, "WARN", $host[nnode.ip], "Hardware MAC
|
406
|
+
$event_win.add_event(EventWindow::AVAIL_EVENT_TYPE, "WARN", $host[nnode.ip], "Hardware MAC address collision, find #{nnode.mac}")
|
407
407
|
end
|
408
408
|
else
|
409
409
|
#mac is not set for this node at this point, so adding it
|
@@ -505,15 +505,16 @@ def tmacip ()
|
|
505
505
|
$log.info("difficulty to find MAC address for #{ip}")
|
506
506
|
end
|
507
507
|
else
|
508
|
-
if
|
508
|
+
if $config.mac_lock #we verify mac address
|
509
509
|
begin
|
510
510
|
timeout($config.mac_delay.to_i) {
|
511
511
|
Thread.start {
|
512
|
+
#trying to get the mac addr using the arp table or snmp request
|
512
513
|
res=mac(ip)
|
513
514
|
if res != ""
|
514
515
|
if $host[ip] && $host[ip].mac != res && $host[ip].status != CRITICAL
|
515
516
|
$host[ip].set_avail_severity(MINOR)
|
516
|
-
$event_win.add_event(EventWindow::AVAIL_EVENT_TYPE, "WARN", $host[ip], "Hardware MAC
|
517
|
+
$event_win.add_event(EventWindow::AVAIL_EVENT_TYPE, "WARN", $host[ip], "Hardware MAC address changed")
|
517
518
|
else
|
518
519
|
if $host[ip].status == MINOR
|
519
520
|
$host[ip].set_avail_severity(CRITICAL)
|
@@ -550,11 +551,11 @@ end
|
|
550
551
|
|
551
552
|
def t_find_remote_new_host ()
|
552
553
|
Thread.start {
|
553
|
-
while $config.
|
554
|
-
sleep($config.
|
554
|
+
while $config.active_find_node_state
|
555
|
+
sleep($config.active_find_node_delay.to_i)
|
555
556
|
$log.debug("in t_find_remote_new_host")
|
556
557
|
$network.each_value {|node|
|
557
|
-
if !$config.
|
558
|
+
if !$config.active_find_node_state
|
558
559
|
break
|
559
560
|
end
|
560
561
|
if node.ip != ROOTMAPADDR
|
@@ -568,7 +569,7 @@ def t_find_remote_new_host ()
|
|
568
569
|
end
|
569
570
|
end
|
570
571
|
}
|
571
|
-
sleep($config.
|
572
|
+
sleep($config.active_find_node_delay.to_i)
|
572
573
|
end
|
573
574
|
}
|
574
575
|
end
|
@@ -594,8 +595,8 @@ end
|
|
594
595
|
#
|
595
596
|
def t_find_local_segment_pinging()
|
596
597
|
Thread.start {
|
597
|
-
while $config.
|
598
|
-
sleep($config.
|
598
|
+
while $config.active_find_node_state
|
599
|
+
sleep($config.active_find_node_delay.to_i)
|
599
600
|
if !defined?($in_confirm_exit_window) || ($in_confirm_exit_window == false)
|
600
601
|
mask=local_mask()
|
601
602
|
mask = DEFAULT_CLASS_C_NETMASK if !mask
|
@@ -632,14 +633,93 @@ def t_find_local_segment_pinging()
|
|
632
633
|
end
|
633
634
|
end
|
634
635
|
end
|
635
|
-
sleep($config.
|
636
|
+
sleep($config.active_find_node_delay.to_i)
|
637
|
+
end
|
638
|
+
}
|
639
|
+
end
|
640
|
+
|
641
|
+
#
|
642
|
+
# threat which is sending SSDP discovery requests
|
643
|
+
#
|
644
|
+
def t_find_ssdp_discovery()
|
645
|
+
if Process.euid != 0
|
646
|
+
return
|
647
|
+
end
|
648
|
+
Thread.start {
|
649
|
+
$log.debug("in t_find_ssdp_discovery")
|
650
|
+
dest = "239.255.255.250"
|
651
|
+
port = 1900
|
652
|
+
msearch =
|
653
|
+
"M-SEARCH * HTTP/1.1\r\n" +
|
654
|
+
"Host:#{dest}:#{port}\r\n" +
|
655
|
+
"ST:upnp:rootdevice\r\n" +
|
656
|
+
"Man:\"ssdp:discover\"\r\n" +
|
657
|
+
"MX:3\r\n\r\n"
|
658
|
+
|
659
|
+
udp_sock = UDPSocket.new
|
660
|
+
while $config.passive_find_node_state
|
661
|
+
begin
|
662
|
+
udp_sock.bind("0.0.0.0", port)
|
663
|
+
rescue Errno::EADDRINUSE
|
664
|
+
rescue Errno::EINVAL
|
665
|
+
rescue Exception => msg
|
666
|
+
$log.error("in t_find_ssdp_discovery during udp binding: #{msg}")
|
667
|
+
end
|
668
|
+
begin
|
669
|
+
udp_sock.send(msearch, 0, dest, port)
|
670
|
+
res = nil
|
671
|
+
1.upto(5) do
|
672
|
+
res,addr,info = udp_sock.recvfrom(65535, 1.0)
|
673
|
+
break if res and res =~ /^(Server|Location)/mi
|
674
|
+
sleep(10)
|
675
|
+
udp_sock.send msearch, 0, dest, port
|
676
|
+
end
|
677
|
+
rescue Exception => msg
|
678
|
+
$log.error("in t_find_ssdp_discovery: #{msg}")
|
679
|
+
end
|
680
|
+
sleep($config.passive_find_node_delay.to_i)
|
636
681
|
end
|
637
682
|
}
|
638
683
|
end
|
639
684
|
|
640
685
|
#
|
686
|
+
# analyze udp packet to port 1900
|
687
|
+
# trying to extract some upnp data
|
688
|
+
#
|
689
|
+
def ssdp_analyze(pkt)
|
690
|
+
packet_info = [pkt.ip_saddr, pkt.udp_dst]
|
691
|
+
#we assume here dst port is set to default upnp port 1900
|
692
|
+
#if pkt.udp_dst == 1900
|
693
|
+
#puts "%s %s" % packet_info
|
694
|
+
ssdp_body = pkt.udp_header.body
|
695
|
+
#try to find the OS
|
696
|
+
detected_os = "unknown"
|
697
|
+
if ssdp_body.include?("M-SEARCH * HTTP/1.1") and ssdp_body.include?("ssdp:discover") and ssdp_body.include?("upnp:rootdevice")
|
698
|
+
#puts "query"
|
699
|
+
return [pkt.ip_saddr, detected_os]
|
700
|
+
elsif ssdp_body.include?("HTTP/1.1 200 OK") and ssdp_body.include?("upnp:rootdevice")
|
701
|
+
#puts "response"
|
702
|
+
ssdp_body.each_line {|l|
|
703
|
+
l.upcase!
|
704
|
+
if l.include?("SERVER:")
|
705
|
+
if l.include?("WINDOWS")
|
706
|
+
detected_os = "windows"
|
707
|
+
elsif l.include?("LINUX")
|
708
|
+
detected_os = "linux"
|
709
|
+
end
|
710
|
+
return [pkt.ip_saddr, detected_os]
|
711
|
+
end
|
712
|
+
}
|
713
|
+
return [pkt.ip_saddr, detected_os]
|
714
|
+
#end
|
715
|
+
end
|
716
|
+
return nil
|
717
|
+
end
|
718
|
+
|
719
|
+
#
|
720
|
+
# passive scanning
|
641
721
|
# listen for new host in local network,
|
642
|
-
# sniffing for packets arp, lldp/cdp
|
722
|
+
# sniffing for packets arp, lldp/cdp, upnp
|
643
723
|
#
|
644
724
|
def t_find_local_segment_sniffing()
|
645
725
|
#run as root ?
|
@@ -665,7 +745,7 @@ def t_find_local_segment_sniffing()
|
|
665
745
|
loop do
|
666
746
|
cap.stream.each do |p|
|
667
747
|
pkt = PacketFu::Packet.parse p
|
668
|
-
if $config.
|
748
|
+
if $config.passive_find_node_state and !$config.visible()
|
669
749
|
if pkt.is_arp?
|
670
750
|
#check if it's ethernet and arp reply
|
671
751
|
if pkt.arp_hw == 1 and pkt.arp_opcode == 2
|
@@ -702,6 +782,39 @@ def t_find_local_segment_sniffing()
|
|
702
782
|
}
|
703
783
|
end
|
704
784
|
end
|
785
|
+
#check for upnp ssdp packets
|
786
|
+
if pkt.is_udp? and (pkt.udp_dst == 1900)
|
787
|
+
result = ssdp_analyze(pkt)
|
788
|
+
if !result.nil?
|
789
|
+
ip, os = result
|
790
|
+
$log.debug("t_find_local_segment_sniffing: SSDP founds ip=#{ip} os=#{os}")
|
791
|
+
if isValidIPv4(ip) and !exist_host(ip) and !in_exception_list(ip)
|
792
|
+
if $network_map_always == 0
|
793
|
+
choose_network_map(ip)
|
794
|
+
while $network_map_result.nil?
|
795
|
+
sleep(2)
|
796
|
+
end
|
797
|
+
end
|
798
|
+
if !$network_map_result.nil? and !$network_map_result.empty?
|
799
|
+
if isValidIPv4($network_map_result)
|
800
|
+
map = $network_map_result
|
801
|
+
if $network.has_key?(map)
|
802
|
+
addhostentry(ip, 24, map)
|
803
|
+
sleep(2)
|
804
|
+
if $host[ip] and (os != "unknown")
|
805
|
+
$host[ip].os = os
|
806
|
+
end
|
807
|
+
end
|
808
|
+
else
|
809
|
+
add_node_def_exception_list(ip)
|
810
|
+
end
|
811
|
+
end
|
812
|
+
if $network_map_always == 0
|
813
|
+
$network_map_result = nil
|
814
|
+
end
|
815
|
+
end
|
816
|
+
end
|
817
|
+
end
|
705
818
|
begin
|
706
819
|
if pkt.is_lldp?
|
707
820
|
$log.debug("t_find_local_segment_sniffing: LLDP founds ip=#{pkt.lldp_address} mac=#{pkt.lldp_saddr_mac}")
|
@@ -746,6 +859,59 @@ def t_find_local_segment_sniffing()
|
|
746
859
|
end
|
747
860
|
end
|
748
861
|
|
862
|
+
#
|
863
|
+
# active scanning to find new nodes
|
864
|
+
#
|
865
|
+
def t_find_local_segment_scanning()
|
866
|
+
|
867
|
+
end
|
868
|
+
|
869
|
+
#
|
870
|
+
# scan a given ip, proto/port
|
871
|
+
# return 1 when the service is responding
|
872
|
+
# or 0
|
873
|
+
#
|
874
|
+
def scan_port(ip, proto, port)
|
875
|
+
p1 = nil
|
876
|
+
protocol = proto.upcase
|
877
|
+
if protocol == "UDP"
|
878
|
+
p1 = Net::Ping::UDP.new(ip, port)
|
879
|
+
elsif protocol == "TCP"
|
880
|
+
p1 = Net::Ping::TCP.new(ip, port)
|
881
|
+
end
|
882
|
+
if !p1.nil? and p1.ping?
|
883
|
+
return 1
|
884
|
+
end
|
885
|
+
return 0
|
886
|
+
end
|
887
|
+
|
888
|
+
#
|
889
|
+
# scan a given node
|
890
|
+
# trying to reach following services:
|
891
|
+
# ftp, ssh, http(s), dns, smtp, pop3,
|
892
|
+
# imap, nntp, ldap(s), kerberos, rdp
|
893
|
+
#
|
894
|
+
def portscan_node(n)
|
895
|
+
|
896
|
+
tcp_service_to_check = [21, 22, 80, 25, 110, 143, 119, 389, 443, 636, 3389]
|
897
|
+
udp_service_to_check = [53]
|
898
|
+
|
899
|
+
udp_service_to_check.each {|port|
|
900
|
+
p1 = Net::Ping::UDP.new(n.ip, port)
|
901
|
+
if p1.ping?
|
902
|
+
return 1
|
903
|
+
end
|
904
|
+
}
|
905
|
+
|
906
|
+
tcp_service_to_check.each {|port|
|
907
|
+
p1 = Net::Ping::TCP.new(n.ip, port)
|
908
|
+
if p1.ping?
|
909
|
+
return 1
|
910
|
+
end
|
911
|
+
}
|
912
|
+
return 0
|
913
|
+
end
|
914
|
+
|
749
915
|
#
|
750
916
|
# To know if we already know this ip
|
751
917
|
#
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gnms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: facter
|
@@ -378,3 +378,4 @@ signing_key:
|
|
378
378
|
specification_version: 3
|
379
379
|
summary: Gnome Network Management System
|
380
380
|
test_files: []
|
381
|
+
has_rdoc: false
|