summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Blin <oblin@mandriva.org>2005-09-15 03:29:57 +0000
committerOlivier Blin <oblin@mandriva.org>2005-09-15 03:29:57 +0000
commit0846262df5150042d38accad44bb805cbc4945b6 (patch)
treed056db51f2224abcefe5f4732dfedbdcbb7028ee
parentffff9155cd2053d7ec926cc884c413ff6fe7ee5e (diff)
downloaddrakx-0846262df5150042d38accad44bb805cbc4945b6.tar
drakx-0846262df5150042d38accad44bb805cbc4945b6.tar.gz
drakx-0846262df5150042d38accad44bb805cbc4945b6.tar.bz2
drakx-0846262df5150042d38accad44bb805cbc4945b6.tar.xz
drakx-0846262df5150042d38accad44bb805cbc4945b6.zip
fallback to wpa_cli or iwlist/iwconfig when needed (#18516)
-rw-r--r--perl-install/detect_devices.pm4
-rw-r--r--perl-install/network/monitor.pm78
-rwxr-xr-xperl-install/standalone/drakroam142
-rw-r--r--perl-install/standalone/net_applet29
4 files changed, 176 insertions, 77 deletions
diff --git a/perl-install/detect_devices.pm b/perl-install/detect_devices.pm
index 34bddb75d..5d00955d1 100644
--- a/perl-install/detect_devices.pm
+++ b/perl-install/detect_devices.pm
@@ -587,7 +587,7 @@ sub is_wireless_interface {
#- i.e interfaces for which get_wireless_stats() is available
c::isNetDeviceWirelessAware($interface) || -e "/sys/class/net/$interface/wireless";
}
-sub has_wireless() { any { is_wireless_interface($_) } getNet() }
+sub get_wireless_interface() { find { is_wireless_interface($_) } getNet() }
sub is_bridge_interface {
my ($interface) = @_;
@@ -951,7 +951,7 @@ sub matching_type {
if ($type =~ /laptop/i) {
return isLaptop();
} elsif ($type =~ /wireless/i) {
- return has_wireless();
+ return to_bool(get_wireless_interface());
}
}
diff --git a/perl-install/network/monitor.pm b/perl-install/network/monitor.pm
index 38912af97..93384237b 100644
--- a/perl-install/network/monitor.pm
+++ b/perl-install/network/monitor.pm
@@ -15,36 +15,68 @@ sub new {
}
sub list_wireless {
- my ($o) = @_;
- my $results;
- eval { $results = $o->call_method('ScanResults') };
- my %networks;
- #- bssid / frequency / signal level / flags / ssid
- while ($results =~ /^((?:[0-9a-f]{2}:){5}[0-9a-f]{2})\t(\d+)\t(\d+)\t(.*?)\t(.*)$/mg) {
- # wpa_supplicant may list the network two times, use ||=
- $networks{$1}{frequency} ||= $2;
- $networks{$1}{signal_level} ||= $3;
- $networks{$1}{flags} ||= $4;
- $networks{$1}{ssid} ||= $5 if $5 ne '<hidden>';
- $networks{$1}{approx_level} ||= 20 + min(80, int($3/20)*20);
+ my ($monitor, $o_intf) = @_;
+ my ($results, $list, %networks);
+ #- first try to use mandi
+ eval {
+ $results = $monitor->call_method('ScanResults');
+ $list = $monitor->call_method('ListNetworks');
+ };
+ my $has_roaming = defined $results && defined $list;
+ #- try wpa_cli if we're root
+ if ($@ && !$>) {
+ $results = run_program::get_stdout('/usr/sbin/wpa_cli', '2>', '/dev/null', 'scan_results');
+ $list = run_program::get_stdout('/usr/sbin/wpa_cli', '2>', '/dev/null', 'list_networks');
}
- my $list;
- eval { $list = $o->call_method('ListNetworks') };
- #- network id / ssid / bssid / flags
- while ($list =~ /^(\d+)\t(.*?)\t(.*?)\t(.*)$/mg) {
- if (my $net = $networks{$3} || find { $_->{ssid} eq $2 } values(%networks)) {
- $net->{id} = $1;
- $net->{ssid} ||= $2;
- $net->{current} = to_bool($4 eq '[CURRENT]');
+ if (defined $results && defined $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) {
+ # wpa_supplicant may list the network two times, use ||=
+ $networks{$1}{frequency} ||= $2;
+ $networks{$1}{signal_level} ||= $3;
+ $networks{$1}{flags} ||= $4;
+ $networks{$1}{essid} ||= $5 if $5 ne '<hidden>';
}
+ #- network id / ssid / bssid / flags
+ while ($list =~ /^(\d+)\t(.*?)\t(.*?)\t(.*)$/mg) {
+ if (my $net = $networks{$3} || find { $_->{essid} eq $2 } values(%networks)) {
+ $net->{id} = $1;
+ $net->{essid} ||= $2;
+ $net->{current} = to_bool($4 eq '[CURRENT]');
+ }
+ }
+ } elsif ($o_intf) {
+ #- else use iwlist
+ my $current_essid = chomp_(run_program::get_stdout('/sbin/iwgetid', '-r', $o_intf));
+ my $current_ap = lc(chomp_(run_program::get_stdout('/sbin/iwgetid', '-r', '-a', $o_intf)));
+ my @list = run_program::get_stdout('/sbin/iwlist', $o_intf, 'scanning');
+ my $net = {};
+ foreach (@list) {
+ if ((/^\s*$/ || /Cell/) && exists $net->{ap}) {
+ $net->{current} = to_bool($net->{essid} eq $current_essid || $net->{ap} eq $current_ap);
+ $networks{$net->{ap}} = $net;
+ $net = {};
+ }
+ /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]';
+ /key:(\S*)\s/ and $net->{flags} ||= $1 eq 'on' && '[WEP]';
+ }
}
- \%networks;
+
+ $networks{$_}{approx_level} = 20 + min(80, int($networks{$_}{signal_level}/20)*20) foreach keys %networks;
+ (\%networks, $has_roaming);
}
sub select_network {
my ($o, $id) = @_;
- $networks = $o->call_method('SelectNetwork',
- Net::DBus::Binding::Value->new(&Net::DBus::Binding::Message::TYPE_UINT32, $id));
+ $o->call_method('SelectNetwork',
+ Net::DBus::Binding::Value->new(&Net::DBus::Binding::Message::TYPE_UINT32, $id));
}
1;
diff --git a/perl-install/standalone/drakroam b/perl-install/standalone/drakroam
index e5fe256e4..5294cfbd4 100755
--- a/perl-install/standalone/drakroam
+++ b/perl-install/standalone/drakroam
@@ -16,14 +16,18 @@ use interactive;
use mygtk2;
use ugtk2 qw(:create :helpers :wrappers);
use Gtk2::SimpleList;
+use network::ethernet;
use network::monitor;
-use network::wireless;
use network::network;
-use network::ethernet;
+use network::tools;
+use network::wireless;
my $in = 'interactive'->vnew('su');
-my $wireless_device = find { detect_devices::is_wireless_interface($_) } detect_devices::getNet();
+my $arg_ap;
+/^--ap=(.*)/ and $arg_ap = $1 foreach @ARGV;
+
+my $wireless_device = detect_devices::get_wireless_interface();
unless ($wireless_device) {
ugtk2::err_dialog(N("Error"), N("You do not have any wireless interface.
@@ -44,13 +48,15 @@ my $wireless_list = Gtk2::SimpleList->new(
N("SSID") => "text",
'' => "pixbuf",
N("Encryption") => "text",
- N("Signal strength") => "pixbuf"
+ N("Operating Mode") => "text",
+ N("Signal strength") => "pixbuf",
);
$wireless_list->get_selection->set_mode('single');
my $dbus = dbus_object::system_bus();
my $monitor = network::monitor->new($dbus);
my $wireless_networks = {};
+my $has_roaming;
my %pixbufs =
(
@@ -62,35 +68,34 @@ my %pixbufs =
);
sub update_networks() {
- $wireless_networks = $monitor->list_wireless;
+ ($wireless_networks, $has_roaming) = network::monitor::list_wireless($monitor, $wireless_device);
@{$wireless_list->{data}} = ();
while (my ($ap, $network) = each(%$wireless_networks)) {
push @{$wireless_list->{data}}, [
$ap,
$network->{current} ? $pixbufs{state}{connected} : undef,
- $network->{ssid} || $ap,
+ $network->{essid} || $ap,
$network->{flags} ? $pixbufs{keyring} : undef,
$network->{flags},
- $pixbufs{link_level}{$network->{approx_level}}
+ $network->{mode},
+ $pixbufs{link_level}{$network->{approx_level}},
];
}
1;
}
-sub configure_selected() {
- my ($selected) = $wireless_list->get_selected_indices or return;
- my $ap = $wireless_list->{data}[$selected][0];
+sub configure_ap {
+ my ($ap) = @_;
my $network = $wireless_networks->{$ap};
-
- my $ssid = $network->{ssid};
+ my $essid = $network->{essid};
my $wireless_net =
- $ssid && exists $net->{wireless}{$ssid} ?
- $net->{wireless}{$ssid} :
+ $essid && exists $net->{wireless}{$essid} ?
+ $net->{wireless}{$essid} :
exists $net->{wireless}{$ap} ?
$net->{wireless}{$ap} :
{};
- $wireless_net->{WIRELESS_ESSID} = $ssid if $ssid;
+ $wireless_net->{WIRELESS_ESSID} = $essid if $essid;
my ($wireless_enc_mode, $wireless_enc_key, $wireless_restricted);
($wireless_enc_key, $wireless_restricted) = network::wireless::get_wep_key_from_iwconfig($wireless_net->{WIRELESS_ENC_KEY});
@@ -101,10 +106,10 @@ sub configure_selected() {
$in->ask_from_({
title => "Wireless settings",
- messages => N("Please enter settings for wireless network \"%s\"", $ssid || $ap)
+ messages => N("Please enter settings for wireless network \"%s\"", $essid || $ap)
},
[
- { label => N("Network name (ESSID)"), val => \$wireless_net->{WIRELESS_ESSID}, disabled => sub { $ssid } },
+ { label => N("Network name (ESSID)"), val => \$wireless_net->{WIRELESS_ESSID}, disabled => sub { $essid } },
{ label => N("Encryption mode"), val => \$wireless_enc_mode,
list => [ keys %network::wireless::wireless_enc_modes ],
sort => 1,
@@ -118,40 +123,96 @@ sub configure_selected() {
) or return;
$wireless_net->{BOOTPROTO} = $dhcp ? 'dhcp' : 'static';
- $wireless_net->{WIRELESS_ENC_KEY} = network::wireless::convert_wep_key_for_iwconfig($wireless_enc_key, $wireless_enc_mode eq 'restricted');
- $wireless_net->{WIRELESS_WPA_DRIVER} = network::wireless::wpa_supplicant_get_driver($wireless_module);
+ $wireless_net->{WIRELESS_ENC_KEY} = $wireless_enc_key && network::wireless::convert_wep_key_for_iwconfig($wireless_enc_key, $wireless_enc_mode eq 'restricted');
+ $wireless_net->{WIRELESS_MODE} = $network->{mode} eq 'Master' ? 'Managed' : $network->{mode};
- my $wireless_file = "/etc/sysconfig/network-scripts/wireless.d/" . ($ssid || $ap);
+ if ($has_roaming || $wireless_enc_mode eq 'wpa-psk') {
+ $wireless_net->{WIRELESS_WPA_DRIVER} = network::wireless::wpa_supplicant_get_driver($wireless_module);
+ network::wireless::wpa_supplicant_add_network($wireless_net->{WIRELESS_ESSID}, $wireless_enc_mode, $wireless_enc_key);
+ } else {
+ delete $wireless_net->{WIRELESS_WPA_DRIVER};
+ }
+
+ my $ssid = $essid || $ap;
+ $net->{wireless}{$ssid} = $wireless_net;
+
+ my $wireless_file = "/etc/sysconfig/network-scripts/wireless.d/$ssid";
network::network::write_interface_settings($wireless_net, $wireless_file);
- network::wireless::wpa_supplicant_add_network($wireless_net->{WIRELESS_ESSID}, $wireless_enc_mode, $wireless_enc_key);
- system('/usr/sbin/wpa_cli reconfigure'); #- this should be handled by the monitoring daemon instead
+ if ($has_roaming) {
+ #- this should be handled by the monitoring daemon instead
+ run_program::run('/usr/sbin/wpa_cli', 'reconfigure');
+ } else {
+ overwrite_wireless_ifcfg($wireless_net);
+ }
1;
}
-sub connect_to_selected() {
- my ($selected) = $wireless_list->get_selected_indices or return;
- my $ap = $wireless_list->{data}[$selected][0];
- my $network = $wireless_networks->{$ap};
-
- if (defined $network->{id}) {
- eval { $monitor->select_network($network->{id}) };
- $@ and err_dialog(N("Wireless connection"), N("Unable to contact daemon"));
- } else {
- configure_selected();
- #- apply config in wpa_supplicant and retry
- }
+sub overwrite_wireless_ifcfg {
+ my ($wireless_net) = @_;
+ my $ifcfg = $net->{ifcfg}{$wireless_device} ||= {};
+ delete $ifcfg->{$_} foreach grep { /wireless/i } keys %$ifcfg;
+ put_in_hash($ifcfg, $wireless_net);
+ network::network::write_interface_conf($net, $wireless_device);
+}
+sub wait_and_run_sub {
+ my ($time, $sub) = @_;
gtkset_mousecursor_wait();
-
- Glib::Timeout->add(5000, sub {
- update_networks();
+ Glib::Timeout->add($time, sub {
+ $sub->();
gtkset_mousecursor_normal();
0;
});
}
+sub connect_to_ap {
+ my ($ap, $o_disable_configure) = @_;
+ my $network = $wireless_networks->{$ap};
+ my $found;
+
+ if ($network) {
+ my $wireless_net = !$has_roaming && ($net->{wireless}{$ap} || $net->{wireless}{$network->{essid}});
+ if (defined $network->{id}) {
+ eval { $monitor->select_network($network->{id}) };
+ $found = !$@;
+ $found or err_dialog(N("Wireless connection"), N("Unable to contact daemon"));
+ } elsif ($wireless_net) {
+ network::tools::stop_interface($wireless_device, 0);
+ overwrite_wireless_ifcfg($wireless_net);
+ network::tools::start_interface($wireless_device, 1);
+ $found = 1;
+ }
+ }
+
+ $found || !$o_disable_configure or return;
+
+ if (!$found) {
+ if ($has_roaming) {
+ configure_ap($ap);
+ #- wait for wpa_supplicant to reconfigure the device
+ wait_and_run_sub(2000, sub { connect_to_ap($ap, 1) });
+ return;
+ } else {
+ network::tools::stop_interface($wireless_device, 0);
+ configure_ap($ap);
+ network::tools::start_interface($wireless_device, 0);
+ }
+ }
+ wait_and_run_sub(5000, \&update_networks);
+}
+
+sub configure_selected() {
+ my ($selected) = $wireless_list->get_selected_indices or return;
+ configure_ap($wireless_list->{data}[$selected][0]);
+}
+
+sub connect_to_selected() {
+ my ($selected) = $wireless_list->get_selected_indices or return;
+ connect_to_ap($wireless_list->{data}[$selected][0]);
+}
+
update_networks();
Glib::Timeout->add(30000, \&update_networks);
@@ -160,7 +221,7 @@ gtkadd($w->{window},
gtknew('VBox', spacing => 5, children => [
$::isEmbedded ? () : (0, Gtk2::Banner->new('/usr/share/mcc/themes/default/drakroam-mdk.png', N("Wireless connection"))),
1, gtknew('HBox', spacing => 5, children => [
- 1, gtknew('ScrolledWindow', width => 420, height => 300, child => $wireless_list),
+ 1, gtknew('ScrolledWindow', width => 500, height => 300, child => $wireless_list),
0, gtknew('VButtonBox', layout => 'edge', children_loose => [
gtknew('Button', text => N("Configure"), clicked => \&configure_selected),
gtknew('Button', text => N("Connect"), clicked => \&connect_to_selected),
@@ -169,5 +230,8 @@ gtkadd($w->{window},
]),
]),
]),
- );
+ );
+
+$arg_ap and Glib::Timeout->add(100, sub { connect_to_ap($arg_ap); 0 });
+
$w->main;
diff --git a/perl-install/standalone/net_applet b/perl-install/standalone/net_applet
index 939c697f7..bfc751064 100644
--- a/perl-install/standalone/net_applet
+++ b/perl-install/standalone/net_applet
@@ -21,11 +21,11 @@ use ugtk2 qw(:create :helpers :wrappers :dialogs);
my $onstartupfile = "$ENV{HOME}/.net_applet";
shouldStart() or die "$onstartupfile should be set to TRUE or use net_applet --force";
-# Allow multiple instances, but only one per user:
+#- Allow multiple instances, but only one per user:
is_running('net_applet') and die "net_applet already running\n";
my ($eventbox, $img, $bubble);
-my ($current_state, $current_interface, $menu, $wireless_menu, $timeout, $update_timeout);
+my ($current_state, $current_interface, $menu, $wireless_device, $wireless_menu, $timeout, $update_timeout);
add_icon_path("/usr/share/libDrakX/pixmaps/");
my $net = {};
@@ -57,7 +57,7 @@ my %actions = (
'downNetwork' => { name => sub { N("Disconnect %s", $_[0]) }, launch => sub { network::tools::stop_interface($_[0], 1) } },
'monitorNetwork' => { name => N("Monitor Network"), launch => \&run_net_monitor },
'monitorIFW' => { name => N("Interactive Firewall"), launch => \&run_drakids },
- 'wireless' => { name => N("Manage wireless networks"), launch => \&run_drakroam },
+ 'wireless' => { name => N("Manage wireless networks"), launch => sub { run_drakroam() } },
'confNetwork' => { name => N("Configure Network"), launch => sub { system("/usr/sbin/drakconnect --skip-wizard &") } },
'chooseInterface' => {
name => N("Watched interface"),
@@ -155,8 +155,9 @@ sub shouldStart() {
sub run_net_monitor() {
run_program::raw({ detach => 1 }, '/usr/sbin/net_monitor', '--defaultintf', $current_interface) unless is_running('net_monitor');
}
-sub run_drakroam() {
- run_program::raw({ detach => 1 }, '/usr/sbin/drakroam') unless is_running('drakroam');
+sub run_drakroam {
+ my ($o_ap) = @_;
+ run_program::raw({ detach => 1 }, '/usr/sbin/drakroam', if_($o_ap, "--ap=$o_ap")) unless is_running('drakroam');
}
sub run_drakids() {
$ifw_alert = 0;
@@ -167,7 +168,7 @@ sub run_drakids() {
}
}
sub generate_wireless_menuitem {
- my ($net) = @_;
+ my ($net, $ap) = @_;
$net->{menuitem} = Gtk2::CheckMenuItem->new;
$net->{menuitem}->set_draw_as_radio(1);
$net->{menuitem}->add(gtkpack_(gtkshow(Gtk2::HBox->new),
@@ -179,7 +180,7 @@ sub generate_wireless_menuitem {
eval { $monitor->select_network($net->{id}) };
$@ and err_dialog(N("Interactive Firewall"), N("Unable to contact daemon"));
} else {
- run_drakroam();
+ run_drakroam($ap);
}
checkNetworkForce();
});
@@ -187,7 +188,7 @@ sub generate_wireless_menuitem {
}
sub update_wireless_item {
my ($net, $ap_address) = @_;
- $net->{ssid_label}->set_text($net->{ssid} || "[$ap_address]");
+ $net->{ssid_label}->set_text($net->{essid} || "[$ap_address]");
$net->{keyring_image}->visible(to_bool($net->{flags}));
$net->{level_image}->set_from_pixbuf($pixbufs{link_level}{$net->{approx_level}});
@@ -196,11 +197,12 @@ sub update_wireless_item {
$net->{menuitem}->signal_handler_unblock($net->{activate});
}
sub checkWireless() {
- my $networks = eval { $monitor->list_wireless };
+ $wireless_device or return;
+ my ($networks) = network::monitor::list_wireless($monitor, $wireless_device);
foreach (keys %$networks) {
my $net = $wireless_networks{$_} ||= {};
put_in_hash($net, $networks->{$_});
- exists $net->{menuitem} or generate_wireless_menuitem($net);
+ exists $net->{menuitem} or generate_wireless_menuitem($net, $_);
update_wireless_item($net, $_);
}
$wireless_networks{$_}{menuitem}->visible(exists $networks->{$_}) foreach keys %wireless_networks;
@@ -215,6 +217,7 @@ sub checkNetworkForce() {
$net = {};
network::network::read_net_conf($net);
undef $current_state;
+ $wireless_device = detect_devices::get_wireless_interface();
checkWireless();
checkNetwork();
}
@@ -231,6 +234,7 @@ sub go2State {
if ($current_state ne $state_type || $current_interface ne $interface) {
$current_state = $state_type;
$current_interface = $interface;
+ $wireless_device = detect_devices::get_wireless_interface();
if ($menu) {
if (my $m = $wireless_menu && $wireless_menu->get_submenu) {
$_->{menuitem}->get_parent and $m->remove($_->{menuitem}) foreach values %wireless_networks;
@@ -283,7 +287,6 @@ sub generate_menu {
};
my (@settings);
- my $has_wireless = $monitor && detect_devices::has_wireless();
my $interactive;
eval { $interactive = $ifw->get_interactive };
@@ -296,7 +299,7 @@ sub generate_menu {
$menu->append($create_item->('confNetwork'));
if ($current_state ne 'notconfigured') {
- $menu->append($create_item->('wireless')) if $has_wireless;
+ $menu->append($create_item->('wireless')) if $wireless_device;
push @settings, $create_item->('chooseInterface');
}
@@ -311,7 +314,7 @@ sub generate_menu {
toggled => sub { setAutoStart(uc(bool2text($_[0]->get_active))) }));
$menu->append(gtkshow(Gtk2::SeparatorMenuItem->new));
- $has_wireless and $menu->append(gtkshow($wireless_menu = create_menu(N("Wireless networks"),
+ $wireless_device and $menu->append(gtkshow($wireless_menu = create_menu(N("Wireless networks"),
map { $_->{menuitem} } values %wireless_networks)));
$menu->append(gtkshow(create_menu(N("Settings"), grep { $_ } @settings)));
$menu->append(gtkshow(Gtk2::SeparatorMenuItem->new));