netcrawl 0.0.2 → 0.0.3
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.
- checksums.yaml +7 -0
- data/lib/netcrawl.rb +8 -9
- data/lib/netcrawl/cli.rb +5 -3
- data/lib/netcrawl/config.rb +1 -0
- data/lib/netcrawl/method/cdp.rb +22 -22
- data/lib/netcrawl/method/lldp.rb +28 -23
- data/lib/netcrawl/method/xdp.rb +41 -0
- data/lib/netcrawl/output.rb +37 -23
- data/lib/netcrawl/output/dot.rb +28 -8
- data/lib/netcrawl/peer.rb +31 -0
- data/lib/netcrawl/snmp.rb +66 -11
- data/netcrawl.gemspec +1 -1
- metadata +7 -19
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e88a7108f8469c3a858d557c74ffea3a00f4ed7e
|
4
|
+
data.tar.gz: e80b670c19a52eda6e64b59408ec18aee2528653
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9a0ad9ec096098a890da9214f1fc97a10d3de0d279c4a39e70c41992583de1e5310cf1f604bdc1181267754f9226fc1bd040ec3aa174714d50c98b0ce3917266
|
7
|
+
data.tar.gz: a5519ab481db54c1c4cd7b6259b59e36e4b59261b3f72fa22c04575a2b69e53f0e1a8633fdbacaf041aeae5ab79baf14fedf82aed9257237030050044f70b048
|
data/lib/netcrawl.rb
CHANGED
@@ -16,9 +16,9 @@ class NetCrawl
|
|
16
16
|
def get host
|
17
17
|
peers = []
|
18
18
|
@methods.each do |method|
|
19
|
-
peers += method.send(:
|
19
|
+
peers += method.send(:peers, host)
|
20
20
|
end
|
21
|
-
peers.uniq
|
21
|
+
peers.uniq { |peer| peer.ip }
|
22
22
|
end
|
23
23
|
|
24
24
|
# Given string of IP address, recurses through peers seen and populates @hosts hash
|
@@ -28,9 +28,9 @@ class NetCrawl
|
|
28
28
|
peers = get host
|
29
29
|
@hosts[host] = peers
|
30
30
|
peers.each do |peer|
|
31
|
-
next if @hosts.has_key? peer
|
32
|
-
next unless @poll.include? peer
|
33
|
-
crawl peer
|
31
|
+
next if @hosts.has_key? peer.ip
|
32
|
+
next unless @poll.include? peer.ip
|
33
|
+
crawl peer.ip
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -46,7 +46,7 @@ class NetCrawl
|
|
46
46
|
file = 'netcrawl/method/' + method.downcase
|
47
47
|
require_relative file
|
48
48
|
@methods.push NetCrawl.const_get(method)
|
49
|
-
rescue NameError, LoadError
|
49
|
+
rescue NameError, LoadError
|
50
50
|
raise MethodNotFound, "unable to find method '#{method}'"
|
51
51
|
end
|
52
52
|
end
|
@@ -56,8 +56,7 @@ class NetCrawl
|
|
56
56
|
end
|
57
57
|
require_relative 'netcrawl/pollmap'
|
58
58
|
require_relative 'netcrawl/namemap'
|
59
|
-
require_relative 'netcrawl/
|
60
|
-
require_relative 'netcrawl/method/
|
61
|
-
require_relative 'netcrawl/method/lldp'
|
59
|
+
require_relative 'netcrawl/peer'
|
60
|
+
require_relative 'netcrawl/method/xdp'
|
62
61
|
require_relative 'netcrawl/dns'
|
63
62
|
require_relative 'netcrawl/output'
|
data/lib/netcrawl/cli.rb
CHANGED
@@ -8,8 +8,8 @@ class NetCrawl
|
|
8
8
|
|
9
9
|
def run
|
10
10
|
output = NetCrawl.new.crawl @host
|
11
|
-
output.clean if @opts[:purge]
|
12
|
-
output.resolve if @opts[:resolve]
|
11
|
+
output.clean! if @opts[:purge]
|
12
|
+
output.resolve! if @opts[:resolve]
|
13
13
|
if @opts[:graphviz]
|
14
14
|
output.to_dot
|
15
15
|
elsif @opts[:list]
|
@@ -36,12 +36,13 @@ class NetCrawl
|
|
36
36
|
@host = DNS.getip args.shift
|
37
37
|
CFG.snmp.community = @opts[:community] if @opts[:community]
|
38
38
|
CFG.debug = true if @opts[:debug]
|
39
|
+
CFG.ipname = true if @opts[:ipname]
|
39
40
|
raise MissingHost, 'no hostname given as argument' unless @host
|
40
41
|
end
|
41
42
|
|
42
43
|
|
43
44
|
def opt_parse
|
44
|
-
|
45
|
+
Slop.parse(:help=>true) do
|
45
46
|
banner 'Usage: netcrawl [options] hostname'
|
46
47
|
on 'g', 'graphviz', 'dot output use \'dot -Tpng -o map.png map.dot\''
|
47
48
|
on 'l', 'list', 'list nodes'
|
@@ -52,6 +53,7 @@ class NetCrawl
|
|
52
53
|
on 'p', 'purge', 'remove peers not in configured CIDR'
|
53
54
|
on 'c=', 'community', 'SNMP community to use'
|
54
55
|
on 'd', 'debug', 'turn debugging on'
|
56
|
+
on 'i', 'ipname', 'use rev(ip) name instead of discovered name'
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
data/lib/netcrawl/config.rb
CHANGED
@@ -13,6 +13,7 @@ class NetCrawl
|
|
13
13
|
Config.default.snmp.retries = 2
|
14
14
|
Config.default.snmp.bulkrows = 35 # 1500B packet should fit about 50 :cdpCacheAddress rows
|
15
15
|
Config.default.dot.bothlinks = false # keep both a-b and b-a links
|
16
|
+
Config.default.dot.linklabels = true # label link with interface names
|
16
17
|
Config.default.dot.color = [ # regexp of host => color
|
17
18
|
[ 'cpe', 'gold' ],
|
18
19
|
[ '-sw', 'blue' ],
|
data/lib/netcrawl/method/cdp.rb
CHANGED
@@ -1,32 +1,32 @@
|
|
1
|
-
require_relative '../snmp'
|
2
1
|
class NetCrawl
|
3
|
-
class CDP
|
4
|
-
|
2
|
+
class CDP < XDP
|
3
|
+
MIB = '1.3.6.1.4.1.9.9.23' # ciscoCdpMIB
|
5
4
|
OID = {
|
6
5
|
# http://tools.cisco.com/Support/SNMP/do/BrowseOID.do?local=en&translate=Translate&objectInput=1.3.6.1.4.1.9.9.23.1.2.1.1
|
7
|
-
:
|
8
|
-
:
|
6
|
+
:cdpInterfaceName => '1.3.6.1.4.1.9.9.23.1.1.1.1.6',
|
7
|
+
:cdpCacheAddress => '1.3.6.1.4.1.9.9.23.1.2.1.1.4',
|
8
|
+
:cdpCacheDeviceId => '1.3.6.1.4.1.9.9.23.1.2.1.1.6',
|
9
|
+
:cdpCacheDevicePort => '1.3.6.1.4.1.9.9.23.1.2.1.1.7',
|
9
10
|
}
|
10
|
-
|
11
|
-
# @param [String] host host to query
|
12
|
-
# @return [Hash] neighbor information
|
13
|
-
def self.get host
|
14
|
-
cdp = new(host)
|
15
|
-
cdp.peers
|
16
|
-
end
|
17
|
-
|
18
|
-
def peers
|
19
|
-
addrs = @snmp.walk2hash(OID[:cdpCacheAddress]) { |vb| vb.as_ip }
|
20
|
-
names = @snmp.walk2hash(OID[:cdpCacheDeviceId]) { |vb| DNS.getip namemap(vb.value) }
|
21
|
-
names.keys.map { |id| names[id] or addrs[id] }.compact
|
22
|
-
rescue SNMP::NoResponse
|
23
|
-
[]
|
24
|
-
end
|
11
|
+
PEERS_BY = OID[:cdpCacheDeviceId]
|
25
12
|
|
26
13
|
private
|
27
14
|
|
28
|
-
def
|
29
|
-
|
15
|
+
def make_peers
|
16
|
+
peers = []
|
17
|
+
@mib.by_oid(PEERS_BY).each do |_, vb|
|
18
|
+
peer = Peer.new
|
19
|
+
peer_id = vb.oid_id(PEERS_BY)
|
20
|
+
peer.oid = get_oid_hash peer_id
|
21
|
+
peer.raw_ip = @mib[OID[:cdpCacheAddress], peer_id].as_ip
|
22
|
+
peer.raw_name = @mib[OID[:cdpCacheDeviceId], peer_id].value
|
23
|
+
peer.ip = get_ip peer.raw_ip, peer.raw_name
|
24
|
+
peer.dst = @mib[OID[:cdpCacheDevicePort], peer_id].value
|
25
|
+
peer.src = @mib[OID[:cdpInterfaceName], peer_id.first].value
|
26
|
+
peer.raw_ip = @mib[OID[:cdpCacheAddress], peer_id].value
|
27
|
+
peers << peer
|
28
|
+
end
|
29
|
+
peers
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
data/lib/netcrawl/method/lldp.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require_relative '../snmp'
|
2
1
|
class NetCrawl
|
3
|
-
class LLDP
|
4
|
-
|
2
|
+
class LLDP < XDP
|
3
|
+
MIB = '1.0.8802.1.1.2' # lldpMIB
|
5
4
|
OID = {
|
6
5
|
# http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf
|
7
6
|
# finding IP address for LLDP neighbour as of JunOS 13.3R1 and IOS 15.0(2)SG8 is not practical
|
@@ -13,34 +12,40 @@ class NetCrawl
|
|
13
12
|
# in IOS it was usable address
|
14
13
|
# .1.0.8802.1.1.2.1.4.2.1.3.0.257.1.1.4.62.243.146.245
|
15
14
|
# (1.4 is IPv4)
|
15
|
+
# as well LocPortId/RemPortId is hard, it is 'local' (snmpifindex really) in JunOS, but ifName in IOS
|
16
|
+
:lldpLocPortId => '1.0.8802.1.1.2.1.3.7.1.3',
|
16
17
|
:lldpRemChassisIdSubtype => '1.0.8802.1.1.2.1.4.1.1.4', # CSCO and JNPR use 4 (MAC address) rendering ChassisID useless
|
17
18
|
:lldpRemChassisId => '1.0.8802.1.1.2.1.4.1.1.5',
|
19
|
+
:lldpRemPortIdSubtype => '1.0.8802.1.1.2.1.4.1.1.6',
|
20
|
+
:lldpRemPortId => '1.0.8802.1.1.2.1.4.1.1.7',
|
18
21
|
:lldpRemSysName => '1.0.8802.1.1.2.1.4.1.1.9',
|
19
22
|
:lldpRemManAddrIfSubtype => '1.0.8802.1.1.2.1.4.2.1.3',
|
20
23
|
}
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
lldp = new(host)
|
26
|
-
lldp.peers
|
27
|
-
end
|
28
|
-
|
29
|
-
def peers
|
30
|
-
addrs = @snmp.walk2hash(OID[:lldpRemManAddrIfSubtype]) do |vb|
|
31
|
-
key = vb.oid[OID[:lldpRemManAddrIfSubtype].split('.').size .. -7]
|
32
|
-
[vb.oid.last(4).join('.'), key]
|
33
|
-
end # FIXME: I am IPv4 specific and generally dodgy
|
34
|
-
names = @snmp.walk2hash(OID[:lldpRemSysName]) { |vb| DNS.getip namemap(vb.value) }
|
35
|
-
names.keys.map { |id| names[id] or addrs[id] }.compact
|
36
|
-
rescue SNMP::NoResponse
|
37
|
-
[]
|
38
|
-
end
|
24
|
+
PEERS_BY = OID[:lldpRemChassisId]
|
25
|
+
PortSubType = {
|
26
|
+
:mac_address => 3,
|
27
|
+
}
|
39
28
|
|
40
29
|
private
|
41
30
|
|
42
|
-
def
|
43
|
-
|
31
|
+
def make_peers
|
32
|
+
peers = []
|
33
|
+
@mib.by_oid(PEERS_BY).each do |_, vb|
|
34
|
+
peer = Peer.new
|
35
|
+
peer_id = vb.oid_id(PEERS_BY)
|
36
|
+
peer.oid = get_oid_hash peer_id
|
37
|
+
ip = @mib.by_partial OID[:lldpRemManAddrIfSubtype], peer_id
|
38
|
+
peer.raw_ip = ip.oid[-4..-1].join('.') if ip # FIXME: IPv4 specific
|
39
|
+
peer.raw_name = @mib[OID[:lldpRemSysName], peer_id].value
|
40
|
+
peer.ip = get_ip peer.raw_ip, peer.raw_name
|
41
|
+
peer.dst = @mib[OID[:lldpRemPortId], peer_id].value
|
42
|
+
if @mib[OID[:lldpRemPortIdSubtype], peer_id].value.to_i == PortSubType[:mac_address]
|
43
|
+
peer.dst = peer.dst.each_char.map{|e|"%02x" % e.ord}.join.scan(/..../).join('.')
|
44
|
+
end
|
45
|
+
peer.src = @mib[OID[:lldpLocPortId], peer_id[1]].value
|
46
|
+
peers << peer
|
47
|
+
end
|
48
|
+
peers
|
44
49
|
end
|
45
50
|
|
46
51
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative '../snmp'
|
2
|
+
class NetCrawl
|
3
|
+
class XDP
|
4
|
+
attr_reader :mib
|
5
|
+
include NameMap
|
6
|
+
|
7
|
+
# @param [String] host host to query
|
8
|
+
# @return [Array(NetCrawl::Peer)] neighbor information
|
9
|
+
def self.peers host
|
10
|
+
new(host).poll
|
11
|
+
end
|
12
|
+
|
13
|
+
def poll
|
14
|
+
@mib = @snmp.hashwalk self.class::MIB
|
15
|
+
make_peers
|
16
|
+
rescue SNMP::NoResponse
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def initialize host
|
23
|
+
@snmp = SNMP.new host
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_ip ip, name
|
27
|
+
name = DNS.getip namemap(name)
|
28
|
+
name or ip
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_oid_hash peer_id
|
32
|
+
oid_hash = {}
|
33
|
+
self.class::OID.each do |name, oid|
|
34
|
+
oid_hash[name] = @mib[oid, peer_id]
|
35
|
+
end
|
36
|
+
oid_hash
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
require_relative 'cdp'
|
41
|
+
require_relative 'lldp'
|
data/lib/netcrawl/output.rb
CHANGED
@@ -1,64 +1,66 @@
|
|
1
1
|
class NetCrawl
|
2
2
|
class Output
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :peers, :resolve
|
4
4
|
|
5
5
|
# @return [String] pretty print of hash
|
6
6
|
def to_hash
|
7
7
|
require 'pp'
|
8
8
|
out = ''
|
9
|
-
PP.pp
|
9
|
+
PP.pp to_h, out
|
10
10
|
out
|
11
11
|
end
|
12
12
|
|
13
13
|
# @return [String] yaml of hosts and peers found
|
14
14
|
def to_yaml
|
15
15
|
require 'yaml'
|
16
|
-
YAML.dump
|
16
|
+
YAML.dump to_h
|
17
17
|
end
|
18
18
|
|
19
19
|
# @return [String] json of hosts and peers found
|
20
20
|
def to_json
|
21
21
|
require 'json'
|
22
|
-
JSON.pretty_generate
|
22
|
+
JSON.pretty_generate to_h
|
23
23
|
end
|
24
24
|
|
25
25
|
# @return [Array] of nodes found
|
26
26
|
def to_list
|
27
27
|
nodes = []
|
28
|
-
@
|
28
|
+
@peers.each do |host, peers|
|
29
29
|
nodes << host
|
30
|
-
|
30
|
+
peers.each do |peer|
|
31
|
+
nodes.push @resolve ? peer.name : peer.ip
|
32
|
+
end
|
31
33
|
end
|
32
34
|
nodes.flatten.uniq.sort
|
33
35
|
end
|
34
36
|
|
35
|
-
# resolves ip addresses and
|
37
|
+
# resolves ip addresses of peers and @peers keys
|
36
38
|
# @return [void]
|
37
|
-
def resolve
|
38
|
-
@
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
39
|
+
def resolve!
|
40
|
+
@resolve = true
|
41
|
+
newpeers = {}
|
42
|
+
@peers.each do |host, peers|
|
43
|
+
peers.each { |peer| peer.name }
|
44
|
+
name = DNS.getname host
|
45
|
+
newpeers[name] = peers
|
45
46
|
end
|
46
|
-
@
|
47
|
+
@peers = newpeers
|
47
48
|
end
|
48
49
|
|
49
|
-
# remove peers not
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
# remove peers not matching to configured CIDR
|
51
|
+
# @return [void]
|
52
|
+
def clean!
|
53
|
+
@peers.each do |host, peers|
|
54
|
+
peers.delete_if{|peer|not @pollmap.include? peer.ip}
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
56
58
|
private
|
57
59
|
|
58
|
-
def initialize
|
59
|
-
@
|
60
|
-
@hash = @iphash
|
60
|
+
def initialize peers, pollmap
|
61
|
+
@peers = peers
|
61
62
|
@pollmap = pollmap
|
63
|
+
@resolve = false
|
62
64
|
end
|
63
65
|
|
64
66
|
def method_missing name, *args
|
@@ -68,5 +70,17 @@ class NetCrawl
|
|
68
70
|
output = NetCrawl::Output.const_get output.capitalize
|
69
71
|
output.send :output, self
|
70
72
|
end
|
73
|
+
|
74
|
+
def to_h
|
75
|
+
hash = {}
|
76
|
+
@peers.each do |host, peers|
|
77
|
+
ary = []
|
78
|
+
peers.each do |peer|
|
79
|
+
ary << peer.to_hash
|
80
|
+
end
|
81
|
+
hash[host] = ary
|
82
|
+
end
|
83
|
+
hash
|
84
|
+
end
|
71
85
|
end
|
72
86
|
end
|
data/lib/netcrawl/output/dot.rb
CHANGED
@@ -10,13 +10,16 @@ class NetCrawl
|
|
10
10
|
def to_s
|
11
11
|
str = "graph NetCrawl {\n"
|
12
12
|
@output.to_list.each do |host|
|
13
|
-
|
14
|
-
str << INDENT + id(host) + "[label=\"#{
|
15
|
-
if @
|
16
|
-
@
|
17
|
-
|
18
|
-
@connections
|
19
|
-
|
13
|
+
host_label = label(host)
|
14
|
+
str << INDENT + id(host) + "[label=\"#{host_label}\" color=\"#{color(host_label)}\"]\n"
|
15
|
+
if @peers.has_key? host
|
16
|
+
@peers[host].each do |peer|
|
17
|
+
peer_name = @resolve ? peer.name : peer.ip
|
18
|
+
next if not CFG.dot.bothlinks and @connections.include?([peer_name, host].sort)
|
19
|
+
@connections << [peer_name, host].sort
|
20
|
+
labels = ''
|
21
|
+
labels = "[headlabel=\"#{peer.dst.to_s}\" taillabel=\"#{peer.src.to_s}\"]" if CFG.dot.linklabel
|
22
|
+
str << INDENT + INDENT + id(host) + ' -- ' + id(peer_name) + labels + "\n"
|
20
23
|
end
|
21
24
|
end
|
22
25
|
end
|
@@ -29,7 +32,8 @@ class NetCrawl
|
|
29
32
|
def initialize output
|
30
33
|
@output = output
|
31
34
|
@connections = []
|
32
|
-
@
|
35
|
+
@peers = @output.peers
|
36
|
+
@resolve = @output.resolve
|
33
37
|
end
|
34
38
|
|
35
39
|
def id host
|
@@ -37,6 +41,22 @@ class NetCrawl
|
|
37
41
|
'_' + host
|
38
42
|
end
|
39
43
|
|
44
|
+
def label wanthost
|
45
|
+
label = nil
|
46
|
+
return wanthost if CFG.ipname == true
|
47
|
+
@peers.each do |host, peers|
|
48
|
+
peers.each do |peer|
|
49
|
+
gothost = @resolve ? peer.name : peer.ip
|
50
|
+
if wanthost == gothost
|
51
|
+
label = peer.raw_name
|
52
|
+
break
|
53
|
+
end
|
54
|
+
end
|
55
|
+
break if label
|
56
|
+
end
|
57
|
+
label or wanthost
|
58
|
+
end
|
59
|
+
|
40
60
|
def color host
|
41
61
|
color = nil
|
42
62
|
CFG.dot.color.each do |re, clr|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class NetCrawl
|
2
|
+
class Peer
|
3
|
+
attr_accessor :ip, :raw_ip, :raw_name, :src, :dst, :oid
|
4
|
+
def initialize
|
5
|
+
@ip = nil # Best guess of system IP
|
6
|
+
@name = nil # Reverse of said IP
|
7
|
+
@raw_ip = nil # IP as seen in polling
|
8
|
+
@raw_name = nil # Name as seen in polling
|
9
|
+
@src = nil # SRC/local interface
|
10
|
+
@dst = nil # DSR/remote interface
|
11
|
+
@oid = {} # Hash of oids collected
|
12
|
+
end
|
13
|
+
def name
|
14
|
+
@name ||= DNS.getname @ip
|
15
|
+
end
|
16
|
+
def to_hash
|
17
|
+
{
|
18
|
+
'ip' => ip.to_s,
|
19
|
+
'name' => name.to_s,
|
20
|
+
'interface' => {
|
21
|
+
'source' => src.to_s,
|
22
|
+
'destination' => dst.to_s,
|
23
|
+
},
|
24
|
+
'raw' => {
|
25
|
+
'ip' => raw_ip.to_s,
|
26
|
+
'name' => raw_name.to_s,
|
27
|
+
},
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/netcrawl/snmp.rb
CHANGED
@@ -39,20 +39,16 @@ class NetCrawl
|
|
39
39
|
results
|
40
40
|
end
|
41
41
|
|
42
|
-
# bulkwalks oid
|
43
|
-
# shold rturn either hash_value or [hash_value, hash_key]
|
44
|
-
# if block does not return hash_key, hash_key is oid-root, e.g. if root is
|
45
|
-
# 1.2 and oid is 1.2.3.4.5 then key is 3.4.5
|
42
|
+
# bulkwalks oid and returns hash with oid as key
|
46
43
|
# @param [String] oid root oid to walk
|
47
|
-
# @yield [
|
44
|
+
# @yield [VBHash] hash containing oids found
|
48
45
|
# @return [Hash] resulting hash
|
49
|
-
def
|
50
|
-
|
51
|
-
hash = {}
|
46
|
+
def hashwalk oid, &block
|
47
|
+
hash = VBHash.new
|
52
48
|
bulkwalk(oid).each do |vb|
|
53
|
-
value, key = block.call(vb)
|
54
|
-
key ||= vb.oid
|
55
|
-
hash[key] =
|
49
|
+
#value, key = block.call(vb)
|
50
|
+
key ||= vb.oid
|
51
|
+
hash[key] = vb
|
56
52
|
end
|
57
53
|
hash
|
58
54
|
end
|
@@ -74,13 +70,72 @@ class NetCrawl
|
|
74
70
|
raise NoResponse, msg
|
75
71
|
end
|
76
72
|
|
73
|
+
# Hash with some helper methods to easier work with VarBinds
|
74
|
+
class VBHash < Hash
|
75
|
+
alias :org_bracket :[]
|
76
|
+
undef :[]
|
77
|
+
|
78
|
+
# @param [Array(Strin, Array)] oid root oid under which you want all oids below it
|
79
|
+
# @return [VBHash] oids which start with param oid
|
80
|
+
def by_oid *oid
|
81
|
+
oid = arg_to_oid(*oid)
|
82
|
+
hash = select do |key, value|
|
83
|
+
key[0..oid.size-1] == oid
|
84
|
+
end
|
85
|
+
newhash = VBHash.new
|
86
|
+
newhash.merge hash
|
87
|
+
end
|
88
|
+
|
89
|
+
# @param [Array(String, Array)] args partial match 3.4.6 would match to 1.2.3.4.6.7.8
|
90
|
+
# @return [SNMP::VarBind] matching element
|
91
|
+
def by_partial *args
|
92
|
+
oid = arg_to_oid(*args)
|
93
|
+
got = nil
|
94
|
+
keys.each do |key|
|
95
|
+
if key.each_cons(oid.size).find{|e|e==oid}
|
96
|
+
got = self[key]
|
97
|
+
break
|
98
|
+
end
|
99
|
+
end
|
100
|
+
got
|
101
|
+
end
|
102
|
+
|
103
|
+
# @param [Array[String, Array)] key which you want, multiple arguments compiled into single key
|
104
|
+
# @return [SNMP::VarBind] matching element
|
105
|
+
def [] *args
|
106
|
+
org_bracket arg_to_oid(*args)
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def arg_to_oid *args
|
112
|
+
key = []
|
113
|
+
args.each do |arg|
|
114
|
+
if Array === arg
|
115
|
+
key += arg.map{|e|e.to_i}
|
116
|
+
elsif Fixnum === arg
|
117
|
+
key << arg
|
118
|
+
else
|
119
|
+
key += arg.split('.').map{|e|e.to_i}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
key
|
123
|
+
end
|
124
|
+
end
|
77
125
|
end
|
78
126
|
end
|
79
127
|
|
80
128
|
module SNMP
|
81
129
|
class VarBind
|
130
|
+
# @return [String] VarBind value as IP address
|
82
131
|
def as_ip
|
83
132
|
SNMP::IpAddress.new(value).to_s
|
84
133
|
end
|
134
|
+
# @param [String] root oid which is removed from self.oid
|
135
|
+
# @return [Array] oid remaining after specified root oid
|
136
|
+
def oid_id root
|
137
|
+
root = root.split('.').map{|e|e.to_i}
|
138
|
+
oid[root.size..-1]
|
139
|
+
end
|
85
140
|
end
|
86
141
|
end
|
data/netcrawl.gemspec
CHANGED
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: netcrawl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.3
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Saku Ytti
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-
|
11
|
+
date: 2014-04-05 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: snmp
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: slop
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: asetus
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -79,40 +72,35 @@ files:
|
|
79
72
|
- lib/netcrawl/dns.rb
|
80
73
|
- lib/netcrawl/method/cdp.rb
|
81
74
|
- lib/netcrawl/method/lldp.rb
|
75
|
+
- lib/netcrawl/method/xdp.rb
|
82
76
|
- lib/netcrawl/namemap.rb
|
83
77
|
- lib/netcrawl/output.rb
|
84
78
|
- lib/netcrawl/output/dot.rb
|
79
|
+
- lib/netcrawl/peer.rb
|
85
80
|
- lib/netcrawl/pollmap.rb
|
86
81
|
- lib/netcrawl/snmp.rb
|
87
82
|
- netcrawl.gemspec
|
88
83
|
homepage: http://github.com/ytti/netcrawl
|
89
84
|
licenses: []
|
85
|
+
metadata: {}
|
90
86
|
post_install_message:
|
91
87
|
rdoc_options: []
|
92
88
|
require_paths:
|
93
89
|
- lib
|
94
90
|
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
-
none: false
|
96
91
|
requirements:
|
97
92
|
- - '>='
|
98
93
|
- !ruby/object:Gem::Version
|
99
94
|
version: '0'
|
100
|
-
segments:
|
101
|
-
- 0
|
102
|
-
hash: 2137776821860602171
|
103
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
-
none: false
|
105
96
|
requirements:
|
106
97
|
- - '>='
|
107
98
|
- !ruby/object:Gem::Version
|
108
99
|
version: '0'
|
109
|
-
segments:
|
110
|
-
- 0
|
111
|
-
hash: 2137776821860602171
|
112
100
|
requirements: []
|
113
101
|
rubyforge_project: netcrawl
|
114
|
-
rubygems_version:
|
102
|
+
rubygems_version: 2.0.3
|
115
103
|
signing_key:
|
116
|
-
specification_version:
|
104
|
+
specification_version: 4
|
117
105
|
summary: lldp/cdp crawler
|
118
106
|
test_files: []
|