Class: IWList

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

Constant Summary collapse

@@IWList_block =

The regex used for extracting each AP’s data from the output of iwlist.

%r{
\s+  Cell \s (\d+) \s - \s Address: \s 
  ((?:[A-Z0-9][A-Z0-9]:?)+)  # two hex digits, followed by possible colon, as much as possible
\s+  ESSID:"([^"]+)"  (\[\d+\])?     # the essid index might not be there.
\s+  Protocol:([^\n]+)  # Everything up to end of line.
\s+  Mode: ([^\n]+)
\s+  Channel:(\d+)
\s+  Encryption \s key:(on|off)
\s+  Bit \s Rates:(.*?)     # This will be parsed out later
\s+  Quality:(\d+)
\s+  Signal \s level:(\d+)
\s+  Noise \s level:(\d+)
\s+  (IE: .*? )?     # I'll worry about this later.
\s+  Extra: \s Last \s beacon: \s (\d+)ms \s ago
}mx

Class Method Summary collapse

Class Method Details

.scan(interface, options = {}) ⇒ Object

Runs “iwlist interface scan” in a subshell and returns a list of hashes.

The first parameter should be "ethN" or "wlanN" where N is a number. The second parameter is a hash of options. The possible keys are:

* :bin - The full path to the iwlist program; defaults to <tt>'/usr/sbin/iwlist'</tt>
* :test_io - An IO instance to read from, instead of running iwlist

NOTE! IWLIST MUST BE RUN AS ROOT. TREAT USER INPUT WITH CARE. If you get no results, it’s probably because you aren’t running as root.

Raises InvalidInterface exception if the first parameter doesn’t look like a reasonable interface.



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
# File 'lib/iwlist.rb', line 36

def self.scan(interface, options = {})

  if interface !~ /^(eth|wlan)\d+$/  # Is someone playing games?
    raise InvalidInterface
  end

  iwlist_output = ""
  iwlist_command = "/usr/sbin/iwlist" || options[:bin]

  if options[:test_io]      # To allow for testing.
    iwlist_output = options[:test_io].gets(nil)
  else
    IO.popen(iwlist_command + " " + interface + " scan") do |pipe|
      iwlist_output = pipe.gets(nil)
    end
  end

  aps = iwlist_output.scan(@@IWList_block).collect {|m|
    ap = AP.new()
    self.order().each_with_index do |name, i|
      value = m[i]
  
      # Bitrates is a list of 'number Mb/s;'.  This is to simplify the IWList_block regex
      if name == :bitrates
        value = value.scan(%r{[0-9.]+ Mb/s;?})
        value.collect! do |rate|
          rate =~ /([0-9.]+)/
          $1.to_f
        end
      end
  
      # Convert numbers.
      if value =~ /^(\d+)$/
        value = value.to_i
      end

      ap.send(name.to_s + "=", value)
    end
    ap
  }
  return aps
end