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.
@@ -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: []