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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe7164b3a564dbaca837819687bd21014d190564
4
- data.tar.gz: 61f8f487a6570d32013f26895f0015060147abd8
3
+ metadata.gz: 26b25f88e85a64e4c69b0f9329a054dc35bf0c35
4
+ data.tar.gz: 3c57622a6c1f3aa1258d910f9c8c36f187c0dbad
5
5
  SHA512:
6
- metadata.gz: 63de61f3a84464c2b0c3370fc9de0398b09d8927a097ff090b6305ae74ffb46f87f83fc8fc776bff7debf5e0002e01d19143f939f7855a5eb40fcaef7b6bdff6
7
- data.tar.gz: 9ac80ce35d020fe3cc43576738e43ae75e7a458311882fea80867273fb386af99a622215a678d61d5aa21430ad2278e2ad072421499073dff3faa5c93e56462f
6
+ metadata.gz: 3cf3772c8c087e120bfcefbc06a6a081d1040a932b941f6a5c95127045ccb9f051064afd6d85269ea65f8d2f394306399d8d65922eb75186fb29bec52d1332b0
7
+ data.tar.gz: 584abd5fe3d7c4ae8a017f0abb241f87123003346335f6bef794fde4cd775062ca1674d4653484a8a603894f7290c4078c7e4ea24216560aa1325b0bc1df0681
data/README.md CHANGED
@@ -49,6 +49,7 @@ Or simply by ports:
49
49
  ```
50
50
  hoo list 80
51
51
  hoo list 6777 udp
52
+ hoo list 3000 4000 5000
52
53
  ```
53
54
 
54
55
  ## Monitor
@@ -9,6 +9,7 @@ require 'paint/pa'
9
9
  require 'table_print'
10
10
 
11
11
  require 'hooray/settings'
12
+ require 'hooray/local'
12
13
  require 'hooray/node'
13
14
  require 'hooray/port'
14
15
  require 'hooray/seek'
@@ -37,8 +37,12 @@ module Hooray
37
37
 
38
38
  LONG
39
39
  def list(*filter)
40
- pa "Listing devices * #{filter}", :red
41
- print_table Seek.new(options[:network], *filter).nodes
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
- tp nodes, :name, :ip, :mac
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
- pa "#{nodes.count} devices @ #{Time.now} #{took}s", '#777', :bold
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)
@@ -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
@@ -4,10 +4,17 @@ module Hooray
4
4
  attr_accessor :host, :name, :nick, :mac, :ip, :ports
5
5
 
6
6
  def initialize(params = {})
7
- @ip = params[:ip]
7
+ self.ip = params[:ip]
8
8
  @mac = params[:mac]
9
- @mac ||= Mac.addr if @ip == Seek.my_lan_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 to_ip
23
- IPAddr.new(ip)
29
+ def ports
30
+ @ports.sort.map(&:number).join(', ')
24
31
  end
25
32
 
26
33
  def <=>(other)
@@ -6,5 +6,13 @@ module Hooray
6
6
  def name
7
7
  @name || Settings.services[number][protocol]
8
8
  end
9
+
10
+ def <=>(other)
11
+ number <=> other.number
12
+ end
13
+
14
+ def to_s
15
+ "#{number}/#{protocol}"
16
+ end
9
17
  end
10
18
  end
@@ -3,95 +3,78 @@ module Hooray
3
3
  # Main runner
4
4
  #
5
5
  class Seek
6
- attr_accessor :network, :opts, :nodes
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
- @network = network || Seek.local_mask
13
- set_query(params)
14
- set_nodes
12
+ @scan = {}
13
+ @bots = []
14
+ config_network network
15
+ config_filters params
15
16
  end
16
- alias_method :devices, :nodes
17
17
 
18
- #
19
- # Form need params based on user input
20
- #
21
- def set_query(params)
22
- return if params.empty?
23
- ports, words = params.flatten.partition { |s| s =~ /\d+/ }
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 set_nodes
35
- @nodes = ping.sort.map do |n|
36
- Node.new(ip: n, mac: arp_table[n.to_s]) # , name: find_name(n))
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 @protocol
42
- @protocol =~ /udp/ ? Net::Ping::UDP : Net::Ping::TCP
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
- # fast -> -sn -PA
47
- #
48
- def ping
49
- scan = []
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
- # ARP Table reader
68
+ # fast -> -sn -PA
68
69
  #
69
- def arp_table
70
- return @arp_table if @arp_table
71
- @arp_table ||= {}
72
- `arp -na`.split(/\n/).each do |l|
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
@@ -1,4 +1,4 @@
1
1
  # Hooray version
2
2
  module Hooray
3
- VERSION = '0.0.9'
3
+ VERSION = '0.1.5'
4
4
  end
@@ -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').to_ip).to be_a(IPAddr)
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
@@ -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.0.9
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 00:00:00.000000000 Z
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
@@ -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