Class: Lanet::Scanner

Inherits:
Object
  • Object
show all
Defined in:
lib/lanet/scanner.rb

Constant Summary collapse

COMMON_PORTS =
{
  21 => "FTP",
  22 => "SSH",
  23 => "Telnet",
  25 => "SMTP",
  80 => "HTTP",
  443 => "HTTPS",
  3389 => "RDP",
  5900 => "VNC",
  8080 => "HTTP-ALT",
  137 => "NetBIOS",
  139 => "NetBIOS",
  445 => "SMB",
  1025 => "RPC",
  8443 => "HTTPS-ALT"
}.freeze
QUICK_CHECK_PORTS =
[80, 443, 22, 445, 139, 8080].freeze

Instance Method Summary collapse

Constructor Details

#initializeScanner

Returns a new instance of Scanner.



30
31
32
33
34
# File 'lib/lanet/scanner.rb', line 30

def initialize
  @hosts = []
  @mutex = Mutex.new
  @arp_cache = {}
end

Instance Method Details

#scan(cidr, timeout = 1, max_threads = 32, verbose = false) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/lanet/scanner.rb', line 36

def scan(cidr, timeout = 1, max_threads = 32, verbose = false)
  @verbose = verbose
  @timeout = timeout
  @hosts = []
  range = IPAddr.new(cidr).to_range
  queue = Queue.new
  range.each { |ip| queue << ip.to_s }
  total_ips = queue.size
  completed = 0

  # Initial ARP cache population
  @arp_cache = parse_arp_table

  threads = Array.new([max_threads, total_ips].min) do
    Thread.new do
      loop do
        begin
          ip = queue.pop(true)
        rescue ThreadError
          break
        end
        scan_host(ip)
        @mutex.synchronize do
          completed += 1
          if total_ips < 100 || (completed % 10).zero? || completed == total_ips
            print_progress(completed, total_ips)
          end
        end
      end
    end
  end

  # Periodically update ARP cache
  arp_updater = Thread.new do
    while threads.any?(&:alive?)
      sleep 5
      @mutex.synchronize { @arp_cache = parse_arp_table }
    end
  end

  begin
    threads.each(&:join)
    print_progress(total_ips, total_ips)
    puts "\nScan complete. Found #{@hosts.size} active hosts."
    @verbose ? @hosts : @hosts.map { |h| h[:ip] }
  rescue Interrupt
    puts "\nScan interrupted. Returning partial results..."
    @verbose ? @hosts : @hosts.map { |h| h[:ip] }
  ensure
    arp_updater.kill if arp_updater.alive?
  end
end