netcrawl 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -16,9 +16,9 @@ class NetCrawl
16
16
  def get host
17
17
  peers = []
18
18
  @methods.each do |method|
19
- peers += method.send(:get, host)
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 => error
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/pollmap'
60
- require_relative 'netcrawl/method/cdp'
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'
@@ -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
- opts = Slop.parse(:help=>true) do
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
 
@@ -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' ],
@@ -1,32 +1,32 @@
1
- require_relative '../snmp'
2
1
  class NetCrawl
3
- class CDP
4
- include NameMap
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
- :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',
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 initialize host
29
- @snmp = SNMP.new host
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
@@ -1,7 +1,6 @@
1
- require_relative '../snmp'
2
1
  class NetCrawl
3
- class LLDP
4
- include NameMap
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
- # @param [String] host host to query
23
- # @return [Hash] neighbor information
24
- def self.get host
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 initialize host
43
- @snmp = SNMP.new host
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'
@@ -1,64 +1,66 @@
1
1
  class NetCrawl
2
2
  class Output
3
- attr_reader :iphash, :namehash, :hash
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 @hash, out
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 @hash
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 @hash
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
- @hash.each do |host, peers|
28
+ @peers.each do |host, peers|
29
29
  nodes << host
30
- nodes << peers
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 changes @hash to point to the resolved hash
37
+ # resolves ip addresses of peers and @peers keys
36
38
  # @return [void]
37
- def resolve
38
- @namehash = {}
39
- @iphash.each do |host, peers|
40
- host = DNS.getname host
41
- @namehash[host] = []
42
- peers.each do |peer|
43
- @namehash[host].push DNS.getname(peer)
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
- @hash = @namehash
47
+ @peers = newpeers
47
48
  end
48
49
 
49
- # remove peers not matchin configured CIDR
50
- def clean
51
- @hash.each do |host, peers|
52
- peers = peers.delete_if{|peer|not @pollmap.include? peer}
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 hash, pollmap
59
- @iphash = hash
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
@@ -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
- str << INDENT + id(host) + "[color=\"#{color(host)}\"]\n"
14
- str << INDENT + id(host) + "[label=\"#{host}\"]\n"
15
- if @hash.has_key? host
16
- @hash[host].each do |peer|
17
- next if not CFG.dot.bothlinks and @connections.include?([peer, host].sort)
18
- @connections << [peer, host].sort
19
- str << INDENT + INDENT + id(host) + ' -- ' + id(peer) + "\n"
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
- @hash = @output.hash
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
@@ -39,20 +39,16 @@ class NetCrawl
39
39
  results
40
40
  end
41
41
 
42
- # bulkwalks oid returning hash based on block block gets SNMP::VarBind and
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 [SNMP::VarBind] gives vb to block, expect back hash_value or [hash_value, hash_key]
44
+ # @yield [VBHash] hash containing oids found
48
45
  # @return [Hash] resulting hash
49
- def walk2hash oid, &block
50
- index = oid.split('.').size
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[index..-1]
55
- hash[key] = value
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'netcrawl'
3
- s.version = '0.0.2'
3
+ s.version = '0.0.3'
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.authors = [ 'Saku Ytti' ]
6
6
  s.email = %w( saku@ytti.fi )
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.2
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-03-31 00:00:00.000000000 Z
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: 1.8.25
102
+ rubygems_version: 2.0.3
115
103
  signing_key:
116
- specification_version: 3
104
+ specification_version: 4
117
105
  summary: lldp/cdp crawler
118
106
  test_files: []