hooray 0.0.9 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/lib/hooray.rb +1 -0
- data/lib/hooray/cli.rb +14 -4
- data/lib/hooray/local.rb +37 -0
- data/lib/hooray/node.rb +11 -4
- data/lib/hooray/port.rb +8 -0
- data/lib/hooray/seek.rb +42 -59
- data/lib/hooray/version.rb +1 -1
- data/spec/hooray/node_spec.rb +1 -4
- data/spec/hooray/seek_spec.rb +19 -3
- metadata +3 -3
- data/lib/hooray/scan.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26b25f88e85a64e4c69b0f9329a054dc35bf0c35
|
4
|
+
data.tar.gz: 3c57622a6c1f3aa1258d910f9c8c36f187c0dbad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cf3772c8c087e120bfcefbc06a6a081d1040a932b941f6a5c95127045ccb9f051064afd6d85269ea65f8d2f394306399d8d65922eb75186fb29bec52d1332b0
|
7
|
+
data.tar.gz: 584abd5fe3d7c4ae8a017f0abb241f87123003346335f6bef794fde4cd775062ca1674d4653484a8a603894f7290c4078c7e4ea24216560aa1325b0bc1df0681
|
data/README.md
CHANGED
data/lib/hooray.rb
CHANGED
data/lib/hooray/cli.rb
CHANGED
@@ -37,8 +37,12 @@ module Hooray
|
|
37
37
|
|
38
38
|
LONG
|
39
39
|
def list(*filter)
|
40
|
-
|
41
|
-
|
40
|
+
if (nodes = Seek.new(options[:network], *filter).nodes).empty?
|
41
|
+
pa "No results for filter #{filter.join(' ')}", :red
|
42
|
+
else
|
43
|
+
print_table(nodes)
|
44
|
+
end
|
45
|
+
puts
|
42
46
|
end
|
43
47
|
|
44
48
|
desc 'watch FILTER', 'watch in realtime FILTER'
|
@@ -93,10 +97,16 @@ module Hooray
|
|
93
97
|
end
|
94
98
|
|
95
99
|
def print_table(nodes)
|
96
|
-
|
100
|
+
return if nodes.empty?
|
101
|
+
if nodes.first.ports.empty?
|
102
|
+
tp nodes, :name, :ip, :mac
|
103
|
+
else
|
104
|
+
tp nodes, :name, :ip, :mac, :ports
|
105
|
+
end
|
97
106
|
puts '---'
|
98
107
|
took = (Time.now - @start).round(2)
|
99
|
-
|
108
|
+
count_plural = nodes.size > 1 ? 's' : ''
|
109
|
+
pa "#{nodes.count} device#{count_plural} @ #{Time.now} #{took}s", '#777', :bold
|
100
110
|
end
|
101
111
|
|
102
112
|
def method_missing(*params)
|
data/lib/hooray/local.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Hooray
|
2
|
+
#
|
3
|
+
# Information from the machine
|
4
|
+
#
|
5
|
+
class Local
|
6
|
+
class << self
|
7
|
+
#
|
8
|
+
# ARP Table reader
|
9
|
+
#
|
10
|
+
def arp_table
|
11
|
+
return @arp_table if @arp_table
|
12
|
+
@arp_table ||= {}
|
13
|
+
`arp -na`.split(/\n/).each do |l|
|
14
|
+
_q, ip, _at, mac, *iface = l.split(/\s+/)
|
15
|
+
next unless mac =~ /:\w{2}:/
|
16
|
+
ip = ip[1..-2] # (ip) -> ip
|
17
|
+
@arp_table.merge!(ip => mac) if iface
|
18
|
+
end
|
19
|
+
@arp_table
|
20
|
+
end
|
21
|
+
|
22
|
+
def ips
|
23
|
+
Socket.ip_address_list.select do |ip|
|
24
|
+
ip.ipv4_private? && !ip.ipv4_loopback?
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def lan_ip
|
29
|
+
IPAddr.new(ips.first.ip_address)
|
30
|
+
end
|
31
|
+
|
32
|
+
def mask(bits = 24)
|
33
|
+
lan_ip.mask(bits)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/hooray/node.rb
CHANGED
@@ -4,10 +4,17 @@ module Hooray
|
|
4
4
|
attr_accessor :host, :name, :nick, :mac, :ip, :ports
|
5
5
|
|
6
6
|
def initialize(params = {})
|
7
|
-
|
7
|
+
self.ip = params[:ip]
|
8
8
|
@mac = params[:mac]
|
9
|
-
@mac ||= Mac.addr if @ip ==
|
9
|
+
@mac ||= Mac.addr if @ip == Hooray::Local.lan_ip
|
10
10
|
@name = params[:name] || find_name
|
11
|
+
return unless params[:ports]
|
12
|
+
@ports = params[:ports].reject(&:nil?).map { |n| Hooray::Port.new(n) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def ip=(param)
|
16
|
+
return unless param
|
17
|
+
@ip = param.is_a?(IPAddr) ? param : IPAddr.new(param)
|
11
18
|
end
|
12
19
|
|
13
20
|
def find_name
|
@@ -19,8 +26,8 @@ module Hooray
|
|
19
26
|
end
|
20
27
|
end
|
21
28
|
|
22
|
-
def
|
23
|
-
|
29
|
+
def ports
|
30
|
+
@ports.sort.map(&:number).join(', ')
|
24
31
|
end
|
25
32
|
|
26
33
|
def <=>(other)
|
data/lib/hooray/port.rb
CHANGED
data/lib/hooray/seek.rb
CHANGED
@@ -3,95 +3,78 @@ module Hooray
|
|
3
3
|
# Main runner
|
4
4
|
#
|
5
5
|
class Seek
|
6
|
-
attr_accessor :network, :
|
6
|
+
attr_accessor :network, :ports, :opts
|
7
7
|
|
8
8
|
NET_MASK = 24
|
9
9
|
TIMEOUT = 1
|
10
10
|
|
11
11
|
def initialize(network = nil, *params)
|
12
|
-
@
|
13
|
-
|
14
|
-
|
12
|
+
@scan = {}
|
13
|
+
@bots = []
|
14
|
+
config_network network
|
15
|
+
config_filters params
|
15
16
|
end
|
16
|
-
alias_method :devices, :nodes
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
@ports = ports.map(&:to_i).first # TODO
|
25
|
-
@protocol = words.select { |w| w =~ /udp|tcp/ }.join
|
18
|
+
def config_network(param)
|
19
|
+
if param && !param.empty?
|
20
|
+
@network = IPAddr.new(param)
|
21
|
+
else
|
22
|
+
@network = Hooray::Local.mask
|
23
|
+
end
|
26
24
|
end
|
27
25
|
|
26
|
+
def config_filters(params)
|
27
|
+
return if params.empty?
|
28
|
+
numbers, @words = params.flatten.partition { |s| s =~ /\d+/ }
|
29
|
+
@ports = numbers.map(&:to_i)
|
30
|
+
end
|
28
31
|
#
|
29
32
|
# Map results to @nodes << Node.new()
|
30
33
|
#
|
31
34
|
# BUG: sometimes ping returns true
|
32
35
|
# When you run list consecutively. Pretty weird!
|
33
36
|
# So we need to remove those without mac
|
34
|
-
def
|
35
|
-
@nodes
|
36
|
-
|
37
|
+
def nodes
|
38
|
+
return @nodes if @nodes
|
39
|
+
@nodes = sweep.map do |k, v|
|
40
|
+
Node.new(ip: k, mac: Hooray::Local.arp_table[k.to_s], ports: v)
|
37
41
|
end.reject { |n| n.mac.nil? } # remove those without mac
|
38
42
|
end
|
43
|
+
alias_method :devices, :nodes
|
39
44
|
|
40
45
|
def ping_class
|
41
|
-
return Net::Ping::External unless
|
42
|
-
@
|
46
|
+
return Net::Ping::External unless ports
|
47
|
+
if @words && @words.join =~ /tcp|udp|http|wmi/
|
48
|
+
Net::Ping.const_get(@words.join.upcase)
|
49
|
+
else
|
50
|
+
Net::Ping::TCP
|
51
|
+
# elsif (serv = Settings.service(@words.join))
|
52
|
+
# @ports = serv.values
|
53
|
+
end
|
43
54
|
end
|
44
55
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
bots = []
|
51
|
-
# pa "Starting #{Settings.list} on '#{network}' #{@ports} #{@protocol}"
|
52
|
-
@network.to_range.each do |ip|
|
53
|
-
# next if ip == my_lan_ip
|
54
|
-
bots << Thread.new do
|
55
|
-
if ping_class.new(ip.to_s, @ports, TIMEOUT).ping?
|
56
|
-
scan << ip
|
56
|
+
def scan_bot(ip)
|
57
|
+
(ports || [nil]).each do |port|
|
58
|
+
@bots << Thread.new do
|
59
|
+
if ping_class.new(ip.to_s, port, TIMEOUT).ping?
|
60
|
+
@scan[ip] << port
|
57
61
|
print '.'
|
58
62
|
end
|
59
63
|
end
|
60
64
|
end
|
61
|
-
bots.each(&:join)
|
62
|
-
puts
|
63
|
-
scan
|
64
65
|
end
|
65
66
|
|
66
67
|
#
|
67
|
-
#
|
68
|
+
# fast -> -sn -PA
|
68
69
|
#
|
69
|
-
def
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
_q, ip, _at, mac, *iface = l.split(/\s+/)
|
74
|
-
next unless mac =~ /:\w{2}:/
|
75
|
-
ip = ip[1..-2] # (ip) -> ip
|
76
|
-
@arp_table.merge!(ip => mac) if iface
|
77
|
-
end
|
78
|
-
@arp_table
|
79
|
-
end
|
80
|
-
|
81
|
-
class << self
|
82
|
-
def my_ips
|
83
|
-
Socket.ip_address_list.select do |ip|
|
84
|
-
ip.ipv4_private? && !ip.ipv4_loopback?
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def my_lan_ip
|
89
|
-
IPAddr.new(my_ips.first.ip_address)
|
90
|
-
end
|
91
|
-
|
92
|
-
def local_mask
|
93
|
-
my_lan_ip.mask(NET_MASK)
|
70
|
+
def sweep
|
71
|
+
network.to_range.each do |ip|
|
72
|
+
@scan[ip] = []
|
73
|
+
scan_bot(ip)
|
94
74
|
end
|
75
|
+
@bots.each(&:join)
|
76
|
+
puts
|
77
|
+
@scan.reject! { |_k, v| v.empty? }
|
95
78
|
end
|
96
79
|
end
|
97
80
|
end
|
data/lib/hooray/version.rb
CHANGED
data/spec/hooray/node_spec.rb
CHANGED
@@ -7,10 +7,9 @@ describe 'Node' do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'should have a #to_ip' do
|
10
|
-
expect(Node.new(ip: '10.1.1.1').
|
10
|
+
expect(Node.new(ip: '10.1.1.1').ip).to be_a(IPAddr)
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
13
|
it 'should have mac address' do
|
15
14
|
expect(Node.new(mac: 'aa:cc:dd:ee:ff:gg').mac).to eq('aa:cc:dd:ee:ff:gg')
|
16
15
|
end
|
@@ -20,11 +19,9 @@ describe 'Node' do
|
|
20
19
|
end
|
21
20
|
|
22
21
|
it 'should have ports' do
|
23
|
-
|
24
22
|
end
|
25
23
|
|
26
24
|
it 'should have hoops' do
|
27
|
-
|
28
25
|
end
|
29
26
|
|
30
27
|
end
|
data/spec/hooray/seek_spec.rb
CHANGED
@@ -1,16 +1,32 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Seek' do
|
4
|
-
|
5
4
|
it 'should detect local ip' do
|
6
5
|
end
|
7
6
|
|
8
7
|
it 'should search local network' do
|
9
|
-
|
10
8
|
end
|
11
9
|
|
12
10
|
it 'should find nodes' do
|
13
|
-
|
14
11
|
end
|
15
12
|
|
13
|
+
describe 'Query' do
|
14
|
+
|
15
|
+
it 'should default to ICMP without port' do
|
16
|
+
expect(Seek.new('').ping_class).to eq(Net::Ping::External)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should accept ports as integers' do
|
20
|
+
expect(Seek.new('', '80').ports).to eq([80])
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should defaults to tcp for ports as integers' do
|
24
|
+
expect(Seek.new('', '80').ping_class).to eq(Net::Ping::TCP)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should accept protocol with port' do
|
28
|
+
expect(Seek.new('', '80', 'udp').ping_class).to eq(Net::Ping::UDP)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
16
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hooray
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcos Piccinini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -92,9 +92,9 @@ files:
|
|
92
92
|
- bin/hoo
|
93
93
|
- lib/hooray.rb
|
94
94
|
- lib/hooray/cli.rb
|
95
|
+
- lib/hooray/local.rb
|
95
96
|
- lib/hooray/node.rb
|
96
97
|
- lib/hooray/port.rb
|
97
|
-
- lib/hooray/scan.rb
|
98
98
|
- lib/hooray/seek.rb
|
99
99
|
- lib/hooray/settings.rb
|
100
100
|
- lib/hooray/settings/devices.yml
|
data/lib/hooray/scan.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
module Hooray
|
2
|
-
#
|
3
|
-
# Main runner
|
4
|
-
#
|
5
|
-
class Scan < Struct.new(:target, :ports, :opts)
|
6
|
-
def run
|
7
|
-
scan = []
|
8
|
-
bots = []
|
9
|
-
pa "Starting #{Settings.list} on '#{target}' #{ports}"
|
10
|
-
[ports].flatten.each do |port|
|
11
|
-
bots << Thread.new do
|
12
|
-
scan << ip if Net::Ping::TCP.new(ip.to_s, port, 1).ping?
|
13
|
-
end
|
14
|
-
end
|
15
|
-
bots.each(&:join)
|
16
|
-
scan
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|