hooray 0.0.9 → 0.1.5
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 +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
|