netcrawl 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ gems
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # Netcrawl
2
+ Given snmp community and single device, crawls the network via discovering
3
+ LLDP/CDP neighbours, while producing list or dot file (for graphviz digraphs)
4
+
5
+ ## Install
6
+ % gem install netcrawl
7
+
8
+ ## Use
9
+ % netcrawl --graphiz router.example.com
10
+
11
+ ## Command line
12
+ ```
13
+ Usage: netcrawl [options] hostname
14
+ -g, --graphviz dot output use 'dot -Tpng -o map.png map.dot'
15
+ -l, --list list nodes
16
+ -j, --json json output
17
+ -y, --yaml yaml output
18
+ -a, --hash hash/associative array output
19
+ -r, --resolve resolve addresses to names
20
+ -p, --purge remove peers not in configured CIDR
21
+ -c, --community SNMP community to use
22
+ -d, --debug turn debugging on
23
+ -h, --help Display this help message.
24
+
25
+ ```
26
+ * graphiz - graphis (dot) output
27
+ * list - list nodes found
28
+ * json - json output
29
+ * yaml - yaml output
30
+ * hash - ruby hash output
31
+ * resolve - resolve IP addresses
32
+ * purge - remove non-cidr matching peers from output
33
+ * community - sets snmp community
34
+ * debug - turn on debugging
35
+
36
+ ## Config
37
+ ```
38
+ ---
39
+ use:
40
+ - LLDP
41
+ - CDP
42
+ poll:
43
+ - 192.0.2.0/24
44
+ snmp:
45
+ community: public
46
+ timeout: 1
47
+ retries: 2
48
+ bulkrows: 35
49
+ dot:
50
+ bothlinks: true
51
+ color:
52
+ - - cpe
53
+ - gold
54
+ - - -sw
55
+ - blue
56
+ - - -pe
57
+ - red
58
+ - - ' -p'
59
+ - yellow
60
+ dns:
61
+ afi:
62
+ log: STDERR
63
+ debug: false
64
+ namemap:
65
+ - - -re\d+
66
+ - ''
67
+ - - (.*(?<!as23456.net)$)
68
+ - \1.as23456.net
69
+ ```
70
+
71
+ * use - methods to use for crawling
72
+ * poll - cidrs to allow snmp for
73
+ * snmp community - snmp community to use
74
+ * snmp timout - snmp timout in seconds
75
+ * snmp retries - snmp retries count
76
+ * snmp bulkrows - snmp row count for bulkget
77
+ * dot bothlinks - show a-b and b-a link
78
+ * dot color - regexp to color, first hit used
79
+ * dns afi - ipv4/ipv6 or nil
80
+ * log - STDERR/STDOUT or file
81
+ * debug - debugging
82
+ * namemap - map (LLDP) name to FQDN (JunOS does not give domain)
83
+
84
+ ## Library use
85
+ require 'netcrawl'
86
+ output = NetCrawl.new.crawl('192.0.2.1').to_hash
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ begin
2
+ require 'rake/testtask'
3
+ require 'bundler'
4
+ Bundler.setup
5
+ rescue LoadError
6
+ warn 'bunler missing'
7
+ exit 42
8
+ end
9
+
10
+ gemspec = eval(File.read(Dir['*.gemspec'].first))
11
+ file = [gemspec.name, gemspec.version].join('-') + '.gem'
12
+
13
+ desc 'Validate gemspec'
14
+ task :gemspec do
15
+ gemspec.validate
16
+ end
17
+
18
+ desc 'Run minitest'
19
+ task :test do
20
+ Rake::TestTask.new do |t|
21
+ t.libs.push "lib"
22
+ t.test_files = FileList['spec/*_spec.rb']
23
+ t.verbose = true
24
+ end
25
+ end
26
+
27
+ desc 'Build gem'
28
+ task :build do
29
+ system "gem build #{gemspec.name}.gemspec"
30
+ FileUtils.mkdir_p 'gems'
31
+ FileUtils.mv file, 'gems'
32
+ end
33
+
34
+ desc 'Install gem'
35
+ task :install => :build do
36
+ system "sudo -E sh -c \'umask 022; gem install gems/#{file}\'"
37
+ end
38
+
39
+ desc 'Remove gems'
40
+ task :clean do
41
+ FileUtils.rm_rf 'gems'
42
+ end
43
+
44
+ desc 'Push to rubygems'
45
+ task :push do
46
+ system "gem push gems/#{file}"
47
+ end
data/bin/netcrawl ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'netcrawl/cli'
5
+ puts NetCrawl::CLI.new.run
6
+ rescue => error
7
+ warn "#{error}"
8
+ raise if NetCrawl::CFG.debug
9
+ end
data/lib/netcrawl.rb ADDED
@@ -0,0 +1,63 @@
1
+ require_relative 'netcrawl/config'
2
+ class NetCrawl
3
+ class NetCrawlError < StandardError; end
4
+ class MethodNotFound < NetCrawlError; end
5
+ attr_reader :hosts
6
+
7
+ # @param [String] host host to start crawl from
8
+ # @return [NetCrawl::Output]
9
+ def crawl host
10
+ recurse host
11
+ Output.new @hosts, @poll
12
+ end
13
+
14
+ # @param [String] host host to get list of peers from
15
+ # @return [Array] list of peers seen connected to host
16
+ def get host
17
+ peers = []
18
+ @methods.each do |method|
19
+ peers += method.send(:get, host)
20
+ end
21
+ peers.uniq
22
+ end
23
+
24
+ # Given string of IP address, recurses through peers seen and populates @hosts hash
25
+ # @param [String] host host to start recurse from
26
+ # @return [void]
27
+ def recurse host
28
+ peers = get host
29
+ @hosts[host] = peers
30
+ peers.each do |peer|
31
+ next if @hosts.has_key? peer
32
+ next unless @poll.include? peer
33
+ crawl peer
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def initialize
40
+ @methods = []
41
+ @hosts = {}
42
+ @poll = PollMap.new
43
+ CFG.use.each do |method|
44
+ begin
45
+ method = File.basename method.to_s
46
+ file = 'netcrawl/method/' + method.downcase
47
+ require_relative file
48
+ @methods.push NetCrawl.const_get(method)
49
+ rescue NameError, LoadError => error
50
+ raise MethodNotFound, "unable to find method '#{method}'"
51
+ end
52
+ end
53
+ end
54
+
55
+
56
+ end
57
+ require_relative 'netcrawl/pollmap'
58
+ require_relative 'netcrawl/namemap'
59
+ require_relative 'netcrawl/pollmap'
60
+ require_relative 'netcrawl/method/cdp'
61
+ require_relative 'netcrawl/method/lldp'
62
+ require_relative 'netcrawl/dns'
63
+ require_relative 'netcrawl/output'
Binary file
@@ -0,0 +1,59 @@
1
+ require_relative '../netcrawl'
2
+ require 'slop'
3
+
4
+ class NetCrawl
5
+ class CLI
6
+ class MissingHost < NetCrawlError; end
7
+ class NoConfig < NetCrawlError; end
8
+
9
+ def run
10
+ output = NetCrawl.new.crawl @host
11
+ output.clean if @opts[:purge]
12
+ output.resolve if @opts[:resolve]
13
+ if @opts[:graphviz]
14
+ output.to_dot
15
+ elsif @opts[:list]
16
+ output.to_list
17
+ elsif @opts[:json]
18
+ output.to_json
19
+ elsif @opts[:yaml]
20
+ output.to_yaml
21
+ else
22
+ output.to_hash
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def initialize
29
+ if Config.system.empty? and Config.user.empty?
30
+ Config.user = Config.default
31
+ Config.save :user
32
+ raise NoConfig, 'edit ~/.config/netcrawl/config'
33
+ end
34
+ @opts = opt_parse
35
+ args = @opts.parse
36
+ @host = DNS.getip args.shift
37
+ CFG.snmp.community = @opts[:community] if @opts[:community]
38
+ CFG.debug = true if @opts[:debug]
39
+ raise MissingHost, 'no hostname given as argument' unless @host
40
+ end
41
+
42
+
43
+ def opt_parse
44
+ opts = Slop.parse(:help=>true) do
45
+ banner 'Usage: netcrawl [options] hostname'
46
+ on 'g', 'graphviz', 'dot output use \'dot -Tpng -o map.png map.dot\''
47
+ on 'l', 'list', 'list nodes'
48
+ on 'j', 'json', 'json output'
49
+ on 'y', 'yaml', 'yaml output'
50
+ on 'a', 'hash', 'hash/associative array output'
51
+ on 'r', 'resolve', 'resolve addresses to names'
52
+ on 'p', 'purge', 'remove peers not in configured CIDR'
53
+ on 'c=', 'community', 'SNMP community to use'
54
+ on 'd', 'debug', 'turn debugging on'
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,37 @@
1
+ require 'asetus'
2
+ require 'logger'
3
+ class NetCrawl
4
+ Config = Asetus.new :name=>'netcrawl', :load=>false
5
+ Config.default.use = %w(LLDP CDP)
6
+ Config.default.poll = [ # addresses accepted for polling
7
+ '192.0.2.0/24',
8
+ '198.51.100.0/24',
9
+ '0.0.0.0/0',
10
+ ]
11
+ Config.default.snmp.community = 'public'
12
+ Config.default.snmp.timeout = 1
13
+ Config.default.snmp.retries = 2
14
+ Config.default.snmp.bulkrows = 35 # 1500B packet should fit about 50 :cdpCacheAddress rows
15
+ Config.default.dot.bothlinks = false # keep both a-b and b-a links
16
+ Config.default.dot.color = [ # regexp of host => color
17
+ [ 'cpe', 'gold' ],
18
+ [ '-sw', 'blue' ],
19
+ [ '-pe', 'red' ],
20
+ [' -p', 'yellow' ],
21
+ ]
22
+ Config.default.dns.afi = nil # could be 'ipv4' or 'ipv6'
23
+ Config.default.log = 'STDERR'
24
+ Config.default.debug = false
25
+ Config.default.namemap = [ # regexp match+sub of hostname (needed for LLDP)
26
+ ['-re\d+', ''],
27
+ ['^KILLME(.*(?<!my.domain.com)$)', '\1.my.domain.com'], #adds missing domain name
28
+ ]
29
+ Config.load
30
+ CFG = Config.cfg
31
+ log = CFG.log
32
+ log = STDERR if log == 'STDERR'
33
+ log = STDOUT if log == 'STDOUT'
34
+ Log = Logger.new log
35
+ Log.level = Logger::INFO
36
+ Log.level = Logger::DEBUG if CFG.debug
37
+ end
@@ -0,0 +1,53 @@
1
+ require 'resolv'
2
+ class NetCrawl
3
+ class Resolve
4
+
5
+ # @param [String] name DNS name which we try to resolve to IP
6
+ # @return [String, nil] string if name resolves to IP, otherwise nil
7
+ def getip name
8
+ if @cacheip.has_key? name
9
+ @cacheip[name]
10
+ else
11
+ ip = nil
12
+ begin
13
+ if CFG.dns.afi == 'ipv4'
14
+ ip = Resolv::DNS.new.getresource(name, Resolv::DNS::Resource::IN::A).address
15
+ elsif CFG.dns.afi == 'ipv6'
16
+ ip = Resolv::DNS.new.getresource(name, Resolv::DNS::Resource::IN::AAAA).address
17
+ else
18
+ ip = Resolv.getaddress name
19
+ end
20
+ rescue => error
21
+ Log.debug "DNS resolution for '#{name}' raised error '#{error.class}' with message '#{error.message}'"
22
+ return nil
23
+ end
24
+ @cacheip[name] = ip
25
+ end
26
+ end
27
+
28
+ # @param [String] ip DNS IP which we try to resolve to name
29
+ # @return [String] name if it resolves, ip otherwise
30
+ def getname ip
31
+ if @cachename.has_key? ip
32
+ @cachename[ip]
33
+ else
34
+ name = nil
35
+ begin
36
+ name = Resolv.getname ip
37
+ rescue => error
38
+ Log.debug "DNS resolution for '#{ip}' raised error '#{error.class}' with message '#{error.message}'"
39
+ name = ip
40
+ end
41
+ @cachename[ip] = name
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def initialize
48
+ @cacheip = {}
49
+ @cachename = {}
50
+ end
51
+ end
52
+ DNS = Resolve.new
53
+ end
@@ -0,0 +1,33 @@
1
+ require_relative '../snmp'
2
+ class NetCrawl
3
+ class CDP
4
+ OID = {
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
6
+ :cdpCacheAddress => '1.3.6.1.4.1.9.9.23.1.2.1.1.4',
7
+ :cdpCacheDeviceId => '1.3.6.1.4.1.9.9.23.1.2.1.1.6',
8
+ }
9
+
10
+ # @param [String] host host to query
11
+ # @return [Hash] neighbor information
12
+ def self.get host
13
+ cdp = new(host)
14
+ cdp.peers
15
+ end
16
+
17
+ def peers
18
+ @snmp.bulkwalk(OID[:cdpCacheAddress]).map do |vb|
19
+ vb.as_ip
20
+ end
21
+ rescue SNMP::NoResponse
22
+ []
23
+ end
24
+
25
+ private
26
+
27
+ def initialize host
28
+ @snmp = SNMP.new host
29
+ end
30
+
31
+
32
+ end
33
+ end
@@ -0,0 +1,35 @@
1
+ require_relative '../snmp'
2
+ class NetCrawl
3
+ class LLDP
4
+ include NameMap
5
+ OID = {
6
+ # http://standards.ieee.org/getieee802/download/802.1AB-2009.pdf
7
+ :lldpRemChassisIdSubtype => '1.0.8802.1.1.2.1.4.1.1.4', # CSCO and JNPR use 4 (MAC address) rendering ChassisID useless
8
+ :lldpRemChassisId => '1.0.8802.1.1.2.1.4.1.1.5',
9
+ :lldpRemSysName => '1.0.8802.1.1.2.1.4.1.1.9',
10
+ }
11
+
12
+ # @param [String] host host to query
13
+ # @return [Hash] neighbor information
14
+ def self.get host
15
+ lldp = new(host)
16
+ lldp.peers
17
+ end
18
+
19
+ def peers
20
+ @snmp.bulkwalk(OID[:lldpRemSysName]).map do |vb|
21
+ DNS.getip namemap(vb.value)
22
+ end.compact
23
+ rescue SNMP::NoResponse
24
+ []
25
+ end
26
+
27
+ private
28
+
29
+ def initialize host
30
+ @snmp = SNMP.new host
31
+ end
32
+
33
+
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ class NetCrawl
2
+ module NameMap
3
+ def namemap name_org
4
+ name = name_org.dup
5
+ CFG.namemap.each do |match, replace|
6
+ re = Regexp.new match
7
+ name = name.sub re, replace
8
+ end
9
+ name
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,72 @@
1
+ class NetCrawl
2
+ class Output
3
+ attr_reader :iphash, :namehash, :hash
4
+
5
+ # @return [String] pretty print of hash
6
+ def to_hash
7
+ require 'pp'
8
+ out = ''
9
+ PP.pp @hash, out
10
+ out
11
+ end
12
+
13
+ # @return [String] yaml of hosts and peers found
14
+ def to_yaml
15
+ require 'yaml'
16
+ YAML.dump @hash
17
+ end
18
+
19
+ # @return [String] json of hosts and peers found
20
+ def to_json
21
+ require 'json'
22
+ JSON.pretty_generate @hash
23
+ end
24
+
25
+ # @return [Array] of nodes found
26
+ def to_list
27
+ nodes = []
28
+ @hash.each do |host, peers|
29
+ nodes << host
30
+ nodes << peers
31
+ end
32
+ nodes.flatten.uniq.sort
33
+ end
34
+
35
+ # resolves ip addresses and changes @hash to point to the resolved hash
36
+ # @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
45
+ end
46
+ @hash = @namehash
47
+ end
48
+
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}
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def initialize hash, pollmap
59
+ @iphash = hash
60
+ @hash = @iphash
61
+ @pollmap = pollmap
62
+ end
63
+
64
+ def method_missing name, *args
65
+ raise NoMethodError, "invalid method #{name} for #{inspect}:#{self.class}" unless name.match(/to_.*/)
66
+ output = File.basename name[3..-1]
67
+ require_relative 'output/' + output
68
+ output = NetCrawl::Output.const_get output.capitalize
69
+ output.send :output, self
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,53 @@
1
+ class NetCrawl
2
+ class Output
3
+ class Dot
4
+ INDENT = ' ' * 2
5
+ DEFAULT_COLOR = 'black'
6
+ def self.output output
7
+ new(output).to_s
8
+ end
9
+
10
+ def to_s
11
+ str = "graph NetCrawl {\n"
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"
20
+ end
21
+ end
22
+ end
23
+ str << "}\n"
24
+ str
25
+ end
26
+
27
+ private
28
+
29
+ def initialize output
30
+ @output = output
31
+ @connections = []
32
+ @hash = @output.hash
33
+ end
34
+
35
+ def id host
36
+ host = host.gsub(/[-.]/, '_')
37
+ '_' + host
38
+ end
39
+
40
+ def color host
41
+ color = nil
42
+ CFG.dot.color.each do |re, clr|
43
+ if host.match re
44
+ color = clr
45
+ break
46
+ end
47
+ end
48
+ color or DEFAULT_COLOR
49
+ end
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,13 @@
1
+ require 'ipaddr'
2
+ class NetCrawl
3
+ class PollMap
4
+ def initialize
5
+ @poll = CFG.poll.map do |cidr|
6
+ IPAddr.new cidr
7
+ end
8
+ end
9
+ def include? addr
10
+ @poll.any? { |cidr| cidr.include? addr }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,68 @@
1
+ require 'snmp'
2
+ class NetCrawl
3
+ class SNMP
4
+ class NoResponse < NetCrawlError; end
5
+ # Closes the SNMP connection
6
+ # @return [void]
7
+ def close
8
+ @snmp.close
9
+ end
10
+
11
+ # Gets one oid, return value
12
+ # @param [String] oid to get
13
+ # @return [SNMP::VarBind]
14
+ def get oid
15
+ mget([oid]).first
16
+ end
17
+
18
+ # Get multiple oids, return array of values
19
+ # @param [Array(String)] oids to get
20
+ # @return [SNMP::VarBindList]
21
+ def mget oids
22
+ snmp :get, oids
23
+ end
24
+
25
+ # Bulkwalk everything below root oid
26
+ # @param [String] root oid to start from
27
+ # @return [Array(SNMP::VarBind)]
28
+ def bulkwalk root
29
+ last, oid, results = false, root.dup, []
30
+ root = root.split('.').map{|chr|chr.to_i}
31
+ while not last
32
+ vbs = snmp(:get_bulk, 0, CFG.snmp.bulkrows, oid).varbind_list
33
+ vbs.each do |vb|
34
+ oid = vb.oid
35
+ (last = true; break) if not oid[0..root.size-1] == root
36
+ results.push vb
37
+ end
38
+ end
39
+ results
40
+ end
41
+
42
+ private
43
+
44
+ def initialize host, community=CFG.snmp.community, timeout=CFG.snmp.timeout, retries=CFG.snmp.retries
45
+ @host = host
46
+ @snmp = ::SNMP::Manager.new :Host=>@host, :Community=>community,
47
+ :Timeout=>timeout, :Retries=>retries,
48
+ :MibModules=>[]
49
+ end
50
+
51
+ def snmp cmd, *args
52
+ @snmp.send cmd, *args
53
+ rescue ::SNMP::RequestTimeout, Errno::EACCES => error
54
+ msg = "host '#{@host}' raised '#{error.class}' with message '#{error.message}' for method '#{cmd}' with args '#{args}'"
55
+ Log.warn msg
56
+ raise NoResponse, msg
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ module SNMP
63
+ class VarBind
64
+ def as_ip
65
+ SNMP::IpAddress.new(value).to_s
66
+ end
67
+ end
68
+ end
data/netcrawl.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'netcrawl'
3
+ s.version = '0.0.1'
4
+ s.platform = Gem::Platform::RUBY
5
+ s.authors = [ 'Saku Ytti' ]
6
+ s.email = %w( saku@ytti.fi )
7
+ s.homepage = 'http://github.com/ytti/netcrawl'
8
+ s.summary = 'lldp/cdp crawler'
9
+ s.description = 'given snmp community and one node crawls through the network to produce list/dot file'
10
+ s.rubyforge_project = s.name
11
+ s.files = `git ls-files`.split("\n")
12
+ s.executables = %w( netcrawl )
13
+ s.require_path = 'lib'
14
+
15
+ s.add_dependency 'snmp'
16
+ s.add_dependency 'slop'
17
+ s.add_dependency 'asetus'
18
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: netcrawl
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Saku Ytti
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-03-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: snmp
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: slop
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: asetus
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ description: given snmp community and one node crawls through the network to produce
63
+ list/dot file
64
+ email:
65
+ - saku@ytti.fi
66
+ executables:
67
+ - netcrawl
68
+ extensions: []
69
+ extra_rdoc_files: []
70
+ files:
71
+ - .gitignore
72
+ - Gemfile
73
+ - README.md
74
+ - Rakefile
75
+ - bin/netcrawl
76
+ - lib/netcrawl.rb
77
+ - lib/netcrawl/.cli.rb.swp
78
+ - lib/netcrawl/cli.rb
79
+ - lib/netcrawl/config.rb
80
+ - lib/netcrawl/dns.rb
81
+ - lib/netcrawl/method/cdp.rb
82
+ - lib/netcrawl/method/lldp.rb
83
+ - lib/netcrawl/namemap.rb
84
+ - lib/netcrawl/output.rb
85
+ - lib/netcrawl/output/dot.rb
86
+ - lib/netcrawl/pollmap.rb
87
+ - lib/netcrawl/snmp.rb
88
+ - netcrawl.gemspec
89
+ homepage: http://github.com/ytti/netcrawl
90
+ licenses: []
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ segments:
102
+ - 0
103
+ hash: -152408900674429923
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ segments:
111
+ - 0
112
+ hash: -152408900674429923
113
+ requirements: []
114
+ rubyforge_project: netcrawl
115
+ rubygems_version: 1.8.25
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: lldp/cdp crawler
119
+ test_files: []