При огранизации соединения между несколькими компьютерами посредством Wi-Fi часто возникает необходимость оценить качество приёма в различных точках помещения. А если говорить об организации Wi-Fi-моста и/или настройке направленных антенн то необходимо ещё учитывать соседние Wi-Fi-точки.
Полноценное исследование эфира требует достаточно высоких затрат, которые обычно не оправданы. Чаще всего просто нужен сканер эфира, который показывает доступные точки и качество их сигнала. Для смартфонов таких приложений существует великое множество, а вот под Linux кроме громоздкого Kismet ничего подходящего найти не удалось. В итоге оказалось проще написать свой инструмент.
Основная идея при написании своего инструмента заключалась в том, что вся необходимая информация содержится в выводе команды:
iwlist wlan0 scan
Но вывод этой команды не удобен для восприятия. В итоге было решено написать скрипт, который в бесконечном цикле будет запускать эту команду, парсить её вывод и отображать результат. Листинг полученного скрипта:
#!/usr/bin/perl use strict; use warnings; use diagnostics; use Math::Round; # Если число аргументов не равно единице if (@ARGV != 1) { # Печатаем краткую справку print "Usage:\n"; print " $0 ifname\n\n"; # Завершаем работу exit; } # Будем использовать полученные данные для очистки экрана в дальнейшем my $clear_screen = `clear`; # Получаем имя интерфейса my $ifname = shift; while (1) { # Сканируем эфир my $scan_result = `iwlist $ifname scan`; # Получаем код ошибки my $error_code = $?; # Завершаем работу если что-то не так exit if $error_code; # Наскорую руку разбиваем результат сканирования на элементы my @scan_results_tmp = split /Cell \d+/is, $scan_result; # Начинаем полноценный разбор my @scan_results = (); # Перебираем элементы foreach my $hotspot_line (@scan_results_tmp) { # Если нет номера канала значит это мусор, который надо пропустить next if $hotspot_line !~ m{Channel\:}is; # Строим элемент my %hotspot = (); # Номер канала $hotspot{'Channel'} = $hotspot_line; $hotspot{'Channel'} =~ s{^.+Channel\:(\d+).+$}{$1}is; # SSID $hotspot{'SSID'} = $hotspot_line; $hotspot{'SSID'} =~ s{^.+ESSID\:"((.+?)?)".+$}{$1}is; # Наличие шифрований $hotspot{'Crypted'} = $hotspot_line; $hotspot{'Crypted'} =~ s{^.+Encryption key:(\w+?)\s.+$}{$1}is; # Уровень сигнала. И сразу переводим его в проценты my $q1 = $hotspot_line; $q1 =~ s{^.+Quality=(\d+)/\d+.+$}{$1}is; my $q2 = $hotspot_line; $q2 =~ s{^.+Quality=\d+/(\d+).+$}{$1}is; $hotspot{'Quality'} = round($q1 * 100 / $q2); push @scan_results, \%hotspot; } # Сортируем @scan_results = sort { sprintf("%02d", $a->{Channel}) cmp sprintf("%02d", $b->{Channel}) } @scan_results; # Очищаем экран print $clear_screen; # Печатаем данные print sprintf(" % 2.2s [% 9.9s] [% 32.32s] [% 7.7s]\n", "Ch", "Quality", "SSID", "Crypt"); print sprintf('%1$s'x61 . "\n", "-"); foreach my $hotspot (@scan_results) { print sprintf(" %02d [% 8d%%] [% 32.32s] [% 7.7s]\n", $hotspot->{Channel}, $hotspot->{Quality}, $hotspot->{SSID}, $hotspot->{Crypted}); } # Делаем паузу sleep 1; }
Скрипт принимает один единственный параметр: имя интерфейса, на котором надо осуществлять мониторинг. Например так:
./wifiscan.pl wlan2
Вывод скрипта выглядит примерно так:
Ch [ Quality] [ SSID] [ Crypt] ------------------------------------------------------------- 01 [ 93%] [ Yuldash House] [ on] 02 [ 94%] [ serr_dom] [ on] 04 [ 94%] [ home-of-moose] [ on] 06 [ 93%] [ wifi.tattele.com] [ off] 06 [ 93%] [ KEENETIC 4G] [ on] 06 [ 94%] [ MTS_telefon_2-65-60-30] [ on] 06 [ 94%] [ home.net] [ on] 08 [ 93%] [ YOTA] [ on] 10 [ 93%] [ Estucador] [ on] 10 [ 93%] [ DIR-300NRUB6] [ on]
Если нужны будут какие-то другие параметры то их получение и отображение легко дописать в скрипт. Автор использовал этот скрипт при эксприментах с баночными антеннами и с помощью этого скрипта смог найти нужное направление на необходимую точку.
На этом всё. Приятной работы!
oermolaev 2013-05-20 23:51:05 (#)