Skip to content

Instantly share code, notes, and snippets.

@qoobaa
Created October 10, 2009 23:34
Show Gist options
  • Save qoobaa/207243 to your computer and use it in GitHub Desktop.
Save qoobaa/207243 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require "rubygems"
require "daemons"
INTERFACE = "wlan0"
TEST_ADDRESSES = %w(http://www.google.pl/ http://www.yahoo.com/ http://www.msn.com/)
TEST_TIMEOUT = 5
SCAN_TIMEOUT = 1
CONNECTION_TIMEOUT = 30
LOOP_DELAY = 60
IP_RANGE = "10.2.1.*"
MAC_ADDRESSES_FILE = "/home/kuba/macswapper/mac_addresses"
def change_mac(mac_address)
`ifconfig #{INTERFACE} hw ether #{mac_address}`
end
def network_manager(command)
`dbus-send --print-reply --system --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.#{command}`
end
def dump_arp_table
`nmap -sP -n #{IP_RANGE}`.scan(/(?:[a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}/)
end
def connection_to(address)
result = `curl -sm#{TEST_TIMEOUT} #{address}`
result if $?.exitstatus.zero?
end
def ping_scan
[].tap do |mac_addresses|
IP_ADDRESSES.each_slice(MAX_PROCESSES) do |ip_addresses|
threads = ip_addresses.map { |ip_address| Thread.new { arping(ip_address) } }
threads.map(&:value).each { |mac_address| mac_addresses << mac_address if mac_address }
end
end
end
def load_mac_address_tables
open(MAC_ADDRESSES_FILE) do |file|
file.readlines.map do |line|
tries, mac_address = line.split(" ").reverse
[tries.to_i, mac_address]
end
end
end
def save_mac_address_tables(mac_address_tables)
open(MAC_ADDRESSES_FILE, "w") do |file|
file.puts(mac_address_tables.sort.reverse.map { |mac_address_table| mac_address_table.reverse.join(" ").downcase } )
end
end
def connection_working?
TEST_ADDRESSES.map { |address| connection_to(address) }.compact.uniq.size == TEST_ADDRESSES.size
end
def reconnect(mac_address_tables)
mac_address_tables.sort.reverse.find do |mac_address_table|
network_manager("sleep")
change_mac(mac_address_table[1])
network_manager("wake")
sleep(CONNECTION_TIMEOUT)
connection_working?.tap do |working|
mac_address_table[0] += working ? 1 : -1
save_mac_address_tables(mac_address_tables)
end
end
end
def add_new_mac_addresses(mac_address_tables)
dump_arp_table.each do |mac_address|
mac_address_tables << [0, mac_address.downcase] unless mac_address_tables.find do |mac_address_table|
mac_address_table.last.downcase == mac_address.downcase
end
end
save_mac_address_tables(mac_address_tables)
end
Daemons.run_proc("macswapper.rb") do
mac_address_tables = load_mac_address_tables
loop do
if connection_working?
add_new_mac_addresses(mac_address_tables)
else
reconnect(mac_address_tables)
end
sleep(LOOP_DELAY)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment