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 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