arp_scan 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -1
- data/README.md +2 -2
- data/arp_scan.gemspec +1 -1
- data/lib/arp_scan/arp_scanner.rb +8 -1
- data/lib/arp_scan/host.rb +9 -0
- data/lib/arp_scan/scan_report.rb +13 -0
- data/lib/arp_scan/scan_result_processor.rb +9 -0
- data/lib/arp_scan/version.rb +1 -1
- data/lib/arp_scan.rb +7 -3
- data/spec/arp_scan_spec.rb +2 -12
- data/spec/arp_scanner_spec.rb +7 -7
- data/spec/host_spec.rb +19 -12
- data/spec/scan_report_spec.rb +54 -38
- data/spec/scan_result_processor_spec.rb +35 -32
- data/spec/spec_helper.rb +1 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7b960cabf68bf289134ad75739ab76573745ed6
|
4
|
+
data.tar.gz: 9b5cce94f3350b24e70053d6e0e4aa8045436403
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42b6b7058c6dd4d2f5fbae4c0a3a3c0dca2f1fbf09bf52151f9c3a11191d0b43a06bbe927794611637a424155cae7924f671b501d51d8e536e7627633d976289
|
7
|
+
data.tar.gz: b9a8177864994bb4eef7993f638e1a6772f54ff5e4febe0211e691fb6a366c3b2700719a8a6f277f7a86717987dfd7624bff738e217f9e1f271e7a6ad478f496
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -24,8 +24,8 @@ should probably go with the `/etc/sudoers` method.
|
|
24
24
|
|
25
25
|
## Notes
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
There are some tests now, but output containing host names instead of IP
|
28
|
+
addresses will not be properly parsed. This might be fixed soon.
|
29
29
|
|
30
30
|
## Installation
|
31
31
|
|
data/arp_scan.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["mikebrodrigues@gmail.com"]
|
11
11
|
spec.summary = %q{A ruby wrapper for the arp-scan utility.}
|
12
12
|
spec.description = %q{Easily use the arp-scan utility from within your ruby programs.}
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "https://github.com/mikerodrigues/arp_scan"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
data/lib/arp_scan/arp_scanner.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require_relative './scan_result_processor'
|
2
2
|
|
3
3
|
module ARPScan
|
4
|
+
# This module manages finding the arp-scan binary and running the scan. It
|
5
|
+
# delegates the parsing of the scan results to the ScanResultProcessor module.
|
6
|
+
#
|
4
7
|
module ARPScanner
|
5
|
-
|
6
8
|
# I got this method from: http://stackoverflow.com/questions/2108727
|
7
9
|
# Cross-platform way of finding an executable in the $PATH.
|
8
10
|
#
|
9
11
|
# which('ruby') #=> /usr/bin/ruby
|
12
|
+
#
|
10
13
|
def self.which(cmd)
|
11
14
|
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
12
15
|
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
@@ -18,6 +21,10 @@ module ARPScan
|
|
18
21
|
return nil
|
19
22
|
end
|
20
23
|
|
24
|
+
# This method runs the actual scan by passing the arguments to the arp-scan
|
25
|
+
# binary. The results are passed to the ScanResultProcessor and a ScanReport
|
26
|
+
# is returned.
|
27
|
+
#
|
21
28
|
def self.scan(argument_string = nil)
|
22
29
|
result_string = `#{which 'arp-scan'} #{argument_string}`
|
23
30
|
ScanResultProcessor.process(result_string)
|
data/lib/arp_scan/host.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
module ARPScan
|
2
|
+
# Abstracts replying hosts from the arp-scan output.
|
3
|
+
#
|
2
4
|
class Host
|
3
5
|
attr_reader :ip_addr, :mac, :oui
|
4
6
|
|
7
|
+
# Create a new hsot. IP address, MAC address and OUI information are
|
8
|
+
# expected.
|
9
|
+
#
|
5
10
|
def initialize(ip_addr, mac, oui)
|
6
11
|
@ip_addr = ip_addr
|
7
12
|
@mac = mac
|
8
13
|
@oui = oui
|
9
14
|
end
|
10
15
|
|
16
|
+
# Returns a hash representation of the Host object.
|
17
|
+
#
|
11
18
|
def to_hash
|
12
19
|
{ :ip_addr => @ip_addr,
|
13
20
|
:mac => @mac,
|
@@ -15,6 +22,8 @@ module ARPScan
|
|
15
22
|
}
|
16
23
|
end
|
17
24
|
|
25
|
+
# Returns an array representation of the Host object.
|
26
|
+
#
|
18
27
|
def to_array
|
19
28
|
[ @ip_addr,
|
20
29
|
@mac,
|
data/lib/arp_scan/scan_report.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
module ARPScan
|
2
|
+
|
3
|
+
# This class abstracts the string output from arp-scan into an Object. A
|
4
|
+
# ScanReports are usually created through the ScanResultProcessor module.
|
5
|
+
#
|
2
6
|
class ScanReport
|
3
7
|
|
4
8
|
attr_reader :hosts, :interface, :datalink, :version, :range_size, :scan_time, :scan_rate, :reply_count
|
5
9
|
|
10
|
+
# Create a new scan report, passing in every attribute. The best way to do
|
11
|
+
# this is with the ScanResultProcessor module.
|
12
|
+
#
|
6
13
|
def initialize(hash)
|
7
14
|
@hosts = hash[:hosts]
|
8
15
|
@interface = hash[:interface]
|
@@ -14,6 +21,9 @@ module ARPScan
|
|
14
21
|
@reply_count = Integer(hash[:reply_count])
|
15
22
|
end
|
16
23
|
|
24
|
+
# Returns an array representation of the ScanReport. Metadata about the
|
25
|
+
# scan, and an array of Host arrays comprise the array.
|
26
|
+
#
|
17
27
|
def to_array
|
18
28
|
self.instance_variables.map do |var|
|
19
29
|
if var == :@hosts
|
@@ -24,6 +34,9 @@ module ARPScan
|
|
24
34
|
end
|
25
35
|
end
|
26
36
|
|
37
|
+
# Returns a hash representation of the ScanReport. Metadata about the scan,
|
38
|
+
# and array of Host hashes comprise the hash.
|
39
|
+
#
|
27
40
|
def to_hash
|
28
41
|
{ :hosts => @hosts.map {|host| host.to_hash},
|
29
42
|
:interface => @interface,
|
@@ -2,12 +2,21 @@ require_relative './host'
|
|
2
2
|
require_relative './scan_report'
|
3
3
|
|
4
4
|
module ARPScan
|
5
|
+
# This module is an interface for creating ScanReport objects from arp-scan
|
6
|
+
# output.
|
7
|
+
#
|
5
8
|
module ScanResultProcessor
|
6
9
|
|
10
|
+
# Regexes for parsing the arp-scan output.
|
11
|
+
#
|
7
12
|
Host_Entry_Regex = /(\d+.\d+.\d+.\d+)\s(\w\w:\w\w:\w\w:\w\w:\w\w:\w\w)\s(.*)/
|
8
13
|
Interface_Summary_Regex = /Interface: (?<interface>.+), datalink type: (?<datalink>.*$)/
|
9
14
|
Scan_Summary_Regex = /Ending arp-scan (?<version>.*): (?<range_size>.*) hosts scanned in (?<scan_time>.*) seconds \((?<scan_rate>.*) hosts\/sec\). (?<reply_count>.*) responded/
|
10
15
|
|
16
|
+
# This method does the actual processing of the arp-scan result string. It
|
17
|
+
# uses the Regexes to capture data then passes the results to ScanRepor.new
|
18
|
+
# to return a ScanReport object.
|
19
|
+
#
|
11
20
|
def self.process(string)
|
12
21
|
results = {}
|
13
22
|
results[:hosts] = string.scan(Host_Entry_Regex).map {|entry| Host.new(*entry)}
|
data/lib/arp_scan/version.rb
CHANGED
data/lib/arp_scan.rb
CHANGED
@@ -4,10 +4,14 @@ require_relative "./arp_scan/scan_report"
|
|
4
4
|
require_relative "./arp_scan/scan_result_processor"
|
5
5
|
require_relative "./arp_scan/host"
|
6
6
|
|
7
|
-
module
|
8
|
-
|
9
|
-
end
|
7
|
+
# This module just acts as a namespace for the gem.
|
8
|
+
#
|
9
|
+
module ARPScan; end
|
10
10
|
|
11
|
+
# The main interface for the gem. This method accepts arp-scan arguments in the
|
12
|
+
# form of a single string. Currently only IP addresses (no hostnames) are
|
13
|
+
# supported.
|
14
|
+
#
|
11
15
|
def ARPScan(argument_string = nil)
|
12
16
|
ARPScan::ARPScanner.scan argument_string
|
13
17
|
end
|
data/spec/arp_scan_spec.rb
CHANGED
@@ -1,18 +1,8 @@
|
|
1
|
-
require '../lib/arp_scan'
|
2
1
|
require_relative './spec_helper.rb'
|
3
2
|
|
4
3
|
RSpec.describe ARPScan do
|
5
4
|
report = ARPScan('-l')
|
6
|
-
|
7
|
-
|
8
|
-
expect(ARPScan('-l').class).to eq(ARPScan::ScanReport)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "returns a nested hash of attributes" do
|
12
|
-
expect(report.to_hash.class).to eq(Hash)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "returns a nested array of attributes" do
|
16
|
-
expect(report.to_array.class).to eq(Array)
|
5
|
+
it "is a method" do
|
6
|
+
expect(ARPScan.respond_to?('__send__')).to eq(true)
|
17
7
|
end
|
18
8
|
end
|
data/spec/arp_scanner_spec.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require '../lib/arp_scan'
|
2
1
|
require_relative './spec_helper'
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module ARPScan
|
4
|
+
describe ARPScanner do
|
5
|
+
describe "#scan" do
|
6
|
+
it "accepts arp-scan arguments as a string" do
|
7
|
+
expect(ARPScanner.scan('-l').class).to eq(ScanReport)
|
8
|
+
end
|
9
|
+
end
|
8
10
|
end
|
9
|
-
|
10
11
|
end
|
11
|
-
|
data/spec/host_spec.rb
CHANGED
@@ -1,20 +1,27 @@
|
|
1
|
-
require '../lib/arp_scan'
|
2
1
|
require_relative './spec_helper'
|
3
2
|
|
4
|
-
|
3
|
+
module ARPScan
|
4
|
+
describe Host do
|
5
5
|
|
6
|
-
|
6
|
+
host = Host.new('10.0.0.1', '00:11:22:33:44:55', "NIC Manufacturer")
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
describe "#ip_addr" do
|
9
|
+
it "returns the host's IP address" do
|
10
|
+
expect(host.ip_addr).to eq('10.0.0.1')
|
11
|
+
end
|
12
|
+
end
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
14
|
+
describe "#mac" do
|
15
|
+
it "returns the host's MAC address" do
|
16
|
+
expect(host.mac).to eq('00:11:22:33:44:55')
|
17
|
+
end
|
18
|
+
end
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
describe "#oui" do
|
21
|
+
it "returns the host's OUI information" do
|
22
|
+
expect(host.oui).to eq('NIC Manufacturer')
|
23
|
+
end
|
24
|
+
end
|
19
25
|
|
26
|
+
end
|
20
27
|
end
|
data/spec/scan_report_spec.rb
CHANGED
@@ -1,52 +1,68 @@
|
|
1
|
-
require '../lib/arp_scan'
|
2
1
|
require_relative './spec_helper'
|
3
2
|
|
4
|
-
|
3
|
+
module ARPScan
|
4
|
+
describe ScanReport do
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
report_hash = {
|
7
|
+
:hosts => [Host.new(*['10.0.0.1', '00:11:22:33:44:55', 'NIC Manufacturer'])],
|
8
|
+
:interface => "eth0",
|
9
|
+
:datalink => "EN10MB (Ethernet)",
|
10
|
+
:version => "1.8.1",
|
11
|
+
:range_size => 256,
|
12
|
+
:scan_time => 1.503,
|
13
|
+
:scan_rate => 170.33,
|
14
|
+
:reply_count => 1
|
15
|
+
}
|
16
16
|
|
17
|
-
|
17
|
+
scan_report = ScanReport.new(report_hash)
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
describe "#hosts" do
|
20
|
+
it "returns an Array of Host objects" do
|
21
|
+
expect(scan_report.hosts.class).to eq(Array)
|
22
|
+
expect(scan_report.hosts.first.class).to eq(Host)
|
23
|
+
end
|
24
|
+
end
|
22
25
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
+
describe "#interface" do
|
27
|
+
it "returns the network interface used to scan" do
|
28
|
+
expect(scan_report.interface).to eq("eth0")
|
29
|
+
end
|
30
|
+
end
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
32
|
+
describe "#datalink" do
|
33
|
+
it "returns the datalink type of the network interface used to scan" do
|
34
|
+
expect(scan_report.datalink).to eq('EN10MB (Ethernet)')
|
35
|
+
end
|
36
|
+
end
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
|
38
|
+
describe "#version" do
|
39
|
+
it "returns the version of `arp-scan` used for the scan" do
|
40
|
+
expect(scan_report.version).to eq('1.8.1')
|
41
|
+
end
|
42
|
+
end
|
34
43
|
|
35
|
-
|
36
|
-
|
37
|
-
|
44
|
+
describe "#range_size" do
|
45
|
+
it "returns the size of the range of scanned IPs" do
|
46
|
+
expect(scan_report.range_size).to eq(256)
|
47
|
+
end
|
48
|
+
end
|
38
49
|
|
39
|
-
|
40
|
-
|
41
|
-
|
50
|
+
describe "#scan_time" do
|
51
|
+
it "returns the duration of the scan in seconds" do
|
52
|
+
expect(scan_report.scan_time).to eq(1.503)
|
53
|
+
end
|
54
|
+
end
|
42
55
|
|
43
|
-
|
44
|
-
|
45
|
-
|
56
|
+
describe "#scan_rate" do
|
57
|
+
it "returns the scan rate in hosts per second" do
|
58
|
+
expect(scan_report.scan_rate).to eq(170.33)
|
59
|
+
end
|
60
|
+
end
|
46
61
|
|
47
|
-
|
48
|
-
|
62
|
+
describe "#reply_count" do
|
63
|
+
it "returns the number of hosts that responded" do
|
64
|
+
expect(scan_report.reply_count).to eq(1)
|
65
|
+
end
|
66
|
+
end
|
49
67
|
end
|
50
|
-
|
51
|
-
|
52
68
|
end
|
@@ -1,45 +1,48 @@
|
|
1
|
-
require '../lib/arp_scan'
|
2
1
|
require_relative './spec_helper'
|
3
2
|
|
4
|
-
|
3
|
+
module ARPScan
|
4
|
+
describe ScanResultProcessor do
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
it "processes arp-scan output to create a ScanReport object" do
|
10
|
-
expect(report.class).to eq(ARPScan::ScanReport)
|
11
|
-
end
|
6
|
+
report_string = File.read './test_output.txt'
|
7
|
+
report = ARPScan::ScanResultProcessor.process(report_string)
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
|
9
|
+
describe "#process" do
|
10
|
+
it "processes arp-scan output to create a ScanReport object" do
|
11
|
+
expect(report.class).to eq(ARPScan::ScanReport)
|
12
|
+
end
|
16
13
|
|
17
|
-
it "parses the scan interface name" do
|
18
|
-
expect(report.interface).to eq("eth0")
|
19
|
-
end
|
20
14
|
|
21
|
-
|
22
|
-
|
23
|
-
|
15
|
+
it "builds an array of Host objects" do
|
16
|
+
expect(report.hosts[0].class).to eq(ARPScan::Host)
|
17
|
+
end
|
24
18
|
|
25
|
-
|
26
|
-
|
27
|
-
|
19
|
+
it "parses the scan interface name" do
|
20
|
+
expect(report.interface).to eq("eth0")
|
21
|
+
end
|
28
22
|
|
29
|
-
|
30
|
-
|
31
|
-
|
23
|
+
it "parses the datalink type information" do
|
24
|
+
expect(report.datalink).to eq("EN10MB (Ethernet)")
|
25
|
+
end
|
32
26
|
|
33
|
-
|
34
|
-
|
35
|
-
|
27
|
+
it "parses the version of arp-scan that ran the scan" do
|
28
|
+
expect(report.version).to eq('1.8.1')
|
29
|
+
end
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
it "parses the number of hosts scanned" do
|
32
|
+
expect(report.range_size).to eq(256)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "parses the duration of the scan in seconds" do
|
36
|
+
expect(report.scan_time).to eq(1.494)
|
37
|
+
end
|
40
38
|
|
41
|
-
|
42
|
-
|
39
|
+
it "parses the rate of the scan in hosts per second" do
|
40
|
+
expect(report.scan_rate).to eq(171.35)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "parses the number of hosts that responded to the scan" do
|
44
|
+
expect(report.reply_count).to eq(1)
|
45
|
+
end
|
46
|
+
end
|
43
47
|
end
|
44
48
|
end
|
45
|
-
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require '../lib/arp_scan'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arp_scan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Rodrigues
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-09-
|
11
|
+
date: 2014-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -62,7 +62,7 @@ files:
|
|
62
62
|
- spec/scan_result_processor_spec.rb
|
63
63
|
- spec/spec_helper.rb
|
64
64
|
- spec/test_output.txt
|
65
|
-
homepage:
|
65
|
+
homepage: https://github.com/mikerodrigues/arp_scan
|
66
66
|
licenses:
|
67
67
|
- MIT
|
68
68
|
metadata: {}
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
82
|
version: '0'
|
83
83
|
requirements: []
|
84
84
|
rubyforge_project:
|
85
|
-
rubygems_version: 2.
|
85
|
+
rubygems_version: 2.4.1
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
88
|
summary: A ruby wrapper for the arp-scan utility.
|