bettercap 1.1.9 → 1.1.10
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/CONTRIBUTING.md +2 -2
- data/TODO.md +5 -2
- data/bin/bettercap +19 -11
- data/lib/bettercap.rb +5 -1
- data/lib/bettercap/base/ifirewall.rb +2 -0
- data/lib/bettercap/base/ispoofer.rb +2 -0
- data/lib/bettercap/context.rb +5 -2
- data/lib/bettercap/discovery/{arp.rb → agents/arp.rb} +15 -14
- data/lib/bettercap/discovery/{base.rb → agents/base.rb} +4 -4
- data/lib/bettercap/discovery/{icmp.rb → agents/icmp.rb} +2 -3
- data/lib/bettercap/discovery/{udp.rb → agents/udp.rb} +2 -2
- data/lib/bettercap/{discovery.rb → discovery/discovery.rb} +8 -1
- data/lib/bettercap/factories/firewall_factory.rb +2 -0
- data/lib/bettercap/factories/parser_factory.rb +11 -5
- data/lib/bettercap/factories/spoofer_factory.rb +3 -1
- data/lib/bettercap/firewalls/linux.rb +2 -0
- data/lib/bettercap/firewalls/osx.rb +2 -0
- data/lib/bettercap/firewalls/redirection.rb +2 -1
- data/lib/bettercap/httpd/server.rb +2 -3
- data/lib/bettercap/logger.rb +27 -10
- data/lib/bettercap/monkey/packetfu/utils.rb +5 -5
- data/lib/bettercap/network.rb +26 -16
- data/lib/bettercap/options.rb +27 -6
- data/lib/bettercap/proxy/certstore.rb +4 -3
- data/lib/bettercap/proxy/module.rb +2 -2
- data/lib/bettercap/proxy/proxy.rb +5 -5
- data/lib/bettercap/proxy/request.rb +2 -2
- data/lib/bettercap/proxy/response.rb +2 -0
- data/lib/bettercap/proxy/stream_logger.rb +15 -3
- data/lib/bettercap/proxy/streamer.rb +3 -1
- data/lib/bettercap/proxy/thread_pool.rb +4 -2
- data/lib/bettercap/shell.rb +2 -0
- data/lib/bettercap/sniffer/parsers/base.rb +3 -12
- data/lib/bettercap/sniffer/parsers/custom.rb +21 -0
- data/lib/bettercap/sniffer/parsers/ftp.rb +2 -0
- data/lib/bettercap/sniffer/parsers/httpauth.rb +4 -5
- data/lib/bettercap/sniffer/parsers/https.rb +3 -4
- data/lib/bettercap/sniffer/parsers/irc.rb +2 -0
- data/lib/bettercap/sniffer/parsers/mail.rb +2 -0
- data/lib/bettercap/sniffer/parsers/ntlmss.rb +3 -3
- data/lib/bettercap/sniffer/parsers/post.rb +7 -7
- data/lib/bettercap/sniffer/parsers/url.rb +11 -11
- data/lib/bettercap/sniffer/sniffer.rb +8 -2
- data/lib/bettercap/spoofers/arp.rb +15 -5
- data/lib/bettercap/spoofers/none.rb +2 -0
- data/lib/bettercap/target.rb +29 -10
- data/lib/bettercap/update_checker.rb +2 -0
- data/lib/bettercap/version.rb +1 -1
- metadata +8 -40
- data/Rakefile +0 -7
- data/test/factories/firewall_factory_test.rb +0 -54
- data/test/factories/parser_factory_test.rb +0 -36
- data/test/factories/spoofer_factory_test.rb +0 -15
- data/test/firewalls/linux_firewall_test.rb +0 -72
- data/test/firewalls/osx_firewall_test.rb +0 -72
- data/test/helpers/mock_shell.rb +0 -17
- data/test/logger_test.rb +0 -12
- data/test/network_test.rb +0 -14
- data/test/pcap/ftp.pcap +0 -0
- data/test/pcap/http.pcap +0 -0
- data/test/pcap/packets.pcap +0 -0
- data/test/proxy/response_test.rb +0 -56
- data/test/shell_test.rb +0 -15
- data/test/sniffer/parsers/base_parser_test.rb +0 -20
- data/test/sniffer/parsers/ftp_parser_test.rb +0 -27
- data/test/sniffer/parsers/url_parser_test.rb +0 -25
- data/test/target_test.rb +0 -24
- data/test/test_helper.rb +0 -47
@@ -11,7 +11,7 @@ This project is released under the GPL 3 license.
|
|
11
11
|
=end
|
12
12
|
require 'bettercap/logger'
|
13
13
|
|
14
|
-
module
|
14
|
+
module BetterCap
|
15
15
|
class StreamLogger
|
16
16
|
@@MAX_REQ_SIZE = 50
|
17
17
|
|
@@ -23,12 +23,24 @@ class StreamLogger
|
|
23
23
|
}
|
24
24
|
|
25
25
|
def self.addr2s( addr )
|
26
|
-
|
26
|
+
ctx = Context.get
|
27
|
+
|
28
|
+
return 'local' if addr == ctx.ifconfig[:ip_saddr]
|
29
|
+
|
30
|
+
target = ctx.find_target addr, nil
|
27
31
|
return target.to_s_compact unless target.nil?
|
32
|
+
|
28
33
|
addr
|
29
34
|
end
|
30
35
|
|
31
|
-
def self.
|
36
|
+
def self.log_raw( pkt, label, payload )
|
37
|
+
nl = if label.include?"\n" then "\n" else " " end
|
38
|
+
label = label.strip
|
39
|
+
Logger.raw( "[#{self.addr2s(pkt.ip_saddr)} > #{self.addr2s(pkt.ip_daddr)}:#{pkt.tcp_dst}] " \
|
40
|
+
"[#{label.green}]#{nl}#{payload.strip.yellow}" )
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.log_http( is_https, client, request, response )
|
32
44
|
request_s = "#{is_https ? 'https' : 'http'}://#{request.host}#{request.url}"
|
33
45
|
response_s = "( #{response.content_type} )"
|
34
46
|
request_s = request_s.slice(0..@@MAX_REQ_SIZE) + '...' unless request_s.length <= @@MAX_REQ_SIZE
|
@@ -11,6 +11,7 @@ This project is released under the GPL 3 license.
|
|
11
11
|
=end
|
12
12
|
require 'bettercap/logger'
|
13
13
|
|
14
|
+
module BetterCap
|
14
15
|
module Proxy
|
15
16
|
class Streamer
|
16
17
|
def initialize( processor )
|
@@ -51,7 +52,7 @@ class Streamer
|
|
51
52
|
rescue Exception => e
|
52
53
|
Logger.debug e
|
53
54
|
end
|
54
|
-
|
55
|
+
|
55
56
|
elsif response.content_length.nil?
|
56
57
|
Logger.debug "Reading response body using 1024 bytes chunks ..."
|
57
58
|
|
@@ -169,3 +170,4 @@ class Streamer
|
|
169
170
|
|
170
171
|
end
|
171
172
|
end
|
173
|
+
end
|
@@ -12,6 +12,7 @@ This project is released under the GPL 3 license.
|
|
12
12
|
require 'thread'
|
13
13
|
|
14
14
|
# Tnx to Puma ThreadPool!
|
15
|
+
module BetterCap
|
15
16
|
module Proxy
|
16
17
|
class ThreadPool
|
17
18
|
|
@@ -62,10 +63,10 @@ class ThreadPool
|
|
62
63
|
#
|
63
64
|
# Must be called with @mutex held!
|
64
65
|
#
|
65
|
-
def spawn_thread
|
66
|
+
def spawn_thread
|
66
67
|
@spawned += 1
|
67
68
|
|
68
|
-
th = Thread.new do
|
69
|
+
th = Thread.new do
|
69
70
|
todo = @todo
|
70
71
|
block = @block
|
71
72
|
mutex = @mutex
|
@@ -199,3 +200,4 @@ class ThreadPool
|
|
199
200
|
end
|
200
201
|
end
|
201
202
|
end
|
203
|
+
end
|
data/lib/bettercap/shell.rb
CHANGED
@@ -9,29 +9,20 @@ Blog : http://www.evilsocket.net/
|
|
9
9
|
This project is released under the GPL 3 license.
|
10
10
|
|
11
11
|
=end
|
12
|
-
|
13
|
-
require 'colorize'
|
14
|
-
|
12
|
+
module BetterCap
|
15
13
|
class BaseParser
|
16
14
|
def initialize
|
17
15
|
@filters = []
|
18
16
|
@name = 'BASE'
|
19
17
|
end
|
20
18
|
|
21
|
-
def addr2s( addr )
|
22
|
-
target = Context.get.find_target addr, nil
|
23
|
-
return target.to_s_compact unless target.nil?
|
24
|
-
addr
|
25
|
-
end
|
26
|
-
|
27
19
|
def on_packet( pkt )
|
28
20
|
s = pkt.to_s
|
29
21
|
@filters.each do |filter|
|
30
22
|
if s =~ filter
|
31
|
-
|
32
|
-
"[#{@name}] ".green +
|
33
|
-
pkt.payload.strip.yellow
|
23
|
+
StreamLogger.log_raw( pkt, @name, pkt.payload )
|
34
24
|
end
|
35
25
|
end
|
36
26
|
end
|
37
27
|
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
BETTERCAP
|
4
|
+
|
5
|
+
Author : Simone 'evilsocket' Margaritelli
|
6
|
+
Email : evilsocket@gmail.com
|
7
|
+
Blog : http://www.evilsocket.net/
|
8
|
+
|
9
|
+
This project is released under the GPL 3 license.
|
10
|
+
|
11
|
+
=end
|
12
|
+
require 'bettercap/sniffer/parsers/base'
|
13
|
+
|
14
|
+
module BetterCap
|
15
|
+
class CustomParser < BaseParser
|
16
|
+
def initialize( filter )
|
17
|
+
@filters = [ filter ]
|
18
|
+
@name = 'DATA'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -13,6 +13,7 @@ require 'bettercap/sniffer/parsers/base'
|
|
13
13
|
require 'colorize'
|
14
14
|
require 'base64'
|
15
15
|
|
16
|
+
module BetterCap
|
16
17
|
class HttpauthParser < BaseParser
|
17
18
|
def on_packet( pkt )
|
18
19
|
lines = pkt.to_s.split("\n")
|
@@ -31,14 +32,12 @@ class HttpauthParser < BaseParser
|
|
31
32
|
decoded = Base64.decode64(encoded)
|
32
33
|
user, pass = decoded.split(':')
|
33
34
|
|
34
|
-
|
35
|
-
'[HTTP BASIC AUTH]'.green + " http://#{hostname}#{path} - username=#{user} password=#{pass}".yellow
|
35
|
+
StreamLogger.log_raw( pkt, '[HTTP BASIC AUTH]'.green + " http://#{hostname}#{path} - username=#{user} password=#{pass}".yellow )
|
36
36
|
|
37
37
|
elsif line =~ /Authorization:\s*Digest\s+(.+)/i
|
38
|
-
|
39
|
-
'[HTTP DIGEST AUTH]'.green + " http://#{hostname}#{path}\n#{$1}".yellow
|
40
|
-
|
38
|
+
StreamLogger.log_raw( pkt, '[HTTP DIGEST AUTH]'.green + " http://#{hostname}#{path}\n#{$1}".yellow )
|
41
39
|
end
|
42
40
|
end
|
43
41
|
end
|
44
42
|
end
|
43
|
+
end
|
@@ -13,6 +13,7 @@ require 'bettercap/sniffer/parsers/base'
|
|
13
13
|
require 'colorize'
|
14
14
|
require 'resolv'
|
15
15
|
|
16
|
+
module BetterCap
|
16
17
|
class HttpsParser < BaseParser
|
17
18
|
@@prev = nil
|
18
19
|
|
@@ -28,10 +29,7 @@ class HttpsParser < BaseParser
|
|
28
29
|
end
|
29
30
|
|
30
31
|
if @@prev.nil? or @@prev != hostname
|
31
|
-
|
32
|
-
'[HTTPS] '.green +
|
33
|
-
"https://#{hostname}/".yellow
|
34
|
-
|
32
|
+
StreamLogger.log_raw( pkt, 'HTTPS', "https://#{hostname}/" )
|
35
33
|
@@prev = hostname
|
36
34
|
end
|
37
35
|
end
|
@@ -40,3 +38,4 @@ class HttpsParser < BaseParser
|
|
40
38
|
end
|
41
39
|
end
|
42
40
|
end
|
41
|
+
end
|
@@ -11,9 +11,11 @@ This project is released under the GPL 3 license.
|
|
11
11
|
=end
|
12
12
|
require 'bettercap/sniffer/parsers/base'
|
13
13
|
|
14
|
+
module BetterCap
|
14
15
|
class IrcParser < BaseParser
|
15
16
|
def initialize
|
16
17
|
@filters = [ /NICK\s+.+/, /NS IDENTIFY\s+.+/, /nickserv :identify\s+.+/ ]
|
17
18
|
@name = 'IRC'
|
18
19
|
end
|
19
20
|
end
|
21
|
+
end
|
@@ -11,9 +11,11 @@ This project is released under the GPL 3 license.
|
|
11
11
|
=end
|
12
12
|
require 'bettercap/sniffer/parsers/base'
|
13
13
|
|
14
|
+
module BetterCap
|
14
15
|
class MailParser < BaseParser
|
15
16
|
def initialize
|
16
17
|
@filters = [ /(\d+ )?(auth|authenticate) ([a-z\-_0-9]+)/i ]
|
17
18
|
@name = 'MAIL'
|
18
19
|
end
|
19
20
|
end
|
21
|
+
end
|
@@ -12,6 +12,7 @@ This project is released under the GPL 3 license.
|
|
12
12
|
require 'bettercap/sniffer/parsers/base'
|
13
13
|
require 'colorize'
|
14
14
|
|
15
|
+
module BetterCap
|
15
16
|
class NtlmssParser < BaseParser
|
16
17
|
def bin2hex( data )
|
17
18
|
hex = ''
|
@@ -30,9 +31,8 @@ class NtlmssParser < BaseParser
|
|
30
31
|
s = pkt.to_s
|
31
32
|
if s =~ /NTLMSSP\x00\x03\x00\x00\x00.+/
|
32
33
|
# TODO: Parse NTLMSSP packet.
|
33
|
-
|
34
|
-
'[NTLMSS] '.green +
|
35
|
-
bin2hex( pkt.payload ).yellow
|
34
|
+
StreamLogger.log_raw( pkt, 'NTLMSS', bin2hex( pkt.payload ) )
|
36
35
|
end
|
37
36
|
end
|
38
37
|
end
|
38
|
+
end
|
@@ -12,13 +12,13 @@ This project is released under the GPL 3 license.
|
|
12
12
|
require 'bettercap/sniffer/parsers/base'
|
13
13
|
require 'colorize'
|
14
14
|
|
15
|
+
module BetterCap
|
15
16
|
class PostParser < BaseParser
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
"[POST]\n".green +
|
21
|
-
pkt.payload.strip.yellow
|
22
|
-
end
|
17
|
+
def on_packet( pkt )
|
18
|
+
s = pkt.to_s
|
19
|
+
if s =~ /POST\s+[^\s]+\s+HTTP.+/
|
20
|
+
StreamLogger.log_raw( pkt, "POST\n", pkt.payload )
|
23
21
|
end
|
22
|
+
end
|
23
|
+
end
|
24
24
|
end
|
@@ -12,17 +12,17 @@ This project is released under the GPL 3 license.
|
|
12
12
|
require 'bettercap/sniffer/parsers/base'
|
13
13
|
require 'colorize'
|
14
14
|
|
15
|
+
module BetterCap
|
15
16
|
class UrlParser < BaseParser
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
"http://#{host}#{url}".yellow
|
25
|
-
end
|
26
|
-
end
|
17
|
+
def on_packet( pkt )
|
18
|
+
s = pkt.to_s
|
19
|
+
if s =~ /GET\s+([^\s]+)\s+HTTP.+Host:\s+([^\s]+).+/m
|
20
|
+
host = $2
|
21
|
+
url = $1
|
22
|
+
if not url =~ /.+\.(png|jpg|jpeg|bmp|gif|img|ttf|woff|css|js).*/i
|
23
|
+
StreamLogger.log_raw( pkt, 'GET', "http://#{host}#{url}" )
|
24
|
+
end
|
27
25
|
end
|
26
|
+
end
|
27
|
+
end
|
28
28
|
end
|
@@ -14,6 +14,7 @@ require 'bettercap/factories/parser_factory'
|
|
14
14
|
require 'colorize'
|
15
15
|
require 'packetfu'
|
16
16
|
|
17
|
+
module BetterCap
|
17
18
|
class Sniffer
|
18
19
|
include PacketFu
|
19
20
|
|
@@ -87,12 +88,16 @@ class Sniffer
|
|
87
88
|
def self.setup( ctx )
|
88
89
|
@@ctx = ctx
|
89
90
|
|
90
|
-
|
91
|
+
unless @@ctx.options.sniffer_pcap.nil?
|
91
92
|
@@pcap = PcapFile.new
|
92
93
|
Logger.warn "Saving packets to #{@@ctx.options.sniffer_pcap} ."
|
93
94
|
end
|
94
95
|
|
95
|
-
|
96
|
+
if @@ctx.options.custom_parser.nil?
|
97
|
+
@@parsers = ParserFactory.load_by_names @@ctx.options.parsers
|
98
|
+
else
|
99
|
+
@@parsers = ParserFactory.load_custom @@ctx.options.custom_parser
|
100
|
+
end
|
96
101
|
|
97
102
|
@@cap = Capture.new(
|
98
103
|
iface: @@ctx.options.iface,
|
@@ -101,3 +106,4 @@ class Sniffer
|
|
101
106
|
)
|
102
107
|
end
|
103
108
|
end
|
109
|
+
end
|
@@ -16,6 +16,7 @@ require 'bettercap/network'
|
|
16
16
|
require 'bettercap/logger'
|
17
17
|
require 'colorize'
|
18
18
|
|
19
|
+
module BetterCap
|
19
20
|
class ArpSpoofer < ISpoofer
|
20
21
|
def initialize
|
21
22
|
@ctx = Context.get
|
@@ -52,7 +53,7 @@ class ArpSpoofer < ISpoofer
|
|
52
53
|
def start
|
53
54
|
Logger.info "Starting ARP spoofer ( #{@ctx.options.half_duplex ? 'Half' : 'Full'} Duplex ) ..."
|
54
55
|
|
55
|
-
stop()
|
56
|
+
stop() if @running
|
56
57
|
@running = true
|
57
58
|
|
58
59
|
@ctx.firewall.enable_forwarding(true) unless @forwarding
|
@@ -75,7 +76,7 @@ class ArpSpoofer < ISpoofer
|
|
75
76
|
# we're only interested in 'who-has' packets
|
76
77
|
if pkt.arp_opcode == 1 and pkt.arp_dst_mac.to_s == '00:00:00:00:00:00'
|
77
78
|
is_from_us = ( pkt.arp_src_ip.to_s == @ctx.ifconfig[:ip_saddr] )
|
78
|
-
|
79
|
+
unless is_from_us
|
79
80
|
Logger.info "[ARP] #{pkt.arp_src_ip.to_s} is asking who #{pkt.arp_dst_ip.to_s} is."
|
80
81
|
|
81
82
|
send_spoofed_packet pkt.arp_dst_ip.to_s, @ctx.ifconfig[:eth_saddr], pkt.arp_src_ip.to_s, pkt.arp_src_mac.to_s
|
@@ -109,16 +110,24 @@ class ArpSpoofer < ISpoofer
|
|
109
110
|
@ctx.targets.each do |target|
|
110
111
|
# targets could change, update mac addresses if needed
|
111
112
|
if target.mac.nil?
|
112
|
-
Logger.warn "Getting target #{target.ip} MAC address ..."
|
113
|
-
|
114
113
|
hw = Network.get_hw_address( @ctx.ifconfig, target.ip )
|
115
114
|
if hw.nil?
|
116
|
-
Logger.warn "Couldn't determine target MAC"
|
115
|
+
Logger.warn "Couldn't determine target #{ip} MAC!"
|
117
116
|
next
|
118
117
|
else
|
119
118
|
Logger.info " Target MAC : #{hw}"
|
120
119
|
target.mac = hw
|
121
120
|
end
|
121
|
+
# target was specified by MAC address
|
122
|
+
elsif target.ip_refresh
|
123
|
+
ip = Network.get_ip_address( @ctx, target.mac )
|
124
|
+
if ip.nil?
|
125
|
+
Logger.warn "Couldn't determine target #{target.mac} IP!"
|
126
|
+
next
|
127
|
+
else
|
128
|
+
Logger.info "Target #{target.mac} IP : #{ip}" if target.ip.nil? or target.ip != ip
|
129
|
+
target.ip = ip
|
130
|
+
end
|
122
131
|
end
|
123
132
|
|
124
133
|
send_spoofed_packet( @gateway.ip, @ctx.ifconfig[:eth_saddr], target.ip, target.mac )
|
@@ -159,3 +168,4 @@ class ArpSpoofer < ISpoofer
|
|
159
168
|
sleep 1
|
160
169
|
end
|
161
170
|
end
|
171
|
+
end
|
@@ -12,6 +12,7 @@ This project is released under the GPL 3 license.
|
|
12
12
|
require 'bettercap/base/ispoofer'
|
13
13
|
require 'bettercap/logger'
|
14
14
|
|
15
|
+
module BetterCap
|
15
16
|
class NoneSpoofer < ISpoofer
|
16
17
|
def initialize
|
17
18
|
Logger.warn 'Spoofing disabled.'
|
@@ -21,3 +22,4 @@ class NoneSpoofer < ISpoofer
|
|
21
22
|
|
22
23
|
def stop; end
|
23
24
|
end
|
25
|
+
end
|
data/lib/bettercap/target.rb
CHANGED
@@ -12,8 +12,9 @@ This project is released under the GPL 3 license.
|
|
12
12
|
require 'bettercap/logger'
|
13
13
|
require 'socket'
|
14
14
|
|
15
|
+
module BetterCap
|
15
16
|
class Target
|
16
|
-
attr_accessor :ip, :mac, :vendor, :hostname
|
17
|
+
attr_accessor :ip, :mac, :vendor, :hostname, :ip_refresh
|
17
18
|
|
18
19
|
NBNS_TIMEOUT = 30
|
19
20
|
NBNS_PORT = 137
|
@@ -23,11 +24,19 @@ class Target
|
|
23
24
|
@@prefixes = nil
|
24
25
|
|
25
26
|
def initialize( ip, mac=nil )
|
26
|
-
|
27
|
-
|
27
|
+
if Network.is_ip?(ip)
|
28
|
+
@ip = ip
|
29
|
+
@ip_refresh = false
|
30
|
+
else
|
31
|
+
@ip = nil
|
32
|
+
mac = ip
|
33
|
+
@ip_refresh = true
|
34
|
+
end
|
35
|
+
|
36
|
+
@mac = Target.normalized_mac(mac) unless mac.nil?
|
28
37
|
@vendor = Target.lookup_vendor(@mac) unless mac.nil?
|
29
38
|
@hostname = nil
|
30
|
-
@resolver = Thread.new { resolve! }
|
39
|
+
@resolver = Thread.new { resolve! } unless Context.get.options.no_target_nbns or @ip.nil?
|
31
40
|
end
|
32
41
|
|
33
42
|
def sortable_ip
|
@@ -35,12 +44,12 @@ class Target
|
|
35
44
|
end
|
36
45
|
|
37
46
|
def mac=(value)
|
38
|
-
@mac = normalized_mac
|
47
|
+
@mac = Target.normalized_mac(value)
|
39
48
|
@vendor = Target.lookup_vendor(@mac) if not @mac.nil?
|
40
49
|
end
|
41
50
|
|
42
51
|
def to_s
|
43
|
-
s = sprintf( '%-15s : %-17s', @ip, @mac )
|
52
|
+
s = sprintf( '%-15s : %-17s', if @ip.nil? then '???' else @ip end, @mac )
|
44
53
|
s += " / #{@hostname}" unless @hostname.nil?
|
45
54
|
s += if @vendor.nil? then " ( ??? )" else " ( #{@vendor} )" end
|
46
55
|
s
|
@@ -55,15 +64,24 @@ class Target
|
|
55
64
|
end
|
56
65
|
|
57
66
|
def equals?(ip, mac)
|
58
|
-
|
67
|
+
# compare by ip
|
68
|
+
if mac.nil?
|
69
|
+
return ( @ip == ip )
|
70
|
+
# compare by mac
|
71
|
+
elsif !@mac.nil? and ( @mac == mac )
|
72
|
+
Logger.info "Found IP #{ip} for target #{@mac}!" if @ip.nil?
|
73
|
+
@ip = ip
|
74
|
+
return true
|
75
|
+
end
|
76
|
+
false
|
59
77
|
end
|
60
78
|
|
61
|
-
|
62
|
-
|
63
|
-
def normalized_mac(v)
|
79
|
+
def self.normalized_mac(v)
|
64
80
|
v.split(':').map { |e| if e.size == 2 then e.upcase else "0#{e.upcase}" end }.join(':')
|
65
81
|
end
|
66
82
|
|
83
|
+
private
|
84
|
+
|
67
85
|
def resolve!
|
68
86
|
resp, sock = nil, nil
|
69
87
|
begin
|
@@ -103,3 +121,4 @@ private
|
|
103
121
|
@@prefixes[ mac.split(':')[0,3].join('').upcase ]
|
104
122
|
end
|
105
123
|
end
|
124
|
+
end
|