diff options
Diffstat (limited to 'lib/network/monitor.pm')
-rw-r--r-- | lib/network/monitor.pm | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/lib/network/monitor.pm b/lib/network/monitor.pm index c0ed8f8..7cd1277 100644 --- a/lib/network/monitor.pm +++ b/lib/network/monitor.pm @@ -31,28 +31,41 @@ sub list_wireless { if ($results && $list) { #- bssid / frequency / signal level / flags / ssid while ($results =~ /^((?:[0-9a-f]{2}:){5}[0-9a-f]{2})\t(\d+)\t(\d+)\t(.*?)\t(.*)$/mg) { + my ($ap, $frequency, $signal_strength, $flags, $essid) = ($1, $2, $3, $4, $5); + $networks{$ap}{ap} ||= $ap; #- wpa_supplicant may list the network two times, use ||= - $networks{$1}{frequency} ||= $2; + $networks{$ap}{frequency} ||= $frequency; #- signal level is really too high in wpa_supplicant #- this should be standardized at some point - $networks{$1}{signal_level} ||= int($3/3.5); - $networks{$1}{flags} ||= $4; - $networks{$1}{essid} ||= $5 if $5 ne '<hidden>'; + $networks{$ap}{signal_strength} ||= int($signal_strength/3.5); + my $adhoc = $flags =~ s/\[ibss\]//i; + $networks{$ap}{mode} ||= $adhoc ? "Ad-Hoc" : "Managed"; + $networks{$ap}{flags} ||= $flags; + $networks{$ap}{essid} ||= $essid; } #- network id / ssid / bssid / flags while ($list =~ /^(\d+)\t(.*?)\t(.*?)\t(.*)$/mg) { - if (my $net = $networks{$3} || find { $_->{essid} eq $2 } values(%networks)) { + foreach my $net (uniq(if_($networks{$3}, $networks{$3}), grep { $_->{essid} eq $2 } values(%networks))) { + $net->{ap} = $3 if $3 ne 'any'; $net->{id} = $1; $net->{essid} ||= $2; $net->{current} = to_bool($4 eq '[CURRENT]'); } } - } elsif ($o_intf) { + } else { #- else use iwlist - my $current_essid = chomp_(`/sbin/iwgetid -r $o_intf`); - my $current_ap = lc(chomp_(`/sbin/iwgetid -r -a $o_intf`)); - my @list = `/sbin/iwlist $o_intf scanning`; + require network::connection::wireless; + my ($current_essid, $current_ap) = network::connection::wireless::get_access_point($o_intf); + if ($o_intf && !$> && !`/sbin/ip link show $o_intf up`) { + system("/sbin/ip link set $o_intf up"); + } + my @list = `/sbin/iwlist $o_intf scanning 2>/dev/null`; my $net = {}; + my $quality_match = qr/Quality[:=](\S*)/; + my $eval_quality = sub { + my ($qual) = @_; + $qual =~ m!/! ? eval($qual)*100 : $qual; + }; foreach (@list) { if ((/^\s*$/ || /Cell/) && exists $net->{ap}) { $net->{current} = to_bool($net->{essid} && $net->{essid} eq $current_essid || $net->{ap} eq $current_ap); @@ -62,16 +75,23 @@ sub list_wireless { /Address: (.*)/ and $net->{ap} = lc($1); /ESSID:"(.*?)"/ and $net->{essid} = $1; /Mode:(\S*)/ and $net->{mode} = $1; - if (m!Quality[:=](\S*)/!) { - my $qual = $1; - $net->{signal_level} = $qual =~ m!/! ? eval($qual)*100 : $qual; - } - /Extra:wpa_ie=/ and $net->{flags} = '[WPA]'; + $_ =~ $quality_match and $net->{signal_strength} = $eval_quality->($1); + m|Signal level:([0-9]+/[0-9]+)| && !$net->{signal_strength} and $net->{signal_strength} = eval($1)*100; + /Extra:wpa_ie=|IE:.*WPA/ and $net->{flags} = '[WPA]'; /key:(\S*)\s/ and $net->{flags} ||= $1 eq 'on' && '[WEP]'; } + if ($current_ap && exists $networks{$current_ap}) { + foreach (`/sbin/iwconfig $o_intf 2>/dev/null`) { + my $quality = $_ =~ $quality_match && $eval_quality->($1); + $networks{$current_ap}{signal_strength} = $quality if $quality; + } + } } - $networks{$_}{approx_level} = 20 + min(80, int($networks{$_}{signal_level}/20)*20) foreach keys %networks; + foreach (values %networks) { + $_->{essid} eq '<hidden>' and undef $_->{essid}; + $_->{name} = $_->{essid} || "[$_->{ap}]"; + } (\%networks, $has_roaming); } |