summaryrefslogtreecommitdiffstats
path: root/lib/network
diff options
context:
space:
mode:
authorOlivier Blin <oblin@mandriva.com>2007-05-25 15:39:46 +0000
committerOlivier Blin <oblin@mandriva.com>2007-05-25 15:39:46 +0000
commit1d37bfdbbe874abd6dcb5563eea19f531de09e1c (patch)
tree74845e43ed8fa59c7aaafd1a87efaa6b0c83c228 /lib/network
parentc6ba983db7d5a82ee63599e775be0f8211447c72 (diff)
downloaddrakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.tar
drakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.tar.gz
drakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.tar.bz2
drakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.tar.xz
drakx-net-1d37bfdbbe874abd6dcb5563eea19f531de09e1c.zip
sync with 2007.1 (because of SVN loss)2007.1
Diffstat (limited to 'lib/network')
-rw-r--r--lib/network/.perl_checker1
-rw-r--r--lib/network/adsl.pm334
-rw-r--r--lib/network/connection.pm235
-rw-r--r--lib/network/connection/cable.pm77
-rw-r--r--lib/network/connection/cellular.pm52
-rw-r--r--lib/network/connection/cellular_bluetooth.pm94
-rw-r--r--lib/network/connection/cellular_card.pm180
-rw-r--r--lib/network/connection/dvb.pm73
-rw-r--r--lib/network/connection/ethernet.pm512
-rw-r--r--lib/network/connection/isdn.pm (renamed from lib/network/isdn.pm)107
-rw-r--r--lib/network/connection/isdn/consts.pm (renamed from lib/network/isdn_consts.pm)2
-rw-r--r--lib/network/connection/pots.pm133
-rw-r--r--lib/network/connection/ppp.pm138
-rw-r--r--lib/network/connection/providers/cellular.pm28
-rw-r--r--lib/network/connection/providers/xdsl.pm (renamed from lib/network/adsl_consts.pm)453
-rw-r--r--lib/network/connection/wireless.pm744
-rw-r--r--lib/network/connection/xdsl.pm375
-rw-r--r--lib/network/drakfirewall.pm34
-rw-r--r--lib/network/drakvpn.pm120
-rw-r--r--lib/network/ethernet.pm162
-rw-r--r--lib/network/ifw.pm16
-rw-r--r--lib/network/invictus.pm30
-rw-r--r--lib/network/ipsec.pm178
-rw-r--r--lib/network/modem.pm9
-rw-r--r--lib/network/monitor.pm50
-rw-r--r--lib/network/ndiswrapper.pm46
-rw-r--r--lib/network/netconnect.pm1200
-rw-r--r--lib/network/network.pm299
-rw-r--r--lib/network/rfswitch.pm38
-rw-r--r--lib/network/shorewall.pm151
-rw-r--r--lib/network/signal_strength.pm14
-rw-r--r--lib/network/squid.pm5
-rw-r--r--lib/network/test.pm79
-rw-r--r--lib/network/thirdparty.pm451
-rw-r--r--lib/network/tools.pm76
-rw-r--r--lib/network/vpn.pm191
-rw-r--r--lib/network/vpn/openvpn.pm407
-rw-r--r--lib/network/vpn/vpnc.pm74
-rw-r--r--lib/network/wireless.pm239
39 files changed, 4873 insertions, 2534 deletions
diff --git a/lib/network/.perl_checker b/lib/network/.perl_checker
new file mode 100644
index 0000000..2326e2f
--- /dev/null
+++ b/lib/network/.perl_checker
@@ -0,0 +1 @@
+Basedir ../..
diff --git a/lib/network/adsl.pm b/lib/network/adsl.pm
index 3768c17..c012219 100644
--- a/lib/network/adsl.pm
+++ b/lib/network/adsl.pm
@@ -4,10 +4,6 @@ use common;
use run_program;
use network::tools;
use modules;
-use vars qw(@ISA @EXPORT);
-
-@ISA = qw(Exporter);
-@EXPORT = qw(adsl_conf_backend);
sub adsl_probe_info {
my ($net) = @_;
@@ -16,12 +12,16 @@ sub adsl_probe_info {
foreach (qw(/etc/ppp/peers/ppp0 /etc/ppp/options /etc/ppp/options.adsl)) {
($login) = map { if_(/^user\s+"([^"]+)"/, $1) } cat_("$::prefix/$_") if !$login && -r "$::prefix/$_";
}
- my %pppoe_conf; %pppoe_conf = getVarsFromSh($pppoe_file) if (!exists $net->{adsl}{method} || $net->{adsl}{method} eq 'pppoe') && -f $pppoe_file;
- $login ||= $pppoe_conf{USER};
+ my %pppoe_conf = -f $pppoe_file && getVarsFromSh($pppoe_file);
+ $login = $pppoe_conf{USER} if !$login || $net->{adsl}{method} eq 'pppoe';
my $passwd = network::tools::passwd_by_login($login);
if (!$net->{adsl}{vpi} && !$net->{adsl}{vci}) {
- ($net->{adsl}{vpi}, $net->{adsl}{vci}) =
- (map { if_(/^.*-vpi\s+(\d+)\s+-vci\s+(\d+)/, map { sprintf("%x", $_) } $1, $2) } cat_("$::prefix/etc/ppp/peers/ppp0"));
+ foreach (cat_("$::prefix/etc/ppp/peers/ppp0")) {
+ if (/^.*-vpi\s+(\d+)\s+-vci\s+(\d+)/ || /^plugin pppoatm.so (\d+)\.(\d+)$/) {
+ ($net->{adsl}{vpi}, $net->{adsl}{vci}) = ($1, $2);
+ last;
+ }
+ }
}
$pppoe_conf{DNS1} ||= '';
$pppoe_conf{DNS2} ||= '';
@@ -29,308 +29,24 @@ sub adsl_probe_info {
add2hash($net->{adsl}, { login => $login, passwd => $passwd });
}
-sub adsl_detect() {
- require list_modules;
- require detect_devices;
- my @modules = list_modules::category2modules('network/usb_dsl');
- # return an hash compatible with what drakconnect expect us to return:
- my %compat = (
- 'speedtch' => 'speedtouch',
- 'eagle-usb' => 'sagem',
- );
-
- return {
- bewan => [ detect_devices::getBewan() ],
- eci => [ detect_devices::getECI() ],
- map { $compat{$_} || $_ => [ detect_devices::matching_driver($_) ] } @modules,
- };
-}
-
-sub sagem_set_parameters {
- my ($net) = @_;
- my %l = map { $_ => sprintf("%08s", $net->{adsl}{$_}) } qw(vci vpi Encapsulation);
-
- my $static_ip = $net->{adsl}{method} eq 'static' && $net->{ifcfg}{sagem}{IPADDR};
- foreach my $cfg_file (qw(/etc/analog/adiusbadsl.conf /etc/eagle-usb/eagle-usb.conf)) {
- substInFile {
- s/Linetype=.*\n/Linetype=0000000A\n/; #- use CMVs
- s/VCI=.*\n/VCI=$l{vci}\n/;
- s/VPI=.*\n/VPI=$l{vpi}\n/;
- s/Encapsulation=.*\n/Encapsulation=$l{Encapsulation}\n/;
- s/ISP=.*\n/ISP=$net->{adsl}{provider_id}\n/;
- s/STATIC_IP=.*\n//;
- s!</eaglectrl>!STATIC_IP=$static_ip\n</eaglectrl>! if $static_ip;
- } "$::prefix$cfg_file";
- }
- #- create CMV symlinks for both POTS and ISDN lines
- foreach my $type (qw(p i)) {
- my $cmv;
- my ($country) = $net->{adsl}{provider_id} =~ /^([a-zA-Z]+)\d+$/;
- #- try to find a CMV for this specific ISP
- $cmv = "$::prefix/etc/eagle-usb/CMVe${type}$net->{adsl}{provider_id}.txt" if $net->{adsl}{provider_id};
- #- if not found, try to found a CMV for the country
- -f $cmv or $cmv = "$::prefix/etc/eagle-usb/CMVe${type}${country}.txt";
- #- fallback on the generic CMV if no other matched
- -f $cmv or $cmv = "$::prefix/etc/eagle-usb/CMVe${type}WO.txt";
- symlinkf($cmv, "$::prefix/etc/eagle-usb/CMVe${type}.txt");
- }
- #- remove this otherwise eaglectrl won't start
- unlink("$::prefix/etc/eagle-usb/eagle-usb_must_be_configured");
-}
-
sub adsl_conf_backend {
- my ($in, $modules_conf, $net) = @_;
-
- my $bewan_module;
- $bewan_module = $net->{adsl}{bus} eq 'PCI' ? 'unicorn_pci_atm' : 'unicorn_usb_atm' if $net->{adsl}{device} eq "bewan";
-
- my $adsl_type = $net->{adsl}{method};
- my $adsl_device = $net->{adsl}{device};
-
- # all supported modems came with their own pppoa module, so no need for "plugin pppoatm.so"
- my %modems =
- (
- bewan =>
- {
- start => qq(
-# ActivationMode=1
-modprobe $bewan_module
-# wait for the modem to be set up:
-sleep 10
-),
- stop => qq(modprobe -r $bewan_module),
- plugin => {
- pppoa => "pppoatm.so " . join('.', hex($net->{adsl}{vpi}), hex($net->{adsl}{vci}))
- },
- ppp_options => qq(
-default-asyncmap
-hide-password
-noaccomp
-nobsdcomp
-nodeflate
-novj novjccomp
-lcp-echo-interval 20
-lcp-echo-failure 3
-sync
-),
- },
-
- speedtouch =>
- {
- modules => [ qw(speedtch) ],
- start => '/usr/bin/speedtouch-start --nocall',
- overide_script => 1,
- server => {
- pppoa => qq("/usr/sbin/pppoa3 -c")
- },
- plugin => {
- pppoa => "pppoatm.so " . join('.', hex($net->{adsl}{vpi}), hex($net->{adsl}{vci})),
- },
- ppp_options => qq(
-sync
-noaccomp),
- aliases => [
- ['char-major-108', 'ppp_generic'],
- ['tty-ldisc-3', 'ppp_async'],
- ['tty-ldisc-13', 'n_hdlc'],
- ['tty-ldisc-14', 'ppp_synctty'],
- ['ppp-compress-21', 'bsd_comp'],
- ['ppp-compress-24', 'ppp_deflate'],
- ['ppp-compress-26', 'ppp_deflate']
- ],
- },
-
- sagem =>
- {
- modules => [ qw(eagle-usb) ],
- start => '/sbin/eaglectrl -i >/dev/null 2>/dev/null || /sbin/eaglectrl -d',
- stop => "/usr/bin/killall pppoa",
- get_intf => '/sbin/eaglectrl -i',
- server => {
- pppoa => q("/sbin/fctStartAdsl -t 1 -i"),
- },
- ppp_options => qq(
-mru 1492
-mtu 1492
-nobsdcomp
-nodeflate
-noaccomp -am
-novjccomp),
- aliases => [
- ['char-major-108', 'ppp_generic'],
- ['tty-ldisc-3', 'ppp_async'],
- ['tty-ldisc-13', 'n_hdlc'],
- ['tty-ldisc-14', 'ppp_synctty']
- ],
- },
-
- eci =>
- {
- start => '/usr/bin/startmodem',
- server => {
- pppoe => qq("/usr/bin/pppoeci -v 1 -vpi $net->{adsl}{vpi} -vci $net->{adsl}{vci}"),
- },
- ppp_options => qq(
-noipdefault
-sync
-noaccomp
-linkname eciadsl
-lcp-echo-interval 0)
- },
-
- pptp_modem =>
- {
- server => {
- pptp => qq("/usr/sbin/pptp 10.0.0.138 --nolaunchpppd"),
- },
- },
-
- capi_modem =>
- {
- ppp_options => qq(
-connect /bin/true
-ipcp-accept-remote
-ipcp-accept-local
-
-sync
-noauth
-lcp-echo-interval 5
-lcp-echo-failure 3
-lcp-max-configure 50
-lcp-max-terminate 2
-
-noccp
-noipx
-mru 1492
-mtu 1492),
- plugin => {
- capi => qq(capiplugin.so
-avmadsl)
- },
- },
- );
-
- my %generic =
- (
- pppoe =>
- {
- server => '"pppoe -I ' . (exists $modems{$adsl_device}{get_intf} ? "`$modems{$adsl_device}{get_intf}`" : $net->{adsl}{ethernet_device}) . '"',
- ppp_options => qq(default-asyncmap
-mru 1492
-mtu 1492
-noaccomp
-noccp
-nobsdcomp
-novjccomp
-nodeflate
-lcp-echo-interval 20
-lcp-echo-failure 3
-),
- }
- );
-
- if ($adsl_type =~ /^pp|^capi$/) {
- mkdir_p("$::prefix/etc/ppp");
- $in->do_pkgs->install('ppp');
- my %packages = (
- pppoa => [ qw(ppp-pppoatm) ],
- pppoe => [ qw(ppp-pppoe rp-pppoe) ],
- pptp => [ qw(pptp-linux) ],
- capi => [ qw(isdn4k-utils) ], #- capi4linux service
- );
- $in->do_pkgs->install(@{$packages{$adsl_type}});
-
- my $pty_option =
- exists $modems{$adsl_device}{server}{$adsl_type} ? "pty $modems{$adsl_device}{server}{$adsl_type}" :
- exists $generic{$adsl_type}{server} ? "pty $generic{$adsl_type}{server}" :
- "";
- my $plugin = exists $modems{$adsl_device}{plugin}{$adsl_type} && "plugin $modems{$adsl_device}{plugin}{$adsl_type}";
- my $noipdefault = $adsl_type eq 'pptp' ? '' : 'noipdefault';
- my $ppp_options =
- exists $modems{$adsl_device}{ppp_options} ? $modems{$adsl_device}{ppp_options} :
- exists $generic{$adsl_type}{ppp_options} ? $generic{$adsl_type}{ppp_options} :
- "";
- output("$::prefix/etc/ppp/peers/ppp0",
-qq(lock
-persist
-noauth
-usepeerdns
-defaultroute
-$noipdefault
-$ppp_options
-kdebug 1
-nopcomp
-noccp
-novj
-holdoff 4
-maxfail 25
-$pty_option
-$plugin
-user "$net->{adsl}{login}"
-));
-
- network::tools::write_secret_backend($net->{adsl}{login}, $net->{adsl}{passwd});
-
- my $ethernet_device = $net->{adsl}{ethernet_device};
- if ($ethernet_device =~ /^eth/) {
- $net->{ifcfg}{$ethernet_device} = {
- DEVICE => $ethernet_device,
- BOOTPROTO => 'none',
- NETMASK => '255.255.255.0',
- NETWORK => '10.0.0.0',
- BROADCAST => '10.0.0.255',
- MII_NOT_SUPPORTED => 'yes',
- ONBOOT => 'yes',
- };
- }
- }
-
- #- FIXME: ppp0 and ippp0 are hardcoded
- my $metric = network::tools::get_default_metric("adsl"); #- FIXME, do not override if already set
- put_in_hash($net->{ifcfg}{ppp0} ||= {}, {
- DEVICE => 'ppp0',
- TYPE => 'ADSL',
- METRIC => $metric,
- }) unless member($adsl_type, qw(static dhcp));
- #- don't overwrite ONBOOT setting, it may have been handled earlier in netconnect
- $net->{ifcfg}{ppp0}{ONBOOT} ||= 'yes';
-
- #- remove file used with sagem for dhcp/static connections
- unlink("$::prefix/etc/sysconfig/network-scripts/ifcfg-sagem");
-
- #- set vpi, vci and encapsulation parameters for sagem
- $adsl_device eq 'sagem' and sagem_set_parameters($net);
-
- #- set aliases
- if (exists $modems{$adsl_device}{aliases}) {
- $modules_conf->set_alias($_->[0], $_->[1]) foreach @{$modems{$adsl_device}{aliases}};
- $::isStandalone and $modules_conf->write;
- }
- #- remove the "speedtch off" alias that was written by Mandrakelinux 10.0
- $adsl_device eq 'speedtouch' and $modules_conf->remove_alias('speedtch');
-
- if ($adsl_type eq "capi") {
- require network::isdn;
- network::isdn::setup_capi_conf($in, $net->{adsl}{capi_card});
- services::disable('isdn4linux');
- services::enable('capi4linux');
-
- #- install and run drdsl for dsl connections, once capi driver is loaded
- $in->do_pkgs->ensure_is_installed_if_available("drdsl", "/usr/sbin/drdsl");
- run_program::rooted($::prefix, "/usr/sbin/drdsl");
- }
-
- #- load modules and run modem-specific start programs
- #- useful during install, or in case the packages have been installed after the device has been plugged
- my @modules = (@{$modems{$adsl_device}{modules}}, map { $_->[1] } @{$modems{$adsl_device}{aliases}});
- @modules or @modules = qw(ppp_synctty ppp_async ppp_generic n_hdlc); #- required for pppoe/pptp connections
- #- pppoa connections need the pppoatm module
- #- pppd should run "modprobe pppoatm", but it will fail during install
- push @modules, 'pppoatm' if $adsl_type eq 'pppoa';
- foreach (@modules) {
- eval { modules::load($_) } or log::l("failed to load $_ module: $@");
- }
- $modems{$adsl_device}{start} and run_program::rooted($::prefix, $modems{$adsl_device}{start});
+ my ($in, $net) = @_;
+
+ require network::connection::xdsl;
+ my $xdsl = network::connection::xdsl->new(
+ $net->{adsl}{method} eq "capi" ?
+ $net->{adsl}{capi_card} :
+ { driver => $net->{adsl}{driver}, ethernet_device => $net->{adsl}{ethernet_device} });
+ $xdsl->{protocol} = $net->{adsl}{method};
+ $xdsl->{access}{login} = $net->{adsl}{login};
+ $xdsl->{access}{password} = $net->{adsl}{passwd};
+ $xdsl->{access}{vpi} = $net->{adsl}{vpi};
+ $xdsl->{access}{vci} = $net->{adsl}{vci};
+
+ $xdsl->install_packages($in);
+ $xdsl->unload_connection;
+ $xdsl->write_settings($net);
+ $xdsl->prepare_connection;
}
1;
diff --git a/lib/network/connection.pm b/lib/network/connection.pm
new file mode 100644
index 0000000..0088ede
--- /dev/null
+++ b/lib/network/connection.pm
@@ -0,0 +1,235 @@
+package network::connection;
+
+use common;
+use network::vpn;
+
+sub get_types {
+ sort { $a->get_metric <=> $b->get_metric } grep { $_->can('get_devices') } common::load_modules_from_base(__PACKAGE__);
+}
+
+=item get_type_name()
+
+Get the connection type name, unstranslated
+
+=cut
+
+sub get_type_name() { N("Unknown connection type") }
+sub get_type_description {
+ my ($class) = @_;
+ $class->get_type_name;
+}
+
+=item get_type_icon()
+
+Get the connection type icon path
+
+=cut
+
+sub get_type_icon() { '/usr/share/mcc/themes/default/drakconnect-mdk.png' }
+
+=item get_devices()
+
+Get the devices supported by this connection type
+
+=cut
+
+=item get_connections()
+
+List connections that can be configured by the class
+
+=cut
+
+sub get_connections {
+ my ($class, %options) = @_;
+ map { $class->new($_) } $class->get_devices(%options);
+}
+
+=item find_ifcfg_type($ifcfg)
+
+Returns the class matching the connection type of the ifcfg hash
+
+=cut
+
+sub find_ifcfg_type {
+ my ($_class, $ifcfg) = @_;
+ find { $_->can('handles_ifcfg') && $_->handles_ifcfg($ifcfg) } sort { $b->get_metric <=> $a->get_metric } get_types();
+}
+
+sub new {
+ my ($class, $device) = @_;
+ bless {
+ device => $device,
+ settings => {},
+ networks => {},
+ }, $class;
+}
+
+sub get_description {
+ my ($self) = @_;
+ $self->{device}{description};
+}
+
+sub get_driver {
+ my ($self) = @_;
+ $self->{device}{driver};
+}
+
+sub get_interface {
+ my ($_self) = @_;
+ die "unable to get interface";
+}
+
+sub get_metric { 60 }
+
+sub get_status {
+ my ($self) = @_;
+ require network::tools;
+ my ($_is_up, $gw_address) = network::tools::get_interface_status($self->get_interface);
+ $self->{status} = to_bool($gw_address);
+}
+
+sub get_ifcfg_bool {
+ my ($self, $field) = @_;
+ defined $self->{ifcfg}{$field} ? text2bool($self->{ifcfg}{$field}) : undef;
+}
+
+sub get_selected_network {
+ my ($self) = @_;
+ exists $self->{networks}{$self->{network}} && $self->{networks}{$self->{network}};
+}
+
+sub load_interface_settings {
+ my ($self) = @_;
+ require network::network;
+ my $file = network::network::get_ifcfg_file($self->get_interface);
+ $self->{ifcfg} = { getVarsFromSh($file) };
+ $self->{vpn_list} = [ map { $_->get_configured_connections } network::vpn->list_types ];
+ $self->{control}{onboot} = $self->get_ifcfg_bool('ONBOOT');
+ $self->{control}{userctl} = $self->get_ifcfg_bool('USERCTL');
+ $self->{control}{metric} = $self->{ifcfg}{METRIC};
+}
+
+#- override to return 1 if the connection network scan is slow
+sub network_scan_is_slow { 0 }
+
+sub get_network_access_settings_label { N("Network access settings") }
+sub get_access_settings_label { N("Access settings") }
+sub get_address_settings_label { N("Address settings") }
+
+sub set_provider {
+ my ($self, $provider_data) = @_;
+ $self->{provider} = $provider_data;
+}
+
+#- check that $self->can('get_protocols') first
+sub get_protocol_settings {
+ my ($self) = @_;
+ my $protocols = $self->get_protocols;
+ [
+ {
+ val => \$self->{protocol}, type => 'list',
+ list => [ sort { $protocols->{$a} cmp $protocols->{$b} } keys %$protocols ],
+ format => sub { $protocols->{$_[0]} },
+ }
+ ];
+}
+
+sub guess_network_control_settings {
+ my ($self) = @_;
+ $self->{control}{vpn} = find {
+ $self->{ifcfg}{VPN_TYPE} eq $_->get_type &&
+ $self->{ifcfg}{VPN_NAME} eq $_->get_name;
+ } @{$self->{vpn_list}};
+}
+
+sub get_network_control_settings {
+ my ($self) = @_;
+ [
+ if_(@{$self->{vpn_list}},
+ { label => N("VPN connection"), val => \$self->{control}{vpn},
+ list => [ undef, @{$self->{vpn_list}} ],
+ format => sub { defined $_[0] ? $_[0]->get_label : N("None") } }),
+ ];
+}
+
+sub guess_control_settings {
+ my ($self) = @_;
+ $self->{control}{metric} ||= $self->get_metric;
+}
+
+sub get_control_settings {
+ my ($self) = @_;
+ [
+ { text => N("Allow users to manage the connection"), val => \$self->{control}{userctl}, type => "bool" },
+ { text => N("Start the connection at boot"), val => \$self->{control}{onboot}, type => "bool" },
+ { label => N("Metric"), val => \$self->{control}{metric}, advanced => 1 },
+ ];
+}
+
+sub build_ifcfg_settings {
+ my ($self, $o_options) = @_;
+ put_in_hash($o_options, {
+ DEVICE => $self->get_interface,
+ ONBOOT => bool2yesno($self->{control}{onboot}),
+ USERCTL => bool2yesno($self->{control}{userctl}),
+ METRIC => $self->{control}{metric},
+ VPN_TYPE => defined $self->{control}{vpn} && $self->{control}{vpn}->get_type,
+ VPN_NAME => defined $self->{control}{vpn} && $self->{control}{vpn}->get_name,
+ #- FIXME: add MS_DNSx variables if DNS servers are specified
+ });
+}
+
+sub write_settings {
+ my ($self, $_o_net, $_o_modules_conf) = @_;
+ require network::network;
+ my $file = network::network::get_ifcfg_file($self->get_interface);
+ network::network::write_interface_settings($self->build_ifcfg_settings, $file);
+ network::network::write_hostname($self->{address}{hostname}) if $self->{address}{hostname};
+ require network::shorewall;
+ network::shorewall::update_interfaces_list($self->get_interface);
+ network::network::reload_net_applet();
+}
+
+sub connect {
+ my ($self) = @_;
+ require network::tools;
+ network::tools::start_interface($self->get_interface, 0);
+}
+
+sub disconnect {
+ my ($self) = @_;
+ require network::tools;
+ network::tools::stop_interface($self->get_interface, 0);
+}
+
+sub setup_thirdparty {
+ my ($self, $in) = @_;
+ my $driver = $self->get_driver;
+ # FIXME: weird return code
+ $driver && $self->can('get_thirdparty_settings') or return 1;
+ require network::thirdparty;
+ $self->{thirdparty} = network::thirdparty::apply_settings($in, ref $self, $self->get_thirdparty_settings, $driver);
+ $self->{device} = $self->{thirdparty}{device} if $self->{thirdparty} && $self->{thirdparty}{device};
+ $self->{thirdparty};
+}
+
+sub prepare_device {
+ my ($self) = @_;
+ my $driver = $self->get_driver;
+ if ($driver) {
+ require modules;
+ eval { modules::load($driver) };
+ }
+}
+
+#- status messages can be sent using mdv-network-event
+sub get_status_message {
+ my ($self, $status) = @_;
+ my $interface = $self->get_interface;
+ {
+ link_up => N("Link detected on interface %s", $interface),
+ link_down => N("Link beat lost on interface %s", $interface),
+ }->{$status};
+}
+
+1;
diff --git a/lib/network/connection/cable.pm b/lib/network/connection/cable.pm
new file mode 100644
index 0000000..e74ac6a
--- /dev/null
+++ b/lib/network/connection/cable.pm
@@ -0,0 +1,77 @@
+package network::connection::cable;
+
+use strict;
+use common;
+
+use base qw(network::connection::ethernet);
+
+use strict;
+use common;
+use modules;
+use detect_devices;
+
+sub get_type_name() { N("Cable") }
+sub get_type_description() { N("Cable modem") }
+sub get_type_icon() { 'cablemodem-24.png' }
+sub get_metric { 20 }
+
+sub handles_ifcfg {
+ my ($_class, $_ifcfg) = @_;
+ 0;
+}
+
+my $bpalogin_file = '/etc/bpalogin.conf';
+
+sub guess_protocol {
+ my ($self) = @_;
+ $self->{protocol} = 'dhcp';
+}
+
+sub guess_access_settings {
+ my ($self) = @_;
+ $self->{access}{use_bpalogin} = -e $::prefix . $bpalogin_file;
+ if ($self->{access}{use_bpalogin}) {
+ foreach (cat_($::prefix . $bpalogin_file)) {
+ /^username (.*)/ and $self->{access}{login} = $1;
+ /^password (.*)/ and $self->{access}{password} = $1;
+ }
+ }
+}
+
+sub get_access_settings {
+ my ($self) = @_;
+ my %auth = (
+ 0 => N("None"),
+ 1 => N("Use BPALogin (needed for Telstra)"),
+ );
+ [
+ { label => N("Authentication"), type => "list", val => \$self->{access}{use_bpalogin},
+ list => [ sort keys %auth ], format => sub { $auth{$_[0]} } },
+ { label => N("Account Login (user name)"), val => \$self->{access}{login},
+ disabled => sub { !$self->{access}{use_bpalogin} } },
+ { label => N("Account Password"), val => \$self->{access}{password}, hidden => 1,
+ disabled => sub { !$self->{access}{use_bpalogin} } },
+ ];
+}
+
+sub write_settings {
+ my ($self, $o_net, $o_modules_conf) = @_;
+ if ($self->{access}{use_bpalogin}) {
+ substInFile {
+ s/username\s+.*\n/username $self->{access}{login}\n/;
+ s/password\s+.*\n/password $self->{access}{password}\n/;
+ } $::prefix . $bpalogin_file;
+ }
+ services::set_status("bpalogin", $self->{access}{use_bpalogin});
+ $self->SUPER::write_settings($o_net, $o_modules_conf);
+}
+
+sub install_packages {
+ my ($self, $in) = @_;
+ if ($self->{access}{use_bpalogin}) {
+ $in->do_pkgs->ensure_is_installed('bpalogin', '/usr/sbin/bpalogin') or return;
+ }
+ $self->SUPER::install_packages($in);
+}
+
+1;
diff --git a/lib/network/connection/cellular.pm b/lib/network/connection/cellular.pm
new file mode 100644
index 0000000..a9c0d78
--- /dev/null
+++ b/lib/network/connection/cellular.pm
@@ -0,0 +1,52 @@
+package network::connection::cellular;
+
+use base qw(network::connection::ppp);
+
+use strict;
+use common;
+
+my $cellular_d = "/etc/sysconfig/network-scripts/cellular.d";
+
+sub get_providers {
+ require network::connection::providers::cellular;
+ (\%network::connection::providers::cellular::data, '|');
+}
+
+sub get_cellular_settings_file {
+ my ($self) = @_;
+ my $network = $self->get_selected_network or return;
+ $::prefix . $cellular_d . '/' . $network->{name};
+}
+
+sub load_cellular_settings {
+ my ($self) = @_;
+ my $file = $self->get_cellular_settings_file or return;
+ -f $file && { getVarsFromSh($file) };
+}
+
+sub selected_network_is_configured {
+ my ($self) = @_;
+ defined($self->load_cellular_settings);
+}
+
+sub write_cellular_settings {
+ my ($self) = @_;
+ my $file = $self->get_cellular_settings_file or return;
+ setVarsInShMode($file, 0600, { map { (uc($_) => $self->{access}{$_}) } qw(login password apn) });
+}
+
+sub guess_access_settings {
+ my ($self) = @_;
+ my $settings = $self->load_cellular_settings || {};
+ $self->{access}{$_} = $settings->{uc($_)} || $self->{provider}{$_} foreach qw(login password apn);
+}
+
+sub get_access_settings {
+ my ($self) = @_;
+ [
+ { label => N("Access Point Name"), val => \$self->{access}{apn} },
+ @{$self->SUPER::get_access_settings},
+ ];
+}
+
+1;
diff --git a/lib/network/connection/cellular_bluetooth.pm b/lib/network/connection/cellular_bluetooth.pm
new file mode 100644
index 0000000..1457795
--- /dev/null
+++ b/lib/network/connection/cellular_bluetooth.pm
@@ -0,0 +1,94 @@
+package network::connection::cellular_bluetooth;
+
+use base qw(network::connection::cellular);
+
+use strict;
+use common;
+
+my $rfcomm_dev_prefix = "/dev/rfcomm";
+
+sub get_type_name { N("Bluetooth") }
+sub get_type_description { N("Bluetooth Dial Up Networking") }
+sub get_type_icon { 'bluetooth-24.png' }
+sub get_devices { search_services('DUN') }
+sub get_metric { 45 }
+sub get_interface { "ppp0" }
+
+sub get_rfcomm_device {
+ my ($self) = @_;
+ $self->{rfcomm_device} ||= find { ! -e ($rfcomm_dev_prefix . $_) } 0 .. 99;
+}
+
+sub get_tty_device {
+ my ($self) = @_;
+ $rfcomm_dev_prefix . $self->get_rfcomm_device;
+}
+
+# http://www.hingston.demon.co.uk/mike/nokia6680.html
+# http://kapsi.fi/~mcfrisk/linux_gprs.html
+# GPRS specific commands http://www.phonestar.com.my/s_at_10.html
+
+sub search_services {
+ my ($service_type) = @_;
+ my (@services);
+ my $service = {};
+ my ($key, $value);
+ my $push_service = sub { push @services, $service if exists $service->{class} };
+ my $use_key = sub { $key = $_[0]; undef $value };
+ foreach (run_program::rooted_get_stdout($::prefix, 'sdptool', 'search', $service_type)) {
+ if (/^Searching for $service_type on (.+) \.\.\.$/) {
+ $push_service->();
+ $service = { addr => $1 };
+ } elsif (/^Service Name:\s+(.*)$/) {
+ $service->{name} = $1;
+ } elsif (/^Service Provider:\s+(.*)$/) {
+ $service->{name} = $1;
+ } elsif (/^\s*Channel:\s*(\d+)$/) {
+ $service->{channel} = $1;
+ } elsif (/^Service Class ID List/) {
+ $use_key->('class');
+ } else {
+ $value = chomp_($_);
+ }
+ if ($key && $value) {
+ $service->{$key} = $value;
+ $use_key->(undef);
+ }
+ }
+ $push_service->();
+ my %names;
+ foreach (@services) {
+ $names{$_->{addr}} ||= chomp_(run_program::rooted_get_stdout($::prefix, 'hcitool', 'name', $_->{addr}));
+ $_->{description} = $names{$_->{addr}};
+ }
+ @services;
+}
+
+sub write_settings {
+ my ($self) = @_;
+
+ $self->write_cellular_settings;
+
+ my $dev = $self->get_rfcomm_device;
+ output("$::prefix/etc/bluetooth/rfcomm.conf", qq(
+rfcomm$dev {
+ bind yes;
+ device $self->{device}{addr};
+ channel $self->{device}{channel};
+ comment "Dial-up networking";
+}
+));
+
+ my $cid = 1;
+ $self->{access}{at_commands} = [ qq(AT+CGDCONT=$cid,"IP","$self->{access}{apn}") ];
+ $self->{access}{dial_number} = "*99***$cid#";
+
+ $self->SUPER::write_settings;
+}
+
+sub prepare_connection {
+ my ($self) = @_;
+ run_program::rooted_get_stdout($::prefix, 'rfcomm', 'bind', $self->get_rfcomm_device);
+}
+
+1;
diff --git a/lib/network/connection/cellular_card.pm b/lib/network/connection/cellular_card.pm
new file mode 100644
index 0000000..9132f49
--- /dev/null
+++ b/lib/network/connection/cellular_card.pm
@@ -0,0 +1,180 @@
+package network::connection::cellular_card;
+
+use base qw(network::connection::cellular);
+
+use strict;
+use common;
+
+sub get_type_name() { N("GPRS/Edge/3G") }
+sub get_type_icon() { 'cellular-24.png' }
+sub get_devices() {
+ require detect_devices;
+ my @maybe_usbserial_modules = ('usbserial_generic', 'unknown');
+ my @serial = grep { $_->{description} =~ /GPRS|EDGE|3G|UMTS|H.DPA/i } detect_devices::matching_driver('serial_cs', 'usbserial', @maybe_usbserial_modules);
+ member($_->{driver}, @maybe_usbserial_modules) and $_->{driver} = 'usbserial' foreach @serial;
+ @serial, detect_devices::probe_category('network/cellular');
+}
+sub get_metric { 40 }
+sub get_interface() { "ppp0" }
+
+sub get_packages { 'comgt', 'ppp' }
+
+my @thirdparty_settings = (
+ {
+ name => 'nozomi',
+ description => 'Option GlobeTrotter 3G/EDGE and FUSION+',
+ url => 'http://www.pharscape.org/',
+ kernel_module => 1,
+ },
+);
+
+sub get_thirdparty_settings() {
+ \@thirdparty_settings;
+}
+
+sub guess_hardware_settings {
+ my ($self) = @_;
+ $self->{hardware}{pin} ||= chomp_(cat_("/etc/sysconfig/network-scripts/pin-" . $self->get_interface));
+}
+
+sub get_tty_device {
+ my ($self) = @_;
+ $self->{device}{device} ?
+ "/dev/" . $self->{device}{device} :
+ $self->get_driver eq "nozomi" ?
+ "/dev/noz0" :
+ "/dev/ttyUSB0";
+}
+
+sub network_scan_is_slow() { 1 }
+
+sub get_networks {
+ my ($self) = @_;
+ my $cmd = "gcom -d " . $self->get_tty_device;
+ my ($network, $state) = `$cmd reg` =~ /^Registered on \w+ network: "(.*)",(\d+)$/m;
+ my ($strength) = `$cmd sig` =~ /^Signal Quality:\s+(\d+),\d+$/;
+ $self->{networks} = $network && {
+ $network => {
+ name => $network,
+ signal_strength => $strength * 5,
+ current => $state == 2,
+ }
+ };
+}
+
+sub get_hardware_settings {
+ my ($self) = @_;
+ [ { label => N("PIN number"), val => \$self->{hardware}{pin}, hidden => 1 } ];
+}
+
+sub get_peer_default_options {
+ my ($self) = @_;
+ $self->SUPER::get_peer_default_options,
+ "noccp", # disable CCP to avoid warning messages
+ "debug";
+}
+
+sub build_peer {
+ my ($self) = @_;
+ $self->SUPER::build_peer;
+ #- don't run gcom for now, it hangs on ttyUSB0 devices when run from pppd
+ #- $self->{access}{peer}->{init} = "gcom -d $dev < $pin_file"
+}
+
+sub write_settings {
+ my ($self) = @_;
+
+ $self->write_cellular_settings;
+
+ my $interface = $self->get_interface;
+ my $pin_file = "/etc/sysconfig/network-scripts/pin-$interface";
+
+ output_with_perm($pin_file, 0600, $self->{hardware}{pin} . "\n");
+
+ my $cid = 3;
+ $self->{access}{at_commands} = [
+ "AT+CPIN?",
+ # Set +CGEE to 2
+ "AT+CMEE=2",
+ qq(AT+CGDCONT=$cid,"IP","$self->{access}{apn}"),
+ # Setup +CGEQREG (QoS, don't set it for now)
+ # qq(AT+CGEQREQ=3,3,64,384,0,0,2,0,"0E0","0E0",3,0,0),
+ # Attached to network, will return 1
+ "AT+CGATT?",
+ ];
+ $self->{access}{dial_number} = "*99***$cid#";
+
+ $self->SUPER::write_settings;
+}
+
+sub prepare_device {
+ my ($self) = @_;
+
+ my $driver = $self->get_driver;
+ require modules;
+ my $modules_conf = !is_empty_hash_ref($::o) ? $::o->{modules_conf} : modules::any_conf->read;
+ modules::load_and_configure($modules_conf, $driver,
+ if_($driver eq 'usbserial', join(
+ ' ',
+ "vendor=0x" . sprintf("%4x", $self->{device}{vendor}),
+ "product=0x" . sprintf("%4x", $self->{device}{id}))));
+ $modules_conf->write if !ref $::o;
+ sleep 2 if $driver eq 'usbserial';
+}
+
+sub check_device {
+ my ($self) = @_;
+
+ my $dev = $self->get_tty_device;
+ if (! -e $dev) {
+ $self->{device}{error} = N("Unable to open device %s", $dev);
+ return;
+ }
+
+ 1;
+}
+
+sub check_hardware {
+ my ($self) = @_;
+
+ my $device_ready = 0;
+
+ require IPC::Open2;
+ require IO::Select;
+ require c;
+ use POSIX qw(:errno_h);
+
+ my $pid = IPC::Open2::open2(my $cmd_out, my $cmd_in, "gcom", "-d", $self->get_tty_device);
+ common::nonblock($cmd_out);
+ my $selector = IO::Select->new($cmd_out);
+ while ($selector->can_read) {
+ local $_;
+ my $rv = sysread($cmd_out, $_, 512);
+ $rv == 0 and $selector->remove($cmd_out);
+ if (/^\*\*\*SIM ERROR\*\*\*/m) {
+ $self->{hardware}{error} = N("Please check that your SIM card is inserted.");
+ last;
+ } elsif (/^Enter PIN number:/m) {
+ $self->{hardware}{pin} or last;
+ print $cmd_in $self->{hardware}{pin} . "\n";
+ } elsif (/^ERROR entering PIN/m) {
+ $self->{hardware}{error} = N("You entered a wrong PIN code.
+Entering the wrong PIN code multiple times may lock your SIM card!");
+ last;
+ } elsif (/^Waiting for Registration/m) {
+ #- the card seems to be resetted if gcom is killed right here, wait a bit
+ sleep 1;
+ #- don't wait the full scan
+ $device_ready = 1;
+ last;
+ }
+ }
+ kill 'TERM', $pid;
+ close($cmd_out);
+ close($cmd_in);
+ waitpid($pid, c::WNOHANG());
+
+ $device_ready;
+}
+
+1;
diff --git a/lib/network/connection/dvb.pm b/lib/network/connection/dvb.pm
new file mode 100644
index 0000000..3364886
--- /dev/null
+++ b/lib/network/connection/dvb.pm
@@ -0,0 +1,73 @@
+package network::connection::dvb;
+
+use strict;
+use common;
+
+use base qw(network::connection::ethernet);
+
+use strict;
+use common;
+use modules;
+
+sub get_type_name() { N("DVB") }
+sub get_type_description() { N("Satellite (DVB)") }
+sub get_type_icon() { 'dvb-24.png' }
+
+sub get_devices() {
+ require detect_devices;
+ detect_devices::probe_category("multimedia/dvb");
+}
+
+sub get_metric { 15 }
+
+sub handles_ifcfg {
+ my ($_class, $ifcfg) = @_;
+ exists $ifcfg->{DVB_ADAPTER_ID};
+}
+
+sub get_interface {
+ my ($self) = @_;
+ defined $self->{hardware}{adapter_id} && defined $self->{hardware}{network_demux} or return "dvb";
+ 'dvb' . $self->{hardware}{adapter_id} . '_' . $self->{hardware}{network_demux};
+}
+
+sub get_dvb_device {
+ find { sysopen(undef, $_, c::O_RDWR() | c::O_NONBLOCK()) } glob("/dev/dvb/adapter*/net*");
+}
+
+sub load_interface_settings {
+ my ($self) = @_;
+ $self->guess_hardware_settings; #- so that matching interface settings can be loaded
+ $self->network::connection::load_interface_settings;
+ $self->{hardware}{adapter_id} = $self->{ifcfg}{DVB_ADAPTER_ID};
+ $self->{hardware}{network_demux} = $self->{ifcfg}{DVB_NETWORK_DEMUX};
+ $self->{hardware}{network_pid} = $self->{ifcfg}{DVB_NETWORK_PID};
+}
+
+sub guess_hardware_settings {
+ my ($self) = @_;
+ my $device = get_dvb_device() or return;
+ ($self->{hardware}{adapter_id}, $self->{hardware}{network_demux}) = $device =~ m,/dev/dvb/adapter(\d+)/net(\d+),;
+}
+
+sub get_hardware_settings {
+ my ($self) = @_;
+ [
+ { label => N("Adapter card"), val => \$self->{hardware}{adapter_id} },
+ { label => N("Net demux"), val => \$self->{hardware}{network_demux} },
+ { label => N("PID"), val => \$self->{hardware}{network_pid} },
+ ];
+}
+
+sub build_ifcfg_settings {
+ my ($self) = @_;
+ my $settings = {
+ DVB_ADAPTER_ID => qq("$self->{hardware}{adapter_id}"),
+ DVB_NETWORK_DEMUX => qq("$self->{hardware}{network_demux}"),
+ DVB_NETWORK_PID => qq("$self->{hardware}{network_pid}"),
+ MII_NOT_SUPPORTED => "yes",
+ };
+ $self->SUPER::build_ifcfg_settings($settings);
+}
+
+1;
diff --git a/lib/network/connection/ethernet.pm b/lib/network/connection/ethernet.pm
new file mode 100644
index 0000000..39752f5
--- /dev/null
+++ b/lib/network/connection/ethernet.pm
@@ -0,0 +1,512 @@
+package network::connection::ethernet; # $Id: ethernet.pm 147431 2007-03-21 17:06:09Z blino $
+
+use base qw(network::connection);
+
+use strict;
+use common;
+
+our @dhcp_clients = qw(dhclient dhcpcd pump dhcpxd);
+
+sub get_type_name() { N("Ethernet") }
+sub get_type_icon() { 'ethernet-24.png' }
+
+sub get_devices() {
+ #require list_modules;
+ #- FIXME: try to use list_modules::ethernet_categories() (but remove wireless stuff)
+ require detect_devices;
+ my @devices = detect_devices::probe_category('network/main|gigabit|pcmcia|tokenring|usb|firewire');
+ my @lan = grep { detect_devices::is_lan_interface($_) && !detect_devices::is_wireless_interface($_) } detect_devices::get_all_net_devices();
+ @devices, get_unlisted_devices(\@lan, \@devices);
+}
+
+sub get_unlisted_devices {
+ my ($interfaces, $listed_devices) = @_;
+ my @unlisted_interfaces = sort(difference2($interfaces, [ map { device_to_interface($_) } @$listed_devices ]));
+ map { interface_to_device($_) || +{ description => $_, interface => $_ } } @unlisted_interfaces;
+}
+
+sub handles_ifcfg {
+ my ($_class, $ifcfg) = @_;
+ require detect_devices;
+ detect_devices::is_lan_interface($ifcfg->{DEVICE});
+}
+
+sub is_gigabit {
+ my ($self) = @_;
+ require list_modules;
+ member($self->get_driver, list_modules::category2modules('network/gigabit'));
+}
+
+sub get_metric {
+ my ($self) = @_;
+ $self->is_gigabit ? 5 : 10;
+}
+
+sub get_interface {
+ my ($self) = @_;
+ $self->{device}{interface} || device_to_interface($self->{device});
+}
+
+sub check_device {
+ my ($self) = @_;
+ if (!$self->get_interface) {
+ $self->{device}{error} = N("Unable to find network interface for selected device (using %s driver).", $self->get_driver);
+ return 0;
+ }
+ return 1;
+}
+
+sub get_protocols() {
+ {
+ static => N("Manual configuration"),
+ dhcp => N("Automatic IP (BOOTP/DHCP)"),
+ };
+}
+
+sub load_interface_settings {
+ my ($self) = @_;
+
+ $self->network::connection::load_interface_settings;
+
+ $self->{protocol} = $self->{ifcfg}{BOOTPROTO};
+
+ $self->{address}{needhostname} = $self->get_ifcfg_bool('NEEDHOSTNAME');
+ $self->{address}{peerdns} = $self->get_ifcfg_bool('PEERDNS');
+ $self->{address}{peeryp} = $self->get_ifcfg_bool('PEERYP');
+ $self->{address}{peerntpd} = $self->get_ifcfg_bool('PEERNTPD');
+
+ $self->{address}{dhcp_client} = $self->{ifcfg}{DHCP_CLIENT};
+ $self->{address}{dhcp_hostname} = $self->{ifcfg}{DHCP_HOSTNAME};
+ $self->{address}{dhcp_timeout} = $self->{ifcfg}{DHCP_TIMEOUT};
+ $self->{address}{ip_address} = $self->{ifcfg}{IPADDR};
+ $self->{address}{netmask} = $self->{ifcfg}{NETMASK};
+ $self->{address}{gateway} = $self->{ifcfg}{GATEWAY};
+ $self->{address}{dns1} = $self->{ifcfg}{DNS1} || $self->{ifcfg}{MS_DNS1};
+ $self->{address}{dns2} = $self->{ifcfg}{DNS2} || $self->{ifcfg}{MS_DNS2};
+ $self->{address}{domain} = $self->{ifcfg}{DOMAIN};
+
+ my $blacklist_ifplugd = $self->get_ifcfg_bool('MII_NOT_SUPPORTED');
+ $self->{control}{use_ifplugd} = !$blacklist_ifplugd if defined $blacklist_ifplugd;
+ $self->{control}{ipv6_tunnel} = $self->get_ifcfg_bool('IPV6TO4INIT');
+}
+
+sub guess_protocol {
+ my ($self) = @_;
+ $self->{protocol} ||= 'dhcp';
+}
+
+sub guess_address_settings {
+ my ($self) = @_;
+ $self->{address}{dhcp_client} ||= find { -x "$::prefix/sbin/$_" } @dhcp_clients;
+ $self->{address}{peerdns} = 1 if !defined $self->{address}{peerdns};
+ $self->{address}{peeryp} = 1 if !defined $self->{address}{peeryp};
+ $self->supplement_address_settings;
+}
+
+sub supplement_address_settings {
+ my ($self) = @_;
+ if ($self->{protocol} eq 'static' && network::network::is_ip($self->{address}{ip_address})) {
+ require network::network;
+ $self->{address}{netmask} ||= network::network::netmask($self->{address}{ip_address});
+ $self->{address}{gateway} ||= network::network::gateway($self->{address}{ip_address});
+ $self->{address}{dns1} ||= network::network::dns($self->{address}{ip_address});
+ }
+}
+
+sub get_address_settings_label { N("IP settings") }
+
+sub get_address_settings {
+ my ($self, $o_show_all) = @_;
+ my $auto_dns = sub { $self->{protocol} eq 'dhcp' && $self->{address}{peerdns} };
+ my $not_static = sub { $self->{protocol} ne 'static' };
+ my $not_dhcp = sub { $self->{protocol} ne 'dhcp' };
+ [
+ if_($self->{protocol} eq 'static' || $o_show_all,
+ { label => N("IP address"), val => \$self->{address}{ip_address}, disabled => $not_static,
+ focus_out => sub {
+ $self->supplement_address_settings if $self->can('supplement_address_settings');
+ },
+ help => N("Please enter the IP configuration for this machine.
+Each item should be entered as an IP address in dotted-decimal
+notation (for example, 1.2.3.4).") },
+ { label => N("Netmask"), val => \$self->{address}{netmask}, disabled => $not_static },
+ { label => N("Gateway"), val => \$self->{address}{gateway}, disabled => $not_static },
+ ),
+ if_($self->{protocol} eq 'dhcp' || $o_show_all,
+ { text => N("Get DNS servers from DHCP"), val => \$self->{address}{peerdns}, type => "bool", disabled => $not_dhcp },
+ ),
+ { label => N("DNS server 1"), val => \$self->{address}{dns1}, disabled => $auto_dns },
+ { label => N("DNS server 2"), val => \$self->{address}{dns2}, disabled => $auto_dns },
+ { label => N("Search domain"), val => \$self->{address}{domain}, disabled => $auto_dns, advanced => 1,
+ help => N("By default search domain will be set from the fully-qualified host name") },
+ if_($self->{protocol} eq 'dhcp',
+ { label => N("DHCP client"), val => \$self->{address}{dhcp_client}, list => \@dhcp_clients, advanced => 1 },
+ { label => N("DHCP timeout (in seconds)"), val => \$self->{address}{dhcp_timeout}, advanced => 1 },
+ { text => N("Get YP servers from DHCP"), val => \$self->{address}{peeryp}, type => "bool", advanced => 1 },
+ { text => N("Get NTPD servers from DHCP"), val => \$self->{address}{peerntpd}, type => "bool", advanced => 1 },
+ { label => N("DHCP host name"), val => \$self->{address}{dhcp_hostname}, advanced => 1 },
+ #- FIXME: install zcip if not checked
+ if_(0, { text => N("Do not fallback to Zeroconf (169.254.0.0 network)"), type => "bool", val => \$self->{address}{skip_zeroconf}, advanced => 1 }),
+ ),
+ ];
+}
+
+sub check_address_settings {
+ my ($self, $net) = @_;
+
+ if ($self->{protocol} eq 'static') {
+ require network::network;
+ if (!network::network::is_ip($self->{address}{ip_address})) {
+ $self->{address}{error}{message} = N("IP address should be in format 1.2.3.4");
+ $self->{address}{error}{field} = \$self->{address}{ip_address};
+ return 0;
+ }
+ if (!network::network::is_ip($self->{address}{netmask})) {
+ $self->{address}{error}{message} = N("Netmask should be in format 255.255.224.0");
+ $self->{address}{error}{field} = \$self->{address}{netmask};
+ return 0;
+ }
+ if (network::network::is_ip_forbidden($self->{address}{ip_address})) {
+ $self->{address}{error}{message} = N("Warning: IP address %s is usually reserved!", $self->{address}{ip_address});
+ $self->{address}{error}{field} = \$self->{address}{ip_address};
+ return 0;
+ }
+ #- test if IP address is already used
+ if (find { text2bool($_->{ONBOOT}) && $_->{DEVICE} ne $self->get_interface && $_->{IPADDR} eq $self->{address}{ip_address} } values %{$net->{ifcfg}}) {
+ $self->{address}{error}{message} = N("%s already in use\n", $self->{address}{ip_address});
+ $self->{address}{error}{field} = \$self->{address}{ip_address};
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+sub guess_hostname_settings {
+ my ($self) = @_;
+ $self->{address}{needhostname} = 0 if !defined $self->{address}{needhostname};
+ if (!defined $self->{address}{hostname}) {
+ require network::network;
+ my $network = network::network::read_conf($::prefix . $network::network::network_file);
+ $self->{address}{hostname} = $network->{HOSTNAME};
+ }
+}
+
+sub get_hostname_settings {
+ my ($self) = @_;
+ my $auto_hostname = sub { $self->{protocol} eq 'dhcp' && $self->{address}{needhostname} };
+ [
+ if_($self->{protocol} eq 'dhcp',
+ { text => N("Assign host name from DHCP address"), val => \$self->{address}{needhostname}, type => "bool" },
+ ),
+ { label => N("Host name"), val => \$self->{address}{hostname}, disabled => $auto_hostname },
+ ];
+}
+
+sub guess_control_settings {
+ my ($self) = @_;
+
+ $self->network::connection::guess_control_settings($self);
+
+ $self->{control}{onboot} = 1 if !defined $self->{control}{onboot};
+ $self->{control}{use_ifplugd} = !is_ifplugd_blacklisted($self->get_driver)
+ if !defined $self->{control}{use_ifplugd};
+}
+
+sub get_control_settings {
+ my ($self) = @_;
+ [
+ @{$self->network::connection::get_control_settings},
+ { text => N("Network Hotplugging"), val => \$self->{control}{use_ifplugd}, type => "bool",
+ #- FIXME: force ifplugd if wireless roaming is enabled
+ disabled => sub { $self->{control}{force_ifplugd} }, advanced => 1, },
+ #- FIXME: $need_network_restart = $ipv6_tunnel ^ text2bool($ethntf->{IPV6TO4INIT});
+ { text => N("Enable IPv6 to IPv4 tunnel"), val => \$self->{control}{ipv6_tunnel}, type => "bool", advanced => 1 },
+ ];
+}
+
+sub install_packages {
+ my ($self, $in) = @_;
+ if ($self->{protocol} eq 'dhcp') {
+ install_dhcp_client($in, $self->{address}{dhcp_client}) or return;
+ }
+ 1;
+}
+
+sub build_ifcfg_settings {
+ my ($self, $o_options) = @_;
+ my $settings = put_in_hash($o_options, {
+ BOOTPROTO => $self->{protocol},
+ IPADDR => $self->{address}{ip_address},
+ GATEWAY => $self->{address}{gateway},
+ NETMASK => $self->{address}{netmask},
+ NEEDHOSTNAME => bool2yesno($self->{address}{needhostname}),
+ PEERYP => bool2yesno($self->{address}{peeryp}),
+ PEERDNS => bool2yesno($self->{address}{peerdns}),
+ RESOLV_MODS => bool2yesno($self->{address}{dns1} || $self->{address}{dns2}),
+ PEERNTPD => bool2yesno($self->{address}{peerntpd}),
+ DHCP_CLIENT => $self->{address}{dhcp_client},
+ DHCP_HOSTNAME => $self->{address}{dhcp_hostname},
+ DHCP_TIMEOUT => $self->{address}{dhcp_timeout},
+ MII_NOT_SUPPORTED => bool2yesno(!$self->{control}{use_ifplugd}),
+ IPV6INIT => bool2yesno($self->{control}{ipv6_tunnel}),
+ IPV6TO4INIT => bool2yesno($self->{control}{ipv6_tunnel}),
+ DNS1 => $self->{address}{dns1},
+ DNS2 => $self->{address}{dns2},
+ DOMAIN => $self->{address}{domain},
+ LINK_DETECTION_DELAY => $self->get_link_detection_delay,
+ });
+ $self->network::connection::build_ifcfg_settings($settings);
+}
+
+sub write_settings {
+ my ($self, $o_net, $o_modules_conf) = @_;
+ $o_modules_conf->set_alias($self->get_interface, $self->get_driver) if $o_modules_conf;
+ $self->SUPER::write_settings($o_net, $o_modules_conf);
+}
+
+sub get_status_message {
+ my ($self, $status) = @_;
+ my $interface = $self->get_interface;
+ {
+ link_up => N("Link beat detected on interface %s", $interface),
+ link_down => N("Link beat lost on interface %s", $interface),
+ map { (
+ "$_->[0]_request" => N("Requesting a network address on interface %s (%s protocol)...", $interface, $_->[1]),
+ "$_->[0]_success" => N("Got a network address on interface %s (%s protocol)", $interface, $_->[1]),
+ "$_->[0]_failure" => N("Failed to get a network address on interface %s (%s protocol)", $interface, $_->[1]),
+ ) } ([ 'dhcp', 'DHCP' ], [ 'zcip', 'ZeroConf' ]),
+ }->{$status} || $self->network::connection::get_status_message($status);
+}
+
+use c;
+use detect_devices;
+use common;
+use run_program;
+
+sub install_dhcp_client {
+ my ($in, $client) = @_;
+ my %packages = (
+ "dhclient" => "dhcp-client",
+ );
+ #- use default dhcp client if none is provided
+ $client ||= $dhcp_clients[0];
+ $client = $packages{$client} if exists $packages{$client};
+ $in->do_pkgs->ensure_is_installed($client, undef, 1);
+}
+
+my @hwaddr_fields = qw(pci_domain pci_bus pci_device pci_function);
+
+sub are_same_HwIDs {
+ my ($device1, $device2) = @_;
+ every { $device1->{$_} == $device2->{$_} } @hwaddr_fields;
+}
+
+sub parse_hwaddr {
+ my ($hw_addr) = @_;
+ return if !$hw_addr;
+ my %device;
+ @device{@hwaddr_fields} = map { hex($_) } ($hw_addr =~ /([0-9a-f]+):([0-9a-f]+):([0-9a-f]+)\.([0-9a-f]+)/);
+ (every { defined $_ } keys %device) ? \%device : undef;
+}
+
+sub mapIntfToDevice {
+ my ($interface) = @_;
+ my $hw_addr = c::getHwIDs($interface);
+ return {} if $hw_addr =~ /^usb/;
+ my $device = parse_hwaddr($hw_addr);
+ $device ? grep { are_same_HwIDs($_, $device) } detect_devices::probeall__real() : {};
+}
+
+sub device_matches_interface_HwIDs {
+ my ($device, $interface) = @_;
+ my $hw_addr = c::getHwIDs($interface);
+ $hw_addr =~ /^usb/ and return;
+ my ($device2) = parse_hwaddr($hw_addr);
+ return if !$device2;
+ are_same_HwIDs($device, $device2);
+}
+
+sub get_interface_sysfs_path {
+ my ($interface) = @_;
+ my $dev_path = "/sys/class/net/$interface/device";
+ my $bus = detect_devices::get_sysfs_field_from_link($dev_path, 'bus');
+ if ($bus eq 'ieee1394') {
+ my $child = first(glob("$dev_path/host_id/*-*"));
+ $dev_path = $child if $child;
+ }
+ $dev_path;
+}
+
+sub get_interface_ids {
+ my ($interface) = @_;
+ detect_devices::get_ids_from_sysfs_device(get_interface_sysfs_path($interface));
+}
+
+sub device_matches_interface {
+ my ($device, $interface) = @_;
+ detect_devices::device_matches_sysfs_ids($device, get_interface_ids($interface));
+}
+
+sub device_to_interface {
+ my ($device) = @_;
+ my @all_interfaces = detect_devices::get_net_interfaces();
+ find {
+ device_matches_interface_HwIDs($device, $_) ||
+ device_matches_interface($device, $_);
+ } @all_interfaces;
+}
+
+sub interface_to_device {
+ my ($interface) = @_;
+ my $sysfs_ids = get_interface_ids($interface);
+ find { detect_devices::device_matches_sysfs_ids($_, $sysfs_ids) } detect_devices::probeall__real();
+}
+
+sub interface_to_driver {
+ my ($interface) = @_;
+ my $dev_path = get_interface_sysfs_path($interface);
+ #- FIXME: use $bus and move in get_interface_sysfs_path if possible
+ my $child = -f "$dev_path/idVendor" && first(glob("$dev_path/*-*:*.*"));
+ $dev_path = $child if -f "$child/driver";
+ detect_devices::get_sysfs_field_from_link($dev_path, 'driver');
+}
+
+# return list of [ intf_name, module, device_description ] tuples such as:
+# [ "eth0", "3c59x", "3Com Corporation|3c905C-TX [Fast Etherlink]" ]
+#
+# this function try several method in order to get interface's driver and description in order to support both:
+# - hotplug managed devices (USB, firewire)
+# - special interfaces (IP aliasing, VLAN)
+sub get_eth_cards {
+ my ($modules_conf) = @_;
+ my @all_cards = detect_devices::get_lan_interfaces();
+
+ my @devs = detect_devices::pcmcia_probe();
+ my $saved_driver;
+ # compute device description and return (interface, driver, description) tuples:
+ return map {
+ my $interface = $_;
+ my $description;
+ # 1) get interface's driver through ETHTOOL ioctl:
+ my ($a, $detected_through_ethtool);
+ $a = c::getNetDriver($interface);
+ if ($a) {
+ $detected_through_ethtool = 1;
+ } else {
+ # 2) get interface's driver through module aliases:
+ $a = $modules_conf->get_alias($interface);
+ }
+
+ # workaround buggy drivers that returns a bogus driver name for the GDRVINFO command of the ETHTOOL ioctl:
+ my %fixes = (
+ "p80211_prism2_cs" => 'prism2_cs',
+ "p80211_prism2_pci" => 'prism2_pci',
+ "p80211_prism2_usb" => 'prism2_usb',
+ "ip1394" => "eth1394",
+ "DL2K" => "dl2k",
+ "orinoco" => undef, #- should be orinoco_{cs,nortel,pci,plx,tmd}
+ "hostap" => undef, #- should be hostap_{cs,pci,plx}
+ );
+ if (exists $fixes{$a}) {
+ $a = $fixes{$a};
+ $a or undef $detected_through_ethtool;
+ }
+
+ # 3) try to match a PCMCIA device for device description:
+ if (my $b = find { $_->{device} eq $interface } @devs) { # PCMCIA case
+ $a = $b->{driver};
+ $description = $b->{description};
+ } else {
+ # 4) try to lookup a device by hardware address for device description:
+ # maybe should have we try sysfs first for robustness?
+ ($description) = (mapIntfToDevice($interface))[0]->{description};
+ }
+ # 5) try to match a device through sysfs for driver & device description:
+ # (eg: ipw2100 driver for intel centrino do not support ETHTOOL)
+ if (!$description || !$a) {
+ my $drv = interface_to_driver($interface);
+ $a = $drv if $drv && !$detected_through_ethtool;
+ my $card = interface_to_device($interface);
+ $description ||= $card->{description} if $card;
+ }
+ # 6) try to match a device by driver for device description:
+ # (eg: madwifi, ndiswrapper, ...)
+ if (!$description) {
+ my @cards = grep { $_->{driver} eq ($a || $saved_driver) } detect_devices::probeall__real();
+ $description = $cards[0]{description} if @cards == 1;
+ }
+ $a and $saved_driver = $a; # handle multiple cards managed by the same driver
+ [ $interface, $saved_driver, if_($description, $description) ];
+ } @all_cards;
+}
+
+sub get_eth_cards_names {
+ my (@all_cards) = @_;
+ map { $_->[0] => join(': ', $_->[0], $_->[2]) } @all_cards;
+}
+
+#- returns (link_type, mac_address)
+sub get_eth_card_mac_address {
+ my ($intf) = @_;
+ #- don't look for 6 bytes addresses only because of various non-standard MAC addresses
+ `$::prefix/sbin/ip -o link show $intf 2>/dev/null` =~ m|.*link/(\S+)\s((?:[0-9a-f]{2}:?)+)\s|;
+}
+
+#- write interfaces MAC address in iftab
+sub update_iftab() {
+ #- skip aliases interfaces
+ foreach my $intf (grep { !/:\d+$/ } detect_devices::get_lan_interfaces()) {
+ my ($link_type, $mac_address) = get_eth_card_mac_address($intf) or next;
+ #- do not write zeroed MAC addresses in iftab, it confuses ifrename
+ $mac_address =~ /^[0:]+$/ and next;
+ # ifrename supports alsa IEEE1394, EUI64 and IRDA
+ member($link_type, 'ether', 'ieee1394', 'irda', '[27]') or next;
+ substInFile {
+ s/^$intf\s+.*\n//;
+ s/^.*\s+$mac_address\n//;
+ $_ .= qq($intf mac $mac_address\n) if eof;
+ } "$::prefix/etc/iftab";
+ }
+}
+
+sub update_udev_net_config() {
+ my $lib = arch() =~ /x86_64/ ? "lib64" : "lib";
+ my $net_name_helper = "/$lib/udev/net_name_helper";
+ my $udev_net_config = "/etc/udev/rules.d/61-net_config.rules";
+ my @old_config = cat_($udev_net_config);
+ #- skip aliases and vlan interfaces
+ foreach my $intf (grep { !/[:.]\d+$/ } detect_devices::get_lan_interfaces()) {
+ (undef, my $mac_address) = get_eth_card_mac_address($intf) or next;
+ #- do not write zeroed MAC addresses
+ $mac_address =~ /^[0:]+$/ and next;
+ #- skip already configured addresses
+ any { !/^\s*#/ && /"$mac_address"/ } @old_config and next;
+ local $ENV{INTERFACE} = $intf;
+ local $ENV{SUBSYSTEM} = 'net';
+ run_program::rooted($::prefix, $net_name_helper, '>', '/dev/null', $mac_address);
+ }
+}
+
+# automatic net aliases configuration
+sub configure_eth_aliases {
+ my ($modules_conf) = @_;
+ foreach my $card (get_eth_cards($modules_conf)) {
+ $modules_conf->set_alias($card->[0], $card->[1]);
+ }
+ $::isStandalone and $modules_conf->write;
+ update_iftab();
+ update_udev_net_config();
+}
+
+sub get_link_detection_delay {
+ my ($self) = @_;
+ member($self->get_driver, qw(forcedeth r8169 skge sky2 tg3)) && 6;
+}
+
+sub is_ifplugd_blacklisted {
+ my ($module) = @_;
+ !$module || member($module, qw(via-velocity));
+}
+
+1;
diff --git a/lib/network/isdn.pm b/lib/network/connection/isdn.pm
index 740741b..4b85d1d 100644
--- a/lib/network/isdn.pm
+++ b/lib/network/connection/isdn.pm
@@ -1,18 +1,40 @@
-package network::isdn; # $Id$
+package network::connection::isdn;
+
+use base qw(network::connection);
use strict;
-use network::isdn_consts;
use common;
+
+sub get_type_name { N("ISDN") }
+sub get_type_icon { 'isdn-24.png' }
+
+sub get_devices {
+ require modules;
+ #- FIXME: module alias should be written when config is written only
+ @{detect_backend(modules::any_conf->read)};
+}
+sub get_metric { 30 }
+
+use network::connection::isdn::consts;
use modules;
use run_program;
use log;
use network::tools;
use services;
-
-sub write_config {
+sub apply_config {
my ($in, $isdn) = @_;
- $in->do_pkgs->install('isdn4net', if_($isdn->{speed} =~ /128/, 'ibod'), 'isdn4k-utils');
+
+ $isdn = find_capi_card($isdn) if $isdn->{driver} eq "capidrv";
+ unload_connection($isdn);
+ install_packages($isdn, $in);
+ write_settings($isdn);
+ write_capi_conf($isdn) if $isdn->{driver} eq "capidrv";
+ prepare_connection($isdn);
+}
+
+sub write_settings {
+ my ($isdn) = @_;
output_with_perm("$::prefix/etc/isdn/profile/link/myisp", 0600,
qq(
@@ -44,33 +66,13 @@ usepeerdns
defaultroute
";
- services::stop("isdn4linux"); #- to be stopped before capi is loaded
- if ($isdn->{driver} eq "capidrv") {
- setup_capi_conf($in, get_capi_card($in, $isdn));
- services::enable('capi4linux');
- } else {
- services::disable('capi4linux');
- }
- services::enable('isdn4linux');
-
network::tools::write_secret_backend($isdn->{login}, $isdn->{passwd});
1;
}
-
-sub setup_capi_conf {
- my ($in, $capi_card) = @_;
-
- $in->do_pkgs->ensure_is_installed('isdn4k-utils', "/etc/rc.d/init.d/capi4linux"); #- capi4linux service
- is_module_installed($capi_card->{driver}) or $in->do_pkgs->install(@{$capi_card->{packages}});
- if ($capi_card->{firmware} && ! -f "$::prefix/usr/lib/isdn/$capi_card->{firmware}") {
- $in->do_pkgs->install("$capi_card->{driver}-firmware");
- }
-
- #- stop capi4linux before new config is written so that it can unload the driver
- services::stop("capi4linux");
-
+sub write_capi_conf {
+ my ($capi_card) = @_;
my $capi_conf;
my $firmware = $capi_card->{firmware} || '-';
if ($capi_card->{driver} eq "fcclassic") {
@@ -80,9 +82,43 @@ sub setup_capi_conf {
} else {
$capi_conf = "$capi_card->{driver} $firmware - - - - -\n";
}
+
output("$::prefix/etc/capi.conf", $capi_conf);
}
+sub unload_connection {
+ my ($isdn) = @_;
+ require services;
+ services::stop("isdn4linux"); #- to be stopped before capi is loaded
+ if ($isdn->{driver} eq "capidrv") {
+ #- stop capi4linux before new config is written so that it can unload the driver
+ services::stop("capi4linux");
+ }
+}
+
+sub install_packages {
+ my ($isdn, $in) = @_;
+
+ $in->do_pkgs->install(
+ 'isdn4k-utils',
+ $isdn->{driver} eq "capidrv" ?
+ (if_(!modules::module_is_available($isdn->{driver}), @{$isdn->{packages}}),
+ if_($isdn->{firmware} && ! -f "$::prefix/usr/lib/isdn/$isdn->{firmware}", "$isdn->{driver}-firmware"))
+ :
+ ('isdn4net', if_($isdn->{speed} =~ /128/, 'ibod'))
+ );
+}
+
+sub prepare_connection {
+ my ($isdn) = @_;
+ if ($isdn->{driver} eq "capidrv") {
+ services::enable('capi4linux');
+ } else {
+ services::disable('capi4linux');
+ }
+ services::enable('isdn4linux');
+}
+
sub read_config {
my ($isdn) = @_;
@@ -145,7 +181,7 @@ sub detect_backend {
}
$c->{options} =~ /protocol=(\d)/ and $isdn->{protocol} = $1;
push @isdn, $isdn;
- } modules::probe_category('network/isdn');
+ } detect_devices::probe_category('network/isdn');
\@isdn;
}
@@ -168,21 +204,20 @@ sub get_cards() {
}
-sub is_module_installed {
- my ($driver) = @_;
- find { m!/\Q$driver\E\.k?o! } cat_($::prefix . '/lib/modules/' . c::kernel_version() . '/modules.dep');
+sub find_capi_card {
+ my ($isdn) = @_;
+ find {
+ hex($isdn->{vendor}) == $_->{vendor} && hex($isdn->{id}) == $_->{id};
+ } @isdn_capi;
}
-
sub get_capi_card {
my ($in, $isdn) = @_;
- my $capi_card = find {
- hex($isdn->{vendor}) == $_->{vendor} && hex($isdn->{id}) == $_->{id};
- } @isdn_capi or return;
+ my $capi_card = find_capi_card($isdn) or return;
#- check if the capi driver is available
- unless (is_module_installed($capi_card->{driver}) || ($capi_card->{packages} = $in->do_pkgs->check_kernel_module_packages("$capi_card->{driver}-kernel"))) {
+ unless (modules::module_is_available($capi_card->{driver}) || ($capi_card->{packages} = $in->do_pkgs->check_kernel_module_packages($capi_card->{driver}))) {
log::explanations("a capi driver ($capi_card->{driver}) exists to replace $isdn->{driver}, but it is not installed and no packages provide it");
return;
}
diff --git a/lib/network/isdn_consts.pm b/lib/network/connection/isdn/consts.pm
index b2361fe..a53ddbe 100644
--- a/lib/network/isdn_consts.pm
+++ b/lib/network/connection/isdn/consts.pm
@@ -1,4 +1,4 @@
-package network::isdn_consts; # $Id$
+package network::connection::isdn::consts; # $Id: consts.pm 54070 2006-08-07 17:34:38Z blino $
use vars qw(@ISA @EXPORT);
@ISA = qw(Exporter);
@EXPORT = qw(@isdndata @isdn_capi);
diff --git a/lib/network/connection/pots.pm b/lib/network/connection/pots.pm
new file mode 100644
index 0000000..be7bf9f
--- /dev/null
+++ b/lib/network/connection/pots.pm
@@ -0,0 +1,133 @@
+package network::connection::pots;
+
+use base qw(network::connection::ppp);
+
+use strict;
+use common;
+
+sub get_type_name {
+ #-PO: POTS means "Plain old telephone service"
+ N("POTS");
+}
+sub get_type_description {
+ #-PO: POTS means "Plain old telephone service"
+ #-PO: remove it if it doesn't have an equivalent in your language
+ #-PO: for example, in French, it can be translated as "RTC"
+ N("Analog telephone modem (POTS)");
+}
+sub get_type_icon { 'potsmodem-24.png' }
+sub get_metric { 50 }
+
+sub handles_ifcfg {
+ my ($_class, $ifcfg) = @_;
+ $ifcfg->{DEVICE} =~ /^ppp/ && exists $ifcfg->{MODEMPORT};
+}
+
+sub get_devices {
+ require detect_devices;
+ require modules;
+ #- FIXME: module alias should be written when config is written only
+ #detect_devices::getModem(modules::any_conf->read);
+ ();
+}
+
+my @thirdparty_settings = (
+ {
+ matching => qr/^Hcf:/,
+ description => 'HCF 56k Modem',
+ url => 'http://www.linuxant.com/drivers/hcf/',
+ name => 'hcfpcimodem',
+ kernel_module => {
+ test_file => 'hcfpciengine',
+ },
+ tools => {
+ test_file => '/usr/sbin/hcfpciconfig',
+ },
+ device => '/dev/ttySHCF0',
+ post => '/usr/sbin/hcfpciconfig --auto',
+ restart_service => 'hcfpci',
+ },
+
+ {
+ matching => qr/^Hsf:/,
+ description => 'HSF 56k Modem',
+ url => 'http://www.linuxant.com/drivers/hsf/',
+ name => 'hsfmodem',
+ kernel_module => {
+ test_file => 'hsfengine',
+ },
+ tools => {
+ test_file => '/usr/sbin/hsfconfig',
+ },
+ device => '/dev/ttySHSF0',
+ post => '/usr/sbin/hsfconfig --auto',
+ restart_service => 'hsf',
+ },
+
+ {
+ matching => qr/^LT:/,
+ description => 'LT WinModem',
+ url => 'http://www.heby.de/ltmodem/',
+ name => 'ltmodem',
+ kernel_module => 1,
+ tools => {
+ test_file => '/etc/devfs/conf.d/ltmodem.conf',
+ },
+ device => '/dev/ttyS14',
+ links => [
+ 'http://linmodems.technion.ac.il/Ltmodem.html',
+ 'http://linmodems.technion.ac.il/packages/ltmodem/',
+ ],
+ },
+
+ {
+ matching => [ list_modules::category2modules('network/slmodem') ],
+ description => 'Smartlink WinModem',
+ url => 'http://www.smlink.com/content.aspx?id=135/',
+ name => 'slmodem',
+ kernel_module => 1,
+ tools => {
+ test_file => '/usr/sbin/slmodemd',
+ },
+ device => '/dev/ttySL0',
+ post => sub {
+ my ($driver) = @_;
+ addVarsInSh("$::prefix/etc/sysconfig/slmodemd", { SLMODEMD_MODULE => $driver });
+ },
+ restart_service => "slmodemd",
+ },
+
+ {
+ name => 'sm56',
+ description => 'Motorola SM56 WinModem',
+ url => 'http://www.motorola.com/softmodem/driver.htm#linux',
+ kernel_module => {
+ package => 'sm56',
+ },
+ no_club => 1,
+ device => '/dev/sm56',
+ },
+);
+
+sub get_thirdparty_settings { \@thirdparty_settings }
+
+sub get_providers {
+ my $db_path = "/usr/share/apps/kppp/Provider";
+ #$in->do_pkgs->ensure_is_installed('kdenetwork-kppp-provider', $db_path);
+ my $separator = "|";
+ my %providers;
+ foreach (all($::prefix . $db_path)) {
+ s!_! !g;
+ my $country = $_;
+ my $t_country = translate($country);
+ my $country_root = $::prefix . $db_path . '/' . $country;
+ foreach (grep { $_ ne '.directory' } all($country_root)) {
+ my $path = $country_root . $_;
+ s/%([0-9]{3})/chr(int($1))/eg;
+ $providers{$t_country . $separator . $_} = { path => $path };
+ }
+ }
+ (\%providers, $separator);
+}
+
+1;
diff --git a/lib/network/connection/ppp.pm b/lib/network/connection/ppp.pm
new file mode 100644
index 0000000..d1db2b3
--- /dev/null
+++ b/lib/network/connection/ppp.pm
@@ -0,0 +1,138 @@
+package network::connection::ppp;
+
+use strict;
+use common;
+
+use base qw(network::connection);
+
+my %authentication_methods = (
+ script => N_("Script-based"),
+ pap => N_("PAP"),
+ terminal_ => N_("Terminal-based"),
+ chap => N_("CHAP"),
+ pap_chap => N_("PAP/CHAP"),
+);
+
+my @kppp_authentication_methods = qw(script pap terminal chap pap_chap);
+my @secrets_files = qw(pap-secrets chap-secrets);
+
+sub get_access_settings {
+ my ($self) = @_;
+ [
+ { label => N("Account Login (user name)"), val => \$self->{access}{login} },
+ { label => N("Account Password"), val => \$self->{access}{password}, hidden => 1 },
+ ];
+}
+
+sub get_secret {
+ my ($_self, $login) = @_;
+ foreach (@secrets_files) {
+ my $file = "$::prefix/etc/ppp/$_";
+ foreach (cat_($file)) {
+ my ($l, undef, $password) = split(' ');
+ if ($l && $password) {
+ s/^(['"]?)(.*)\1$/$2/ foreach $l, $password;
+ return $password if $l eq $login;
+ }
+ }
+ }
+}
+
+sub write_secrets {
+ my ($self) = @_;
+ foreach (@secrets_files) {
+ my $file = "$::prefix/etc/ppp/$_";
+ substInFile {
+ s/^'$self->{access}{login}'.*\n//;
+ $_ .= "\n'$self->{access}{login}' * '$self->{access}{password}' * \n" if eof;
+ } $file;
+ chmod 0600, $file;
+ }
+}
+
+sub get_options {
+ #- options: PAPNAME PEERDNS
+}
+
+sub get_tty_device { "/dev/modem" }
+
+sub build_ifcfg_settings {
+ my ($self) = @_;
+ my $modemport = $self->get_tty_device;
+ my $settings = put_in_hash($self->{settings}, {
+ if_($modemport, MODEMPORT => $modemport),
+ LINESPEED => "115200",
+ PERSIST => "yes",
+ DEBUG => "yes",
+ DEFROUTE => "yes",
+ });
+ $self->SUPER::build_ifcfg_settings($settings);
+}
+
+sub build_chat {
+ my ($self) = @_;
+ #- required access parameters:
+ #- dial_number
+ #- optional:
+ #- auth_method: key of %authentication_methods
+ #- login
+ #- password
+ #- at_commands: array ref of AT commands
+ (map { "ABORT $_" } "BUSY", "ERROR", "'NO CARRIER'", "'NO DIALTONE'", "'Invalid Login'", "'Login incorrect'", "VOICE", "'NO ANSWER'", "DELAYED", "'SIM PIN'"),
+ qq('' ATZ),
+ if_(ref $self->{access}{at_commands}, map { qq(OK-AT-OK '$_') } @{$self->{access}{at_commands}}),
+ qq(OK 'ATDT$self->{access}{dial_number}'),
+ qq(TIMEOUT 120),
+ qq(CONNECT ''),
+ if_(member($self->{access}{auth_method}, qw(script terminal)),
+ qq('ogin:--ogin:' '$self->{access}{login}'),
+ qq('ord:' '$self->{access}{password}')),
+ qq(TIMEOUT 5),
+ qq('~--' '');
+}
+
+sub write_chat {
+ my ($self) = @_;
+ my $interface = $self->get_interface;
+ my $chat_file = "/etc/sysconfig/network-scripts/chat-$interface";
+ output_with_perm($::prefix . $chat_file, 0755, join("\n", $self->build_chat, ''));
+}
+
+sub get_peer_default_options {
+ my ($_self) = @_;
+ qw(noauth defaultroute usepeerdns);
+}
+
+sub build_peer {
+ my ($self) = @_;
+ #- options:
+ #- init
+ #- connect
+ #- pty
+ #- plugin
+ if ($self->{access}{dial_number}) {
+ my $interface = $self->get_interface;
+ my $chat_file = "/etc/sysconfig/network-scripts/chat-$interface";
+ $self->{access}{peer}{connect} ||= qq("/usr/sbin/chat -v -f $chat_file");
+ }
+ $self->get_peer_default_options,
+ (map { if_($self->{access}{peer}{$_}, $_ . " " . $self->{access}{peer}{$_}) } qw(init connect pty plugin)),
+ if_($self->{access}{login}, qq(user "$self->{access}{login}"));
+}
+
+sub write_peer {
+ my ($self) = @_;
+ my $interface = $self->get_interface;
+ my $peer_file = "/etc/ppp/peers/$interface";
+ output_with_perm($::prefix . $peer_file, 0755, join("\n", $self->build_peer, ''));
+}
+
+sub write_settings {
+ my ($self) = @_;
+ $self->write_secrets if $self->{access}{login};
+ $self->write_chat if $self->{access}{dial_number};
+ $self->write_peer;
+ $self->network::connection::write_settings;
+}
+
+1;
diff --git a/lib/network/connection/providers/cellular.pm b/lib/network/connection/providers/cellular.pm
new file mode 100644
index 0000000..ef630b4
--- /dev/null
+++ b/lib/network/connection/providers/cellular.pm
@@ -0,0 +1,28 @@
+package network::connection::providers::cellular;
+
+use common;
+use utf8;
+
+# http://www.reqwireless.com/apns.html
+# http://wiki.mig33.com/mig33/show/apn
+# http://www.unlocks.co.uk/gprs_settings.php
+# http://www.opera.com/products/smartphone/docs/connect/
+# http://www.taniwha.org.uk/gprs.html
+
+our %data = (
+ N("France") . "|Orange Grand Public" => {
+ apn => "orange.fr",
+ login => "orange",
+ password => "orange",
+ },
+ N("France") . "|Orange Entreprises" => {
+ apn => "internet-entreprise",
+ login => "orange",
+ password => "orange",
+ },
+ N("France") . "|SFR" => {
+ apn => "websfr",
+ },
+);
+
+1;
diff --git a/lib/network/adsl_consts.pm b/lib/network/connection/providers/xdsl.pm
index c3cc03b..6956e1c 100644
--- a/lib/network/adsl_consts.pm
+++ b/lib/network/connection/providers/xdsl.pm
@@ -1,20 +1,23 @@
-package network::adsl_consts; # $Id$
+# -*- coding: utf-8 -*-
+package network::connection::providers::xdsl; # $Id: xdsl.pm 59309 2006-09-01 12:08:15Z tv $
# This should probably be splitted out into ldetect-lst as some provider db
-use vars qw(@ISA @EXPORT);
use common;
use utf8;
-@ISA = qw(Exporter);
-@EXPORT = qw(@adsl_data);
-
# Originally from :
# http://www.eagle-usb.org/article.php3?id_article=23
# http://www.sagem.com/web-modems/download/support-fast1000-fr.htm
# http://perso.wanadoo.fr/michel-m/protocolesfai.htm
+# Then other ISP found in :
+# http://www.adslayuda.com/Comtrend500+file-16.html
+
+# the output is provided in html at http://faq.eagle-usb.org/wakka.php?wiki=ListConfigADSL
+# this file should be put in /usr/share/eagle-usb/ for eagle-usb driver
+# or in /usr/lib/libDrakX/network/ as part of the drakxtools
-our %adsl_data = (
+our %data = (
## format chosen is the following :
# country|provider => { VPI, VCI_hexa, ... } all parameters
# country is automagically translated into LANG with N function
@@ -32,11 +35,11 @@ our %adsl_data = (
# 6 RFC2364 PPPoA VCmux
# see http://faq.eagle-usb.org/wakka.php?wiki=AdslDescription
# dns are provided for when !usepeerdns in peers config file
- # dnsServer2 dnsServer3 : main DNS
- # dnsServers_text : string with any valid DNS (when more than 2)
+ # dnsServers : array ref with any valid DNS (order matters)
# DOMAINNAME2 : used for search key in /etc/resolv.conf
# method : PPPoA, pppoe, static or dhcp
- # methods_all : all methods for connection with this ISP (when more than 1)
+ # login_format : e.g. fti/login for France Telecom
+ # encryption : for pppd connection, when encryption is supported
# modem : model of modem provided by ISP or tested with ISP
# please forward updates to http://forum.eagle-usb.org
# try to order alphabetically by country (in English) / ISP (local language)
@@ -48,19 +51,37 @@ our %adsl_data = (
vci => 23,
Encapsulation => 1,
method => 'pppoe',
- dnsServer2 => '82.101.136.29',
- dnsServer3 => '82.101.136.206',
+ dnsServers => [ qw(82.101.136.29 82.101.136.206) ],
+ },
+
+ N("Algeria") . "|Algerie Telecom (FAWRI)" =>
+ {
+ provider_id => 'DZ02',
+ vpi => 0,
+ vci => 26,
+ Encapsulation => 1,
+ method => 'pppoe',
+ dnsServers => [ qw(61.88.88.88 205.252.144.228) ],
},
N("Argentina") . "|Speedy" =>
{
provider_id => 'AR01',
- vpi => 1,
+ vpi => 8,
vci => 23,
Encapsulation => 1,
method => 'pppoe',
- dnsServer2 => '200.51.254.238',
- dnsServer3 => '200.51.209.22',
+ dnsServers => [ qw(200.51.254.238 200.51.209.22) ],
+ },
+
+ N("Argentina") . "|Arnet" =>
+ {
+ provider_id => 'AR02',
+ vpi => 8,
+ vci => 21,
+ Encapsulation => 1,
+ method => 'pppoe',
+ dnsServers => [ qw(200.45.191.35 200.45.191.40) ],
},
N("Austria") . "|Any" =>
@@ -90,6 +111,36 @@ our %adsl_data = (
method => 'pppoe',
},
+ N("Australia") . "|Arachnet" =>
+ {
+ provider_id => 'AU01',
+ url_tech => "http://www.ains.com.au/consumer/support/technical.htm",
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 6,
+ method => 'pppoa',
+ },
+
+ N("Australia") . "|Speedstream On net" =>
+ {
+ provider_id => 'AU02',
+ url_tech => "http://www.ains.com.au/consumer/support/technical.htm",
+ vpi => 8,
+ vci => 22,
+ Encapsulation => 6,
+ method => 'pppoa',
+ },
+
+ N("Australia") . "|Speedstream Off net" =>
+ {
+ provider_id => 'AU03',
+ url_tech => "http://www.ains.com.au/consumer/support/technical.htm",
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 1,
+ method => 'pppoe',
+ },
+
N("Belgium") . "|ADSL Office" =>
{
provider_id => 'BE04',
@@ -106,8 +157,7 @@ our %adsl_data = (
vci => 23,
Encapsulation => 6,
method => 'pppoa',
- dnsServer2 => '212.35.2.1',
- dnsServer3 => '212.35.2.2',
+ dnsServers => [ qw(212.35.2.1 212.35.2.2 212.233.1.34 212.233.2.34) ],
DOMAINNAME2 => 'tiscali.be',
},
@@ -129,6 +179,15 @@ our %adsl_data = (
method => 'pppoa',
},
+ N("Belgium") . "|Scarlet ADSL" =>
+ {
+ provider_id => 'BE05',
+ vpi => 8,
+ vci => 20,
+ Encapsulation => 6,
+ method => 'pppoa',
+ },
+
N("Brazil") . "|Speedy/Telefonica" =>
{
provider_id => 'BR01',
@@ -136,8 +195,7 @@ our %adsl_data = (
vci => 23,
Encapsulation => 1,
method => 'pppoe',
- dnsServer2 => '200.204.0.10',
- dnsServer3 => '200.204.0.138',
+ dnsServers => [ qw(200.204.0.10 200.204.0.138) ],
},
N("Brazil") . "|Velox/Telemar" =>
@@ -365,23 +423,61 @@ our %adsl_data = (
method => 'pppoe',
},
- N("Czech Republic") . "|Cesky Telecom" =>
+ N("Czech Republic") . "|Cesky Telecom PPPoA" =>
{
provider_id => 'CZ01',
url_tech => 'http://www.telecom.cz/domacnosti/internet/pristupove_sluzby/broadband/vse_o_kz_a_moznostech_instalace.php',
vpi => 8,
- vci => 48,
+ vci => 30,
Encapsulation => 6,
method => 'pppoa',
},
+ N("Czech Republic") . "|Cesky Telecom PPPoE" =>
+ {
+ provider_id => 'CZ02',
+ url_tech => 'http://www.telecom.cz/zakaznicka_podpora/dokumenty_ke_stazeni/internet_expres.php',
+ vpi => 8,
+ vci => 30,
+ Encapsulation => 1,
+ method => 'pppoe',
+ },
+
N("Denmark") . "|Any" =>
{
provider_id => 'DK01',
vpi => 0,
vci => 65,
- method => 'pppoe',
Encapsulation => 3,
+ method => 'pppoe',
+ },
+
+ N("Denmark") . "|Cybercity" =>
+ {
+ provider_id => 'DK02',
+ vpi => 0,
+ vci => 23,
+ Encapsulation => 6,
+ method => 'pppoa',
+ },
+
+ N("Denmark") . "|Tiscali" =>
+ {
+ provider_id => 'DK03',
+ vpi => 0,
+ vci => 23,
+ Encapsulation => 6,
+ method => 'pppoa',
+ },
+
+ N("Egypt") . "|Raya Telecom" =>
+ {
+ provider_id => 'EG01',
+ vpi => 8,
+ vci => 50,
+ method => 'pppoa',
+ Encapsulation => 6,
+ dnsServers => [ qw(62.240.110.197 62.240.110.198) ],
},
N("Finland") . "|Sonera" =>
@@ -399,8 +495,20 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '213.228.0.23',
- dnsServer3 => '212.27.32.176',
+ CMVep => 'FR',
+ dnsServers => [ qw(213.228.0.23 212.27.32.176) ],
+ method => 'pppoa',
+ DOMAINNAME2 => 'free.fr',
+ },
+
+ N("France") . "|Free non dégroupé ADSL Max" =>
+ {
+ provider_id => 'FR11',
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 6,
+ CMVep => 'FR04',
+ dnsServers => [ qw(213.228.0.23 212.27.32.176) ],
method => 'pppoa',
DOMAINNAME2 => 'free.fr',
},
@@ -411,8 +519,8 @@ our %adsl_data = (
vpi => 8,
vci => 24,
Encapsulation => 4,
- dnsServer2 => '213.228.0.23',
- dnsServer3 => '212.27.32.176',
+ CMVep => 'FR04',
+ dnsServers => [ qw(213.228.0.23 212.27.32.176 213.228.0.68 212.27.32.176 212.27.32.177 212.27.39.2 212.27.39.1) ],
method => 'dhcp',
DOMAINNAME2 => 'free.fr',
},
@@ -423,8 +531,8 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '212.30.93.108',
- dnsServer3 => '212.203.124.146',
+ CMVep => 'FR',
+ dnsServers => [ qw(212.30.93.108 212.203.124.146 62.62.156.12 62.62.156.13) ],
method => 'pppoa',
},
@@ -434,9 +542,22 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '212.94.174.85',
- dnsServer3 => '212.94.174.86',
+ CMVep => 'FR',
+ dnsServers => [ qw(212.94.174.85 212.94.174.86) ],
+ method => 'pppoa',
+ login_format => 'login@cegetel.net',
+ },
+
+ N("France") . "|Cegetel ADSL Max 8 Mb" =>
+ {
+ provider_id => 'FR10',
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 6,
+ CMVep => 'FR10',
+ dnsServers => [ qw(212.94.174.85 212.94.174.86) ],
method => 'pppoa',
+ login_format => 'login@cegetel.net',
},
N("France") . "|Club-Internet" =>
@@ -445,8 +566,8 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '194.117.200.10',
- dnsServer3 => '194.117.200.15',
+ CMVep => 'FR',
+ dnsServers => [ qw(194.117.200.10 194.117.200.15) ],
method => 'pppoa',
DOMAINNAME2 => 'club-internet.fr',
},
@@ -457,9 +578,10 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '80.10.246.2',
- dnsServer3 => '80.10.246.129',
+ CMVep => 'FR',
+ dnsServers => [ qw(80.10.246.2 80.10.246.129) ],
method => 'pppoa',
+ login_format => 'fti/login',
DOMAINNAME2 => 'wanadoo.fr',
},
@@ -469,8 +591,8 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '212.151.136.242',
- dnsServer3 => '130.244.127.162',
+ CMVep => 'FR',
+ dnsServers => [ qw(212.151.136.242 130.244.127.162 212.151.136.246) ],
method => 'pppoa',
},
@@ -480,8 +602,8 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 5,
- dnsServer2 => '213.36.80.1',
- dnsServer3 => '213.36.80.2',
+ CMVep => 'FR',
+ dnsServers => [ qw(213.36.80.1 213.36.80.2) ],
method => 'pppoa',
},
@@ -491,8 +613,8 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '213.36.80.1',
- dnsServer3 => '213.36.80.2',
+ CMVep => 'FR',
+ dnsServers => [ qw(213.36.80.1 213.36.80.2) ],
method => 'pppoa',
},
@@ -511,8 +633,17 @@ our %adsl_data = (
vpi => 1,
vci => 20,
Encapsulation => 1,
- dnsServer2 => '195.20.224.234',
- dnsServer3 => '194.25.2.129',
+ dnsServers => [ qw(195.20.224.234 194.25.2.129) ],
+ method => 'pppoe',
+ },
+
+ N("Germany") . "|Alice DSL" =>
+ {
+ provider_id => 'DE03',
+ vpi => 1,
+ vci => 20,
+ Encapsulation => 1,
+ dnsServers => [ qw(213.191.73.65 213.191.74.20) ],
method => 'pppoe',
},
@@ -549,20 +680,34 @@ our %adsl_data = (
vpi => 8,
vci => 30,
Encapsulation => 6,
- dnsServer2 => '192.115.106.10',
- dnsServer3 => '192.115.106.11',
+ dnsServers => [ qw(192.115.106.10 192.115.106.11 192.115.106.35) ],
method => 'pppoa',
},
- N("Italy") . "|Libero.it" =>
+ N("India") . "|Any" =>
{
- provider_id => 'IT04',
- url_tech => 'http://internet.libero.it/assistenza/adsl/installazione_ass.phtml',
- vpi => 8,
+ provider_id => 'IN01',
+ vpi => 0,
+ vci => 20,
+ Encapsulation => 6,
+ method => 'pppoa',
+ },
+
+ N("Iceland") . "|Islandssimi" =>
+ {
+ provider_id => 'IS01',
+ vpi => 0,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '193.70.192.25',
- dnsServer3 => '193.70.152.25',
+ method => 'pppoa',
+ },
+
+ N("Iceland") . "|Landssimi" =>
+ {
+ provider_id => 'IS02',
+ vpi => 8,
+ vci => 30,
+ Encapsulation => 6,
method => 'pppoa',
},
@@ -572,8 +717,8 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '195.20.224.234',
- dnsServer3 => '194.25.2.129',
+ CMVep => 'IT',
+ dnsServers => [ qw(195.20.224.234 194.25.2.129) ],
method => 'pppoa',
},
@@ -583,6 +728,7 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 3,
+ CMVep => 'IT',
method => 'static',
},
@@ -592,9 +738,33 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '195.20.224.234',
- dnsServer3 => '194.25.2.129',
+ CMVep => 'IT',
+ dnsServers => [ qw(195.20.224.234 194.25.2.129) ],
+ method => 'pppoa',
+ },
+
+ N("Italy") . "|Libero.it" =>
+ {
+ provider_id => 'IT04',
+ url_tech => 'http://internet.libero.it/assistenza/adsl/installazione_ass.phtml',
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 6,
+ CMVep => 'IT',
+ dnsServers => [ qw(193.70.192.25 193.70.152.25) ],
+ method => 'pppoa',
+ },
+
+ N("Sri Lanka") . "|Srilanka Telecom" =>
+ {
+ provider_id => 'LK01',
+ url_tech => 'http://www.sltnet.lk',
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 6,
+ dnsServers => [ qw(203.115.0.1 203.115.0.18) ],
method => 'pppoa',
+ encryption => 1,
},
N("Lithuania") . "|Lietuvos Telekomas" =>
@@ -606,14 +776,34 @@ our %adsl_data = (
method => 'pppoe',
},
+ N("Mauritius") . "|wanadoo.mu" =>
+ {
+ provider_id => 'MU01',
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 6,
+ dnsServers => [ qw(202.123.2.6 202.123.2.11) ],
+ method => 'pppoa',
+ },
+
+ N("Mauritius") . "|Telecom Plus (Mauritius Telecom)" =>
+ {
+ provider_id => 'MU02',
+ url_tech => 'http://www.telecomplus.net',
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 6,
+ dnsServers => [ qw(202.123.1.6 202.123.1.11) ],
+ method => 'pppoa',
+ },
+
N("Morocco") . "|Maroc Telecom" =>
{
provider_id => 'MA01',
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '212.217.0.1',
- dnsServer3 => '212.217.0.12',
+ dnsServers => [ qw(212.217.0.1 212.217.0.12) ],
method => 'pppoa',
},
@@ -632,7 +822,7 @@ our %adsl_data = (
vpi => 0,
vci => 21,
Encapsulation => 3,
- method => 'dhcp',
+ method => 'pppoe',
},
N("Netherlands") . "|Tiscali" =>
@@ -640,8 +830,8 @@ our %adsl_data = (
provider_id => 'NL03',
vpi => 0,
vci => 22,
- Encapsulation => 3,
- method => 'dhcp',
+ Encapsulation => 1,
+ method => 'pppoe',
},
N("Netherlands") . "|Versatel" =>
@@ -650,54 +840,71 @@ our %adsl_data = (
vpi => 0,
vci => 20,
Encapsulation => 3,
- method => 'dhcp',
+ method => 'pppoe',
},
N("Norway") . "|Bluecom" =>
{
+ provider_id => 'NO01',
method => 'dhcp',
},
N("Norway") . "|Firstmile" =>
{
+ provider_id => 'NO02',
method => 'dhcp',
},
N("Norway") . "|NextGenTel" =>
{
+ provider_id => 'NO03',
method => 'dhcp',
},
N("Norway") . "|SSC" =>
{
+ provider_id => 'NO04',
method => 'dhcp',
},
N("Norway") . "|Tele2" =>
{
+ provider_id => 'NO05',
method => 'dhcp',
},
N("Norway") . "|Telenor ADSL" =>
{
+ provider_id => 'NO06',
method => 'PPPoE',
},
N("Norway") . "|Tiscali" =>
{
+ provider_id => 'NO07',
vpi => 8,
vci => 35,
method => 'dhcp',
},
+ N("Pakistan") . "|Micronet BroadBand" =>
+ {
+ provider_id => 'PK01',
+ vpi => 1,
+ vci => 20,
+ Encapsulation => 3,
+ dnsServers => [ qw(203.82.48.3 203.82.48.4) ],
+ method => 'pppoe',
+ encryption => 1,
+ },
+
N("Poland") . "|Telekomunikacja Polska (TPSA/neostrada)" =>
{
provider_id => 'PL01',
vpi => 0,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '194.204.152.34',
- dnsServer3 => '217.98.63.164',
+ dnsServers => [ qw(194.204.152.34 217.98.63.164) ],
method => 'pppoa',
},
@@ -708,8 +915,7 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 1,
- dnsServer2 => '195.114.181.130',
- dnsServer3 => '195.114.161.61',
+ dnsServers => [ qw(195.114.181.130 195.114.161.61) ],
method => 'pppoe',
},
@@ -727,13 +933,21 @@ our %adsl_data = (
provider_id => 'RU01',
url_tech => 'http://stream.ru/s-requirements',
vpi => 1,
- vci => 50,
+ vci => 32,
Encapsulation => 1,
- dnsServer2 => '212.188.4.10',
- dnsServer3 => '195.34.32.116',
+ dnsServers => [ qw(212.188.4.10 195.34.32.116) ],
method => 'pppoe',
},
-
+
+ N("Singapore") . "|Singnet" =>
+ {
+ provider_id => 'SG01',
+ vpi => 0,
+ vci => 64,
+ method => 'pppoa',
+ Encapsulation => 6,
+ },
+
N("Senegal") . "|Sonatel Multimedia Sentoo" =>
{
provider_id => 'SN01',
@@ -751,8 +965,7 @@ our %adsl_data = (
vci => 20,
method => 'pppoe',
Encapsulation => 1,
- dnsServer2 => '193.189.160.11',
- dnsServer3 => '193.189.160.12',
+ dnsServers => [ qw(193.189.160.11 193.189.160.12) ],
DOMAINNAME2 => 'siol.net',
},
@@ -762,9 +975,10 @@ our %adsl_data = (
vpi => 8,
vci => 20,
Encapsulation => 1,
- dnsServer2 => '80.58.32.33',
- dnsServer3 => '80.58.0.97',
+ CMVep => 'ES',
+ dnsServers => [ qw(80.58.32.33 80.58.0.97) ],
method => 'pppoe',
+ login_format => 'adslppp@telefonicanetpa / adslppp',
},
N("Spain") . "|Telefónica ip fija" =>
@@ -773,9 +987,10 @@ our %adsl_data = (
vpi => 8,
vci => 20,
Encapsulation => 3,
+ CMVep => 'ES',
+ dnsServers => [ qw(80.58.32.33 80.58.0.97) ],
method => 'static',
- dnsServer2 => '80.58.32.33',
- dnsServer3 => '80.58.0.97',
+ login_format => 'adslppp@telefonicanetpa / adslppp',
},
N("Spain") . "|Wanadoo/Eresmas Retevision" =>
@@ -784,9 +999,11 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 6,
- dnsServer2 => '80.58.0.33',
- dnsServer3 => '80.58.32.97',
+ CMVep => 'ES',
+ dnsServers => [ qw(80.58.0.33 80.58.32.97) ],
method => 'pppoa',
+ login_format => 'rtxxxxx@wanadooadsl',
+ encryption => 1,
},
N("Spain") . "|Wanadoo PPPoE" =>
@@ -795,6 +1012,7 @@ our %adsl_data = (
vpi => 8,
vci => 20,
Encapsulation => 1,
+ CMVep => 'ES',
method => 'pppoe',
},
@@ -804,6 +1022,7 @@ our %adsl_data = (
vpi => 8,
vci => 20,
Encapsulation => 3,
+ CMVep => 'ES',
method => 'static',
},
@@ -813,7 +1032,9 @@ our %adsl_data = (
vpi => 1,
vci => 20,
Encapsulation => 6,
+ CMVep => 'ES',
method => 'pppoa',
+ login_format => 'login@tiscali.es',
},
N("Spain") . "|Arrakis" =>
@@ -822,6 +1043,7 @@ our %adsl_data = (
vpi => 0,
vci => 23,
Encapsulation => 6,
+ CMVep => 'ES',
method => 'pppoa',
},
@@ -831,6 +1053,7 @@ our %adsl_data = (
vpi => 0,
vci => 23,
Encapsulation => 6,
+ CMVep => 'ES',
method => 'pppoa',
},
@@ -840,6 +1063,7 @@ our %adsl_data = (
vpi => 0,
vci => 21,
Encapsulation => 6,
+ CMVep => 'ES',
method => 'pppoa',
},
@@ -849,6 +1073,7 @@ our %adsl_data = (
vpi => 8,
vci => 20,
Encapsulation => 1,
+ CMVep => 'ES',
method => 'pppoe',
},
@@ -858,6 +1083,7 @@ our %adsl_data = (
vpi => 1,
vci => 21,
Encapsulation => 6,
+ CMVep => 'ES',
method => 'pppoa',
},
@@ -867,7 +1093,9 @@ our %adsl_data = (
vpi => 8,
vci => 20,
Encapsulation => 1,
+ CMVep => 'ES',
method => 'pppoe',
+ login_format => 'adXXXXXXXXX@yacomadsl',
},
N("Spain") . "|Ya.com static" =>
@@ -876,7 +1104,46 @@ our %adsl_data = (
vpi => 8,
vci => 20,
Encapsulation => 3,
+ CMVep => 'ES',
method => 'static',
+ login_format => 'adXXXXXXXXX@yacomadsl',
+ },
+
+ N("Spain") . "|Arsys" =>
+ {
+ provider_id => 'ES14',
+ vpi => 1,
+ vci => 21,
+ Encapsulation => 1,
+ CMVep => 'ES',
+ dnsServers => [ qw(217.76.128.4 217.76.129.4) ],
+ method => 'pppoe',
+ login_format => 'login@arsystel',
+ },
+
+ N("Spain") . "|Terra" =>
+ {
+ provider_id => 'ES15',
+ vpi => 8,
+ vci => 20,
+ Encapsulation => 1,
+ CMVep => 'ES',
+ dnsServers => [ qw(213.4.132.1 213.4.141.1) ],
+ method => 'pppoe',
+ login_format => 'login@terraadsl',
+ },
+
+ N("Spain") . "|Jazztel" =>
+ {
+ provider_id => 'ES16',
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 6,
+ CMVep => 'ES',
+ dnsServers => [ qw(62.14.63.145 62.14.2.1) ],
+ method => 'pppoa',
+ login_format => 'username@adsl',
+ encryption => 1,
},
N("Sweden") . "|Telia" =>
@@ -903,12 +1170,11 @@ our %adsl_data = (
vpi => 8,
vci => 23,
Encapsulation => 5,
- dnsServer2 => '195.186.4.108',
- dnsServer3 => '195.186.4.109',
+ dnsServers => [ qw(195.186.4.108 195.186.4.109) ],
method => 'pppoa',
},
- N("Switzerland") . "|Tiscali.ch" =>
+ N("Switzerland") . "|VTX Datacomm (ex-Tiscali)" =>
{
provider_id => 'CH03',
vpi => 8,
@@ -923,21 +1189,32 @@ our %adsl_data = (
vpi => 0,
vci => 64,
Encapsulation => 1,
- dnsServer2 => '203.144.225.242',
- dnsServer3 => '203.144.225.72',
+ dnsServers => [ qw(203.144.225.242 203.144.225.72 203.144.223.66) ],
method => 'pppoe',
},
N("Tunisia") . "|Planet.tn" =>
{
- provider_id => 'TH01',
+ provider_id => 'TU01',
url_tech => 'http://www.planet.tn/',
vpi => 0,
vci => 23,
Encapsulation => 5,
- dnsServer2 => '193.95.93.77',
- dnsServer3 => '193.95.66.10',
+ dnsServers => [ qw(193.95.93.77 193.95.66.10) ],
+ method => 'pppoe',
+ },
+
+ N("Turkey") . "|TTnet" =>
+ {
+ provider_id => 'TR01',
+ url_tech => 'http://www.ttnet.net.tr',
+ vpi => 8,
+ vci => 23,
+ Encapsulation => 1,
+ dnsServers => [ qw(195.175.37.14 195.175.37.69) ],
method => 'pppoe',
+ encryption => 1,
+ login_format => 'login@ttnet',
},
N("United Arab Emirates") . "|Etisalat" =>
@@ -946,8 +1223,7 @@ our %adsl_data = (
vpi => 0,
vci => 32,
Encapsulation => 5,
- dnsServer2 => '213.42.20.20',
- dnsServer3 => '195.229.241.222',
+ dnsServers => [ qw(213.42.20.20 195.229.241.222) ],
method => 'pppoa',
},
@@ -957,8 +1233,7 @@ our %adsl_data = (
vpi => 0,
vci => 26,
Encapsulation => 6,
- dnsServer2 => '212.74.112.66',
- dnsServer3 => '212.74.112.67',
+ dnsServers => [ qw(212.74.112.66 212.74.112.67) ],
method => 'pppoa',
},
@@ -968,12 +1243,10 @@ our %adsl_data = (
vpi => 0,
vci => 26,
Encapsulation => 6,
- dnsServer2 => '194.74.65.69',
- dnsServer3 => '194.72.9.38',
+ dnsServers => [ qw(194.74.65.69 194.72.9.38) ],
method => 'pppoa',
},
);
-
1;
diff --git a/lib/network/connection/wireless.pm b/lib/network/connection/wireless.pm
new file mode 100644
index 0000000..df1a210
--- /dev/null
+++ b/lib/network/connection/wireless.pm
@@ -0,0 +1,744 @@
+package network::connection::wireless;
+
+use strict;
+use common;
+
+use base qw(network::connection::ethernet);
+
+use strict;
+use common;
+
+sub get_type_name() { N("Wireless") }
+sub get_type_icon() { 'wireless-24.png' }
+sub get_devices {
+ my ($_class, %options) = @_;
+ require detect_devices;
+ my @devices = detect_devices::probe_category('network/wireless');
+ my @wireless = grep { detect_devices::is_wireless_interface($_) } detect_devices::get_lan_interfaces();
+ my @all_devices = (@devices, network::connection::ethernet::get_unlisted_devices(\@wireless, \@devices));
+ foreach (@all_devices) {
+ my $interface = network::connection::ethernet::device_to_interface($_) or next;
+ my $driver = network::connection::ethernet::interface_to_driver($interface) or next;
+ $_->{driver} = $driver if $driver;
+ }
+ @all_devices,
+ if_(!$options{automatic_only}, {
+ driver => 'ndiswrapper',
+ description => N("Use a Windows driver (with ndiswrapper)"),
+ });
+}
+
+sub handles_ifcfg {
+ my ($_class, $ifcfg) = @_;
+ require detect_devices;
+ detect_devices::is_wireless_interface($ifcfg->{DEVICE}) || exists $ifcfg->{WIRELESS_MODE};
+}
+
+sub get_metric { 35 }
+
+#- class attributes:
+#- network: ID of the selected network
+
+our %wireless_enc_modes = (
+ none => N_("None"),
+ open => N_("Open WEP"),
+ restricted => N_("Restricted WEP"),
+ 'wpa-psk' => N_("WPA Pre-Shared Key"),
+);
+
+my @thirdparty_settings = (
+ {
+ name => 'zd1201',
+ description => 'ZyDAS ZD1201',
+ url => 'http://linux-lc100020.sourceforge.net/',
+ firmware => {
+ test_file => 'zd1201*.fw',
+ },
+ },
+
+ (map {
+ {
+ name => "ipw${_}",
+ description => "Intel(R) PRO/Wireless ${_}",
+ url => "http://ipw${_}.sourceforge.net/",
+ firmware => {
+ url => "http://ipw${_}.sourceforge.net/firmware.php",
+ test_file => "ipw$_-*.fw",
+ },
+ };
+ } (2100, 2200)),
+
+ {
+ name => "ipw3945",
+ description => "Intel(R) PRO/Wireless 3945",
+ url => "http://ipw3945.sourceforge.net/",
+ firmware => {
+ package => "ipw3945-ucode",
+ test_file => "ipw3945.ucode",
+ },
+ tools => {
+ package => "ipw3945d",
+ test_file => '/usr/sbin/ipw3945d',
+ },
+ },
+
+ {
+ name => 'prism54',
+ description => 'Prism GT / Prism Duette / Prism Indigo Chipsets',
+ url => 'http://prism54.org/',
+ firmware => {
+ url => 'http://prism54.org/~mcgrof/firmware/',
+ test_file => "isl38*",
+ },
+ },
+
+ {
+ name => 'atmel',
+ matching => [ qw(at76_usb atmel_cs atmel_pci) ],
+ description => 'Atmel at76c50x cards',
+ url => 'http://thekelleys.org.uk/atmel/',
+ firmware => {
+ test_file => 'atmel_at76c50*',
+ },
+ links => 'http://at76c503a.berlios.de/',
+ },
+
+ {
+ name => 'madwifi',
+ matching => 'ath_pci',
+ description => 'Multiband Atheros Driver for WiFi',
+ url => 'http://madwifi.org/',
+ kernel_module => 1,
+ tools => {
+ optional => 1,
+ test_file => '/usr/bin/athstats',
+ },
+ },
+
+ {
+ name => 'prism2',
+ matching => qr/^prism2_/,
+ description => 'Prism2 based cards',
+ tools => {
+ package => 'prism2-utils',
+ test_file => '/sbin/wlanctl-ng',
+ },
+ },
+
+ {
+ name => 'zd1211',
+ matching => 'zd1211rw',
+ description => 'ZD1211 chip',
+ firmware => {
+ url => 'http://sourceforge.net/projects/zd1211/',
+ test_file => 'zd1211/zd1211_*',
+ },
+ },
+
+ {
+ name => 'bcm43xx',
+ description => 'Broadcom bcm43xx wireless chips',
+ url => 'http://bcm43xx.berlios.de/',
+ firmware => {
+ test_file => 'bcm43xx_microcode*.fw',
+ extract => {
+ name => 'bcm43xx-fwcutter',
+ test_file => '/usr/bin/bcm43xx-fwcutter',
+ windows_source => 'bcmwl5.sys',
+ default_source => 'bcmwl5.sys',
+ run => sub {
+ my ($file) = @_;
+ run_program::rooted($::prefix, '/usr/bin/bcm43xx-fwcutter',
+ '-w', $network::thirdparty::firmware_directory, $file);
+ },
+ },
+ },
+ },
+
+ {
+ name => 'acx100',
+ matching => [ qw(acx-pci acx-usb) ],
+ description => 'ACX100/ACX111/TNETW1450',
+ firmware => {
+ url => 'http://acx100.sourceforge.net/wiki/Firmware',
+ test_file => 'tiacx1*',
+ no_package => 1,
+ },
+ },
+
+ {
+ name => 'ndiswrapper',
+ description => 'Wireless device using ndiswrapper (windows drivers)',
+ tools => {
+ test_file => '/usr/sbin/ndiswrapper',
+ },
+ firmware => {
+ user_install => sub {
+ my ($settings, $in) = @_;
+ require network::ndiswrapper;
+ $settings->{device} = network::ndiswrapper::select_device($in) or return;
+ $settings->{device}{driver} = $settings->{name};
+ network::ndiswrapper::setup_device($in, $settings->{device});
+ },
+ url => 'http://ndiswrapper.sourceforge.net/mediawiki/index.php/List',
+ explanations => N_("Firmware files are required for this device."),
+ no_package => 1,
+ },
+ },
+
+ {
+ name => 'rt61',
+ description => 'Ralink RT61 802.11abg WLAN',
+ firmware => {
+ url => 'http://rt2x00.serialmonkey.com/',
+ test_file => 'rt2661.bin',
+ },
+ },
+
+ {
+ name => 'rt73',
+ description => 'Ralink RT73 802.11abg WLAN',
+ firmware => {
+ url => 'http://rt2x00.serialmonkey.com/',
+ test_file => 'rt73.bin',
+ },
+ },
+
+);
+
+sub get_packages { 'wireless-tools' }
+
+sub get_thirdparty_settings() {
+ \@thirdparty_settings;
+}
+
+sub setup_thirdparty {
+ my ($self, $in) = @_;
+ require network::rfswitch;
+ network::rfswitch::configure();
+ if ($self->get_driver eq 'ndiswrapper') {
+ require network::ndiswrapper;
+ my @devices = map { network::ndiswrapper::present_devices($_) } network::ndiswrapper::installed_drivers();
+ return {} if member($self->{device}, @devices) && network::ndiswrapper::find_interface($self->{device});
+ }
+ my $thirdparty = $self->SUPER::setup_thirdparty($in);
+ my $driver = $self->get_driver;
+ if ($self->{thirdparty} && $driver eq 'ipw3945' && !$self->rf_killed && !$self->SUPER::check_device) {
+ log::explanations("Reloading module $driver");
+ eval { modules::unload($driver) };
+ eval { modules::load($driver) };
+ }
+ $thirdparty;
+}
+
+sub rf_killed {
+ my ($self) = @_;
+ if ($self->{device}{sysfs_device}) {
+ my $rf_kill_path = $self->{device}{sysfs_device} . "/rf_kill";
+ if (-e $rf_kill_path) {
+ my $rf_kill = chomp_(cat_($rf_kill_path));
+ #- for ipw drivers, 0 means no RF kill switch
+ return $rf_kill != 0;
+ }
+ }
+ undef;
+}
+
+sub check_device {
+ my ($self) = @_;
+ if ($self->rf_killed) {
+ $self->{device}{error} = N("Your wireless card is disabled, please enable the wireless switch (RF kill switch) first.");
+ return 0;
+ }
+ return $self->SUPER::check_device;
+}
+
+sub load_interface_settings {
+ my ($self) = @_;
+ $self->SUPER::load_interface_settings;
+}
+
+sub get_networks {
+ my ($self) = @_;
+ require network::monitor;
+ ($self->{networks}, $self->{control}{roaming}) = network::monitor::list_wireless(undef, $self->get_interface);
+ $self->{networks};
+}
+
+sub guess_network {
+ my ($_self) = @_;
+ #- FIXME: try to find the AP matching $self->{ifcfg}{WIRELESS_ESSID};
+}
+
+sub get_network_ifcfg {
+ my ($ssid) = @_;
+ require network::network;
+ my $file = $::prefix . $network::network::wireless_d . '/' . $ssid;
+ -f $file && { getVarsFromSh($file) };
+}
+
+sub guess_network_access_settings {
+ my ($self) = @_;
+
+ my $ifcfg;
+ my $network = $self->get_selected_network;
+ $ifcfg = $network ?
+ get_network_ifcfg($network->{ap}) || get_network_ifcfg($network->{essid}) :
+ $self->{ifcfg};
+ $ifcfg ||= {};
+
+ $self->{access}{network}{essid} = $network && $network->{essid} || $ifcfg->{WIRELESS_ESSID} || !$network && "any";
+ ($self->{access}{network}{key}, my $restricted) = get_wep_key_from_iwconfig($ifcfg->{WIRELESS_ENC_KEY});
+ $self->{access}{network}{encryption} =
+ $network && $network->{flags} =~ /wpa/i ?
+ 'wpa-psk' :
+ $network && $network->{flags} =~ /wep/i || $self->{access}{network}{key} ?
+ ($restricted ? 'restricted' : 'open') :
+ 'none';
+
+ undef $self->{ifcfg}{WIRELESS_IWPRIV} if is_old_rt2x00($self->get_driver) && $self->{ifcfg}{WIRELESS_IWPRIV} =~ /WPAPSK/;
+
+ $self->{control}{roaming} = exists $self->{ifcfg}{WIRELESS_WPA_DRIVER} && !is_old_rt2x00($self->get_driver);
+
+ $self->{access}{network}{mode} =
+ $network && $network->{mode} ||
+ $ifcfg->{WIRELESS_MODE} ||
+ 'Managed';
+}
+
+sub get_network_access_settings_label { N("Wireless settings") }
+
+sub get_network_access_settings {
+ my ($self) = @_;
+ [
+ { label => N("Operating Mode"), val => \$self->{access}{network}{mode},
+ list => [ N_("Ad-hoc"), N_("Managed"), N_("Master"), N_("Repeater"), N_("Secondary"), N_("Auto") ],
+ format => \&translate,
+ },
+ { label => N("Network name (ESSID)"), val => \$self->{access}{network}{essid},
+ disabled => sub { my $network = $self->get_selected_network; $network && $network->{essid} } },
+ { label => N("Encryption mode"), val => \$self->{access}{network}{encryption}, list => [ keys %wireless_enc_modes ],
+ sort => 1, format => sub { translate($wireless_enc_modes{$_[0]}) } },
+ { label => N("Encryption key"), val => \$self->{access}{network}{key},
+ disabled => sub { $self->{access}{network}{encryption} eq 'none' } },
+ { label => N("Network ID"), val => \$self->{ifcfg}{WIRELESS_NWID}, advanced => 1 },
+ { label => N("Operating frequency"), val => \$self->{ifcfg}{WIRELESS_FREQ}, advanced => 1 },
+ { label => N("Sensitivity threshold"), val => \$self->{ifcfg}{WIRELESS_SENS}, advanced => 1 },
+ { label => N("Bitrate (in b/s)"), val => \$self->{ifcfg}{WIRELESS_RATE}, advanced => 1 },
+ { label => N("RTS/CTS"), val => \$self->{ifcfg}{WIRELESS_RTS}, advanced => 1,
+ help => N("RTS/CTS adds a handshake before each packet transmission to make sure that the
+channel is clear. This adds overhead, but increase performance in case of hidden
+nodes or large number of active nodes. This parameter sets the size of the
+smallest packet for which the node sends RTS, a value equal to the maximum
+packet size disable the scheme. You may also set this parameter to auto, fixed
+or off.")
+ },
+ { label => N("Fragmentation"), val => \$self->{ifcfg}{WIRELESS_FRAG}, advanced => 1 },
+ { label => N("iwconfig command extra arguments"), val => \$self->{ifcfg}{WIRELESS_IWCONFIG}, advanced => 1,
+ help => N("Here, one can configure some extra wireless parameters such as:
+ap, channel, commit, enc, power, retry, sens, txpower (nick is already set as the hostname).
+
+See iwconfig(8) man page for further information."),
+ },
+ { label =>
+ #-PO: split the "xyz command extra argument" translated string into two lines if it's bigger than the english one
+ N("iwspy command extra arguments"), val => \$self->{ifcfg}{WIRELESS_IWSPY}, advanced => 1,
+ help => N("iwspy is used to set a list of addresses in a wireless network
+interface and to read back quality of link information for each of those.
+
+This information is the same as the one available in /proc/net/wireless :
+quality of the link, signal strength and noise level.
+
+See iwpspy(8) man page for further information."),
+ },
+ { label => N("iwpriv command extra arguments"), val => \$self->{ifcfg}{WIRELESS_IWPRIV}, advanced => 1,
+ disabled => sub { $self->need_rt2x00_iwpriv },
+ help => N("iwpriv enable to set up optionals (private) parameters of a wireless network
+interface.
+
+iwpriv deals with parameters and setting specific to each driver (as opposed to
+iwconfig which deals with generic ones).
+
+In theory, the documentation of each device driver should indicate how to use
+those interface specific commands and their effect.
+
+See iwpriv(8) man page for further information."),
+ },
+ ];
+}
+
+sub check_network_access_settings {
+ my ($self) = @_;
+
+ if ($self->{access}{network}{encryption} ne 'none' && !$self->{access}{network}{key}) {
+ $self->{network_access}{error}{message} = N("An encryption key is required.");
+ $self->{network_access}{error}{field} = \$self->{access}{network}{key};
+ return 0;
+ }
+
+ if ($self->{ifcfg}{WIRELESS_FREQ} && $self->{ifcfg}{WIRELESS_FREQ} !~ /[0-9.]*[kGM]/) {
+ $self->{network_access}{error}{message} = N("Freq should have the suffix k, M or G (for example, \"2.46G\" for 2.46 GHz frequency), or add enough '0' (zeroes).");
+ $self->{network_access}{error}{field} = \$self->{ifcfg}{WIRELESS_FREQ};
+ return 0;
+ }
+
+ if ($self->{ifcfg}{WIRELESS_RATE} && $self->{ifcfg}{WIRELESS_RATE} !~ /[0-9.]*[kGM]/) {
+ $self->{network_access}{error}{message} = N("Rate should have the suffix k, M or G (for example, \"11M\" for 11M), or add enough '0' (zeroes).");
+ $self->{network_access}{error}{field} = \$self->{ifcfg}{WIRELESS_RATE};
+ return 0;
+ }
+
+ return 1;
+}
+
+sub get_control_settings {
+ my ($self) = @_;
+ [
+ @{$self->SUPER::get_control_settings},
+ { text => N("Allow access point roaming"), val => \$self->{control}{roaming}, type => "bool",
+ disabled => sub { is_wpa_supplicant_blacklisted($self->get_driver) } },
+ ];
+}
+
+sub need_wpa_supplicant {
+ my ($self) = @_;
+ ($self->{control}{roaming} || $self->{access}{network}{encryption} eq 'wpa-psk') && !is_old_rt2x00($self->get_driver);
+}
+
+sub install_packages {
+ my ($self, $in) = @_;
+ if ($self->need_wpa_supplicant) {
+ $in->do_pkgs->ensure_is_installed('wpa_supplicant', '/usr/sbin/wpa_supplicant') or return;
+ }
+ $self->SUPER::install_packages($in);
+}
+
+
+sub build_ifcfg_settings {
+ my ($self) = @_;
+ my $settings = {
+ WIRELESS_MODE => $self->{access}{network}{mode},
+ if_($self->need_wpa_supplicant,
+ WIRELESS_WPA_DRIVER => wpa_supplicant_get_driver($self->get_driver),
+ MII_NOT_SUPPORTED => 'no',
+ ),
+ WIRELESS_ESSID => $self->{access}{network}{essid},
+ if_($self->{access}{network}{encryption} ne 'none',
+ WIRELESS_ENC_KEY => convert_wep_key_for_iwconfig($self->{access}{network}{key}, $self->{access}{network}{encryption} eq 'restricted')),
+ if_($self->need_rt2x00_iwpriv,
+ #- use iwpriv for WPA with rt2400/rt2500 drivers, they don't plan to support wpa_supplicant
+ WIRELESS_IWPRIV => qq(set AuthMode=WPAPSK
+set EncrypType=TKIP
+set SSID=$self->{access}{network}{essid}
+set WPAPSK="$self->{access}{network}{key}"
+set TxRate=0)),
+ (map { $_ => $self->{ifcfg}{$_} }
+ qw(WIRELESS_NWID WIRELESS_FREQ WIRELESS_SENS WIRELESS_RATE WIRELESS_RTS WIRELESS_FRAG WIRELESS_IWCONFIG WIRELESS_IWSPY), if_(!$self->need_rt2x00_iwpriv, 'WIRELESS_IWPRIV')),
+ };
+ $self->SUPER::build_ifcfg_settings($settings);
+}
+
+sub write_settings {
+ my ($self, $o_net, $o_modules_conf) = @_;
+
+ wpa_supplicant_add_network($self->{access}{network}{essid}, $self->{access}{network}{encryption}, $self->{access}{network}{key}, $self->{access}{network}{mode}) if $self->need_wpa_supplicant;
+
+ wlan_ng_configure($self->{access}{network}{essid}, $self->{access}{network}{key}, $self->get_interface, $self->get_driver) if $self->{thirdparty}{name} eq 'prism2';
+
+ my $network = $self->get_selected_network;
+ network::network::write_wireless_conf($_, $self->build_ifcfg_settings) foreach
+ grep { $_ } ($network ? $network->{ap} : ()), $self->{access}{network}{essid};
+
+ $self->SUPER::write_settings($o_net, $o_modules_conf);
+}
+
+sub network_is_configured {
+ my ($self, $network) = @_;
+ if ($self->{control}{roaming}) {
+ return defined $network->{id};
+ } else {
+ my $wireless_ifcfg = get_network_ifcfg($network->{ap}) || defined $network->{essid} && get_network_ifcfg($network->{essid});
+ return $wireless_ifcfg;
+ }
+}
+
+sub selected_network_is_configured {
+ my ($self) = @_;
+
+ my $network = $self->get_selected_network or return;
+ $self->network_is_configured($network);
+}
+
+sub prepare_connection {
+ my ($self) = @_;
+ if ($self->{control}{roaming}) {
+ #- this should be handled by the monitoring daemon instead
+ run_program::run('/usr/sbin/wpa_cli', 'reconfigure');
+ sleep 2;
+ }
+}
+
+sub connect {
+ my ($self, $_in, $net) = @_;
+
+ $self->SUPER::connect;
+
+ if ($self->{control}{roaming}) {
+ my $network = $self->get_selected_network;
+ if ($network && defined $network->{id}) {
+ eval { $net->{monitor}->select_network($network->{id}) };
+ return !$@;
+ }
+ }
+}
+
+sub get_status_message {
+ my ($self, $status) = @_;
+ my $interface = $self->get_interface;
+ my ($current_essid, $current_ap) = get_access_point($interface);
+ my $network = $current_essid || $current_ap && "[$current_ap]";
+ {
+ link_up => N("Associated to wireless network \"%s\" on interface %s", $network, $interface),
+ link_down => N("Lost association to wireless network on interface %s", $interface),
+ }->{$status} || $self->SUPER::get_status_message($status);
+}
+
+
+
+my $wpa_supplicant_conf = "/etc/wpa_supplicant.conf";
+
+sub get_access_point {
+ my ($intf) = @_;
+ (chomp_(`/sbin/iwgetid -r $intf 2>/dev/null`), lc(chomp_(`/sbin/iwgetid -r -a $intf 2>/dev/null`)));
+}
+
+sub is_old_rt2x00 {
+ my ($module) = @_;
+ member($module, qw(rt2400 rt2500 rt2570 rt61 rt73));
+}
+
+sub is_wpa_supplicant_blacklisted {
+ my ($module) = @_;
+ is_old_rt2x00($module);
+}
+
+sub need_rt2x00_iwpriv {
+ my ($self) = @_;
+ is_old_rt2x00($self->get_driver) && $self->{access}{network}{encryption} eq 'wpa-psk';
+}
+
+sub get_hex_key {
+ my ($key) = @_;
+ if ($key =~ /^([[:xdigit:]]{4}[\:-]?)+[[:xdigit:]]{2,}$/) {
+ $key =~ s/[\:-]//g;
+ return lc($key);
+ }
+}
+
+sub convert_wep_key_for_iwconfig {
+ #- 5 or 13 characters, consider the key as ASCII and prepend "s:"
+ #- else consider the key as hexadecimal, do not strip dashes
+ #- always quote the key as string
+ my ($real_key, $restricted) = @_;
+ my $key = get_hex_key($real_key) || "s:$real_key";
+ $restricted ? "restricted $key" : "open $key";
+}
+
+sub convert_wep_key_for_wpa_supplicant {
+ my ($key) = @_;
+ get_hex_key($key) || qq("$key");
+}
+
+sub get_wep_key_from_iwconfig {
+ #- strip "s:" if the key is 5 or 13 characters (ASCII)
+ #- else the key as hexadecimal, do not modify
+ my ($key) = @_;
+ my ($mode, $real_key) = $key =~ /^(?:(open|restricted)\s+)?(.*)$/;
+ $real_key =~ s/^s://;
+ ($real_key, $mode eq 'restricted');
+}
+
+sub convert_key_for_wpa_supplicant {
+ my ($key) = @_;
+ length($key) == 64 && get_hex_key($key) || qq("$key");
+}
+
+#- FIXME: to be improved (quotes, comments) and moved in common files
+sub wlan_ng_update_vars {
+ my ($file, $vars) = @_;
+ substInFile {
+ while (my ($key, $value) = each(%$vars)) {
+ s/^#?\Q$key\E=(?:"[^#]*"|[^#\s]*)(\s*#.*)?/$key=$value$1/ and delete $vars->{$key};
+ }
+ $_ .= join('', map { "$_=$vars->{$_}\n" } keys %$vars) if eof;
+ } $file;
+}
+
+sub wlan_ng_configure {
+ my ($essid, $key, $device, $module) = @_;
+ my $wlan_conf_file = "$::prefix/etc/wlan/wlan.conf";
+ my @wlan_devices = split(/ /, (cat_($wlan_conf_file) =~ /^WLAN_DEVICES="(.*)"/m)[0]);
+ push @wlan_devices, $device unless member($device, @wlan_devices);
+ #- enable device and make it use the choosen ESSID
+ wlan_ng_update_vars($wlan_conf_file,
+ {
+ WLAN_DEVICES => qq("@wlan_devices"),
+ "SSID_$device" => qq("$essid"),
+ "ENABLE_$device" => "y"
+ });
+
+ my $wlan_ssid_file = "$::prefix/etc/wlan/wlancfg-$essid";
+ #- copy default settings for this ESSID if config file does not exist
+ -f $wlan_ssid_file or cp_f("$::prefix/etc/wlan/wlancfg-DEFAULT", $wlan_ssid_file);
+
+ #- enable/disable encryption
+ wlan_ng_update_vars($wlan_ssid_file,
+ {
+ (map { $_ => $key ? "true" : "false" } qw(lnxreq_hostWEPEncrypt lnxreq_hostWEPDecrypt dot11PrivacyInvoked dot11ExcludeUnencrypted)),
+ AuthType => $key ? qq("sharedkey") : qq("opensystem"),
+ if_($key,
+ dot11WEPDefaultKeyID => 0,
+ dot11WEPDefaultKey0 => qq("$key")
+ )
+ });
+ #- hide settings for non-root users
+ chmod 0600, $wlan_conf_file;
+ chmod 0600, $wlan_ssid_file;
+
+ #- apply settings on wlan interface
+ require services;
+ services::restart($module eq 'prism2_cs' ? 'pcmcia' : 'wlan');
+}
+
+sub wpa_supplicant_get_driver {
+ my ($module) = @_;
+ $module =~ /^hostap_/ ? "hostap" :
+ $module eq "prism54" ? "prism54" :
+ $module =~ /^ath_/ ? "madwifi" :
+ $module =~ /^at76c50|atmel_/ ? "atmel" :
+ "wext";
+}
+
+sub wpa_supplicant_add_network {
+ my ($essid, $enc_mode, $key, $mode) = @_;
+ my $conf = wpa_supplicant_read_conf();
+ my $network = {
+ ssid => qq("$essid"),
+ scan_ssid => 1,
+ };
+
+ if ($enc_mode eq 'wpa-psk') {
+ $network->{psk} = convert_key_for_wpa_supplicant($key);
+ } else {
+ $network->{key_mgmt} = 'NONE';
+ $network->{mode} = to_bool($mode eq 'Ad-Hoc');
+ if (member($enc_mode, qw(open restricted))) {
+ put_in_hash($network, {
+ wep_key0 => convert_wep_key_for_wpa_supplicant($key),
+ wep_tx_keyidx => 0,
+ auth_alg => $enc_mode eq 'restricted' ? 'SHARED' : 'OPEN',
+ });
+ }
+ }
+
+ @$conf = difference2($conf, [ wpa_supplicant_find_similar($conf, $network) ]);
+ push @$conf, $network;
+ wpa_supplicant_write_conf($conf);
+}
+
+sub wpa_supplicant_find_similar {
+ my ($conf, $network) = @_;
+ grep {
+ my $current = $_;
+ any { exists $network->{$_} && $network->{$_} eq $current->{$_} } qw(ssid bssid);
+ } @$conf;
+}
+
+sub wpa_supplicant_read_conf() {
+ my @conf;
+ my $network;
+ foreach (cat_($::prefix . $wpa_supplicant_conf)) {
+ if ($network) {
+ #- in a "network = {}" block
+ if (/^\s*(\w+)=(.*?)(?:\s*#.*)?$/) {
+ $network->{$1} = $2;
+ } elsif (/^\}/) {
+ #- end of network block
+ push @conf, $network;
+ undef $network;
+ }
+ } elsif (/^\s*network={/) {
+ #- beginning of a new network block
+ $network = {};
+ }
+ }
+ \@conf;
+}
+
+sub wpa_supplicant_write_conf {
+ my ($conf) = @_;
+ my $buf;
+ my @conf = @$conf;
+ my $network;
+ foreach (cat_($::prefix . $wpa_supplicant_conf)) {
+ if ($network) {
+ #- in a "network = {}" block
+ if (/^\s*(\w+)=(.*)$/) {
+ push @{$network->{entries}}, { key => $1, value => $2 };
+ member($1, qw(ssid bssid)) and $network->{$1} = $2;
+ } elsif (/^\}/) {
+ #- end of network block, write it
+ $buf .= "network={$network->{comment}\n";
+
+ my $new_network = first(wpa_supplicant_find_similar(\@conf, $network));
+ foreach (@{$network->{entries}}) {
+ my $key = $_->{key};
+ if ($new_network) {
+ #- do not write entry if not provided in the new network
+ exists $new_network->{$key} or next;
+ #- update value from the new network
+ $_->{value} = delete $new_network->{$key};
+ }
+ $buf .= " ";
+ $buf .= "$key=$_->{value}" if $key;
+ $buf .= "$_->{comment}\n";
+ }
+ if ($new_network) {
+ #- write new keys
+ while (my ($key, $value) = each(%$new_network)) {
+ $buf .= " $key=$value\n";
+ }
+ }
+ $buf .= "}\n";
+ $new_network and @conf = grep { $_ != $new_network } @conf;
+ undef $network;
+ } else {
+ #- unrecognized, keep it anyway
+ push @{$network->{entries}}, { comment => $_ };
+ }
+ } else {
+ if (/^\s*network={/) {
+ #- beginning of a new network block
+ $network = {};
+ } else {
+ #- keep other options, comments
+ $buf .= $_;
+ }
+ }
+ }
+
+ #- write remaining networks
+ foreach (@conf) {
+ $buf .= "\nnetwork={\n";
+ while (my ($key, $value) = each(%$_)) {
+ $buf .= " $key=$value\n";
+ }
+ $buf .= "}\n";
+ }
+
+ output($::prefix . $wpa_supplicant_conf, $buf);
+ #- hide keys for non-root users
+ chmod 0600, $::prefix . $wpa_supplicant_conf;
+}
+
+1;
diff --git a/lib/network/connection/xdsl.pm b/lib/network/connection/xdsl.pm
new file mode 100644
index 0000000..337d4f7
--- /dev/null
+++ b/lib/network/connection/xdsl.pm
@@ -0,0 +1,375 @@
+package network::connection::xdsl;
+
+use base qw(network::connection::ppp);
+
+use strict;
+use common;
+
+sub get_type_name() { N("DSL") }
+sub get_type_icon() { 'xdsl-24.png' }
+
+sub get_devices() {
+ require detect_devices;
+ require network::connection::isdn;
+ require network::connection::ethernet;
+ my @usb_devices = detect_devices::get_xdsl_usb_devices();
+ $_->{xdsl_type} = 'usb' foreach @usb_devices;
+ my @capi_devices = grep { $_->{driver} =~ /dsl/i } map { network::connection::isdn::find_capi_card($_) } network::connection::isdn->get_devices;
+ $_->{xdsl_type} = 'capi' foreach @capi_devices;
+ my @ethernet_devices = network::connection::ethernet::get_devices();
+ $_->{xdsl_type} = 'ethernet' foreach @ethernet_devices;
+ @usb_devices, @capi_devices, @ethernet_devices;
+}
+
+sub get_metric { 25 }
+sub get_interface() { "ppp0" }
+
+my @non_ppp_protocols = qw(static dhcp);
+sub uses_ppp {
+ my ($self) = @_;
+ !member($self->{protocol}, @non_ppp_protocols);
+}
+
+my %protocol_settings = (
+ pppoa => {
+ plugin => sub {
+ my ($self) = @_;
+ "pppoatm.so " . join('.', $self->{access}{peer}{vpi}, $self->{access}{peer}{vci});
+ },
+ },
+ pppoe => {
+ pty => sub {
+ my ($self) = @_;
+ my $eth_interface = $self->network::connection::ethernet::get_interface;
+ qq("pppoe -m 1412 -I $eth_interface");
+ },
+ options => [
+ qw(default-asyncmap noaccomp nobsdcomp novjccomp nodeflate),
+ "mru 1492",
+ "mtu 1492",
+ "lcp-echo-interval 20",
+ "lcp-echo-failure 3",
+ ],
+ },
+ pptp => {
+ pty => qq("/usr/sbin/pptp 10.0.0.138 --nolaunchpppd"),
+ options => [ qw(noipdefault) ],
+ },
+ capi => {
+ plugin => "capiplugin.so avmadsl",
+ options => [
+ qw(ipcp-accept-remote ipcp-accept-local sync noipx),
+ "connect /bin/true",
+ "lcp-echo-interval 5",
+ "lcp-echo-failure 3",
+ "lcp-max-configure 50",
+ "lcp-max-terminate 2",
+ "mru 1492",
+ "mtu 1492"
+ ],
+ },
+);
+
+my @thirdparty_settings = (
+ {
+ matching => 'speedtch',
+ description => N_("Alcatel speedtouch USB modem"),
+ url => "http://www.speedtouch.com/supuser.htm",
+ name => 'speedtouch',
+ firmware =>
+ {
+ package => 'speedtouch-firmware',
+ test_file => 'speedtch-*.bin*',
+ extract => {
+ name => 'speedtouch-firmware-extractor',
+ test_file => '/usr/sbin/firmware-extractor',
+ windows_source => 'alcaudsl.sys',
+ floppy_source => 'mgmt*.o',
+ default_source => '/usr/share/speedtouch/mgmt.o',
+ run => sub {
+ my ($file) = @_;
+ run_program::raw({ root => $::prefix, chdir => $network::thirdparty::firmware_directory },
+ '/usr/sbin/firmware-extractor', $file);
+ },
+ },
+ },
+ links => 'http://linux-usb.sourceforge.net/SpeedTouch/mandrake/index.html',
+ ppp => {
+ options => [ qw(noaccomp sync) ],
+ },
+ },
+
+ {
+ name => 'eciadsl',
+ explanations => N_("The ECI Hi-Focus modem cannot be supported due to binary driver distribution problem.
+
+You can find a driver on http://eciadsl.flashtux.org/"),
+ no_club => 1,
+ tools => {
+ test_file => '/usr/sbin/pppoeci',
+ },
+ ppp => {
+ options => [
+ qw(noipdefault noaccomp sync),
+ "linkname eciadsl",
+ "lcp-echo-interval 0",
+ ],
+ protocols => {
+ pppoe => {
+ pty => sub {
+ my ($self) = @_;
+ qq("/usr/bin/pppoeci -v 1 -vpi $self->{access}{peer}{vpi} -vci $self->{access}{peer}{vci}");
+ },
+ },
+ },
+ },
+ },
+
+ {
+ matching => [ 'ueagle-atm', 'eagle-usb' ],
+ description => 'Eagle chipset (from Analog Devices), e.g. Sagem F@st 800/840/908',
+ url => 'http://www.eagle-usb.org/',
+ name => 'ueagle',
+ firmware => {
+ test_file => 'ueagle-atm/eagle*.fw',
+ },
+ links => 'http://atm.eagle-usb.org/wakka.php?wiki=UeagleAtmDoc',
+ },
+
+ {
+ matching => qr/^unicorn_.*_atm$/,
+ description => 'Bewan Adsl (Unicorn)',
+ url => 'http://www.bewan.com/bewan/users/downloads/',
+ name => 'unicorn',
+ kernel_module => {
+ test_file => 'unicorn_.*_atm',
+ },
+ tools => {
+ optional => 1,
+ test_file => '/usr/bin/bewan_adsl_status',
+ },
+ sleep => 10,
+ ppp => {
+ options => [
+ qw(default-asyncmap hide-password noaccomp nobsdcomp nodeflate novjccomp sync),
+ "lcp-echo-interval 20",
+ "lcp-echo-failure 3",
+ ],
+ },
+ },
+);
+
+sub get_thirdparty_settings() {
+ \@thirdparty_settings;
+}
+
+sub get_providers {
+ my ($self) = @_;
+ require network::connection::providers::xdsl;
+ if_($self->{device}{xdsl_type} ne 'capi', \%network::connection::providers::xdsl::data, '|');
+}
+
+sub get_protocols {
+ my ($self) = @_;
+ $self->{device}{xdsl_type} eq 'capi' ?
+ {
+ capi => N("DSL over CAPI"),
+ } :
+ {
+ dhcp => N("Dynamic Host Configuration Protocol (DHCP)"),
+ static => N("Manual TCP/IP configuration"),
+ pptp => N("Point to Point Tunneling Protocol (PPTP)"),
+ pppoe => N("PPP over Ethernet (PPPoE)"),
+ pppoa => N("PPP over ATM (PPPoA)"),
+ };
+}
+
+sub guess_protocol {
+ my ($self, $net) = @_;
+ $self->{protocol} = $self->{provider} && $self->{provider}{method};
+ if ($self->{device}{xdsl_type} eq 'capi') {
+ $self->{protocol} = 'capi';
+ } elsif ($self->{device}{xdsl_type} eq 'ethernet') {
+ require network::connection::ethernet;
+ my $interface = $self->network::connection::ethernet::get_interface;
+ if (my $ifcfg = $net->{ifcfg}{$interface}) {
+ $self->{protocol} = $ifcfg->{BOOTPROTO} if member($ifcfg->{BOOTPROTO}, @non_ppp_protocols);
+ $self->{protocol} ||= 'dhcp';
+ #- pppoa shouldn't be selected by default for ethernet devices, fallback on pppoe
+ $self->{protocol} = 'pppoe' if $self->{protocol} eq 'pppoa';
+ }
+ }
+}
+
+sub guess_access_settings {
+ my ($self) = @_;
+ require network::adsl;
+ my $probe = {};
+ network::adsl::adsl_probe_info($probe);
+ $self->{access}{login} = $probe->{adsl}{login};
+ $self->{access}{password} = $probe->{adsl}{passwd};
+ $self->{access}{peer}{$_} = $probe->{adsl}{$_} foreach qw(vpi vci);
+ if ($self->{provider}) {
+ $self->{access}{peer}{$_} = hex($self->{provider}{$_}) foreach qw(vpi vci);
+ }
+}
+
+sub get_access_settings {
+ my ($self) = @_;
+
+ [
+ @{$self->network::connection::ppp::get_access_settings},
+ if_(member($self->{protocol}, qw(pppoa pppoe)),
+ { label => N("Virtual Path ID (VPI):"), val => \$self->{access}{peer}{vpi}, advanced => 1 },
+ { label => N("Virtual Circuit ID (VCI):"), val => \$self->{access}{peer}{vci}, advanced => 1 }
+ ),
+ ];
+}
+
+sub get_peer_default_options {
+ my ($self) = @_;
+ $self->network::connection::ppp::get_peer_default_options,
+ qw(lock persist nopcomp noccp novj),
+ "kdebug 1",
+ "holdoff 4",
+ "maxfail 25";
+}
+
+sub build_peer {
+ my ($self) = @_;
+ my $may_call = sub { ref $_[0] eq 'CODE' ? $_[0]->($self) : $_[0] };
+ my @ppp_fields = qw(plugin pty);
+ my @ppp_options;
+ if ($self->{thirdparty}) {
+ foreach my $settings (grep { $_ } $self->{thirdparty}{ppp}{protocols}{$self->{protocol}}, $self->{thirdparty}{ppp}) {
+ @ppp_options = @{$settings->{options}} if $settings->{options};
+ foreach (@ppp_fields) {
+ $self->{access}{peer}{$_} ||= $may_call->($settings->{$_}) if defined $settings->{$_};
+ }
+ }
+ }
+ if (my $generic_settings = $protocol_settings{$self->{protocol}}) {
+ @ppp_options = @{$generic_settings->{options} || []} if !@ppp_options;
+ foreach (@ppp_fields) {
+ $self->{access}{peer}{$_} ||= $may_call->($generic_settings->{$_}) if defined $generic_settings->{$_};
+ }
+ }
+
+ @ppp_options, #- write them before pty/plugin stuff
+ $self->network::connection::ppp::build_peer;
+}
+
+sub write_settings {
+ my ($self, $net) = @_;
+
+ if ($self->{device}{xdsl_type} eq 'ethernet' && $self->{protocol} eq 'pppoe') {
+ my $interface = $self->network::connection::ethernet::get_interface;
+ $net->{ifcfg}{$interface} = {
+ DEVICE => $interface,
+ BOOTPROTO => 'none',
+ NETMASK => '255.255.255.0',
+ NETWORK => '10.0.0.0',
+ BROADCAST => '10.0.0.255',
+ MII_NOT_SUPPORTED => 'yes',
+ ONBOOT => 'yes',
+ };
+ }
+
+ if ($self->{protocol} eq 'capi') {
+ require network::connection::isdn;
+ network::connection::isdn::write_capi_conf($self->{device});
+ }
+
+ #- TODO: add "options ueagle-atm cmv_file= $net->{adsl}{cmv}.bin" in /etc/modprobe.d/ueagle-atm
+ # if ($self->get_driver eq 'ueagle-atm') { ... }
+
+ if ($self->uses_ppp) {
+ $self->network::connection::ppp::write_settings;
+ } else {
+ $self->network::connection::write_settings;
+ }
+}
+
+sub build_ifcfg_settings {
+ my ($self) = @_;
+ my $settings = {
+ if_($self->uses_ppp, TYPE => 'ADSL'),
+ };
+ if ($self->{device}{xdsl_type} eq 'usb' && !$self->uses_ppp) {
+ #- use ATMARP with the atm0 interface
+ put_in_hash({
+ DEVICE => "atm0",
+ ATM_ADDR => join('.', @{$self->{access}{peer}}{qw(vpi vci)}),
+ MII_NOT_SUPPORTED => "yes",
+ }, $settings);
+ }
+ $self->network::connection::build_ifcfg_settings($settings);
+}
+
+sub unload_connection {
+ my ($self) = @_;
+ require network::connection::isdn;
+ network::connection::isdn::unload_connection($self->{device}) if $self->{protocol} eq 'capi';
+}
+
+sub install_packages {
+ my ($self, $in) = @_;
+ my $packages = {
+ pppoa => [ qw(ppp-pppoatm) ],
+ pppoe => [ qw(rp-pppoe) ],
+ pptp => [ qw(pptp-linux) ],
+ capi => [ qw(ppp) ],
+ }->{$self->{protocol}};
+ if ($packages && !$in->do_pkgs->install(@$packages)) {
+ $in->ask_warn(N("Error"), N("Could not install the packages (%s)!", @$packages));
+ return;
+ }
+ if ($self->{protocol} eq 'capi') {
+ require network::connection::isdn;
+ network::connection::isdn::install_packages($self->{device}, $in);
+ $in->do_pkgs->ensure_is_installed_if_available("drdsl", "/usr/sbin/drdsl");
+ }
+ 1;
+}
+
+sub prepare_connection {
+ my ($self) = @_;
+
+ if ($::isInstall) {
+ #- load modules that are not automatically loaded during install
+ my @modules = qw(ppp_synctty ppp_async ppp_generic n_hdlc); #- required for pppoe/pptp connections
+ push @modules, 'pppoatm' if $self->{protocol} eq 'pppoa';
+ foreach (@modules) {
+ eval { modules::load($_) } or log::l("failed to load $_ module: $@");
+ }
+ }
+
+ if ($self->{protocol} eq 'capi') {
+ require network::connection::isdn;
+ network::connection::isdn::prepare_connection($self->{device});
+ require run_program;
+ run_program::rooted($::prefix, "/usr/sbin/drdsl");
+ }
+
+ 1;
+}
+
+sub connect {
+ my ($self) = @_;
+ if ($self->{device}{xdsl_type} eq 'ethernet') {
+ require network::tools;
+ network::tools::start_interface($self->network::connection::ethernet::get_interface, 0);
+ }
+ $self->network::connection::connect;
+}
+
+sub disconnect {
+ my ($self) = @_;
+ $self->network::connection::disconnect;
+ if ($self->{device}{xdsl_type} eq 'ethernet') {
+ require network::tools;
+ network::tools::stop_interface($self->network::connection::ethernet::get_interface, 0);
+ }
+}
+
+1;
diff --git a/lib/network/drakfirewall.pm b/lib/network/drakfirewall.pm
index e67da22..600a5d3 100644
--- a/lib/network/drakfirewall.pm
+++ b/lib/network/drakfirewall.pm
@@ -137,7 +137,7 @@ sub get_ports() {
}
sub set_ports {
- my ($do_pkgs, $disabled, $ports, $o_in) = @_;
+ my ($do_pkgs, $disabled, $ports, $log_net_drop, $o_in) = @_;
my $shorewall = network::shorewall::read($o_in) or return;
@@ -146,8 +146,9 @@ sub set_ports {
$shorewall->{disabled} = $disabled;
$shorewall->{ports} = $ports;
+ $shorewall->{log_net_drop} = $log_net_drop;
log::l($disabled ? "disabling shorewall" : "configuring shorewall to allow ports: $ports");
- network::shorewall::write($shorewall);
+ network::shorewall::write($shorewall, $o_in);
}
}
@@ -160,15 +161,15 @@ sub get_conf {
if ($o_ports) {
$disabled, from_ports($o_ports);
} elsif (my $shorewall = network::shorewall::read()) {
- $shorewall->{disabled}, from_ports($shorewall->{ports});
+ $shorewall->{disabled}, from_ports($shorewall->{ports}), $shorewall->{log_net_drop};
} else {
- $in->ask_okcancel('', N("drakfirewall configurator
+ $in->ask_okcancel(N("Firewall configuration"), N("drakfirewall configurator
This configures a personal firewall for this Mandriva Linux machine.
For a powerful and dedicated firewall solution, please look to the
specialized Mandriva Security Firewall distribution."), 1) or return;
- $in->ask_okcancel('', N("drakfirewall configurator
+ $in->ask_okcancel(N("Firewall configuration"), N("drakfirewall configurator
Make sure you have configured your Network/Internet access with
drakconnect before going any further."), 1) or return;
@@ -178,7 +179,7 @@ drakconnect before going any further."), 1) or return;
}
sub choose_allowed_services {
- my ($in, $disabled, $servers, $unlisted) = @_;
+ my ($in, $disabled, $servers, $unlisted, $log_net_drop) = @_;
$_->{on} = 0 foreach @all_servers;
$_->{on} = 1 foreach @$servers;
@@ -206,10 +207,11 @@ You can also give a range of ports (eg: 24300:24350/udp)", $invalid_port));
[
{ text => N("Everything (no firewall)"), val => \$disabled, type => 'bool' },
(map { { text => translate($_->{name}), val => \$_->{on}, type => 'bool', disabled => sub { $disabled } } } @l),
- { label => N("Other ports"), val => \$unlisted, advanced => 1, disabled => sub { $disabled } }
+ { label => N("Other ports"), val => \$unlisted, advanced => 1, disabled => sub { $disabled } },
+ { text => N("Log firewall messages in system logs"), val => \$log_net_drop, type => 'bool', advanced => 1, disabled => sub { $disabled } },
]) or return;
- $disabled, [ grep { $_->{on} } @l ], $unlisted;
+ $disabled, [ grep { $_->{on} } @l ], $unlisted, $log_net_drop;
}
sub set_ifw {
@@ -218,16 +220,16 @@ sub set_ifw {
$do_pkgs->ensure_is_installed('mandi-ifw', '/etc/ifw/start', $::isInstall) or return;
my $ports_by_proto = network::shorewall::ports_by_proto($ports);
- output_with_perm("$::prefix/etc/ifw/rules", 0644, map { "$_\n" } (
- (map { "source /etc/ifw/rules.d/$_" } @$rules),
+ output_with_perm("$::prefix/etc/ifw/rules", 0644,
+ (map { "source /etc/ifw/rules.d/$_\n" } @$rules),
map {
my $proto = $_;
map {
my $multiport = /:/ && " -m multiport";
"iptables -A Ifw -m state --state NEW -p $proto$multiport --dport $_ -j IFWLOG --log-prefix NEW\n";
} @{$ports_by_proto->{$proto}};
- } keys %$ports_by_proto,
- ));
+ } intersection([ qw(tcp udp) ], [ keys %$ports_by_proto ]),
+ );
}
my $set_in_file = sub {
@@ -252,7 +254,7 @@ sub choose_watched_services {
messages =>
N("Interactive Firewall") . "\n\n" .
N("You can be warned when someone accesses to a service or tries to intrude into your computer.
-Please select which network activity should be watched."),
+Please select which network activities should be watched."),
title => N("Interactive Firewall"),
},
[
@@ -270,14 +272,14 @@ Please select which network activity should be watched."),
sub main {
my ($in, $disabled) = @_;
- ($disabled, my $servers, my $unlisted) = get_conf($in, $disabled) or return;
+ ($disabled, my $servers, my $unlisted, my $log_net_drop) = get_conf($in, $disabled) or return;
- ($disabled, $servers, $unlisted) = choose_allowed_services($in, $disabled, $servers, $unlisted) or return;
+ ($disabled, $servers, $unlisted, $log_net_drop) = choose_allowed_services($in, $disabled, $servers, $unlisted, $log_net_drop) or return;
choose_watched_services($in, $servers, $unlisted) unless $disabled;
my $ports = to_ports($servers, $unlisted);
- set_ports($in->do_pkgs, $disabled, $ports, $in) or return;
+ set_ports($in->do_pkgs, $disabled, $ports, $log_net_drop, $in) or return;
($disabled, $ports);
}
diff --git a/lib/network/drakvpn.pm b/lib/network/drakvpn.pm
new file mode 100644
index 0000000..158b40c
--- /dev/null
+++ b/lib/network/drakvpn.pm
@@ -0,0 +1,120 @@
+package network::drakvpn;
+
+=head1 NAME
+
+network::drakvpn - Interactive VPN configuration
+
+=head1 SYNOPSIS
+
+ use interactive;
+ use network::drakvpn;
+
+ my $in = 'interactive'->vnew('su');
+ network::drakvpn::create_connection($in);
+
+=cut
+
+use strict;
+use common;
+
+use network::vpn;
+
+sub create_connection {
+ my ($in) = @_;
+ my $vpn_type;
+ my $vpn_connection;
+ my $new_name;
+ require wizards;
+ my $wiz = wizards->new({
+ defaultimage => "drakvpn",
+ name => N("VPN configuration"),
+ pages => {
+ welcome => {
+ if_(!$::isInstall, no_back => 1),
+ name => N("Choose the VPN type"),
+ data => [ {
+ val => \$vpn_type, type => 'list',
+ list => [ sort { $a->get_description cmp $b->get_description } network::vpn::list_types ],
+ format => sub { $_[0] && $_[0]->get_description },
+ allow_empty_list => 1,
+ } ],
+ complete => sub {
+ $vpn_type or return 1;
+ my @packages = $vpn_type->get_packages;
+ if (@packages && !$in->do_pkgs->install(@packages)) {
+ $in->ask_warn(N("Error"), N("Could not install the packages (%s)!", join(', ', @packages)));
+ return 1;
+ }
+ if ($vpn_type->can('prepare')) {
+ my $wait = $in->wait_message('', N("Initializing tools and detecting devices for %s...", $vpn_type->get_type));
+ if (!$vpn_type->prepare) {
+ undef $wait;
+ $in->ask_warn(N("Error"), N("Unable to initialize %s connection type!", $vpn_type->get_type));
+ return 1;
+ }
+ }
+ },
+ next => "vpn_name",
+ },
+ vpn_name => {
+ name => N("Please select an existing VPN connection or enter a new name."),
+ data => sub { [
+ { label => N("VPN connection"), val => \$vpn_connection, type => 'list',
+ list => [ $vpn_type->get_configured_connections, '' ],
+ format => sub { $_[0] ? $_[0]{name} : N("Configure a new connection...") },
+ gtk => { use_boxradio => 1 } },
+ { label => N("New name"), val => \$new_name, disabled => sub { $vpn_connection } },
+ ] },
+ complete => sub {
+ if (!$vpn_connection && !$new_name) {
+ $in->ask_warn(N("Warning"), N("You must select an existing connection or enter a new name."));
+ 1;
+ }
+ },
+ post => sub {
+ $vpn_connection ||= $vpn_type->new($new_name);
+ $vpn_connection->read_config;
+ $vpn_connection->can('get_key_settings') ? "vpn_key_settings" : "vpn_settings";
+ },
+ },
+ vpn_key_settings => {
+ name => N("Please enter the required key(s)"),
+ data => sub { $vpn_connection->get_key_settings },
+ next => "vpn_settings",
+ },
+ vpn_settings => {
+ name => N("Please enter the settings of your VPN connection"),
+ data => sub { $vpn_connection->get_settings },
+ post => sub {
+ $vpn_connection->write_config;
+ "connect";
+ },
+ },
+ connect => {
+ name => N("Do you want to start the connection now?"),
+ type => "yesorno",
+ post => sub {
+ my ($connect) = @_;
+ if ($connect) {
+ $vpn_connection->is_started and $vpn_connection->stop;
+ $vpn_connection->start($in) or $in->ask_warn(N("Warning"), N("Connection failed."));
+ }
+ require network::network;
+ network::network::reload_net_applet();
+ "end";
+ },
+ },
+ end => {
+ name => N("The VPN connection is now configured.
+
+This VPN connection can be automatically started together with a network connection.
+It can be done by reconfiguring the network connection and selecting this VPN connection.
+"),
+ end => 1,
+ },
+ },
+ });
+ $wiz->process($in);
+}
+
+1;
diff --git a/lib/network/ethernet.pm b/lib/network/ethernet.pm
deleted file mode 100644
index c97f45f..0000000
--- a/lib/network/ethernet.pm
+++ /dev/null
@@ -1,162 +0,0 @@
-package network::ethernet; # $Id$
-
-use c;
-use detect_devices;
-use common;
-use run_program;
-
-our @dhcp_clients = qw(dhclient dhcpcd pump dhcpxd);
-
-sub install_dhcp_client {
- my ($in, $client) = @_;
- my %packages = (
- "dhclient" => "dhcp-client",
- );
- #- use default dhcp client if none is provided
- $client ||= $dhcp_clients[0];
- $client = $packages{$client} if exists $packages{$client};
- $in->do_pkgs->install($client);
-}
-
-sub mapIntfToDevice {
- my ($interface) = @_;
- my $hw_addr = c::getHwIDs($interface);
- return {} if $hw_addr =~ /^usb/;
- my ($bus, $slot, $func) = map { hex($_) } ($hw_addr =~ /([0-9a-f]+):([0-9a-f]+)\.([0-9a-f]+)/);
- $hw_addr && (every { defined $_ } $bus, $slot, $func) ?
- grep { $_->{pci_bus} == $bus && $_->{pci_device} == $slot && $_->{pci_function} == $func } detect_devices::probeall() : {};
-}
-
-
-# return list of [ intf_name, module, device_description ] tuples such as:
-# [ "eth0", "3c59x", "3Com Corporation|3c905C-TX [Fast Etherlink]" ]
-#
-# this function try several method in order to get interface's driver and description in order to support both:
-# - hotplug managed devices (USB, firewire)
-# - special interfaces (IP aliasing, VLAN)
-sub get_eth_cards {
- my ($modules_conf) = @_;
- my @all_cards = detect_devices::getNet();
-
- my @devs = detect_devices::pcmcia_probe();
- my $saved_driver;
- # compute device description and return (interface, driver, description) tuples:
- return map {
- my $interface = $_;
- my $description;
- # 1) get interface's driver through ETHTOOL ioctl:
- my ($a, $detected_through_ethtool);
- $a = c::getNetDriver($interface);
- if ($a) {
- $detected_through_ethtool = 1;
- } else {
- # 2) get interface's driver through module aliases:
- $a = $modules_conf->get_alias($interface);
- }
-
- # workaround buggy drivers that returns a bogus driver name for the GDRVINFO command of the ETHTOOL ioctl:
- my %fixes = (
- "p80211_prism2_cs" => 'prism2_cs',
- "p80211_prism2_pci" => 'prism2_pci',
- "p80211_prism2_usb" => 'prism2_usb',
- "ip1394" => "eth1394",
- "DL2K" => "dl2k",
- "orinoco" => undef, #- should be orinoco_{cs,nortel,pci,plx,tmd}
- "hostap" => undef, #- should be hostap_{cs,pci,plx}
- );
- if (exists $fixes{$a}) {
- $a = $fixes{$a};
- $a or undef $detected_through_ethtool;
- }
-
- # 3) try to match a PCMCIA device for device description:
- if (my $b = find { $_->{device} eq $interface } @devs) { # PCMCIA case
- $a = $b->{driver};
- $description = $b->{description};
- } else {
- # 4) try to lookup a device by hardware address for device description:
- # maybe should have we try sysfs first for robustness?
- ($description) = (mapIntfToDevice($interface))[0]->{description};
- }
- # 5) try to match a device through sysfs for driver & device description:
- # (eg: ipw2100 driver for intel centrino do not support ETHTOOL)
- if (!$description || !$a) {
- my $dev_path = "/sys/class/net/$interface/device";
- my $drv = readlink("$dev_path/driver");
- if ($drv && $drv =~ s!.*/!!) {
- $a = $drv unless $detected_through_ethtool;
- my $sysfs_fields = detect_devices::get_sysfs_device_id_map($dev_path);
- my %l = map { $_ => hex(chomp_(cat_("$dev_path/" . $sysfs_fields->{$_}))) } keys %$sysfs_fields;
- my @cards = grep { my $dev = $_; every { $dev->{$_} eq $l{$_} } keys %l } detect_devices::probeall();
- $description ||= $cards[0]{description} if @cards == 1;
- } elsif (!$a && -e "/sys/class/net/$interface/wireless") {
- # probably a rt2400/rt2500 device (PCI or PCMCIA CardBus) or zd1201 (USB)
- # these broken drivers don't create the "device" link
- # try to see if rt2400/rt2500/zd1201 is loaded, and assume current wireless device uses it
- # FIXME: remove this code as soon as the drivers are fixed
- $a = find { -e "/sys/bus/pci/drivers/$_" } qw(rt2400 rt2500);
- $a ||= find { -e "/sys/bus/usb/drivers/$_" } qw(zd1201);
- }
- }
- # 6) try to match a device by driver for device description:
- # (eg: madwifi, ndiswrapper, ...)
- if (!$description) {
- my @cards = grep { $_->{driver} eq ($a || $saved_driver) } detect_devices::probeall();
- $description = $cards[0]{description} if @cards == 1;
- }
- $a and $saved_driver = $a; # handle multiple cards managed by the same driver
- [ $interface, $saved_driver, if_($description, $description) ];
- } @all_cards;
-}
-
-sub get_eth_cards_names {
- my (@all_cards) = @_;
- map { $_->[0] => join(': ', $_->[0], $_->[2]) } @all_cards;
-}
-
-#- returns (link_type, mac_address)
-sub get_eth_card_mac_address {
- my ($intf) = @_;
- #- don't look for 6 bytes addresses only because of various non-standard MAC addresses
- `$::prefix/sbin/ip -o link show $intf 2>/dev/null` =~ m|.*link/(\S+)\s((?:[0-9a-f]{2}:?)+)\s|;
-}
-
-#- write interfaces MAC address in iftab
-sub update_iftab() {
- #- skip aliases interfaces
- foreach my $intf (grep { !/:\d+$/ } detect_devices::getNet()) {
- my ($link_type, $mac_address) = get_eth_card_mac_address($intf) or next;
- #- do not write zeroed MAC addresses in iftab, it confuses ifrename
- $mac_address =~ /^[0:]+$/ and next;
- # ifrename supports alsa IEEE1394, EUI64 and IRDA
- member($link_type, 'ether', 'ieee1394', 'irda', '[27]') or next;
- substInFile {
- s/^$intf\s+.*\n//;
- s/^.*\s+$mac_address\n//;
- $_ .= qq($intf mac $mac_address\n) if eof;
- } "$::prefix/etc/iftab";
- }
-}
-
-# automatic net aliases configuration
-sub configure_eth_aliases {
- my ($modules_conf) = @_;
- my @pcmcia_interfaces = map { $_->{device} } detect_devices::pcmcia_probe();
- foreach my $card (get_eth_cards($modules_conf)) {
- if (member($card->[0], @pcmcia_interfaces)) {
- #- do not write aliases for pcmcia cards, or cardmgr will not be loaded
- $modules_conf->remove_alias($card->[0]);
- } else {
- $modules_conf->set_alias($card->[0], $card->[1]);
- }
- }
- $::isStandalone and $modules_conf->write;
- update_iftab();
-}
-
-sub is_ifplugd_blacklisted {
- my ($module) = @_;
- member($module, qw(forcedeth via-velocity));
-}
-
-1;
diff --git a/lib/network/ifw.pm b/lib/network/ifw.pm
index 40ff0ac..44f58da 100644
--- a/lib/network/ifw.pm
+++ b/lib/network/ifw.pm
@@ -18,7 +18,7 @@ sub new {
"com.mandriva.monitoring",
"/com/mandriva/monitoring/ifw",
"com.mandriva.monitoring.ifw");
- dbus_object::set_gtk2_watch($o);
+ $o->set_gtk2_watch;
$o;
}
@@ -138,4 +138,18 @@ sub attack_to_hash {
$attack;
}
+sub parse_listen_message {
+ my ($args) = @_;
+ my $listen = { mapn { $_[0] => $_[1] } [ 'program', 'port' ], $args };
+ $listen->{port} = unpack('S', pack('n', $listen->{port}));
+ $listen->{service} = get_service($listen->{port});
+ $listen->{message} = N("The \"%s\" application is trying to make a service (%s) available to the network.",
+ $listen->{program},
+ $listen->{service} ne $listen->{port} ? $listen->{service} :
+ #-PO: this should be kept lowercase since the expression is meant to be used between brackets
+ N("port %d", $listen->{port}),
+ );
+ $listen;
+}
+
1;
diff --git a/lib/network/invictus.pm b/lib/network/invictus.pm
new file mode 100644
index 0000000..91806d5
--- /dev/null
+++ b/lib/network/invictus.pm
@@ -0,0 +1,30 @@
+package network::invictus;
+
+use MDK::Common;
+
+my $ucarp_d = "/etc/ucarp.d";
+my $ct_sync_config = "/etc/sysconfig/ct_sync";
+
+sub read_config {
+ my ($invictus) = @_;
+ foreach (all($::prefix . $ucarp_d)) {
+ $invictus->{ucarp}{$_} = +{ getVarsFromSh($::prefix . $ucarp_d . '/' . $_) };
+ }
+ $invictus->{ct_sync} = +{ getVarsFromSh($::prefix . $ct_sync_config) };
+ $invictus->{ct_sync}{CMARKBIT} ||= 30;
+}
+
+sub write_config {
+ my ($invictus) = @_;
+ mkdir_p($::prefix . $ucarp_d);
+ foreach (keys %{$invictus->{ucarp}}) {
+ $invictus->{ucarp}{$_}{UPSCRIPT} ||= '/usr/share/invictus-firewall/ucarp-up.sh';
+ $invictus->{ucarp}{$_}{DOWNSCRIPT} ||= '/usr/share/invictus-firewall/ucarp-down.sh';
+ setVarsInShMode($::prefix . $ucarp_d . '/' . $_, 0600, $invictus->{ucarp}{$_},
+ qw(INTERFACE SRCIP VIRTIP VHID PASSWORD TAKEOVER UPSCRIPT DOWNSCRIPT));
+ }
+ setVarsInSh($::prefix . $ct_sync_config, $invictus->{ct_sync},
+ qw(ENABLE INTERFACE CMARKBIT));
+}
+
+1;
diff --git a/lib/network/ipsec.pm b/lib/network/ipsec.pm
index c0ca768..846b07a 100644
--- a/lib/network/ipsec.pm
+++ b/lib/network/ipsec.pm
@@ -9,23 +9,7 @@ use log;
#- debugg functions ----------
sub recreate_ipsec_conf {
- my ($ipsec, $kernel_version) = @_;
- if ($kernel_version < 2.5) {
- #- kernel 2.4 part -------------------------------
- foreach my $key1 (ikeys %$ipsec) {
- print "$ipsec->{$key1}\n" if ! $ipsec->{$key1}{1};
- foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
- if ($ipsec->{$key1}{$key2}[0] =~ m/^#/) {
- print "\t$ipsec->{$key1}{$key2}[0]\n";
- } elsif ($ipsec->{$key1}{$key2}[0] =~ m/(conn|config|version)/) {
- print "$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]\n";
- } else {
- print "\t$ipsec->{$key1}{$key2}[0]=$ipsec->{$key1}{$key2}[1]\n";
- }
- }
- }
- } else {
- #- kernel 2.6 part -------------------------------
+ my ($ipsec) = @_;
foreach my $key1 (ikeys %$ipsec) {
if (! $ipsec->{$key1}{command}) {
print "$ipsec->{$key1}\n";
@@ -43,7 +27,6 @@ sub recreate_ipsec_conf {
$ipsec->{$key1}{level} . ";\n";
}
}
- }
}
sub recreate_racoon_conf {
@@ -479,7 +462,7 @@ sub remove_section_racoon_conf {
#-------------------------------------------------------------------
sub read_ipsec_conf {
- my ($ipsec_conf, $kernel_version) = @_;
+ my ($ipsec_conf) = @_;
my %conf;
my $nb = 0; #total number
my $i = 0; #nb within a connexion
@@ -487,48 +470,6 @@ sub read_ipsec_conf {
my $line = "";
my @line1;
local $_;
- if ($kernel_version < 2.5) {
- #- kernel 2.4 part -------------------------------
- open(my $LIST, "< $ipsec_conf"); #or die "Can not open the $ipsec_conf file for reading";
- while (<$LIST>) {
- chomp($_);
- $line = $_;
- $line =~ s/^\s+//;
- if (!$line) {
- $nb++;
- put_in_hash(\%conf, { $nb => $line });
- $in_a_conn = "n";
- } elsif ($line =~ /^#/) {
- if ($in_a_conn eq "y") {
- put_in_hash($conf{$nb} ||= {}, { $i => [$line] });
- $i++;
- } else {
- $nb++;
- put_in_hash(\%conf, { $nb => $line });
- $in_a_conn = "n";
- }
- } elsif ($line =~ /^conn|^config|^version/ && $in_a_conn eq "n") {
- @line1 = split /\s+/,$line;
- $i=1;
- $nb++;
- put_in_hash($conf{$nb} ||= {}, { $i => [$line1[0], $line1[1]] });
- $in_a_conn = "y" if $line !~ /^version/;
- $i++;
- } elsif ($line =~ /^conn|^config|^version/ && $in_a_conn eq "y") {
- @line1 = split /\s+/,$line;
- $i=1;
- $nb++;
- put_in_hash($conf{$nb} ||= {}, { $i => [$line1[0], $line1[1]] });
- $i++;
- } else {
- @line1 = split /=/,$line;
- put_in_hash($conf{$nb} ||= {}, { $i => [$line1[0], $line1[1]] });
- $i++;
- }
- }
-
- } else {
- #- kernel 2.6 part -------------------------------
my @mylist;
my $myline = "";
open(my $LIST, "< $ipsec_conf"); #or die "Can not open the $ipsec_conf file for reading";
@@ -561,31 +502,12 @@ sub read_ipsec_conf {
put_in_hash(\%conf, { $nb => $myline });
}
}
-
- }
\%conf;
}
sub write_ipsec_conf {
- my ($ipsec_conf, $ipsec, $kernel_version) = @_;
- if ($kernel_version < 2.5) {
- #- kernel 2.4 part -------------------------------
- open(my $ADD, "> $ipsec_conf") or die "Can not open the $ipsec_conf file for writing";
- foreach my $key1 (ikeys %$ipsec) {
- print $ADD "$ipsec->{$key1}\n" if ! $ipsec->{$key1}{1};
- foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
- if ($ipsec->{$key1}{$key2}[0] =~ m/^#/) {
- print $ADD "\t$ipsec->{$key1}{$key2}[0]\n";
- } elsif ($ipsec->{$key1}{$key2}[0] =~ m/(^conn|^config|^version)/) {
- print $ADD "$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]\n";
- } else {
- print $ADD "\t$ipsec->{$key1}{$key2}[0]=$ipsec->{$key1}{$key2}[1]\n" if $ipsec->{$key1}{$key2}[0] && $ipsec->{$key1}{$key2}[1];
- }
- }
- }
- } else {
- #- kernel 2.6 part -------------------------------
+ my ($ipsec_conf, $ipsec) = @_;
my $display = "";
foreach my $key1 (ikeys %$ipsec) {
if (! $ipsec->{$key1}{command}) {
@@ -606,30 +528,12 @@ sub write_ipsec_conf {
}
open(my $ADD, "> $ipsec_conf") or die "Can not open the $ipsec_conf file for writing";
print $ADD $display;
- }
}
sub display_ipsec_conf {
- my ($ipsec, $kernel_version) = @_;
+ my ($ipsec) = @_;
my $display = "";
- if ($kernel_version < 2.5) {
- #- kernel 2.4 part -------------------------------
- foreach my $key1 (ikeys %$ipsec) {
- $display .= "$ipsec->{$key1}\n" if ! $ipsec->{$key1}{1};
- foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
- if ($ipsec->{$key1}{$key2}[0] =~ m/^#/) {
- $display .= "\t$ipsec->{$key1}{$key2}[0]\n";
- } elsif ($ipsec->{$key1}{$key2}[0] =~ m/(^conn|^config|^version)/) {
- $display .= "$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]\n";
- } else {
- $display .= "\t$ipsec->{$key1}{$key2}[0]=$ipsec->{$key1}{$key2}[1]\n";
- }
- }
- }
-
- } else {
- #- kernel 2.6 part -------------------------------
foreach my $key1 (ikeys %$ipsec) {
if (! $ipsec->{$key1}{command}) {
$display .= "$ipsec->{$key1}\n";
@@ -648,54 +552,26 @@ sub display_ipsec_conf {
}
}
- }
-
$display;
}
sub get_section_names_ipsec_conf {
- my ($ipsec, $kernel_version) = @_;
+ my ($ipsec) = @_;
my @section_names;
- if ($kernel_version < 2.5) {
- #- kernel 2.4 part -------------------------------
- foreach my $key1 (ikeys %$ipsec) {
- foreach my $key2 (ikeys %{$ipsec->{$key1}}) {
- if ($ipsec->{$key1}{$key2}[0] =~ m/(^conn|^config|^version)/) {
- push(@section_names, "$ipsec->{$key1}{$key2}[0] $ipsec->{$key1}{$key2}[1]");
- }
- }
- }
-
- } else {
- #- kernel 2.6 part -------------------------------
foreach my $key1 (ikeys %$ipsec) {
if ($ipsec->{$key1}{command} =~ m/(^spdadd)/) {
push(@section_names, "$ipsec->{$key1}{src_range} $ipsec->{$key1}{dst_range}");
}
}
- }
@section_names;
}
sub remove_section_ipsec_conf {
- my ($section_name, $ipsec, $kernel_version) = @_;
- if ($kernel_version < 2.5) {
- #- kernel 2.4 part -------------------------------
- foreach my $key1 (ikeys %$ipsec) {
- if (find {
- my $s = $ipsec->{$key1}{$_}[0];
- $s !~ /^#/ && $s =~ m/(^conn|^config|^version)/ &&
- $section_name eq "$s $ipsec->{$key1}{$_}[1]";
- } ikeys %{$ipsec->{$key1}}) {
- delete $ipsec->{$key1};
- }
- }
- } else {
- #- kernel 2.6 part -------------------------------
+ my ($section_name, $ipsec) = @_;
foreach my $key1 (ikeys %$ipsec) {
if (find {
my $s = "$ipsec->{$key1}{src_range} $ipsec->{$key1}{dst_range}";
@@ -705,7 +581,6 @@ sub remove_section_ipsec_conf {
delete $ipsec->{$key1};
}
}
- }
}
sub add_section_ipsec_conf {
@@ -715,20 +590,7 @@ sub add_section_ipsec_conf {
}
sub already_existing_section_ipsec_conf {
- my ($section_name, $ipsec, $kernel_version) = @_;
- if ($kernel_version < 2.5) {
- #- kernel 2.4 part -------------------------------
- foreach my $key1 (ikeys %$ipsec) {
- if (find {
- my $s = $ipsec->{$key1}{$_}[0];
- $s !~ /^#/ && $s =~ m/(^conn|^config|^version)/ &&
- $section_name eq "$s $ipsec->{$key1}{$_}[1]";
- } ikeys %{$ipsec->{$key1}}) {
- return "already existing";
- }
- }
- } else {
- #- kernel 2.6 part -------------------------------
+ my ($section_name, $ipsec) = @_;
foreach my $key1 (ikeys %$ipsec) {
if (find {
my $s = "$ipsec->{$key1}{src_range} $ipsec->{$key1}{dst_range}";
@@ -738,35 +600,12 @@ sub already_existing_section_ipsec_conf {
return "already existing";
}
}
- }
return "no";
}
-#- returns the reference to the dynamical list for editing
-sub dynamic_list {
- my ($number, $ipsec) = @_;
- my @list = map { { label => $ipsec->{$number}{$_}[0] . "=",
- val => \$ipsec->{$number}{$_}[1] } } ikeys %{$ipsec->{$number}};
-
- @list;
-}
-
#- returns the hash key number of $section_name
sub matched_section_key_number_ipsec_conf {
- my ($section_name, $ipsec, $kernel_version) = @_;
- if ($kernel_version < 2.5) {
- #- kernel 2.4 part -------------------------------
- foreach my $key1 (ikeys %$ipsec) {
- if (find {
- my $s = $ipsec->{$key1}{$_}[0];
- $s !~ /^#/ && $s =~ m/(^conn|^config|^version)/ &&
- $section_name eq "$s $ipsec->{$key1}{$_}[1]";
- } ikeys %{$ipsec->{$key1}}) {
- return $key1;
- }
- }
- } else {
- #- kernel 2.6 part -------------------------------
+ my ($section_name, $ipsec) = @_;
foreach my $key1 (ikeys %$ipsec) {
if (find {
my $s = "$ipsec->{$key1}{src_range} $ipsec->{$key1}{dst_range}";
@@ -776,6 +615,5 @@ sub matched_section_key_number_ipsec_conf {
return $key1;
}
}
- }
}
1
diff --git a/lib/network/modem.pm b/lib/network/modem.pm
index 29afb69..839b71c 100644
--- a/lib/network/modem.pm
+++ b/lib/network/modem.pm
@@ -37,12 +37,7 @@ sub ppp_read_conf() {
/^METRIC=(.*)/ and $modem->{METRIC} = $1;
}
$modem->{login} ||= $l{Username};
- my $secret = network::tools::read_secret_backend();
- foreach (@$secret) {
- $modem->{passwd} ||= $_->{passwd} if $_->{login} eq $modem->{login};
- }
- #my $secret = network::tools::read_secret_backend();
- #my @cnx_list = map { $_->{server} } @$secret;
+ $modem->{passwd} = network::tools::passwd_by_login($modem->{login});
$modem->{$_} ||= '' foreach qw(connection phone login passwd auth domain dns1 dns2);
$modem->{auto_gateway} ||= defined $modem->{Gateway} && $modem->{Gateway} ne '0.0.0.0' ? N("Manual") : N("Automatic");
$modem->{auto_ip} ||= defined $modem->{IPAddr} && $modem->{IPAddr} ne '0.0.0.0' ? N("Manual") : N("Automatic");
@@ -60,7 +55,7 @@ sub ppp_configure {
if ($modem->{device} ne "/dev/modem") {
my $dev = $modem->{device};
$dev =~ s!^/dev/!!;
- any::devfssymlinkf({ device => $dev }, 'modem');
+ devices::symlink_now_and_register({ device => $dev }, 'modem');
}
my %toreplace = map { $_ => $modem->{$_} } qw(Authentication AutoName connection dns1 dns2 domain IPAddr login passwd phone SubnetMask);
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);
}
diff --git a/lib/network/ndiswrapper.pm b/lib/network/ndiswrapper.pm
index 83f0c37..27df51c 100644
--- a/lib/network/ndiswrapper.pm
+++ b/lib/network/ndiswrapper.pm
@@ -15,7 +15,7 @@ sub present_devices {
my ($driver) = @_;
my @supported_devices;
foreach (all($::prefix . "$ndiswrapper_root/$driver")) {
- my ($ids) = /^([0-9A-Z]{4}:[0-9A-Z]{4})\.[05]\.conf$/;
+ my ($ids) = /^([0-9A-F]{4}:[0-9A-F]{4})\.[0-9A-F]\.conf$/;
$ids and push @supported_devices, $ids;
}
grep { member(uc(sprintf("%04x:%04x", $_->{vendor}, $_->{id})), @supported_devices) } detect_devices::probeall();
@@ -30,7 +30,7 @@ sub get_devices {
sub ask_driver {
my ($in) = @_;
- if (my $inf_file = $in->ask_file(N("Please select the Windows driver (.inf file)"), "/mnt/cdrom")) {
+ if (my $inf_file = $in->ask_file(N("Please select the Windows driver (.inf file)"), "/media/cdrom")) {
my $driver = basename(lc($inf_file));
$driver =~ s/\.inf$//;
@@ -53,13 +53,10 @@ sub find_matching_devices {
my $net_path = '/sys/class/net';
my @devices;
+ require network::connection::ethernet;
foreach my $interface (all($net_path)) {
- my $dev_path = "$net_path/$interface/device";
- -l $dev_path or next;
- my $map = detect_devices::get_sysfs_device_id_map($dev_path);
- if (every { hex(chomp_(cat_("$dev_path/" . $map->{$_}))) eq $device->{$_} } keys %$map) {
- my $driver = readlink("$dev_path/driver");
- $driver =~ s!.*/!!;
+ if (network::connection::ethernet::device_matches_interface($device, $interface)) {
+ my $driver = network::connection::ethernet::interface_to_driver($interface);
push @devices, [ $interface, $driver ] if $driver;
}
}
@@ -94,6 +91,10 @@ sub setup_device {
if (@conflicts) {
$in->ask_yesorno(N("Warning"), N("The selected device has already been configured with the %s driver.
Do you really want to use a ndiswrapper driver?", $conflicts[0][1])) or return;
+ #- unload the old module and try immediately to load ndiswrapper
+ eval { modules::unload($conflicts[0][1]) };
+ eval { modules::unload("ndiswrapper") };
+ eval { modules::load("ndiswrapper") };
}
my $interface = find_interface($device);
@@ -105,4 +106,33 @@ Do you really want to use a ndiswrapper driver?", $conflicts[0][1])) or return;
$interface;
}
+sub select_device {
+ my ($in) = @_;
+ my $driver;
+ my @drivers = installed_drivers();
+ if (@drivers) {
+ $driver ||= first(@drivers);
+ $in->ask_from('', N("Choose an ndiswrapper driver"), [
+ { type => "list", val => \$driver, allow_empty_list => 1,
+ list => [ undef, @drivers ],
+ format => sub { defined $_[0] ? N("Use the ndiswrapper driver %s", $_[0]) : N("Install a new driver") } }
+ ]) or return;
+ }
+ $driver ||= ask_driver($in) or return;
+
+ my @devices = get_devices($in, $driver) or return;
+ my $device;
+ if (@devices == 1) {
+ #- only one device matches installed driver
+ $device = $devices[0];
+ } else {
+ $in->ask_from('', N("Select a device:"), [
+ { type => "list", val => \$device, allow_empty_list => 1,
+ list => [ present_devices($driver) ],
+ format => sub { $_[0]{description} } }
+ ]) or return;
+ }
+ return $device;
+}
+
1;
diff --git a/lib/network/netconnect.pm b/lib/network/netconnect.pm
index adf7f20..ee47c56 100644
--- a/lib/network/netconnect.pm
+++ b/lib/network/netconnect.pm
@@ -11,22 +11,14 @@ use services;
use network::network;
use network::tools;
use network::thirdparty;
+use network::connection;
sub detect {
my ($modules_conf, $auto_detect, $o_class) = @_;
my %l = (
isdn => sub {
- require network::isdn;
- $auto_detect->{isdn} = network::isdn::detect_backend($modules_conf);
- },
- lan => sub { # ethernet
- require network::ethernet;
- modules::load_category($modules_conf, list_modules::ethernet_categories());
- $auto_detect->{lan} = { map { $_->[0] => $_->[1] } network::ethernet::get_eth_cards($modules_conf) };
- },
- adsl => sub {
- require network::adsl;
- $auto_detect->{adsl} = network::adsl::adsl_detect();
+ require network::connection::isdn;
+ $auto_detect->{isdn} = network::connection::isdn::detect_backend($modules_conf);
},
modem => sub {
$auto_detect->{modem} = { map { $_->{description} || "$_->{MANUFACTURER}|$_->{DESCRIPTION} ($_->{device})" => $_ } detect_devices::getModem($modules_conf) };
@@ -59,30 +51,17 @@ sub real_main {
my ($net, $in, $modules_conf) = @_;
#- network configuration should have been already read in $net at this point
my $mouse = $::o->{mouse} || {};
- my ($cnx_type, @all_cards, %eth_intf, %all_eth_intf, %unavailable_wireless_intf);
- my (%connections, @connection_list);
+ my (@connections_list, $connection, @providers_data, $provider_name, $protocol_settings, $access_settings, $control_settings);
+ my $connection_compat;
+ my ($hardware_settings, $network_access_settings, $address_settings, $hostname_settings);
my ($modem, $modem_name, $modem_dyn_dns, $modem_dyn_ip);
- my $cable_no_auth;
- my (@adsl_devices, %adsl_cards, %adsl_data, $adsl_data, $adsl_provider, $adsl_old_provider, $adsl_vpi, $adsl_vci);
- my ($ntf_name, $gateway_ex, $up);
+ my ($up);
my ($isdn, $isdn_name, $isdn_type, %isdn_cards, @isdn_dial_methods);
my $my_isdn = join('', N("Manual choice"), " (", N("Internal ISDN card"), ")");
- my (@ndiswrapper_drivers, $ndiswrapper_driver, $ndiswrapper_device);
- my ($is_wireless, $wireless_enc_mode, $wireless_enc_key, $need_rt2x00_iwpriv, $wireless_roaming, $need_wpa_supplicant);
- my ($dvb_adapter, $dvb_ad, $dvb_net, $dvb_pid);
- my ($module, $auto_ip, $protocol, $onboot, $needhostname, $peerdns, $peeryp, $peerntpd, $ifplugd, $track_network_id, $ipv6_tunnel, $need_network_restart);
my $success = 1;
- my $ethntf = {};
my $db_path = "/usr/share/apps/kppp/Provider";
my (%countries, @isp, $country, $provider, $old_provider);
- my %l10n_lan_protocols = (
- static => N("Manual configuration"),
- dhcp => N("Automatic IP (BOOTP/DHCP)"),
- if_(0,
- dhcp_zeroconf => N("Automatic IP (BOOTP/DHCP/Zeroconf)"),
- )
- );
my $_w = N("Protocol for the rest of the world");
my %isdn_protocols = (
2 => N("European protocol (EDSS1)"),
@@ -91,56 +70,6 @@ sub real_main {
$net->{autodetect} = {};
- my $lan_detect = sub {
- detect($modules_conf, $net->{autodetect}, 'lan');
- @all_cards = network::ethernet::get_eth_cards($modules_conf);
- %all_eth_intf = network::ethernet::get_eth_cards_names(@all_cards); #- needed not to loose GATEWAYDEV
- %eth_intf = map { $_->[0] => join(': ', $_->[0], $_->[2] || N("Unknown driver")) }
- grep { to_bool($is_wireless) == detect_devices::is_wireless_interface($_->[0]) } @all_cards;
- my %available;
- $available{$_->[2]} = undef foreach grep { $_->[2] } @all_cards;
- %unavailable_wireless_intf = map {
- $_->{driver} => sprintf('%s (%s): %s', N("unknown"), $_->{driver}, $_->{description});
- } grep { !exists($available{$_->{description}}) } modules::probe_category('network/wireless');
- };
-
- my $is_dvb_interface = sub { $_[0]{DEVICE} =~ /^dvb\d+_\d+/ };
-
- my $find_lan_module = sub {
- if (my $dev = find { $_->{device} eq $ethntf->{DEVICE} } detect_devices::pcmcia_probe()) { # PCMCIA case
- $module = $dev->{driver};
- } elsif ($dev = find { $_->[0] eq $ethntf->{DEVICE} } @all_cards) {
- $module = $dev->[1];
- } elsif ($is_dvb_interface->($ethntf)) {
- $module = $dvb_adapter->{driver};
- } else { $module = "" }
- };
-
- my %adsl_descriptions = (
- speedtouch => N("Alcatel speedtouch USB modem"),
- sagem => N("Sagem USB modem"),
- bewan => N("Bewan modem"),
- eci => N("ECI Hi-Focus modem"), # this one needs eci agreement
- );
-
- my %adsl_types = (
- dhcp => N("Dynamic Host Configuration Protocol (DHCP)"),
- static => N("Manual TCP/IP configuration"),
- pptp => N("Point to Point Tunneling Protocol (PPTP)"),
- pppoe => N("PPP over Ethernet (PPPoE)"),
- pppoa => N("PPP over ATM (PPPoA)"),
- capi => N("DSL over CAPI"),
- );
-
- my %encapsulations = (
- 1 => N("Bridged Ethernet LLC"),
- 2 => N("Bridged Ethernet VC"),
- 3 => N("Routed IP LLC"),
- 4 => N("Routed IP VC"),
- 5 => N("PPPoA LLC"),
- 6 => N("PPPoA VC"),
- );
-
my %ppp_auth_methods = (
0 => N("Script-based"),
1 => N("PAP"),
@@ -149,95 +78,34 @@ sub real_main {
4 => N("PAP/CHAP"),
);
- my $offer_to_connect = sub {
- #- FIXME: create $try_to_connect sub out of this code
- #- merge with "ask_connect_now" post code
- if ($net->{type} eq 'adsl' && !member($net->{adsl}{method}, qw(static dhcp)) ||
- member($net->{type}, qw(modem isdn isdn_external))) {
- return "ask_connect_now";
- }
-
- unless ($::isInstall) {
- if ($need_network_restart) {
- services::restart("network");
- } else {
- #- FIXME: move this in network::tools::restart_net_interface
- network::tools::stop_net_interface($net, 0);
- if (exists $net->{adsl}{ethernet_device}) {
- network::tools::stop_interface($net->{adsl}{ethernet_device}, 0);
- network::tools::start_interface($net->{adsl}{ethernet_device}, 0);
- }
- network::tools::start_net_interface($net, 0);
- }
- }
- #- FIXME: check for connection here
- #- check for real interface in connection test
- #- don't block when checking connection
- #- return "after_connect" (old "disconnect" step)
- return "end";
- };
-
- my $after_lan_intf_selection = sub { $is_wireless ? 'wireless' : 'lan_protocol' };
-
- my $after_start_on_boot_step = sub {
- #- can't be done in adsl_account step because of static/dhcp adsl methods
- #- we need to write sagem specific parameters and load corresponding modules/programs (sagem/speedtouch)
- $net->{type} eq 'adsl' and network::adsl::adsl_conf_backend($in, $modules_conf, $net);
-
- network::network::configure_network($net, $in, $modules_conf);
- #- FIXME: always run "ask_connect_now"
- return $offer_to_connect->();
- };
-
- my $goto_start_on_boot_ifneeded = sub {
- return $after_start_on_boot_step->() if $net->{type} eq "lan";
- return "isdn_dial_on_boot" if $net->{type} eq 'isdn';
- return "network_on_boot";
- };
-
- my $delete_gateway_settings = sub {
- my ($device) = @_;
- #- delete gateway settings if gateway device is invalid or matches the reconfigured device
- if (!$net->{network}{GATEWAYDEV} || !exists $eth_intf{$net->{network}{GATEWAYDEV}} || $net->{network}{GATEWAYDEV} eq $device) {
- delete $net->{network}{GATEWAY};
- delete $net->{network}{GATEWAYDEV};
- }
- };
-
- my $ndiswrapper_do_device_selection = sub {
- $ntf_name = network::ndiswrapper::setup_device($in, $ndiswrapper_device);
- unless ($ntf_name) {
- undef $ndiswrapper_device;
- return;
- }
-
- #- redetect interfaces (so that the ndiswrapper module can be detected)
- $lan_detect->();
-
- $ethntf = $net->{ifcfg}{$ntf_name} ||= { DEVICE => $ntf_name };
-
- 1;
- };
-
- my $ndiswrapper_do_driver_selection = sub {
- my @devices = network::ndiswrapper::get_devices($in, $ndiswrapper_driver);
-
- if (!@devices) {
- undef $ndiswrapper_driver;
- return;
- } elsif (@devices == 1) {
- #- only one device matches installed driver
- $ndiswrapper_device = $devices[0];
- return $ndiswrapper_do_device_selection->();
+ my %steps_compat = (
+ 'network::connection::isdn' => 'isdn',
+ 'network::connection::pots' => 'modem',
+ );
+
+ my $get_next = sub {
+ my ($step) = @_;
+ my @steps = (
+ "select_connection" => sub { 0 },
+ "configure_hardware" => sub { $connection->can('get_hardware_settings') && !$connection->{device}{no_hardware_settings} },
+ #- network is for example wireless/3G access point
+ "select_network" => sub { $connection->can('get_networks') },
+ "configure_network_access" => sub { $connection->can('get_network_access_settings') },
+ #- allow to select provider after network
+ "select_provider" => sub { $connection->can('get_providers') },
+ #- protocol may depend on provider settings (xDSL)
+ "select_protocol" => sub { $connection->can('get_protocols') },
+ #- peer settings may depend on provider and protocol (VPI/VCI for xDSL)
+ "configure_access" => sub { $connection->can('get_access_settings') },
+ "configure_address" => sub { $connection->can('get_address_settings') || $connection->can('get_hostname_settings') },
+ "configure_control" => sub { $connection->can('get_control_settings') },
+ "apply_connection" => sub { 1 },
+ );
+ my $can;
+ foreach (group_by2(@steps)) {
+ $can && $_->[1]->() and return $_->[0];
+ $can ||= $_->[0] eq $step;
}
-
- 1;
- };
-
- my $ndiswrapper_next_step = sub {
- return $ndiswrapper_device ? $after_lan_intf_selection->() :
- $ndiswrapper_driver ? 'ndiswrapper_select_device' :
- 'ndiswrapper_select_driver';
};
use locale;
@@ -249,39 +117,199 @@ sub real_main {
defaultimage => "drakconnect.png",
name => N("Network & Internet Configuration"),
pages => {
- welcome =>
- {
- pre => sub {
- my @connections = (
- [ N("LAN connection"), "lan" ],
- [ N("Wireless connection"), "lan" ],
- [ N("ADSL connection"), "adsl" ],
- [ N("Cable connection"), "cable" ],
- [ N("ISDN connection"), "isdn" ],
- [ N("Modem connection"), "modem" ],
- [ N("DVB connection"), "dvb" ],
- );
-
- foreach (@connections) {
- my ($string, $type) = @$_;
- $connections{$string} = $type;
- }
- @connection_list = { val => \$cnx_type, type => 'list', list => [ map { $_->[0] } @connections ], };
- },
+ welcome => {
+ pre => sub { undef $net->{type} },
if_(!$::isInstall, no_back => 1),
name => N("Choose the connection you want to configure"),
interactive_help_id => 'configureNetwork',
- data => \@connection_list,
- post => sub {
- $is_wireless = $cnx_type eq N("Wireless connection");
- return $net->{type} = $connections{$cnx_type};
+ data => [ { list => [ network::connection::get_types ],
+ type => 'list', val => \$net->{type}, format => sub { $_[0] && $_[0]->get_type_description },
+ gtk => { use_scrolling => 1 } } ],
+ complete => sub {
+ my @packages = $net->{type}->can('get_packages') ? $net->{type}->get_packages : ();
+ if (@packages && !$in->do_pkgs->install(@packages)) {
+ $in->ask_warn(N("Error"), N("Could not install the packages (%s)!", join(', ', @packages)));
+ 1;
+ }
},
+ post => sub {
+ if (exists $steps_compat{$net->{type}}) {
+ return $steps_compat{$net->{type}};
+ }
+ @connections_list = $net->{type}->get_connections;
+ @connections_list ? "select_connection" : "no_connection";
+ },
+ },
+
+ select_connection => {
+ name => sub { $net->{type}->get_type_name . "\n\n" . N("Select the network interface to configure:") },
+ data => [ { val => \$connection, type => 'list', list => \@connections_list,
+ format => sub { $_[0] && $_[0]->get_description }, allow_empty_list => 1 } ],
+ complete => sub {
+ $connection->setup_thirdparty($in) or return 1;
+ $connection->prepare_device;
+ if ($connection->can("check_device") && !$connection->check_device) {
+ $in->ask_warn('', $connection->{device}{error});
+ return 1;
+ }
+ return 0;
+ },
+ post => sub {
+ $connection->load_interface_settings;
+ $get_next->("select_connection");
+ },
+ },
+
+ no_connection => {
+ name => sub { $net->{type}->get_type_name . "\n\n" . N("No device can be found for this connection type.") },
+ end => 1,
+ },
+
+ configure_hardware => {
+ pre => sub {
+ $hardware_settings = $connection->get_hardware_settings;
+ $connection->guess_hardware_settings if $connection->can('guess_hardware_settings');
+ },
+ name => sub { $net->{type}->get_type_name . "\n\n" . N("Hardware Configuration") },
+ data => sub { $hardware_settings },
+ complete => sub {
+ if ($connection->can('check_hardware')) {
+ my $_w = $in->wait_message('', N("Configuring device..."));
+ if (!$connection->check_hardware) {
+ $in->ask_warn(N("Error"), $connection->{hardware}{error}) if $connection->{hardware}{error};
+ return 1;
+ }
+ }
+ },
+ post => sub { $get_next->("configure_hardware") },
+ },
+
+ select_provider => {
+ pre => sub {
+ @providers_data = $connection->get_providers;
+ require lang;
+ my $locale_country = lang::c2name($::o->{locale}{country} || lang::read()->{country});
+ $provider_name = find { /^$locale_country/ } sort(keys %{$providers_data[0]});
+ },
+ name => sub { $net->{type}->get_type_name . "\n\n" . N("Please select your provider:") },
+ data => sub {
+ [ { type => "list", val => \$provider_name, separator => $providers_data[1],
+ list => [ N("Unlisted - edit manually"), sort(keys %{$providers_data[0]}) ], sort => 0 } ];
+ },
+ post => sub {
+ if ($provider ne N("Unlisted - edit manually")) {
+ $connection->set_provider($providers_data[0]{$provider_name});
+ }
+ $get_next->("select_provider");
+ },
+ },
+
+ select_network => {
+ pre => sub {
+ my $_w = $in->wait_message('', N("Scanning for networks..."));
+ $connection->get_networks;
+ },
+ name => sub { $net->{type}->get_type_name . "\n\n" . N("Please select your network:") },
+ data => sub {
+ [ { type => "list", val => \$connection->{network}, allow_empty_list => 1,
+ list => [ keys %{$connection->{networks}}, undef ], gtk => { use_scrolling => 1 },
+ format => sub { exists $connection->{networks}{$_[0]} ?
+ $connection->{networks}{$_[0]}{name} :
+ N("Unlisted - edit manually");
+ } } ];
+ },
+ post => sub {
+ $get_next->("select_network");
+ },
+ },
+
+ configure_network_access => {
+ pre => sub {
+ $network_access_settings = $connection->get_network_access_settings;
+ $connection->guess_network_access_settings if $connection->can('guess_network_access_settings');
+ },
+ name => sub { $net->{type}->get_type_name . "\n\n" . $connection->get_network_access_settings_label },
+ data => sub { $network_access_settings },
+ post => sub { $get_next->("configure_network_access") },
+ },
+
+ select_protocol => {
+ pre => sub {
+ $protocol_settings = $connection->get_protocol_settings;
+ $connection->guess_protocol($net) if $connection->can('guess_protocol');
+ },
+ name => sub { $net->{type}->get_type_name . "\n\n" . N("Please select your connection protocol.
+If you do not know it, keep the preselected protocol.") },
+ data => sub { $protocol_settings },
+ post => sub { $get_next->("select_protocol") },
+ },
+
+ configure_access => {
+ pre => sub {
+ $access_settings = $connection->get_access_settings;
+ $connection->guess_access_settings if $connection->can('guess_access_settings');
+ },
+ name => sub { $net->{type}->get_type_name . "\n\n" . $connection->get_access_settings_label },
+ data => sub { $access_settings },
+ post => sub { $get_next->("configure_access") },
+ },
+
+ configure_address => {
+ pre => sub {
+ $address_settings = $connection->can('get_address_settings') && $connection->get_address_settings;
+ $connection->guess_address_settings if $connection->can('guess_address_settings');
+ $hostname_settings = $connection->can('get_hostname_settings') && $connection->get_hostname_settings;
+ $connection->guess_hostname_settings if $connection->can('guess_hostname_settings');
+ },
+ name => sub { $net->{type}->get_type_name . "\n\n" . $connection->get_address_settings_label },
+ data => sub { [ @$address_settings, @$hostname_settings ] },
+ complete => sub {
+ if ($connection->can('check_address_settings') && !$connection->check_address_settings($net)) {
+ $in->ask_warn(N("Error"), $connection->{address}{error}{message});
+ my $index = eval { find_index { $_->{val} eq $connection->{address}{error}{field} } @$address_settings };
+ return 1, $index;
+ }
+ return 0;
+ },
+ post => sub { $get_next->("configure_address") },
+ },
+
+ configure_control => {
+ pre => sub {
+ $control_settings = $connection->get_control_settings;
+ $connection->can('get_network_control_settings') and
+ push @$control_settings, @{$connection->get_network_control_settings};
+ $connection->guess_control_settings if $connection->can('guess_control_settings');
+ $connection->guess_network_control_settings if $connection->can('guess_network_control_settings');
+ },
+ name => sub { $net->{type}->get_type_name . "\n\n" . N("Connection control") },
+ data => sub { $control_settings },
+ post => sub { $get_next->("configure_control") },
+ },
+
+ apply_connection => {
+ name => N("Do you want to start the connection now?"),
+ type => "yesorno",
+ complete => sub {
+ $connection->can('install_packages') && !$connection->install_packages($in);
+ },
+ post => sub {
+ my ($answer) = @_;
+ $connection->unload_connection if $connection->can('unload_connection');
+ $connection->write_settings($net, $modules_conf);
+ $connection->prepare_connection if $connection->can('prepare_connection');
+ if ($answer) {
+ $connection->disconnect;
+ $connection->connect;
+ }
+ "end"; #- handle disconnection in install?
+ },
},
isdn_account =>
{
pre => sub {
- network::isdn::get_info_providers_backend($isdn, $provider);
+ network::connection::isdn::get_info_providers_backend($isdn, $provider);
$isdn->{huptimeout} ||= 180;
},
name => N("Connection Configuration") . "\n\n" . N("Please fill or check the field below"),
@@ -305,38 +333,10 @@ sub real_main {
];
},
post => sub {
- network::isdn::write_config($in, $isdn);
+ network::connection::isdn::apply_config($in, $isdn);
$net->{net_interface} = 'ippp0';
- "allow_user_ctl";
- },
- },
-
- cable =>
- {
- pre => sub {
- $cable_no_auth = sub { $net->{cable}{bpalogin} eq N("None") };
- },
- name => N("Cable: account options"),
- data => sub {
- [
- { label => N("Authentication"), type => "list", val => \$net->{cable}{bpalogin}, list => [ N("None"), N("Use BPALogin (needed for Telstra)") ] },
- { label => N("Account Login (user name)"), val => \$net->{cable}{login}, disabled => $cable_no_auth },
- { label => N("Account Password"), val => \$net->{cable}{passwd}, hidden => 1, disabled => $cable_no_auth },
- ];
- },
- complete => sub {
- !$cable_no_auth->() && !$in->do_pkgs->ensure_is_installed('bpalogin', '/usr/sbin/bpalogin');
+ "isdn_dial_on_boot";
},
- post => sub {
- my $use_bpalogin = !$cable_no_auth->();
- $use_bpalogin and substInFile {
- s/username\s+.*\n/username $net->{cable}{login}\n/;
- s/password\s+.*\n/password $net->{cable}{passwd}\n/;
- } "$::prefix/etc/bpalogin.conf";
- services::set_status("bpalogin", $use_bpalogin);
- $auto_ip = 1;
- return "lan";
- }
},
isdn =>
@@ -366,11 +366,11 @@ sub real_main {
$isdn->{description} =~ s/\|/ -- /;
}
- network::isdn::read_config($isdn);
+ network::connection::isdn::read_config($isdn);
$isdn->{driver} = $isdn_cards{$isdn_name}{driver}; #- do not let config overwrite default driver
#- let the user choose hisax or capidrv if both are available
- $isdn->{driver} ne "capidrv" && network::isdn::get_capi_card($in, $isdn) and return "isdn_driver";
+ $isdn->{driver} ne "capidrv" && network::connection::isdn::get_capi_card($in, $isdn) and return "isdn_driver";
return "isdn_protocol";
},
},
@@ -379,7 +379,7 @@ sub real_main {
isdn_ask =>
{
pre => sub {
- %isdn_cards = network::isdn::get_cards();
+ %isdn_cards = network::connection::isdn::get_cards();
},
name => N("Select a device!"),
data => sub { [ { label => N("Net Device"), val => \$isdn_name, type => 'list', separator => '|', list => [ keys %isdn_cards ], allow_empty_list => 1 } ] },
@@ -413,7 +413,7 @@ If you have a PCMCIA card, you have to know the \"irq\" and \"io\" of your card.
$e = $in->ask_from_listf(N("ISDN Configuration"),
N("Which of the following is your ISDN card?"),
sub { $_[0]{description} },
- [ network::isdn::get_cards_by_type($isdn->{card_type}) ]) or goto($isdn->{card_type} =~ /usb|pci/ ? 'isdn_ask_step_1' : 'isdn_ask_step_1b');
+ [ network::connection::isdn::get_cards_by_type($isdn->{card_type}) ]) or goto($isdn->{card_type} =~ /usb|pci/ ? 'isdn_ask_step_1' : 'isdn_ask_step_1b');
$e->{$_} and $isdn->{$_} = $e->{$_} foreach qw(driver type mem io io0 io1 irq firmware);
},
@@ -460,7 +460,7 @@ If you have a PCMCIA card, you have to know the \"irq\" and \"io\" of your card.
name => N("ISDN Configuration") . "\n\n" . N("Select your provider.\nIf it is not listed, choose Unlisted."),
data => sub {
[ { label => N("Provider:"), type => "list", val => \$provider, separator => '|',
- list => [ N("Unlisted - edit manually"), network::isdn::read_providers_backend() ] } ];
+ list => [ N("Unlisted - edit manually"), network::connection::isdn::read_providers_backend() ] } ];
},
next => "isdn_account",
},
@@ -497,9 +497,11 @@ Take a look at http://www.linmodems.org"),
#- some modem configuration programs modify modprobe.conf while we're loaded
#- so write it now and reload then
$modules_conf->write;
- my $ret = network::thirdparty::setup_device($in, 'rtc', $driver, $modem, qw(device));
- $modules_conf->read if $ret;
- !$ret;
+ require network::connection::pots;
+ my $settings = network::thirdparty::apply_settings($in, 'pots', network::connection::pots::get_thirdparty_settings(), $driver);
+ $modem->{device} = $settings->{device} if $settings;
+ $modules_conf->read if $settings;
+ !$settings;
},
post => sub {
return 'choose_serial_port' if $modem_name eq N("Manual choice");
@@ -526,7 +528,7 @@ Take a look at http://www.linmodems.org"),
interactive_help_id => 'selectSerialPort',
data => sub {
[ { val => \$modem->{device}, format => \&mouse::serial_port2text, type => "list",
- list => [ grep { $_ ne $mouse->{device} } (mouse::serial_ports(), grep { -e $_ } '/dev/modem', '/dev/ttySL0', '/dev/ttyS14',) ] } ];
+ list => [ grep { $_ ne $mouse->{device} } (mouse::serial_ports(), glob_("/dev/ttyUSB*"), grep { -e $_ } '/dev/modem', '/dev/ttySL0', '/dev/ttyS14',) ] } ];
},
post => sub {
return 'ppp_provider';
@@ -639,669 +641,27 @@ Take a look at http://www.linmodems.org"),
post => sub {
network::modem::ppp_configure($net, $in, $modem);
$net->{net_interface} = 'ppp0';
- "allow_user_ctl";
- },
- },
-
-
- adsl =>
- {
- pre => sub {
- $lan_detect->();
- @adsl_devices = keys %eth_intf;
-
- detect($modules_conf, $net->{autodetect}, 'adsl');
- %adsl_cards = ();
- foreach my $modem_type (keys %{$net->{autodetect}{adsl}}) {
- foreach my $modem (@{$net->{autodetect}{adsl}{$modem_type}}) {
- my $name = join(': ', $adsl_descriptions{$modem_type}, $modem->{description});
- $adsl_cards{$name} = [ $modem_type, $modem ];
- }
- }
- push @adsl_devices, keys %adsl_cards;
-
- detect($modules_conf, $net->{autodetect}, 'isdn');
- if (my @isdn_modems = @{$net->{autodetect}{isdn}}) {
- require network::isdn;
- %isdn_cards = map { $_->{description} => $_ } grep { $_->{driver} =~ /dsl/i } map { network::isdn::get_capi_card($in, $_) } @isdn_modems;
- push @adsl_devices, keys %isdn_cards;
- }
- },
- name => N("ADSL configuration") . "\n\n" . N("Select the network interface to configure:"),
- data => [ { label => N("Net Device"), type => "list", val => \$ntf_name, allow_empty_list => 1,
- list => \@adsl_devices, format => sub { $eth_intf{$_[0]} || $_[0] } } ],
- complete => sub {
- exists $adsl_cards{$ntf_name} && !network::thirdparty::setup_device($in, 'dsl', $adsl_cards{$ntf_name}[0]);
- },
- post => sub {
- if (exists $adsl_cards{$ntf_name}) {
- my $modem;
- ($ntf_name, $modem) = @{$adsl_cards{$ntf_name}};
- $net->{adsl}{bus} = $modem->{bus} if $ntf_name eq 'bewan';
- }
- if (exists($isdn_cards{$ntf_name})) {
- require network::isdn;
- $net->{adsl}{capi_card} = $isdn_cards{$ntf_name};
- $net->{adsl}{method} = "capi";
- return 'adsl_account';
- }
- return 'adsl_provider';
- },
- },
-
-
- adsl_provider =>
- {
- pre => sub {
- require network::adsl_consts;
- %adsl_data = %network::adsl_consts::adsl_data if is_empty_hash_ref(\%adsl_data);
- $adsl_old_provider = $adsl_provider;
- if (!$adsl_provider) {
- require lang;
- my $locale_country = lang::c2name($::o->{locale}{country} || lang::read()->{country});
- $adsl_provider = find { /^$locale_country/ } sort(keys %adsl_data);
- }
- },
- name => N("Please choose your ADSL provider"),
- data => sub {
- [ { label => N("Provider:"), type => "list", val => \$adsl_provider, separator => '|',
- list => [ sort(N("Unlisted - edit manually"), keys %adsl_data) ], sort => 0 } ];
- },
- post => sub {
- $net->{adsl}{method} = 'pppoa' if member($ntf_name, qw(bewan speedtouch));
- if ($adsl_provider ne N("Unlisted - edit manually")) {
- $adsl_data = $adsl_data{$adsl_provider};
- if ($adsl_provider ne $adsl_old_provider) {
- $net->{adsl}{$_} = $adsl_data->{$_} foreach qw(Encapsulation vpi vci provider_id method);
- $net->{resolv}{$_} = $adsl_data->{$_} foreach qw(DOMAINNAME2);
- }
- }
- return 'adsl_protocol';
- },
- },
-
-
- adsl_protocol =>
- {
- pre => sub {
- # preselect right protocol for ethernet though connections:
- if (!exists $adsl_descriptions{$ntf_name}) {
- $ethntf = $net->{ifcfg}{$ntf_name} ||= { DEVICE => $ntf_name };
- $net->{adsl}{method} ||= $ethntf->{BOOTPROTO} || "dhcp";
- #- pppoa shouldn't be selected by default for ethernet devices, fallback on pppoe
- $net->{adsl}{method} = "pppoe" if $net->{adsl}{method} eq "pppoa";
- }
- },
- name => N("Please choose your DSL connection type.
-If you do not know it, keep the preselected type."),
- data => [
- { text => N("ADSL connection type:"), val => \$net->{adsl}{method}, type => "list",
- list => [ sort { $adsl_types{$a} cmp $adsl_types{$b} } keys %adsl_types ],
- format => sub { $adsl_types{$_[0]} },
- },
- ],
- post => sub {
- my $real_interface = $ntf_name;
- $net->{type} = 'adsl';
- # blacklist bogus driver, enable ifplugd support else:
- $find_lan_module->();
- $ethntf->{MII_NOT_SUPPORTED} ||= bool2yesno(network::ethernet::is_ifplugd_blacklisted($module));
- if ($ntf_name eq "sagem" && member($net->{adsl}{method}, qw(static dhcp))) {
- #- "fctStartAdsl -i" builds ifcfg-ethX from ifcfg-sagem and echoes ethX
- #- it auto-detects dhcp/static modes thanks to encapsulation setting
- $ethntf = $net->{ifcfg}{sagem} ||= {};
- $ethntf->{DEVICE} = "`/usr/sbin/fctStartAdsl -i`";
- $ethntf->{MII_NOT_SUPPORTED} = "yes";
- }
- if ($ntf_name eq "speedtouch" && member($net->{adsl}{method}, qw(static dhcp))) {
- #- use ATMARP with the atm0 interface
- $real_interface = "atm0";
- $ethntf = $net->{ifcfg}{$real_interface} ||= {};
- $ethntf->{DEVICE} = $real_interface;
- $ethntf->{ATM_ADDR} = undef;
- $ethntf->{MII_NOT_SUPPORTED} = "yes";
- }
- #- delete gateway settings if gateway device is invalid or if reconfiguring the gateway interface
- exists $net->{ifcfg}{$real_interface} and $delete_gateway_settings->($real_interface);
- # process static/dhcp ethernet devices:
- if (exists($net->{ifcfg}{$real_interface}) && member($net->{adsl}{method}, qw(static dhcp))) {
- $ethntf->{TYPE} = "ADSL";
- $auto_ip = $net->{adsl}{method} eq 'dhcp';
- return 'lan_intf';
- }
- member($net->{adsl}{method}, qw(pppoe pptp)) and $net->{adsl}{ethernet_device} = $ntf_name;
- return 'adsl_account';
- },
- },
-
-
- adsl_account =>
- {
- pre => sub {
- network::adsl::adsl_probe_info($net);
- $net->{net_interface} = 'ppp0';
- $net->{ifcfg}{ppp0} ||= {};
- ($adsl_vpi, $adsl_vci) = (hex($net->{adsl}{vpi}), hex($net->{adsl}{vci}));
- },
- name => N("Connection Configuration") . "\n\n" .
- N("Please fill or check the field below"),
- data => sub {
- [
- if_(0, { label => N("Provider name (ex provider.net)"), val => \$net->{resolv}{DOMAINNAME2} }),
- { label => N("First DNS Server (optional)"), val => \$net->{resolv}{dnsServer2} },
- { label => N("Second DNS Server (optional)"), val => \$net->{resolv}{dnsServer3} },
- { label => N("Account Login (user name)"), val => \$net->{adsl}{login} },
- { label => N("Account Password"), val => \$net->{adsl}{passwd}, hidden => 1 },
- if_($net->{adsl}{method} ne "capi",
- { label => N("Virtual Path ID (VPI):"), val => \$adsl_vpi, advanced => 1 },
- { label => N("Virtual Circuit ID (VCI):"), val => \$adsl_vci, advanced => 1 }
- ),
- if_($ntf_name eq "sagem",
- { label => N("Encapsulation:"), val => \$net->{adsl}{Encapsulation}, list => [ keys %encapsulations ],
- format => sub { $encapsulations{$_[0]} }, advanced => 1,
- },
- ),
- ];
- },
- post => sub {
- #- update ATM_ADDR for ATMARP connections
- exists $ethntf->{ATM_ADDR} and $ethntf->{ATM_ADDR} = join('.', $adsl_vpi, $adsl_vci);
- #- convert VPI/VCI back to hex
- ($net->{adsl}{vpi}, $net->{adsl}{vci}) = map { sprintf("%x", $_) } ($adsl_vpi, $adsl_vci);
-
- $net->{adsl}{device} =
- $net->{adsl}{method} eq 'capi' ? 'capi_modem' :
- $net->{adsl}{method} eq 'pptp' ? 'pptp_modem' :
- $ntf_name;
- # FIXME: duplicate with $after_start_on_boot_step sub
- network::adsl::adsl_conf_backend($in, $modules_conf, $net);
- "allow_user_ctl";
- },
- },
-
-
- lan =>
- {
- pre => $lan_detect,
- name => N("Select the network interface to configure:"),
- data => sub {
- [ { label => N("Net Device"), type => "list", val => \$ntf_name, list => [
- (sort keys %eth_intf, if_($is_wireless, keys %unavailable_wireless_intf)),
- N_("Manually load a driver"),
- if_($is_wireless, N_("Use a Windows driver (with ndiswrapper)")),
- ], allow_empty_list => 1, format => sub {
- translate($eth_intf{$_[0]} || $unavailable_wireless_intf{$_[0]} || $_[0]) } } ];
- },
- complete => sub {
- if (any { $_->[0] eq $ntf_name && !$_->[1] } @all_cards) {
- $in->ask_warn(N("Error"), N("Unknown driver"));
- return 1;
- }
-
- if ($ntf_name eq "Use a Windows driver (with ndiswrapper)") {
- require network::ndiswrapper;
- $in->do_pkgs->ensure_is_installed('ndiswrapper', '/usr/sbin/ndiswrapper') or return 1;
- undef $ndiswrapper_driver;
- undef $ndiswrapper_device;
- unless (network::ndiswrapper::installed_drivers()) {
- $ndiswrapper_driver = network::ndiswrapper::ask_driver($in) or return 1;
- return !$ndiswrapper_do_driver_selection->();
- }
- }
- if (exists $unavailable_wireless_intf{$ntf_name}) {
- my $driver = $ntf_name;
- network::thirdparty::setup_device($in, 'wireless', $driver) or return 1;
- eval {
- modules::unload($driver);
- modules::load($driver);
- };
- $lan_detect->();
- my $eth_card = find { $_->[1] eq $driver } @all_cards;
- unless ($eth_card) {
- #- FIXME (#17545)
- #- "No matching device found for driver %s."
- #- "The driver has probably failed to load because of a missing firmware
- #- or because it doesn't support your card revision.
- #- Have a look at /var/log/messages to find additional information."
- $in->ask_warn(N("Error"), N("No device found"));
- return 1;
- }
- $ntf_name = $eth_card->[0];
- }
- 0;
- },
- post => sub {
- if ($ntf_name eq "Manually load a driver") {
- require modules::interactive;
- modules::interactive::load_category__prompt($in, $modules_conf, list_modules::ethernet_categories());
- return 'lan';
- } elsif ($ntf_name eq "Use a Windows driver (with ndiswrapper)") {
- return $ndiswrapper_next_step->();
- }
- $ethntf = $net->{ifcfg}{$ntf_name} ||= { DEVICE => $ntf_name };
- return $after_lan_intf_selection->();
- },
- },
-
-
- lan_protocol =>
- {
- pre => sub {
- $find_lan_module->();
- $ethntf->{METRIC} = network::tools::get_default_metric(network::tools::get_interface_type($ethntf, $module))
- unless defined($ethntf->{METRIC});
- $protocol = $l10n_lan_protocols{defined $auto_ip ? ($auto_ip ? 'dhcp' : 'static') : $ethntf->{BOOTPROTO}} || 0;
- },
- name => sub {
- my $_msg = N("Zeroconf hostname resolution");
- N("Configuring network device %s (driver %s)", $ethntf->{DEVICE}, $module) . "\n\n" .
- N("The following protocols can be used to configure a LAN connection. Please choose the one you want to use");
- },
- data => sub {
- [ { val => \$protocol, type => "list", list => [ sort values %l10n_lan_protocols ] } ];
- },
- post => sub {
- $auto_ip = $protocol ne $l10n_lan_protocols{static} || 0;
- return 'lan_intf';
- },
- },
-
-
- lan_intf =>
- {
- pre => sub {
- require network::ethernet;
- $onboot = $ethntf->{ONBOOT} ? $ethntf->{ONBOOT} =~ /yes/ : bool2yesno(!member($ethntf->{DEVICE},
- map { $_->{device} } detect_devices::pcmcia_probe()));
- $needhostname = $ethntf->{NEEDHOSTNAME} !~ /no/;
- $peerdns = $ethntf->{PEERDNS} !~ /no/;
- $peeryp = $ethntf->{PEERYP} =~ /yes/;
- $peerntpd = $ethntf->{PEERNTPD} =~ /yes/;
- # blacklist bogus driver, enable ifplugd support else:
- $ifplugd = !text2bool($ethntf->{MII_NOT_SUPPORTED}) && !network::ethernet::is_ifplugd_blacklisted($module);
- $track_network_id = $::isStandalone && $ethntf->{HWADDR} || detect_devices::isLaptop();
- delete $ethntf->{TYPE} if $net->{type} ne 'adsl' || !member($net->{adsl}{method}, qw(static dhcp));
- $ethntf->{DHCP_CLIENT} ||= (find { -x "$::prefix/sbin/$_" } qw(dhclient dhcpcd pump dhcpxd));
- $ipv6_tunnel = text2bool($ethntf->{IPV6TO4INIT});
- },
- name => sub { join('',
- N("Configuring network device %s (driver %s)", $ethntf->{DEVICE}, $module),
- if_(!$auto_ip, "\n\n" . N("Please enter the IP configuration for this machine.
-Each item should be entered as an IP address in dotted-decimal
-notation (for example, 1.2.3.4).")),
- ) },
- data => sub {
- [ $auto_ip ?
- (
- { text => N("Assign host name from DHCP address"), val => \$needhostname, type => "bool" },
- { label => N("DHCP host name"), val => \$ethntf->{DHCP_HOSTNAME} },
- )
- :
- (
- { label => N("IP address"), val => \$ethntf->{IPADDR}, disabled => sub { $auto_ip } },
- { label => N("Netmask"), val => \$ethntf->{NETMASK}, disabled => sub { $auto_ip } },
- ),
- { text => N("Track network card id (useful for laptops)"), val => \$track_network_id, type => "bool" },
- { text => N("Network Hotplugging"), val => \$ifplugd, type => "bool", disabled => sub { $wireless_roaming } },
- if_($net->{type} eq "lan",
- { text => N("Start at boot"), val => \$onboot, type => "bool" },
- ),
- { label => N("Metric"), val => \$ethntf->{METRIC}, advanced => 1 },
- { text => N("Enable IPv6 to IPv4 tunnel"), val => \$ipv6_tunnel, type => "bool", advanced => 1 },
- if_($auto_ip,
- { label => N("DHCP client"), val => \$ethntf->{DHCP_CLIENT},
- list => \@network::ethernet::dhcp_clients, advanced => 1 },
- { label => N("DHCP timeout (in seconds)"), val => \$ethntf->{DHCP_TIMEOUT}, advanced => 1 },
- { text => N("Get DNS servers from DHCP"), val => \$peerdns, type => "bool", advanced => 1 },
- { text => N("Get YP servers from DHCP"), val => \$peeryp, type => "bool", advanced => 1 },
- { text => N("Get NTPD servers from DHCP"), val => \$peerntpd, type => "bool", advanced => 1 },
- ),
- ];
- },
- complete => sub {
- $ethntf->{BOOTPROTO} = $auto_ip ? "dhcp" : "static";
- return 0 if $auto_ip;
- if (!is_ip($ethntf->{IPADDR})) {
- $in->ask_warn(N("Error"), N("IP address should be in format 1.2.3.4"));
- return 1, 0;
- }
- if (!is_ip($ethntf->{NETMASK})) {
- $in->ask_warn(N("Error"), N("Netmask should be in format 255.255.224.0"));
- return 1, 1;
- }
- if (is_ip_forbidden($ethntf->{IPADDR})) {
- $in->ask_warn(N("Error"), N("Warning: IP address %s is usually reserved!", $ethntf->{IPADDR}));
- return 1, 0;
- }
- #- test if IP address is already used (do not test for sagem DSL devices since it may use many ifcfg files)
- if ($ntf_name ne "sagem" && find { $_->{DEVICE} ne $ethntf->{DEVICE} && $_->{IPADDR} eq $ethntf->{IPADDR} } values %{$net->{ifcfg}}) {
- $in->ask_warn(N("Error"), N("%s already in use\n", $ethntf->{IPADDR}));
- return 1, 0;
- }
- },
- focus_out => sub {
- $ethntf->{NETMASK} ||= netmask($ethntf->{IPADDR}) unless $ethntf->{NETMASK};
- },
- post => sub {
- $ethntf->{ONBOOT} = bool2yesno($onboot);
- $ethntf->{NEEDHOSTNAME} = bool2yesno($needhostname);
- $ethntf->{PEERDNS} = bool2yesno($peerdns);
- $ethntf->{PEERYP} = bool2yesno($peeryp);
- $ethntf->{PEERNTPD} = bool2yesno($peerntpd);
- $ethntf->{MII_NOT_SUPPORTED} = bool2yesno(!$ifplugd);
- $ethntf->{HWADDR} = $track_network_id or delete $ethntf->{HWADDR};
- #- FIXME: special case for sagem where $ethntf->{DEVICE} is the result of a command
- #- we can't always use $ntf_name because of some USB DSL modems
- $net->{net_interface} = $ntf_name eq "sagem" ? "sagem" : $ethntf->{DEVICE};
- $need_network_restart = $ipv6_tunnel ^ text2bool($ethntf->{IPV6TO4INIT});
- if ($ipv6_tunnel) {
- $net->{network}{NETWORKING_IPV6} = "yes";
- $net->{network}{IPV6_DEFAULTDEV} = "tun6to4";
- }
- $ethntf->{IPV6INIT} = bool2yesno($ipv6_tunnel);
- $ethntf->{IPV6TO4INIT} = bool2yesno($ipv6_tunnel);
- if ($auto_ip) {
- #- delete gateway settings if gateway device is invalid or if reconfiguring the gateway interface to dhcp
- $delete_gateway_settings->($ntf_name);
- }
- return "static_hostname";
- },
- },
-
- ndiswrapper_select_driver =>
- {
- pre => sub {
- @ndiswrapper_drivers = network::ndiswrapper::installed_drivers();
- $ndiswrapper_driver ||= first(@ndiswrapper_drivers);
- },
- data => sub {
- [ { label => N("Choose an ndiswrapper driver"), type => "list", val => \$ndiswrapper_driver, allow_empty_list => 1,
- list => [ undef, @ndiswrapper_drivers ],
- format => sub { defined $_[0] ? N("Use the ndiswrapper driver %s", $_[0]) : N("Install a new driver") } } ];
- },
- complete => sub {
- $ndiswrapper_driver ||= network::ndiswrapper::ask_driver($in) or return 1;
- !$ndiswrapper_do_driver_selection->();
- },
- post => $ndiswrapper_next_step,
- },
-
- ndiswrapper_select_device =>
- {
- data => sub {
- [ { label => N("Select a device:"), type => "list", val => \$ndiswrapper_device, allow_empty_list => 1,
- list => [ network::ndiswrapper::present_devices($ndiswrapper_driver) ],
- format => sub { $_[0]{description} } } ];
- },
- complete => sub {
- !$ndiswrapper_do_device_selection->();
+ "configure_control_compat";
},
- post => $ndiswrapper_next_step,
},
- wireless =>
- {
- pre => sub {
- require network::wireless;
- $find_lan_module->();
- $need_rt2x00_iwpriv = network::wireless::is_old_rt2x00($module);
- $wireless_roaming = delete $ethntf->{WIRELESS_MODE} eq 'Roaming' && !$need_rt2x00_iwpriv;
- $ethntf->{WIRELESS_MODE} ||= "Managed";
- $ethntf->{WIRELESS_ESSID} ||= "any";
- ($wireless_enc_key, my $restricted) = network::wireless::get_wep_key_from_iwconfig($ethntf->{WIRELESS_ENC_KEY});
- $wireless_enc_mode =
- $ethntf->{WIRELESS_WPA_DRIVER} || $ethntf->{WIRELESS_IWPRIV} =~ /WPAPSK/ ? 'wpa-psk' :
- !$wireless_enc_key ? 'none' :
- $restricted ? 'restricted' :
- 'open';
- delete $ethntf->{WIRELESS_ENC_KEY};
- delete $ethntf->{WIRELESS_IWPRIV};
- delete $ethntf->{WIRELESS_WPA_DRIVER};
- },
- name => N("Please enter the wireless parameters for this card:"),
- data => sub {
- [
- { label => N("Operating Mode"), val => \$ethntf->{WIRELESS_MODE},
- list => [ N_("Ad-hoc"), N_("Managed"), N_("Master"), N_("Repeater"), N_("Secondary"), N_("Auto") ],
- format => \&translate,
- disabled => sub { $wireless_roaming } },
- { label => N("Network name (ESSID)"), val => \$ethntf->{WIRELESS_ESSID} },
- { label => N("Encryption mode"), val => \$wireless_enc_mode,
- list => [ keys %network::wireless::wireless_enc_modes ],
- sort => 1,
- format => sub { translate($network::wireless::wireless_enc_modes{$_[0]}) } },
- { label => N("Encryption key"), val => \$wireless_enc_key, disabled => sub { $wireless_enc_mode eq 'none' } },
- { text => N("Allow access point roaming"), val => \$wireless_roaming, type => "bool",
- disabled => sub { network::wireless::is_wpa_supplicant_blacklisted($module) } },
- { label => N("Network ID"), val => \$ethntf->{WIRELESS_NWID}, advanced => 1 },
- { label => N("Operating frequency"), val => \$ethntf->{WIRELESS_FREQ}, advanced => 1 },
- { label => N("Sensitivity threshold"), val => \$ethntf->{WIRELESS_SENS}, advanced => 1 },
- { label => N("Bitrate (in b/s)"), val => \$ethntf->{WIRELESS_RATE}, advanced => 1 },
- { label => N("RTS/CTS"), val => \$ethntf->{WIRELESS_RTS}, advanced => 1,
- help => N("RTS/CTS adds a handshake before each packet transmission to make sure that the
-channel is clear. This adds overhead, but increase performance in case of hidden
-nodes or large number of active nodes. This parameter sets the size of the
-smallest packet for which the node sends RTS, a value equal to the maximum
-packet size disable the scheme. You may also set this parameter to auto, fixed
-or off.")
- },
- { label => N("Fragmentation"), val => \$ethntf->{WIRELESS_FRAG}, advanced => 1 },
- { label => N("iwconfig command extra arguments"), val => \$ethntf->{WIRELESS_IWCONFIG}, advanced => 1,
- help => N("Here, one can configure some extra wireless parameters such as:
-ap, channel, commit, enc, power, retry, sens, txpower (nick is already set as the hostname).
-
-See iwconfig(8) man page for further information."),
- },
- { label =>
- #-PO: split the "xyz command extra argument" translated string into two lines if it's bigger than the english one
- N("iwspy command extra arguments"), val => \$ethntf->{WIRELESS_IWSPY}, advanced => 1,
- help => N("iwspy is used to set a list of addresses in a wireless network
-interface and to read back quality of link information for each of those.
-
-This information is the same as the one available in /proc/net/wireless :
-quality of the link, signal strength and noise level.
-
-See iwpspy(8) man page for further information."),
- },
- if_(!$need_rt2x00_iwpriv,
- { label => N("iwpriv command extra arguments"), val => \$ethntf->{WIRELESS_IWPRIV}, advanced => 1,
- help => N("iwpriv enable to set up optionals (private) parameters of a wireless network
-interface.
-
-iwpriv deals with parameters and setting specific to each driver (as opposed to
-iwconfig which deals with generic ones).
-
-In theory, the documentation of each device driver should indicate how to use
-those interface specific commands and their effect.
-
-See iwpriv(8) man page for further information."),
- })
- ];
- },
- complete => sub {
- if ($ethntf->{WIRELESS_FREQ} && $ethntf->{WIRELESS_FREQ} !~ /[0-9.]*[kGM]/) {
- $in->ask_warn(N("Error"), N("Freq should have the suffix k, M or G (for example, \"2.46G\" for 2.46 GHz frequency), or add enough '0' (zeroes)."));
- return 1, 6;
- }
- if ($ethntf->{WIRELESS_RATE} && $ethntf->{WIRELESS_RATE} !~ /[0-9.]*[kGM]/) {
- $in->ask_warn(N("Error"), N("Rate should have the suffix k, M or G (for example, \"11M\" for 11M), or add enough '0' (zeroes)."));
- return 1, 8;
- }
- if (network::wireless::wlan_ng_needed($module)) {
- $in->do_pkgs->ensure_is_installed('prism2-utils', '/sbin/wlanctl-ng') or return 1;
- }
- $need_wpa_supplicant = ($wireless_roaming || $wireless_enc_mode eq 'wpa-psk') && !$need_rt2x00_iwpriv;
- if ($need_wpa_supplicant) {
- $in->do_pkgs->ensure_is_installed('wpa_supplicant', '/usr/sbin/wpa_supplicant') or return 1;
- }
- !network::thirdparty::setup_device($in, 'wireless', $module);
- },
- post => sub {
- if ($wireless_roaming) {
- $ethntf->{MII_NOT_SUPPORTED} = 'no';
- $ethntf->{WIRELESS_MODE} = 'Roaming';
- } elsif (member($wireless_enc_mode, qw(open restricted))) {
- $ethntf->{WIRELESS_ENC_KEY} = network::wireless::convert_wep_key_for_iwconfig($wireless_enc_key, $wireless_enc_mode eq 'restricted');
- } elsif ($need_rt2x00_iwpriv) {
- #- use iwpriv for WPA with rt2400/rt2500 drivers, they don't plan to support wpa_supplicant
- $ethntf->{WIRELESS_IWPRIV} = $wireless_enc_mode eq 'wpa-psk' && qq(set AuthMode=WPAPSK
-set EncrypType=TKIP
-set SSID=$ethntf->{WIRELESS_ESSID}
-set WPAPSK="$wireless_enc_key"
-set TxRate=0);
- }
-
- if ($need_wpa_supplicant) {
- $ethntf->{WIRELESS_WPA_DRIVER} = network::wireless::wpa_supplicant_get_driver($module);
- network::wireless::wpa_supplicant_add_network($ethntf->{WIRELESS_ESSID}, $wireless_enc_mode, $wireless_enc_key);
- }
-
- if (network::wireless::wlan_ng_needed($module)) {
- network::wireless::wlan_ng_configure($ethntf->{WIRELESS_ESSID}, $wireless_enc_key, $ethntf->{DEVICE}, $module);
- }
- return "lan_protocol";
- },
+ configure_control_compat => {
+ pre => sub {
+ $connection_compat = $net->{type}->new($connection || {});
+ network::connection::guess_control_settings($connection_compat);
+ $control_settings = network::connection::get_control_settings($connection_compat);
+ },
+ name => sub { N("Connection control") },
+ data => sub { $control_settings },
+ post => sub {
+ $net->{ifcfg}{$net->{net_interface}}{USERCTL} = bool2yesno($connection_compat->{control}{userctl});
+ $net->{ifcfg}{$net->{net_interface}}{ONBOOT} = bool2yesno($connection_compat->{control}{onboot});
+ network::network::configure_network($net, $in, $modules_conf);
+ "ask_connect_now";
+ },
},
-
- dvb =>
- {
- name => N("DVB configuration") . "\n\n" . N("Select the network interface to configure:"),
- data => [ { label => N("DVB Adapter"), type => "list", val => \$dvb_adapter, allow_empty_list => 1,
- list => [ modules::probe_category("multimedia/dvb") ], format => sub { $_[0]{description} } } ],
- next => "dvb_adapter",
- },
-
-
- dvb_adapter =>
- {
- pre => sub {
- my $previous_ethntf = find { $is_dvb_interface->($_) } values %{$net->{ifcfg}};
- $dvb_ad = $previous_ethntf->{DVB_ADAPTER_ID};
- $dvb_net = $previous_ethntf->{DVB_NETWORK_DEMUX};
- $dvb_pid = $previous_ethntf->{DVB_NETWORK_PID};
- if (my $device = find { sysopen(undef, $_, c::O_RDWR() | c::O_NONBLOCK()) } glob("/dev/dvb/adapter*/net*")) {
- ($dvb_ad, $dvb_net) = $device =~ m,/dev/dvb/adapter(\d+)/net(\d+),;
- }
- },
- name => N("DVB adapter settings"),
- data => sub {
- [
- { label => N("Adapter card"), val => \$dvb_ad },
- { label => N("Net demux"), val => \$dvb_net },
- { label => N("PID"), val => \$dvb_pid },
- ];
- },
- post => sub {
- $ntf_name = 'dvb' . $dvb_ad . '_' . $dvb_net;
- $ethntf = $net->{ifcfg}{$ntf_name} ||= {};
- $ethntf->{DEVICE} = $ntf_name;
- $ethntf->{DVB_ADAPTER_ID} = qq("$dvb_ad");
- $ethntf->{DVB_NETWORK_DEMUX} = qq("$dvb_net");
- $ethntf->{DVB_NETWORK_PID} = qq("$dvb_pid");
- return "lan_protocol";
- },
- },
-
- static_hostname =>
- {
- pre => sub {
- if ($ethntf->{IPADDR}) {
- $net->{resolv}{dnsServer} ||= dns($ethntf->{IPADDR});
- $gateway_ex = gateway($ethntf->{IPADDR});
- # $net->{network}{GATEWAY} ||= gateway($ethntf->{IPADDR});
- if ($ntf_name eq "sagem") {
- my @sagem_ip = split(/\./, $ethntf->{IPADDR});
- $sagem_ip[3] = 254;
- $net->{network}{GATEWAY} = join(".", @sagem_ip);
- }
- }
- },
- name => N("Please enter your host name.
-Your host name should be a fully-qualified host name,
-such as ``mybox.mylab.myco.com''.
-You may also enter the IP address of the gateway if you have one.") .
- " " . # better looking text (to be merged into texts since some languages (eg: ja) doesn't need it
-N("Last but not least you can also type in your DNS server IP addresses."),
- data => sub {
- [ { label => $auto_ip ? N("Host name (optional)") : N("Host name"), val => \$net->{network}{HOSTNAME} },
- if_(!$auto_ip,
- { label => N("DNS server 1"), val => \$net->{resolv}{dnsServer} },
- { label => N("DNS server 2"), val => \$net->{resolv}{dnsServer2} },
- { label => N("DNS server 3"), val => \$net->{resolv}{dnsServer3} },
- { label => N("Search domain"), val => \$net->{resolv}{DOMAINNAME},
- help => N("By default search domain will be set from the fully-qualified host name") },
- { label => N("Gateway (e.g. %s)", $gateway_ex), val => \$net->{network}{GATEWAY} },
- if_(@all_cards > 1,
- { label => N("Gateway device"), val => \$net->{network}{GATEWAYDEV}, list => [ N_("None"), sort keys %all_eth_intf ],
- format => sub { $all_eth_intf{$_[0]} || translate($_[0]) } },
- ),
- ),
- ];
- },
- complete => sub {
- foreach my $dns (qw(dnsServer dnsServer2 dnsServer3)) {
- if ($net->{resolv}{$dns} && !is_ip($net->{resolv}{$dns})) {
- $in->ask_warn(N("Error"), N("DNS server address should be in format 1.2.3.4"));
- return 1;
- }
- }
- if ($net->{network}{GATEWAY} && !is_ip($net->{network}{GATEWAY})) {
- $in->ask_warn(N("Error"), N("Gateway address should be in format 1.2.3.4"));
- return 1;
- }
- },
- post => sub {
- $net->{network}{GATEWAYDEV} eq "None" and delete $net->{network}{GATEWAYDEV};
- return "zeroconf";
- }
- },
-
-
- zeroconf =>
- {
- name => N("If desired, enter a Zeroconf hostname.
-This is the name your machine will use to advertise any of
-its shared resources that are not managed by the network.
-It is not necessary on most networks."),
- data => [ { label => N("Zeroconf Host name"), val => \$net->{zeroconf}{hostname} } ],
- complete => sub {
- if ($net->{zeroconf}{hostname} =~ /\./) {
- $in->ask_warn(N("Error"), N("Zeroconf host name must not contain a ."));
- return 1;
- }
- },
- next => "allow_user_ctl",
- },
-
-
- allow_user_ctl =>
- {
- name => N("Do you want to allow users to start the connection?"),
- type => "yesorno",
- default => sub { bool2yesno(text2bool($net->{ifcfg}{$net->{net_interface}}{USERCTL})) },
- post => sub {
- my ($res) = @_;
- $net->{ifcfg}{$net->{net_interface}}{USERCTL} = bool2yesno($res);
- return $goto_start_on_boot_ifneeded->();
- },
- },
-
-
- network_on_boot =>
- {
- name => N("Do you want to start the connection at boot?"),
- type => "yesorno",
- default => sub { ($net->{type} eq 'modem' ? 'no' : 'yes') },
- post => sub {
- my ($res) = @_;
- $net->{ifcfg}{$net->{net_interface}}{ONBOOT} = bool2yesno($res);
- return $after_start_on_boot_step->();
- },
- },
-
-
isdn_dial_on_boot =>
{
pre => sub {
@@ -1327,7 +687,7 @@ It is not necessary on most networks."),
post => sub {
my $method = find { $_->{name} eq $isdn->{dial_method} } @isdn_dial_methods;
$net->{ifcfg}{ippp0}{$_} = bool2yesno($method->{$_}) foreach qw(ONBOOT DIAL_ON_IFUP);
- return $after_start_on_boot_step->();
+ return "configure_control_compat";
},
},
@@ -1343,16 +703,10 @@ It is not necessary on most networks."),
# local $::isWizard = 0;
my $_w = $in->wait_message('', N("Testing your connection..."), 1);
network::tools::stop_net_interface($net, 0);
- if (exists $net->{adsl}{ethernet_device}) {
- network::tools::stop_interface($net->{adsl}{ethernet_device}, 0);
- sleep 1;
- network::tools::start_interface($net->{adsl}{ethernet_device}, 0);
- }
sleep 1;
network::tools::start_net_interface($net, 1);
my $s = 30;
$type =~ /modem/ and $s = 50;
- $type =~ /adsl/ and $s = 35;
$type =~ /isdn/ and $s = 20;
sleep $s;
$up = network::tools::connected();
@@ -1398,11 +752,30 @@ Test your connection via net_monitor or mcc. If your connection does not work, y
#- keeping the translations in case someone want to restore these texts
if_(0,
+ N("Alcatel speedtouch USB modem"),
+ N("Sagem USB modem"),
+ N("Bewan modem"),
+ N("Bewan modem"),
+ N("ECI Hi-Focus modem"), # this one needs eci agreement
+ N("LAN connection"),
+ N("Wireless connection"),
+ N("ADSL connection"),
+ N("Cable connection"),
+ N("ISDN connection"),
+ N("Modem connection"),
+ N("DVB connection"),
# keep b/c of translations in case they can be reused somewhere else:
N("(detected on port %s)", 'toto'),
#-PO: here, "(detected)" string will be appended to eg "ADSL connection"
N("(detected %s)", 'toto'), N("(detected)"),
N("Network Configuration"),
+ N("Zeroconf hostname resolution"),
+ N("If desired, enter a Zeroconf hostname.
+This is the name your machine will use to advertise any of
+its shared resources that are not managed by the network.
+It is not necessary on most networks."),
+ N("Zeroconf Host name"),
+ N("Zeroconf host name must not contain a ."),
N("Because you are doing a network installation, your network is already configured.
Click on Ok to keep your configuration, or cancel to reconfigure your Internet & Network connection.
"),
@@ -1412,6 +785,18 @@ Click on Ok to keep your configuration, or cancel to reconfigure your Internet &
N("Configuration is complete, do you want to apply settings?"),
N("You have configured multiple ways to connect to the Internet.\nChoose the one you want to use.\n\n"),
N("Internet connection"),
+ N("Select the network interface to configure:"),
+ N("Configuring network device %s (driver %s)", '', ''),
+ N("The following protocols can be used to configure a LAN connection. Please choose the one you want to use."),
+ N("Please enter your host name.
+Your host name should be a fully-qualified host name,
+such as ``mybox.mylab.myco.com''.
+You may also enter the IP address of the gateway if you have one."),
+ # better looking text (to be merged into texts since some languages (eg: ja) doesn't need it
+ N("Last but not least you can also type in your DNS server IP addresses."),
+ N("DNS server address should be in format 1.2.3.4"),
+ N("Gateway address should be in format 1.2.3.4"),
+ N("Gateway device"),
);
}
@@ -1429,33 +814,20 @@ sub safe_main {
}
}
-sub start_internet {
- my ($o) = @_;
- #- give a chance for module to be loaded using kernel-BOOT modules...
- #- FIXME, this has nothing to do there
- $::isStandalone or modules::load_category($o->{modules_conf}, 'network/*');
- network::tools::start_net_interface($o->{net}, 1);
-}
-
-sub stop_internet {
- my ($o) = @_;
- network::tools::stop_net_interface($o->{net}, 1);
-}
-
1;
=head1 network::netconnect::detect()
=head2 example of usage
-use lib qw(/usr/lib/libDrakX);
-use network::netconnect;
-use modules;
-use Data::Dumper;
+ use lib qw(/usr/lib/libDrakX);
+ use network::netconnect;
+ use modules;
+ use Data::Dumper;
-my %i;
-my $modules_conf = modules::any_conf->read;
-network::netconnect::detect($modules_conf, \%i);
-print Dumper(\%i),"\n";
+ my %i;
+ my $modules_conf = modules::any_conf->read;
+ network::netconnect::detect($modules_conf, \%i);
+ print Dumper(\%i),"\n";
=cut
diff --git a/lib/network/network.pm b/lib/network/network.pm
index 45c5dc2..ceba576 100644
--- a/lib/network/network.pm
+++ b/lib/network/network.pm
@@ -14,13 +14,14 @@ use network::tools;
use vars qw(@ISA @EXPORT);
use log;
-my $network_file = "/etc/sysconfig/network";
+our $network_file = "/etc/sysconfig/network";
my $resolv_file = "/etc/resolv.conf";
my $tmdns_file = "/etc/tmdns.conf";
+our $wireless_d = "/etc/sysconfig/network-scripts/wireless.d";
@ISA = qw(Exporter);
-@EXPORT = qw(addDefaultRoute dns dnsServers gateway guessHostname is_ip is_ip_forbidden masked_ip netmask resolv sethostname);
+@EXPORT = qw(addDefaultRoute dns dnsServers gateway guessHostname is_ip is_ip_forbidden masked_ip netmask resolv);
#- $net hash structure
#- autodetect
@@ -98,8 +99,8 @@ sub read_zeroconf() {
sub write_network_conf {
my ($net) = @_;
- if ($net->{network}{HOSTNAME} && $net->{network}{HOSTNAME} =~ /\.(.+)$/) {
- $net->{resolv}{DOMAINNAME} = $1;
+ if ($net->{network}{HOSTNAME} && $net->{network}{HOSTNAME} =~ /\.(.+\..+)$/) {
+ $net->{resolv}{DOMAINNAME} ||= $1;
}
$net->{network}{NETWORKING} = 'yes';
@@ -174,18 +175,20 @@ sub update_broadcast_and_network {
my ($intf) = @_;
my @ip = split '\.', $intf->{IPADDR};
my @mask = split '\.', $intf->{NETMASK};
+ #- FIXME: NETWORK and BROADCAST are deprecated, see sysconfig.txt
$intf->{BROADCAST} = join('.', mapn { int($_[0]) | ((~int($_[1])) & 255) } \@ip, \@mask);
$intf->{NETWORK} = join('.', mapn { int($_[0]) & $_[1] } \@ip, \@mask);
}
sub write_interface_settings {
my ($intf, $file) = @_;
- setVarsInSh($file, $intf, qw(DEVICE BOOTPROTO IPADDR NETMASK NETWORK BROADCAST ONBOOT HWADDR METRIC MII_NOT_SUPPORTED TYPE USERCTL ATM_ADDR ETHTOOL_OPTS VLAN MTU MS_DNS1 MS_DNS2 DOMAIN),
+ setVarsInSh($file, $intf, qw(DEVICE BOOTPROTO IPADDR NETMASK NETWORK BROADCAST GATEWAY ONBOOT HWADDR METRIC MII_NOT_SUPPORTED TYPE USERCTL ATM_ADDR ETHTOOL_OPTS VLAN MTU DNS1 DNS2 DOMAIN RESOLV_MODS LINK_DETECTION_DELAY),
qw(WIRELESS_MODE WIRELESS_ESSID WIRELESS_NWID WIRELESS_FREQ WIRELESS_SENS WIRELESS_RATE WIRELESS_ENC_KEY WIRELESS_RTS WIRELESS_FRAG WIRELESS_IWCONFIG WIRELESS_IWSPY WIRELESS_IWPRIV WIRELESS_WPA_DRIVER),
qw(DVB_ADAPTER_ID DVB_NETWORK_DEMUX DVB_NETWORK_PID),
qw(IPV6INIT IPV6TO4INIT),
- qw(MRU REMIP PEERDNS PPPOPTIONS HARDFLOWCTL DEFABORT RETRYTIMEOUT PAPNAME LINESPEED MODEMPORT DEBUG ESCAPECHARS INITSTRING),
+ qw(MRU REMIP PPPOPTIONS HARDFLOWCTL DEFABORT RETRYTIMEOUT PAPNAME LINESPEED MODEMPORT DEBUG ESCAPECHARS INITSTRING),
qw(DISCONNECTTIMEOUT PERSIST DEFROUTE),
+ qw(VPN_NAME VPN_TYPE),
if_($intf->{BOOTPROTO} eq "dhcp", qw(DHCP_CLIENT DHCP_HOSTNAME NEEDHOSTNAME PEERDNS PEERYP PEERNTPD DHCP_TIMEOUT)),
if_($intf->{DEVICE} =~ /^ippp\d+$/, qw(DIAL_ON_IFUP))
);
@@ -194,17 +197,22 @@ sub write_interface_settings {
log::explanations("written $intf->{DEVICE} interface configuration in $file");
}
+sub get_ifcfg_file {
+ my ($name) = @_;
+ "$::prefix/etc/sysconfig/network-scripts/ifcfg-$name";
+}
+
sub write_interface_conf {
my ($net, $name) = @_;
- my $file = "$::prefix/etc/sysconfig/network-scripts/ifcfg-$name";
+ my $file = get_ifcfg_file($name);
#- prefer ifcfg-XXX files
unlink("$::prefix/etc/sysconfig/network-scripts/$name");
my $intf = $net->{ifcfg}{$name};
- require network::ethernet;
- my (undef, $mac_address) = network::ethernet::get_eth_card_mac_address($intf->{DEVICE});
+ require network::connection::ethernet;
+ my (undef, $mac_address) = network::connection::ethernet::get_eth_card_mac_address($intf->{DEVICE});
$intf->{HWADDR} &&= $mac_address; #- set HWADDR to MAC address if required
update_broadcast_and_network($intf);
@@ -218,7 +226,7 @@ sub write_interface_conf {
sub write_wireless_conf {
my ($ssid, $ifcfg) = @_;
- my $wireless_file = "$::prefix/etc/sysconfig/network-scripts/wireless.d/$ssid";
+ my $wireless_file = $::prefix . $wireless_d . '/' . $ssid;
write_interface_settings($ifcfg, $wireless_file);
# FIXME: write only DHCP/IP settings here
substInFile { $_ = '' if /^DEVICE=/ } $wireless_file;
@@ -264,14 +272,19 @@ sub addDefaultRoute {
c::addDefaultRoute($net->{network}{GATEWAY}) if $net->{network}{GATEWAY};
}
-sub sethostname {
- my ($net) = @_;
- my $text;
- my $hostname = $net->{network}{HOSTNAME};
- syscall_("sethostname", $hostname, length $hostname) ? ($text="set sethostname to $hostname") : ($text="sethostname failed: $!");
- log::explanations($text);
+sub write_hostname {
+ my ($hostname) = @_;
+
+ addVarsInSh($::prefix . $network_file, { HOSTNAME => $hostname }, qw(HOSTNAME));
+
+ add2hosts("localhost", "127.0.0.1");
+ add2hosts($hostname, "127.0.0.1") if $hostname;
- run_program::run("/usr/bin/run-parts", "--arg", $hostname, "/etc/sysconfig/network-scripts/hostname.d") unless $::isInstall;
+ unless ($::isInstall) {
+ my $rc = syscall_("sethostname", $hostname, length $hostname);
+ log::explanations($rc ? "set sethostname to $hostname" : "sethostname failed: $!");
+ run_program::run("/usr/bin/run-parts", "--arg", $hostname, "/etc/sysconfig/network-scripts/hostname.d");
+ }
}
sub resolv($) {
@@ -386,11 +399,16 @@ sub netprofile_delete {
log::explanations(qq(Deleting "$profile" profile));
}
+sub netprofile_clone {
+ my ($source_profile, $dest_profile) = @_;
+ return if !$dest_profile || $dest_profile eq "default" || member($dest_profile, netprofile_list());
+ system('/sbin/clone-netprofile', $source_profile, $dest_profile);
+ log::explanations(qq("Creating "$dest_profile" profile));
+}
+
sub netprofile_add {
my ($net, $profile) = @_;
- return if !$profile || $profile eq "default" || member($profile, netprofile_list());
- system('/sbin/clone-netprofile', $net->{PROFILE}, $profile);
- log::explanations(qq("Creating "$profile" profile));
+ netprofile_clone($net->{PROFILE}, $profile);
}
sub netprofile_list() {
@@ -414,11 +432,13 @@ sub miscellaneous_choose {
{ text => N("Use HTTP proxy for HTTPS connections"), val => \$use_http_for_https, type => "bool" },
{ label => N("HTTPS proxy"), val => \$u->{https_proxy}, disabled => sub { $use_http_for_https } },
{ label => N("FTP proxy"), val => \$u->{ftp_proxy} },
+ { label => N("No proxy for (comma separated list):"), val => \$u->{no_proxy} },
],
complete => sub {
$use_http_for_https and $u->{https_proxy} = $u->{http_proxy};
+ $u->{no_proxy} =~ s/\s//g;
$u->{http_proxy} =~ m,^($|http://), or $in->ask_warn('', N("Proxy should be http://...")), return 1,0;
- $u->{https_proxy} =~ m,^($|http://), or $in->ask_warn('', N("Proxy should be https?://...")), return 1,2;
+ $u->{https_proxy} =~ m,^($|https?://), or $in->ask_warn('', N("Proxy should be http://... or https://...")), return 1,2;
$u->{ftp_proxy} =~ m,^($|ftp://|http://), or $in->ask_warn('', N("URL should begin with 'ftp:' or 'http:'")), return 1,3;
0;
}
@@ -426,92 +446,155 @@ sub miscellaneous_choose {
1;
}
-sub proxy_configure {
- my ($u) = @_;
+sub proxy_configure_shell {
+ my ($proxy) = @_;
my $sh_file = "$::prefix/etc/profile.d/proxy.sh";
- setExportedVarsInSh($sh_file, $u, qw(http_proxy https_proxy ftp_proxy));
+ setExportedVarsInSh($sh_file, $proxy, qw(http_proxy https_proxy ftp_proxy no_proxy));
chmod 0755, $sh_file;
my $csh_file = "$::prefix/etc/profile.d/proxy.csh";
- setExportedVarsInCsh($csh_file, $u, qw(http_proxy https_proxy ftp_proxy));
+ setExportedVarsInCsh($csh_file, $proxy, qw(http_proxy https_proxy ftp_proxy no_proxy));
chmod 0755, $csh_file;
+}
+
+sub proxy_configure_kde {
+ my ($proxy) = @_;
- #- KDE proxy settings
my $kde_config_dir = "$::prefix/usr/share/config";
+ -d $kde_config_dir or return;
+
my $kde_config_file = "$kde_config_dir/kioslaverc";
- if (-d $kde_config_dir) {
- update_gnomekderc($kde_config_file,
- undef,
- PersistentProxyConnection => "false"
- );
- update_gnomekderc($kde_config_file,
- "Proxy Settings",
- AuthMode => 0,
- ProxyType => $u->{http_proxy} || $u->{https_proxy} || $u->{ftp_proxy} ? 4 : 0,
- ftpProxy => "ftp_proxy",
- httpProxy => "http_proxy",
- httpsProxy => "https_proxy"
+ update_gnomekderc($kde_config_file,
+ undef,
+ PersistentProxyConnection => "false"
+ );
+ update_gnomekderc($kde_config_file,
+ "Proxy Settings",
+ AuthMode => 0,
+ ProxyType => $proxy->{http_proxy} || $proxy->{https_proxy} || $proxy->{ftp_proxy} ? 4 : 0,
+ ftpProxy => "ftp_proxy",
+ httpProxy => "http_proxy",
+ httpsProxy => "https_proxy",
+ NoProxyFor => "no_proxy",
);
+}
+
+#- (protocol, user, password, host, port)
+my $http_proxy_match = qr,^(http)://(?:([^:\@]+)(?::([^:\@]+))?\@)?([^\:]+)(?::(\d+))?$,;
+#- (protocol, host, port)
+my $https_proxy_match = qr,^(https?)://(?:[^:\@]+(?::[^:\@]+)?\@)?([^\:]+)(?::(\d+))?$,;
+#- (protocol, protocol, host, port)
+my $ftp_proxy_match = qr,^(http|ftp)://(?:[^:\@]+(?::[^:\@]+)?\@)?([^\:]+)(?::(\d+))?$,;
+my %proxy_default_port = (
+ http => 80,
+ https => 443,
+ ftp => 21,
+);
+
+sub proxy_configure_gnome {
+ my ($proxy) = @_;
+
+ -d "$::prefix/etc/gconf/2/" or return;
+
+ my $defaults_dir = "/etc/gconf/gconf.xml.local-defaults";
+ my $p_defaults_dir = "$::prefix$defaults_dir";
+
+ my $use_alternate_proxy;
+ my $gconf_set = sub {
+ my ($key, $type, $value) = @_;
+ #- gconftool-2 is available since /etc/gconf/2/ exists
+ run_program::rooted($::prefix, 'gconftool-2', '>', '/dev/null', "--config-source=xml::$p_defaults_dir", "--direct", "--set", "--type=$type", if_($type eq "list", '--list-type', 'string'), $key, $value);
+ };
+
+ #- http proxy
+ if (my ($protocol, $user, $password, $host, $port) = $proxy->{http_proxy} =~ $http_proxy_match) {
+ $port ||= $proxy_default_port{$protocol} || $proxy_default_port{http};
+ $gconf_set->("/system/http_proxy/use_http_proxy", "bool", 1);
+ $gconf_set->("/system/http_proxy/host", "string", $host);
+ $gconf_set->("/system/http_proxy/port", "int", $port);
+ $gconf_set->("/system/http_proxy/use_authentication", "bool", to_bool($user));
+ $user and $gconf_set->("/system/http_proxy/authentication_user", "string", $user);
+ $password and $gconf_set->("/system/http_proxy/authentication_password", "string", $password);
+ } else {
+ $gconf_set->("/system/http_proxy/use_http_proxy", "bool", 0);
}
- #- Gnome proxy settings
- if (-d "$::prefix/etc/gconf/2/") {
- my $defaults_dir = "/etc/gconf/gconf.xml.local-defaults";
- my $p_defaults_dir = "$::prefix$defaults_dir";
- my $p_defaults_path = "$::prefix/etc/gconf/2/local-defaults.path";
- -r $p_defaults_path or output_with_perm($p_defaults_path, 0755, qq(
-# System local settings
-xml:readonly:$defaults_dir
-));
- -d $p_defaults_dir or mkdir $p_defaults_dir, 0755;
-
- my $use_alternate_proxy;
- my $gconf_set = sub {
- my ($key, $type, $value) = @_;
- #- gconftool-2 is available since /etc/gconf/2/ exists
- system("gconftool-2", "--config-source=xml::$p_defaults_dir", "--direct", "--set", "--type=$type", $key, $value);
- };
-
- #- http proxy
- if (my ($user, $password, $host, $port) = $u->{http_proxy} =~ m,^http://(?:([^:\@]+)(?::([^:\@]+))?\@)?([^\:]+)(?::(\d+))?$,) {
- $port ||= 80;
- $gconf_set->("/system/http_proxy/use_http_proxy", "bool", 1);
- $gconf_set->("/system/http_proxy/host", "string", $host);
- $gconf_set->("/system/http_proxy/port", "int", $port);
- $gconf_set->("/system/http_proxy/use_authentication", "bool", to_bool($user));
- $user and $gconf_set->("/system/http_proxy/authentication_user", "string", $user);
- $password and $gconf_set->("/system/http_proxy/authentication_password", "string", $password);
- } else {
- $gconf_set->("/system/http_proxy/use_http_proxy", "bool", 0);
- }
+ #- https proxy
+ if (my ($protocol, $host, $port) = $proxy->{https_proxy} =~ $https_proxy_match) {
+ $port ||= $proxy_default_port{$protocol} || $proxy_default_port{https};
+ $gconf_set->("/system/proxy/secure_host", "string", $host);
+ $gconf_set->("/system/proxy/secure_port", "int", $port);
+ $use_alternate_proxy = 1;
+ } else {
+ #- clear the ssl host so that it isn't used if the manual proxy is activated for ftp
+ $gconf_set->("/system/proxy/secure_host", "string", "");
+ }
- #- https proxy
- if (my ($host, $port) = $u->{https_proxy} =~ m,^https?://(?:[^:\@]+(?::[^:\@]+)?\@)?([^\:]+)(?::(\d+))?$,) {
- $port ||= 443;
- $gconf_set->("/system/proxy/secure_host", "string", $host);
- $gconf_set->("/system/proxy/secure_port", "int", $port);
- $use_alternate_proxy = 1;
- } else {
- #- clear the ssl host so that it isn't used if the manual proxy is activated for ftp
- $gconf_set->("/system/proxy/secure_host", "string", "");
- }
+ #- ftp proxy
+ if (my ($protocol, $host, $port) = $proxy->{ftp_proxy} =~ $ftp_proxy_match) {
+ $port ||= $proxy_default_port{$protocol} || $proxy_default_port{ftp};
+ $gconf_set->("/system/proxy/ftp_host", "string", $host);
+ $gconf_set->("/system/proxy/ftp_port", "int", $port);
+ $use_alternate_proxy = 1;
+ } else {
+ #- clear the ftp host so that it isn't used if the manual proxy is activated for ssl
+ $gconf_set->("/system/proxy/ftp_host", "string", "");
+ }
- #- ftp proxy
- if (my ($host, $port) = $u->{ftp_proxy} =~ m,^(?:http|ftp)://(?:[^:\@]+(?::[^:\@]+)?\@)?([^\:]+)(?::(\d+))?$,) {
- $port ||= 21;
- $gconf_set->("/system/proxy/ftp_host", "string", $host);
- $gconf_set->("/system/proxy/ftp_port", "int", $port);
- $use_alternate_proxy = 1;
- } else {
- #- clear the ftp host so that it isn't used if the manual proxy is activated for ssl
- $gconf_set->("/system/proxy/ftp_host", "string", "");
- }
+ my $ignore_hosts = join(',', uniq(qw(localhost 127.0.0.0/8)), split(',', $proxy->{no_proxy}));
+ $gconf_set->("/system/http_proxy/ignore_hosts", "list", "[$ignore_hosts]");
+
+ #- set proxy mode to manual if either https or ftp is used
+ $gconf_set->("/system/proxy/mode", "string", $use_alternate_proxy ? "manual" : "none");
+
+ #- make gconf daemons reload their settings
+ system("killall -s HUP gconfd-2");
+}
+
+sub proxy_configure_mozilla_firefox {
+ my ($proxy) = @_;
- #- set proxy mode to manual if either https or ftp is used
- $gconf_set->("/system/proxy/mode", "string", $use_alternate_proxy ? "manual" : "none");
+ my $firefox_config_file = "$::prefix/etc/firefox.cfg";
+ -f $firefox_config_file or return;
- #- make gconf daemons reload their settings
- system("killall -s HUP gconfd-2");
+ my %prefs;
+ foreach (qw(http ssl ftp)) {
+ undef $prefs{"network.proxy.${_}"};
+ undef $prefs{"network.proxy.${_}_port"};
+ }
+ if (my ($protocol, undef, undef, $host, $port) = $proxy->{http_proxy} =~ $http_proxy_match) {
+ $prefs{"network.proxy.http"} = qq("$host");
+ $prefs{"network.proxy.http_port"} = $port || $proxy_default_port{$protocol} || $proxy_default_port{http};
}
+ if (my ($protocol, $host, $port) = $proxy->{https_proxy} =~ $https_proxy_match) {
+ $prefs{"network.proxy.ssl"} = qq("$host");
+ $prefs{"network.proxy.ssl_port"} = $port || $proxy_default_port{$protocol} || $proxy_default_port{https};
+ }
+ if (my ($protocol, $host, $port) = $proxy->{ftp_proxy} =~ $ftp_proxy_match) {
+ $prefs{"network.proxy.ftp"} = qq("$host");
+ $prefs{"network.proxy.ftp_port"} = $port || $proxy_default_port{$protocol} || $proxy_default_port{ftp};
+ }
+ if ($proxy->{no_proxy}) {
+ $prefs{"network.proxy.no_proxies_on"} = qq("$proxy->{no_proxy}");
+ }
+ $prefs{"network.proxy.type"} = any { defined $prefs{"network.proxy.${_}_port"} } qw(http ssl ftp);
+
+ substInFile {
+ while (my ($key, $value) = each(%prefs)) {
+ if (/^defaultPref\("$key",/) {
+ $_ = defined $value && qq(defaultPref("$key", $value);\n);
+ delete $prefs{$key};
+ }
+ }
+ $_ .= join('', map { if_(defined $prefs{$_}, qq(defaultPref("$_", $prefs{$_});\n)) } sort(keys %prefs)) if eof;
+ } $firefox_config_file;
+}
+
+sub proxy_configure {
+ my ($proxy) = @_;
+ proxy_configure_shell($proxy);
+ proxy_configure_kde($proxy);
+ proxy_configure_gnome($proxy);
+ proxy_configure_mozilla_firefox($proxy);
}
sub read_net_conf {
@@ -530,8 +613,8 @@ sub read_net_conf {
}
}
$net->{wireless} ||= {};
- foreach (all("$::prefix/etc/sysconfig/network-scripts/wireless.d")) {
- $net->{wireless}{$_} = { getVarsFromSh("$::prefix/etc/sysconfig/network-scripts/wireless.d/$_") };
+ foreach (all($::prefix . $wireless_d)) {
+ $net->{wireless}{$_} = { getVarsFromSh($::prefix . $wireless_d . '/' . $_) };
}
netprofile_read($net);
if (my $default_intf = network::tools::get_default_gateway_interface($net)) {
@@ -559,9 +642,9 @@ sub easy_dhcp {
return if text2bool($net->{network}{NETWORKING});
require modules;
- require network::ethernet;
+ require network::connection::ethernet;
modules::load_category($modules_conf, list_modules::ethernet_categories());
- my @all_dev = sort map { $_->[0] } network::ethernet::get_eth_cards($modules_conf);
+ my @all_dev = sort map { $_->[0] } network::connection::ethernet::get_eth_cards($modules_conf);
#- only for a single ethernet network card
my @ether_dev = grep { /^eth[0-9]+$/ && `LC_ALL= LANG= $::prefix/sbin/ip -o link show $_ 2>/dev/null` =~ m|\slink/ether\s| } @all_dev;
@@ -589,26 +672,27 @@ sub easy_dhcp {
1;
}
+sub reload_net_applet() {
+ #- make net_applet reload the configuration
+ my $pid = chomp_(`pidof -x net_applet`);
+ $pid and kill 1, $pid;
+}
+
sub configure_network {
my ($net, $in, $modules_conf) = @_;
if (!$::testing) {
- require network::ethernet;
- network::ethernet::configure_eth_aliases($modules_conf);
+ require network::connection::ethernet;
+ network::connection::ethernet::configure_eth_aliases($modules_conf);
write_network_conf($net);
write_resolv_conf($net);
- if ($::isInstall && ! -e "/etc/resolv.conf") {
- #- symlink resolv.conf in install root too so that updates and suppl media can be added
- symlink "$::prefix/etc/resolv.conf", "/etc/resolv.conf";
- }
+ write_hostname($net->{network}{HOSTNAME}) if $net->{network}{HOSTNAME};
foreach (keys %{$net->{ifcfg}}) {
write_interface_conf($net, $_);
my $ssid = $net->{ifcfg}{$_}{WIRELESS_ESSID} or next;
write_wireless_conf($ssid, $net->{ifcfg}{$_});
}
- network::ethernet::install_dhcp_client($in, $_->{DHCP_CLIENT}) foreach grep { $_->{BOOTPROTO} eq "dhcp" } values %{$net->{ifcfg}};
- add2hosts("localhost", "127.0.0.1");
- add2hosts($net->{network}{HOSTNAME}, "127.0.0.1") if $net->{network}{HOSTNAME};
+ network::connection::ethernet::install_dhcp_client($in, $_->{DHCP_CLIENT}) foreach grep { $_->{BOOTPROTO} eq "dhcp" } values %{$net->{ifcfg}};
write_zeroconf($net, $in);
any { $_->{BOOTPROTO} =~ /^(pump|bootp)$/ } values %{$net->{ifcfg}} and $in->do_pkgs->install('pump');
@@ -616,12 +700,9 @@ sub configure_network {
require network::shorewall;
network::shorewall::update_interfaces_list();
- $net->{network}{HOSTNAME} && !$::isInstall and sethostname($net);
}
- #- make net_applet reload the configuration
- my $pid = chomp_(`pidof -x net_applet`);
- $pid and kill 1, $pid;
+ reload_net_applet();
}
1;
diff --git a/lib/network/rfswitch.pm b/lib/network/rfswitch.pm
new file mode 100644
index 0000000..4617990
--- /dev/null
+++ b/lib/network/rfswitch.pm
@@ -0,0 +1,38 @@
+package network::rfswitch;
+
+use strict;
+use MDK::Common;
+use detect_devices;
+
+my $conf_file = "/etc/modprobe.d/rfswitch.conf";
+
+my @settings = (
+ {
+ match => sub {
+ # CL56, with buggy BIOS
+ detect_devices::dmidecode_category('BIOS')->{Vendor} eq 'COMPAL' &&
+ detect_devices::dmidecode_category('System')->{'Product Name'} eq '<BAD INDEX>';
+ },
+ module => 'acerhk',
+ options => 'usedritek=1 autowlan=1 force_series=290',
+ install => 'echo 1 > /proc/driver/acerhk/wirelessled',
+ remove => 'echo 0 > /proc/driver/acerhk/wirelessled',
+ },
+);
+
+sub configure() {
+ my $setting = find { $_->{match}->() } @settings;
+ if ($setting) {
+ output_p($::prefix . $conf_file,
+ join("\n",
+ if_($setting->{options}, "options $setting->{module} $setting->{options}"),
+ if_($setting->{install}, "install $setting->{module} /sbin/modprobe --first-time --ignore-install $setting->{module} && $setting->{install}"),
+ if_($setting->{remove}, "remove $setting->{module} $setting->{remove}; /sbin/modprobe -r --ignore-remove $setting->{module}"),
+ "",
+ ));
+ require modules;
+ modules::set_preload_modules('rfswitch', $setting->{module});
+ }
+}
+
+1;
diff --git a/lib/network/shorewall.pm b/lib/network/shorewall.pm
index 2567b48..ce90d4e 100644
--- a/lib/network/shorewall.pm
+++ b/lib/network/shorewall.pm
@@ -1,12 +1,13 @@
package network::shorewall; # $Id$
use detect_devices;
-use network::ethernet;
use network::network;
use run_program;
use common;
use log;
+my $shorewall_root = "/etc/shorewall";
+
sub check_iptables() {
-f "$::prefix/etc/sysconfig/iptables" ||
$::isStandalone && do {
@@ -26,18 +27,12 @@ sub set_config_file {
} else {
$_ = '' if /^[^#]/;
}
- } "$::prefix/etc/shorewall/$file";
+ } "$::prefix${shorewall_root}/$file";
}
sub get_config_file {
my ($file) = @_;
- map { [ split ' ' ] } grep { !/^#/ } cat_("$::prefix/etc/shorewall/$file");
-}
-
-sub get_ifcfg_interface() {
- my $net = {};
- network::network::read_net_conf($net);
- network::tools::get_default_gateway_interface($net);
+ map { [ split ' ' ] } grep { !/^#/ } cat_("$::prefix${shorewall_root}/$file");
}
sub dev_to_shorewall {
@@ -47,53 +42,47 @@ sub dev_to_shorewall {
$dev;
}
-sub get_shorewall_interface() {
+sub get_net_zone_interfaces {
+ my ($net) = @_;
#- read shorewall configuration first
- foreach (get_config_file('interfaces')) {
- $_->[0] eq 'net' and return $_->[1];
- }
+ my @interfaces = map { $_->[1] } grep { $_->[0] eq 'net' } get_config_file('interfaces');
#- else try to find the best interface available
- dev_to_shorewall(get_ifcfg_interface());
-}
-
-our $ask_shorewall_interface_label = N_("Please enter the name of the interface connected to the internet.
-
-Examples:
- ppp+ for modem or DSL connections,
- eth0, or eth1 for cable connection,
- ippp+ for a isdn connection.
-");
-
-sub shorewall_interface_choices {
- my ($refval) = @_;
- my $modules_conf = modules::any_conf->read;
- my @all_cards = network::ethernet::get_eth_cards($modules_conf);
- my %net_devices = network::ethernet::get_eth_cards_names(@all_cards);
- put_in_hash(\%net_devices, { 'ppp+' => 'ppp+', 'ippp+' => 'ippp+' });
-
- [ { label => N("Net Device"), val => $refval, list => [ sort keys %net_devices ], format => sub { $net_devices{$_[0]} || $_[0] }, not_edit => 0 } ];
+ @interfaces ? @interfaces : dev_to_shorewall(network::tools::get_default_gateway_interface($net));
}
-sub read_default_interfaces {
+sub get_zones {
my ($conf, $o_in) = @_;
- my $interface = get_shorewall_interface();
- $o_in and $o_in->ask_from('', translate($ask_shorewall_interface_label), shorewall_interface_choices(\$interface));
- set_net_interface($conf, $interface);
+ my $net = {};
+ network::network::read_net_conf($net);
+ #- find all interfaces but alias interfaces
+ my @all_intf = grep { !/:/ } uniq(keys(%{$net->{ifcfg}}), detect_devices::get_net_interfaces());
+ my %net_zone = map { $_ => undef } @all_intf;
+ $net_zone{$_} = 1 foreach get_net_zone_interfaces($net);
+ $o_in and $o_in->ask_from('', N("Please select the interfaces that will be protected by the firewall.
+
+All interfaces directly connected to Internet should be selected,
+while interfaces connected to a local network may be unselected.
+
+Which interfaces should be protected?
+"), [
+ map {
+ { text => network::tools::get_interface_description($net, $_), val => \$net_zone{$_}, type => 'bool' };
+ } (sort keys %net_zone) ]);
+ ($conf->{net_zone}, $conf->{loc_zone}) = partition { $net_zone{$_} } keys %net_zone;
}
-sub set_net_interface {
+sub add_interface_to_net_zone {
my ($conf, $interface) = @_;
- $conf->{net_interface} = $interface;
- my $net = {};
- network::network::read_net_conf($net);
- my @all_intf = uniq((map { dev_to_shorewall($_) } keys %{$net->{ifcfg}}), detect_devices::getNet());
- #- keep all other interfaces (but alias interfaces) in local zone
- $conf->{loc_interface} = [ grep { !/:/ && $_ ne $interface } @all_intf ];
+ if (!member($interface, @{$conf->{net_zone}})) {
+ push @{$conf->{net_zone}}, $interface;
+ @{$conf->{loc_zone}} = grep { $_ ne $interface } @{$conf->{loc_zone}};
+ }
}
sub read {
my ($o_in) = @_;
- my @rules = get_config_file('rules');
+ #- read old rules file if config is not moved to rules.drakx yet
+ my @rules = get_config_file(-f "$::prefix${shorewall_root}/rules.drakx" ? 'rules.drakx' : 'rules');
my %conf = (disabled => !glob_("$::prefix/etc/rc3.d/S*shorewall"),
ports => join(' ', map {
my $e = $_;
@@ -103,10 +92,14 @@ sub read {
$conf{redirects}{$_->[3]}{$_->[2]} = $_->[4] foreach grep { $_->[0] eq 'REDIRECT' } @rules;
if (my ($e) = get_config_file('masq')) {
- $conf{masq_subnet} = $e->[1];
+ ($conf{masq}{net_interface}, $conf{masq}{subnet}) = @$e;
}
- read_default_interfaces(\%conf, $o_in);
- $conf{net_interface} && \%conf;
+
+ my @policy = get_config_file('policy');
+ $conf{log_net_drop} = @policy ? (any { $_->[0] eq 'net' && $_->[1] eq 'all' && $_->[2] eq 'DROP' && $_->[3] } @policy) : 1;
+
+ get_zones(\%conf, $o_in);
+ $conf{net_zone}[0] && \%conf;
}
sub ports_by_proto {
@@ -119,12 +112,44 @@ sub ports_by_proto {
\%ports_by_proto;
}
+sub upgrade_to_shorewall3() {
+ #- the 'FW' option has been removed from shorewall.conf as of shorewall 3.0
+ my $ipsecfile_ok;
+ substInFile {
+ undef $_ if /^\s*FW=/;
+ if ((/^\s*IPSECFILE=/ || eof) && !$ipsecfile_ok) {
+ $ipsecfile_ok = 1;
+ $_ = "IPSECFILE=zones\n";
+ }
+ } "$::prefix${shorewall_root}/shorewall.conf";
+}
+
sub write {
- my ($conf) = @_;
- my $default_intf = get_ifcfg_interface();
- my $use_pptp = $default_intf =~ /^ppp/ && cat_("$::prefix/etc/ppp/peers/$default_intf") =~ /pptp/;
+ my ($conf, $o_in) = @_;
+ my $use_pptp = any { /^ppp/ && cat_("$::prefix/etc/ppp/peers/$_") =~ /pptp/ } @{$conf->{net_zone}};
my $ports_by_proto = ports_by_proto($conf->{ports});
+ my ($include_drakx, $other_rules) = partition { $_ eq "INCLUDE\trules.drakx\n" } grep { !/^#/ } cat_("$::prefix${shorewall_root}/rules");
+ #- warn if the config is already in rules.drakx and additionnal rules are configured
+ if (!is_empty_array_ref($include_drakx) && !is_empty_array_ref($other_rules)) {
+ my %actions = (
+ keep => N("Keep custom rules"),
+ drop => N("Drop custom rules"),
+ );
+ my $action = 'keep';
+ !$o_in || $o_in->ask_from_(
+ {
+ messages => N("Your firewall configuration has been manually edited and contains
+rules that may conflict with the configuration that has just been set up.
+What do you want to do?"),
+ title => N("Firewall"),
+ icon => 'banner-security',
+ },
+ [ { val => \$action, type => 'list', list => [ 'keep', 'drop' ], format => sub { $actions{$_[0]} } } ]) or return;
+ #- reset the rules files if the user has chosen to drop modifications
+ undef $include_drakx if $action eq 'drop';
+ }
+
my $interface_settings = sub {
my ($zone, $interface) = @_;
[ $zone, $interface, 'detect', if_(detect_devices::is_bridge_interface($interface), 'routeback') ];
@@ -132,28 +157,34 @@ sub write {
set_config_file("zones",
[ 'net', 'ipv4' ],
- if_($conf->{loc_interface}[0], [ 'loc', 'ipv4' ]),
+ if_($conf->{loc_zone}[0], [ 'loc', 'ipv4' ]),
[ 'fw', 'firewall' ],
);
set_config_file('interfaces',
- $interface_settings->('net', $conf->{net_interface}),
- (map { $interface_settings->('loc', $_) } @{$conf->{loc_interface} || []}),
+ (map { $interface_settings->('net', $_) } @{$conf->{net_zone}}),
+ (map { $interface_settings->('loc', $_) } @{$conf->{loc_zone} || []}),
);
set_config_file('policy',
- if_($conf->{loc_interface}[0], [ 'loc', 'net', 'ACCEPT' ], [ 'loc', 'fw', 'ACCEPT' ], [ 'fw', 'loc', 'ACCEPT' ]),
+ if_($conf->{loc_zone}[0], [ 'loc', 'net', 'ACCEPT' ], [ 'loc', 'fw', 'ACCEPT' ], [ 'fw', 'loc', 'ACCEPT' ]),
[ 'fw', 'net', 'ACCEPT' ],
- [ 'net', 'all', 'DROP', 'info' ],
+ [ 'net', 'all', 'DROP', if_($conf->{log_net_drop}, 'info') ],
[ 'all', 'all', 'REJECT', 'info' ],
);
- set_config_file('rules',
+ if (is_empty_array_ref($include_drakx)) {
+ #- make sure the rules.drakx config is read, erasing user modifications
+ set_config_file('rules', [ 'INCLUDE', 'rules.drakx' ]);
+ }
+ output_with_perm("$::prefix${shorewall_root}/" . 'rules.drakx', 0600, map { join("\t", @$_) . "\n" } (
if_($use_pptp, [ 'ACCEPT', 'fw', 'loc:10.0.0.138', 'tcp', '1723' ]),
if_($use_pptp, [ 'ACCEPT', 'fw', 'loc:10.0.0.138', 'gre' ]),
(map_each { [ 'ACCEPT', 'net', 'fw', $::a, join(',', @$::b), '-' ] } %$ports_by_proto),
(map {
map_each { [ 'REDIRECT', 'loc', $::a, $_, $::b, '-' ] } %{$conf->{redirects}{$_}};
} keys %{$conf->{redirects}}),
- );
- set_config_file('masq', if_($conf->{masq_subnet}, [ $conf->{net_interface}, $conf->{masq_subnet} ]));
+ ));
+ set_config_file('masq', if_(exists $conf->{masq}, [ $conf->{masq}{net_interface}, $conf->{masq}{subnet} ]));
+
+ upgrade_to_shorewall3();
require services;
if ($conf->{disabled}) {
@@ -164,7 +195,9 @@ sub write {
}
}
-sub update_interfaces_list() {
+sub update_interfaces_list {
+ my ($o_intf) = @_;
+ $o_intf && member($o_intf, map { $_->[1] } get_config_file('interfaces')) and return;
my $shorewall = network::shorewall::read();
$shorewall && !$shorewall->{disabled} and network::shorewall::write($shorewall);
}
diff --git a/lib/network/signal_strength.pm b/lib/network/signal_strength.pm
new file mode 100644
index 0000000..0fa891d
--- /dev/null
+++ b/lib/network/signal_strength.pm
@@ -0,0 +1,14 @@
+package network::signal_strength;
+
+use common;
+use ugtk2;
+
+my %pixbufs;
+
+sub get_strength_icon {
+ my ($network) = @_;
+ my $approx = 20 + min(80, int($network->{signal_strength}/20)*20);
+ return $pixbufs{$approx} ||= ugtk2::gtkcreate_pixbuf('wifi-' . sprintf('%03d', $approx) . '.png');
+}
+
+1;
diff --git a/lib/network/squid.pm b/lib/network/squid.pm
index 7ca60d2..0a7dcce 100644
--- a/lib/network/squid.pm
+++ b/lib/network/squid.pm
@@ -18,7 +18,7 @@ sub write_squid_conf {
renamef($squid_conf_file, "$squid_conf_file.old");
output($squid_conf_file, qq(
-http_port $squid_conf->{http_port}[0]
+http_port $squid_conf->{http_port}[0] transparent
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \\?
no_cache deny QUERY
@@ -58,9 +58,6 @@ http_access allow localhost
http_reply_access allow all
icp_access allow all
visible_hostname $squid_conf->{visible_hostname}[0]
-httpd_accel_host virtual
-httpd_accel_with_proxy on
-httpd_accel_uses_host_header on
append_domain .$internal_domain_name
err_html_text $squid_conf->{admin_mail}[0]
deny_info ERR_CUSTOM_ACCESS_DENIED all
diff --git a/lib/network/test.pm b/lib/network/test.pm
index ec680b7..36da41d 100644
--- a/lib/network/test.pm
+++ b/lib/network/test.pm
@@ -95,7 +95,7 @@ sub update_status {
my ($o) = @_;
if ($o->{kid}) {
my $fd = $o->{kid}{fd};
- fcntl($fd, c::F_SETFL(), c::O_NONBLOCK()) or die "can not fcntl F_SETFL: $!";
+ common::nonblock($fd);
local $| = 1;
if (defined(my $output = <$fd>)) {
($o->{address}, $o->{ping}) = $output =~ /^([\d\.]+)\|([\d\.,]+)*$/;
@@ -111,48 +111,51 @@ sub update_status {
=head2 Test synchronously
-#- resolve and get ping to hostname from command line if given, else to www.mandriva.com
-use lib qw(/usr/lib/libDrakX);
-use network::test;
+resolve and get ping to hostname from command line if given, else to www.mandriva.com
-my $net_test = network::test->new($ARGV[0]);
-$net_test->test_synchronous;
+ use lib qw(/usr/lib/libDrakX);
+ use network::test;
-my $is_connected = $net_test->is_connected;
-my $hostname = $net_test->get_hostname;
-my $address = $net_test->get_address;
-my $ping = $net_test->get_ping;
+ my $net_test = network::test->new($ARGV[0]);
+ $net_test->test_synchronous;
-print "connected: $is_connected
-host: $hostname
-resolved host: $address
-ping to host: $ping
-";
+ my $is_connected = $net_test->is_connected;
+ my $hostname = $net_test->get_hostname;
+ my $address = $net_test->get_address;
+ my $ping = $net_test->get_ping;
+
+ print "connected: $is_connected
+ host: $hostname
+ resolved host: $address
+ ping to host: $ping
+ ";
=head2 Test asynchronously
-#- resolve and get ping to hostname from command line if given, else to Mandriva
-#- prints a "." every 10 miliseconds during connection test
-use lib qw(/usr/lib/libDrakX);
-use network::test;
-
-my $net_test = network::test->new($ARGV[0]);
-$net_test->start;
-
-do {
- print ".\n";
- select(undef, undef, undef, 0.01);
-} while !$net_test->is_done;
-
-my $is_connected = $net_test->is_connected;
-my $hostname = $net_test->get_hostname;
-my $address = $net_test->get_address;
-my $ping = $net_test->get_ping;
-
-print "connected: $is_connected
-host: $hostname
-resolved host: $address
-ping to host: $ping
-";
+resolve and get ping to hostname from command line if given, else to Mandriva
+
+prints a "." every 10 miliseconds during connection test
+
+ use lib qw(/usr/lib/libDrakX);
+ use network::test;
+
+ my $net_test = network::test->new($ARGV[0]);
+ $net_test->start;
+
+ do {
+ print ".\n";
+ select(undef, undef, undef, 0.01);
+ } while !$net_test->is_done;
+
+ my $is_connected = $net_test->is_connected;
+ my $hostname = $net_test->get_hostname;
+ my $address = $net_test->get_address;
+ my $ping = $net_test->get_ping;
+
+ print "connected: $is_connected
+ host: $hostname
+ resolved host: $address
+ ping to host: $ping
+ ";
=cut
diff --git a/lib/network/thirdparty.pm b/lib/network/thirdparty.pm
index b7b8c1e..2c8acb0 100644
--- a/lib/network/thirdparty.pm
+++ b/lib/network/thirdparty.pm
@@ -9,6 +9,9 @@ use fs::get;
use fs;
use log;
+#- using bsd_glob() since glob("/DONT_EXIST") return "/DONT_EXIST" instead of () (and we don't want this)
+use File::Glob ':glob';
+
#- network_settings is an hash of categories (rtc, dsl, wireless, ...)
#- each category is an hash of device settings
@@ -61,220 +64,10 @@ use log;
#- o no_club:
#- 1 if the package isn't available on Mandriva club
-my $firmware_directory = "/lib/firmware";
-
-my %network_settings = (
- rtc =>
- [
- {
- matching => qr/^Hcf:/,
- description => 'HCF 56k Modem',
- url => 'http://www.linuxant.com/drivers/hcf/',
- name => 'hcfpcimodem',
- kernel_module => {
- test_file => 'hcfpciengine',
- },
- tools =>
- {
- test_file => '/usr/sbin/hcfpciconfig',
- },
- device => '/dev/ttySHCF0',
- post => '/usr/sbin/hcfpciconfig --auto',
- restart_service => 'hcfpci',
- },
-
- {
- matching => qr/^Hsf:/,
- description => 'HSF 56k Modem',
- url => 'http://www.linuxant.com/drivers/hsf/',
- name => 'hsfmodem',
- kernel_module => {
- test_file => 'hsfengine',
- },
- tools =>
- {
- test_file => '/usr/sbin/hsfconfig',
- },
- device => '/dev/ttySHSF0',
- post => '/usr/sbin/hsfconfig --auto',
- restart_service => 'hsf',
- },
-
- {
- matching => qr/^LT:/,
- description => 'LT WinModem',
- url => 'http://www.heby.de/ltmodem/',
- name => 'ltmodem',
- kernel_module => 1,
- tools =>
- {
- test_file => '/etc/devfs/conf.d/ltmodem.conf',
- },
- device => '/dev/ttyS14',
- links =>
- [
- 'http://linmodems.technion.ac.il/Ltmodem.html',
- 'http://linmodems.technion.ac.il/packages/ltmodem/',
- ],
- },
-
- {
- matching => [ list_modules::category2modules('network/slmodem') ],
- description => 'Smartlink WinModem',
- url => 'http://www.smlink.com/content.aspx?id=135/',
- name => 'slmodem',
- kernel_module => 1,
- tools =>
- {
- test_file => '/usr/sbin/slmodemd',
- },
- device => '/dev/ttySL0',
- post => sub {
- my ($driver) = @_;
- addVarsInSh("$::prefix/etc/sysconfig/slmodemd", { SLMODEMD_MODULE => $driver });
- },
- restart_service => "slmodemd",
- },
-
- {
- matching => 'sm56',
- description => 'Motorola SM56 WinModem',
- url => 'http://www.motorola.com/softmodem/driver.htm#linux',
- name => 'sm56',
- kernel_module =>
- {
- package => 'sm56',
- },
- no_club => 1,
- device => '/dev/sm56',
- },
- ],
-
- wireless =>
- [
- {
- matching => 'zd1201',
- description => 'ZyDAS ZD1201',
- url => 'http://linux-lc100020.sourceforge.net/',
- firmware =>
- {
- test_file => 'zd1201*.fw',
- },
- },
-
- (map {
- {
- matching => "ipw${_}",
- description => "Intel(R) PRO/Wireless ${_}",
- url => "http://ipw${_}.sourceforge.net/",
- name => "ipw${_}",
- firmware =>
- {
- url => "http://ipw${_}.sourceforge.net/firmware.php",
- test_file => ($_ == 2100 ? "ipw2100-*.fw" : "ipw-2.3-*.fw"),
- },
- };
- } (2100, 2200)),
-
- {
- matching => 'prism54',
- description => 'Prism GT / Prism Duette / Prism Indigo Chipsets',
- url => 'http://prism54.org/',
- name => 'prism54',
- firmware =>
- {
- url => 'http://prism54.org/~mcgrof/firmware/',
- test_file => "isl38*",
- },
- },
-
- {
- matching => qr/^at76c50/,
- description => 'Atmel at76c50x cards',
- url => 'http://thekelleys.org.uk/atmel/',
- name => 'atmel',
- firmware =>
- {
- test_file => 'atmel_at76c50*',
- },
- links => 'http://at76c503a.berlios.de/',
- },
-
- {
- matching => 'ath_pci',
- description => 'Multiband Atheros Driver for WiFi',
- url => 'http://madwifi.sourceforge.net/',
- name => 'madwifi',
- kernel_module => 1,
- tools => {
- optionnal => 1,
- test_file => '/usr/bin/athstats',
- },
- },
- ],
-
- dsl =>
- [
- {
- matching => 'speedtouch',
- description => N_("Alcatel speedtouch USB modem"),
- url => "http://www.speedtouch.com/supuser.htm",
- name => 'speedtouch',
- tools =>
- {
- test_file => '/usr/sbin/modem_run',
- },
- firmware =>
- {
- package => 'speedtouch_mgmt',
- prefix => '/usr/share/speedtouch',
- test_file => 'mgmt*.o',
- explanations => N_("Copy the Alcatel microcode as mgmt.o in /usr/share/speedtouch/"),
- user_install => \&install_speedtouch_microcode,
- },
- links => 'http://linux-usb.sourceforge.net/SpeedTouch/mandrake/index.html',
- },
-
- {
- matching => 'eciadsl',
- name => 'eciadsl',
- explanations => N_("The ECI Hi-Focus modem cannot be supported due to binary driver distribution problem.
-
-You can find a driver on http://eciadsl.flashtux.org/"),
- no_club => 1,
- tools => {
- test_file => '/usr/sbin/pppoeci',
- },
- },
-
- {
- matching => 'sagem',
- description => 'Eagle chipset (from Analog Devices), e.g. Sagem F@st 800/840/908',
- url => 'http://www.eagle-usb.org/',
- name => 'eagle-usb',
- tools =>
- {
- test_file => '/sbin/eaglectrl',
- },
- },
-
- {
- matching => 'bewan',
- description => 'Bewan Adsl (Unicorn)',
- url => 'http://www.bewan.com/bewan/users/downloads/',
- name => 'unicorn',
- kernel_module => {
- test_file => 'unicorn_.*_atm',
- },
- tools => {
- optionnal => 1,
- test_file => '/usr/bin/bewan_adsl_status',
- },
- },
- ],
-);
-
-sub device_get_package {
+our $firmware_directory = "/lib/firmware";
+our @thirdparty_types = qw(kernel_module tools firmware);
+
+sub device_get_packages {
my ($settings, $option, $o_default) = @_;
$settings->{$option} or return;
my $package;
@@ -283,25 +76,26 @@ sub device_get_package {
} else {
$package = $settings->{$option};
}
- $package == 1 ? $o_default || $settings->{name} : $package;
+ $package == 1 ? $o_default || $settings->{name} : ref $package eq 'ARRAY' ? @$package : $package;
}
sub device_get_option {
- my ($settings, $option) = @_;
+ my ($settings, $option, $o_default) = @_;
$settings->{$option} or return;
my $value = $settings->{$option};
- $value == 1 ? $settings->{name} : $value;
+ $value == 1 ? $o_default || $settings->{name} : $value;
}
sub find_settings {
- my ($category, $driver) = @_;
+ my ($settings_list, $driver) = @_;
find {
- my $type = ref $_->{matching};
- $type eq 'Regexp' && $driver =~ $_->{matching} ||
- $type eq 'CODE' && $_->{matching}->($driver) ||
- $type eq 'ARRAY' && member($driver, @{$_->{matching}}) ||
- $driver eq $_->{matching};
- } @{$network_settings{$category}};
+ my $match = $_->{matching} || $_->{name};
+ my $type = ref $match;
+ $type eq 'Regexp' && $driver =~ $match ||
+ $type eq 'CODE' && $match->($driver) ||
+ $type eq 'ARRAY' && member($driver, @$match) ||
+ $driver eq $match;
+ } @$settings_list;
}
sub device_run_command {
@@ -318,37 +112,53 @@ sub device_run_command {
sub warn_not_installed {
my ($in, @packages) = @_;
- $in->ask_warn(N("Error"), N("Could not install the packages (%s)!", @packages));
+ $in->ask_warn(N("Error"), N("Could not install the packages (%s)!", join(', ', @packages)));
+}
+
+sub get_checked_element {
+ my ($settings, $driver, $option) = @_;
+ $option eq 'firmware' ?
+ get_firmware_path($settings) :
+ $option eq 'kernel_module' ?
+ $driver :
+ ref $settings->{$option} eq 'HASH' && $settings->{$option}{test_file};
}
sub warn_not_found {
- my ($in, $settings, $option, @packages) = @_;
+ my ($in, $settings, $driver, $option, @packages) = @_;
my %opt;
- $opt{$_} = $settings->{$option}{$_} || $settings->{$_} foreach qw(url explanations no_club);
+ $opt{$_} = ref $settings->{$option} eq 'HASH' && $settings->{$option}{$_} || $settings->{$_} foreach qw(url explanations no_club no_package);
+ my $checked = get_checked_element($settings, $driver, $option);
$in->ask_warn(N("Error"),
- N("Some packages (%s) are required but aren't available.", @packages) .
- (!$opt{no_club} && "\n" . N("These packages can be found in Mandriva Club or in Mandriva commercial releases.")) .
- ($option eq 'firmware' && "\n\n" . N("Info: ") . "\n" . N("due to missing %s", get_firmware_path($settings))) .
- ($opt{url} && "\n\n" . N("The required files can also be installed from this URL:
-%s", $opt{url})) .
- ($opt{explanations} && "\n\n" . translate($opt{explanations})));
+ join('',
+ ($opt{no_package} ?
+ N("Some components (%s) are required but aren't available for %s hardware.", $option, $settings->{name}) :
+ N("Some packages (%s) are required but aren't available.", join(', ', @packages))),
+ join("\n\n",
+ if_(!$opt{no_club} && !$opt{no_package}, N("These packages can be found in Mandriva Club or in Mandriva commercial releases.")),
+ if_($checked, N("The following component is missing: %s", $checked)),
+ if_($opt{explanations}, translate($opt{explanations})),
+ if_($opt{url}, N("The required files can also be installed from this URL:
+%s", $opt{url})),
+ )));
}
sub is_file_installed {
my ($settings, $option) = @_;
- my $file = exists $settings->{$option} && $settings->{$option}{test_file};
+ my $file = ref $settings->{$option} eq 'HASH' && $settings->{$option}{test_file};
$file && -e "$::prefix$file";
}
sub is_module_installed {
my ($settings, $driver) = @_;
+ require modules;
my $module = ref $settings->{kernel_module} eq 'HASH' && $settings->{kernel_module}{test_file} || $driver;
- find { m!/$module\.k?o! } cat_("$::prefix/lib/modules/" . c::kernel_version() . '/modules.dep');
+ modules::module_is_available($module);
}
sub get_firmware_path {
my ($settings) = @_;
- my $wildcard = exists $settings->{firmware} && $settings->{firmware}{test_file} or return;
+ my $wildcard = ref $settings->{firmware} eq 'HASH' && $settings->{firmware}{test_file} or return;
my $path = $settings->{firmware}{prefix} || $firmware_directory;
"$::prefix$path/$wildcard";
}
@@ -356,7 +166,40 @@ sub get_firmware_path {
sub is_firmware_installed {
my ($settings) = @_;
my $pattern = get_firmware_path($settings) or return;
- scalar glob_($pattern);
+ scalar bsd_glob($pattern, undef);
+}
+
+sub extract_firmware {
+ my ($settings, $in) = @_;
+ my $choice;
+ $in->ask_from('', N("Firmware files are required for this device."),
+ [ { type => "list", val => \$choice, format => \&translate,
+ list => [
+ if_(exists $settings->{firmware}{extract}{floppy_source}, N_("Use a floppy")),
+ if_(exists $settings->{firmware}{extract}{windows_source}, N_("Use my Windows partition")),
+ N_("Select file")
+ ] } ]) or return;
+ my ($h, $source);
+ if ($choice eq N_("Use a floppy")) {
+ $source = $settings->{firmware}{extract}{floppy_source};
+ $h = find_file_on_floppy($in, $source);
+ } elsif ($choice eq N_("Use my Windows partition")) {
+ $source = $settings->{firmware}{extract}{windows_source};
+ $h = find_file_on_windows_system($in, $source);
+ } else {
+ $source = $settings->{firmware}{extract}{default_source};
+ $h = { file => $in->ask_file(N("Please select the firmware file (for example: %s)", basename($source)), dirname($source)) };
+ }
+ if (!-e $h->{file}) {
+ log::explanations("Unable to find firmware file (tried to find $source.");
+ return;
+ }
+
+ if ($settings->{firmware}{extract}{name}) {
+ $in->do_pkgs->ensure_is_installed($settings->{firmware}{extract}{name}, $settings->{firmware}{extract}{test_file}) or return;
+ }
+ $settings->{firmware}{extract}{run}->($h->{file});
+ 1;
}
sub find_file_on_windows_system {
@@ -367,7 +210,7 @@ sub find_file_on_windows_system {
fs::get_info_from_fstab($all_hds);
if (my $part = find { $_->{device_windobe} eq 'C' } fs::get::fstab($all_hds)) {
foreach (qw(windows/system winnt/system windows/system32/drivers winnt/system32/drivers)) {
- -d $_ and $source = first(glob_("$part->{mntpoint}/$_/$file")) and last;
+ -d $_ and $source = first(bsd_glob("$part->{mntpoint}/$_/$file", undef)) and last;
}
$source or $in->ask_warn(N("Error"), N("Unable to find \"%s\" on your Windows system!", $file));
} else {
@@ -379,14 +222,14 @@ sub find_file_on_windows_system {
sub find_file_on_floppy {
my ($in, $file) = @_;
my $floppy = detect_devices::floppy();
- my $mountpoint = '/mnt/floppy';
+ my $mountpoint = '/media/floppy';
my $h;
$in->ask_okcancel(N("Insert floppy"),
N("Insert a FAT formatted floppy in drive %s with %s in root directory and press %s", $floppy, $file, N("Next"))) or return;
if (eval { fs::mount::mount(devices::make($floppy), $mountpoint, 'vfat', 'readonly'); 1 }) {
log::explanations("Mounting floppy device $floppy in $mountpoint");
$h = before_leaving { fs::mount::umount($mountpoint) };
- if ($h->{file} = first(glob("$mountpoint/$file"))) {
+ if ($h->{file} = first(bsd_glob("$mountpoint/$file", undef))) {
log::explanations("Found $h->{file} on floppy device");
} else {
log::explanations("Unabled to find $file on floppy device");
@@ -398,84 +241,75 @@ sub find_file_on_floppy {
$h;
}
-sub install_speedtouch_microcode {
- my ($in) = @_;
- my $choice;
- $in->ask_from('',
- N("You need the Alcatel microcode.
-You can provide it now via a floppy or your windows partition,
-or skip and do it later."),
- [ { type => "list", val => \$choice, format => \&translate,
- list => [ N_("Use a floppy"), N_("Use my Windows partition") ] } ]) or return;
- my ($h, $source);
- if ($choice eq N_("Use a floppy")) {
- $source = 'mgmt*.o';
- $h = find_file_on_floppy($in, $source);
+sub get_required_packages {
+ my ($type, $settings) = @_;
+ device_get_packages($settings, $type, if_($type eq 'firmware', "$settings->{name}-firmware"));
+}
+
+sub check_installed {
+ my ($type, $settings, $driver) = @_;
+ $type eq 'kernel_module' ?
+ is_module_installed($settings, $driver) :
+ $type eq 'firmware' ?
+ is_firmware_installed($settings) :
+ is_file_installed($settings, $type);
+}
+
+sub get_available_packages {
+ my ($type, $in, @names) = @_;
+ if ($type eq 'kernel_module') {
+ return map { my $l = $in->do_pkgs->check_kernel_module_packages($_); $l ? @$l : () } @names;
} else {
- $source = 'alcaudsl.sys';
- $h = find_file_on_windows_system($in, $source);
+ return $in->do_pkgs->is_available(@names);
}
- unless (-e $h->{file} && cp_f($h->{file}, "$::prefix/usr/share/speedtouch/mgmt.o")) {
- $in->ask_warn(N("Error"), N("Firmware copy failed, file %s not found", $source));
- log::explanations("Firmware copy of $source ($h->{file}) failed");
- return;
+}
+
+sub user_install {
+ my ($type, $settings, $in) = @_;
+ if ($type eq 'firmware') {
+ ref $settings->{$type} eq 'HASH' or return;
+ if ($settings->{$type}{extract}) {
+ extract_firmware($settings, $in);
+ } else {
+ my $f = $settings->{$type}{user_install};
+ $f && $f->($settings, $in);
+ }
+ } else {
+ my $f = ref $settings->{$type} eq 'HASH' && $settings->{$type}{user_install};
+ $f && $f->($settings, $in);
}
- log::explanations("Firmware copy of $h->{file} succeeded");
- $in->ask_warn(N("Congratulations!"), N("Firmware copy succeeded"));
- 1;
}
sub install_packages {
my ($in, $settings, $driver, @options) = @_;
foreach my $option (@options) {
- my %methods =
- (
- default =>
- {
- find_package_name => sub { device_get_package($settings, $option) },
- check_installed => sub { is_file_installed($settings, $option) },
- get_packages => sub { my ($name) = @_; $in->do_pkgs->is_available($name) },
- user_install => sub { my $f = $settings->{$option}{user_install}; $f && $f->($in) },
- },
- kernel_module =>
- {
- find_package_name => sub { device_get_package($settings, $option, "$settings->{name}-kernel") },
- check_installed => sub { is_module_installed($settings, $driver) },
- get_packages => sub { my ($name) = @_; my $l = $in->do_pkgs->check_kernel_module_packages($name); $l ? @$l : () }
- },
- firmware =>
- {
- find_package_name => sub { device_get_package($settings, $option, "$settings->{name}-firmware") },
- check_installed => sub { is_firmware_installed($settings) },
- },
- );
- my $get_method = sub { my ($method) = @_; exists $methods{$option} && $methods{$option}{$method} || $methods{default}{$method} };
-
- my $name = $get_method->('find_package_name')->();
- unless ($name) {
+ my @packages = get_required_packages($option, $settings);
+ unless (@packages) {
log::explanations(qq(No $option package for module "$driver" is required, skipping));
next;
}
- if ($get_method->('check_installed')->()) {
+ if (check_installed($option, $settings, $driver)) {
+ $settings->{old_status}{$option} = 1;
log::explanations(qq(Required $option package for module "$driver" is already installed, skipping));
next;
}
- if (my @packages = $get_method->('get_packages')->($name)) {
- log::explanations("Installing thirdparty packages ($option) " . join(', ', @packages));
- if (!$in->do_pkgs->install(@packages)) {
- next if ref $settings->{$option} eq 'HASH' && $settings->{$option}{optionnal};
- warn_not_installed($in, @packages);
- } elsif ($get_method->('check_installed')->()) {
- next;
+ my $optional = ref $settings->{$option} eq 'HASH' && $settings->{$option}{optional};
+ if (my @avalaible = get_available_packages($option, $in, @packages)) {
+ log::explanations("Installing thirdparty packages ($option) " . join(', ', @avalaible));
+ if ($in->do_pkgs->install(@avalaible) && check_installed($option, $settings, $in)) {
+ next;
+ } elsif (!$optional) {
+ warn_not_installed($in, @avalaible);
}
}
- log::explanations("Thirdparty package $name ($option) is required but not available");
+ next if $optional;
+ log::explanations("Thirdparty package @packages ($option) is required but not available");
- unless ($get_method->('user_install')->($in)) {
- warn_not_found($in, $settings, $option, $name);
+ unless (user_install($option, $settings, $in)) {
+ warn_not_found($in, $settings, $driver, $option, @packages);
return;
}
}
@@ -483,16 +317,22 @@ sub install_packages {
1;
}
-sub setup_device {
- my ($in, $category, $driver, $o_config, @o_fields) = @_;
+sub apply_settings {
+ my ($in, $category, $settings_list, $driver) = @_;
- my $settings = find_settings($category, $driver);
+ my $settings = find_settings($settings_list, $driver);
if ($settings) {
log::explanations(qq(Found settings for driver "$driver" in category "$category"));
my $wait = $in->wait_message('', N("Looking for required software and drivers..."));
- install_packages($in, $settings, $driver, qw(kernel_module firmware tools)) or return;
+ install_packages($in, $settings, $driver, @thirdparty_types) or return;
+
+ if (exists $settings->{firmware} && !$settings->{old_status}{firmware}) {
+ log::explanations("Reloading module $driver");
+ eval { modules::unload($driver) };
+ eval { modules::load($driver) };
+ }
undef $wait;
$wait = $in->wait_message('', N("Please wait, running device configuration commands..."));
@@ -503,15 +343,14 @@ sub setup_device {
services::restart_or_start($service);
}
+ $settings->{sleep} and sleep $settings->{sleep};
+
log::explanations(qq(Settings for driver "$driver" applied));
} else {
log::explanations(qq(No settings found for driver "$driver" in category "$category"));
}
- #- assign requested settings, erase with undef if no settings have been found
- $o_config->{$_} = $settings->{$_} foreach @o_fields;
-
- 1;
+ $settings || {};
}
1;
diff --git a/lib/network/tools.pm b/lib/network/tools.pm
index 4607979..a65fd7c 100644
--- a/lib/network/tools.pm
+++ b/lib/network/tools.pm
@@ -7,53 +7,15 @@ use c;
use Socket;
sub write_secret_backend {
- my ($a, $b) = @_;
- foreach my $i ("$::prefix/etc/ppp/pap-secrets", "$::prefix/etc/ppp/chap-secrets") {
- substInFile { s/^'$a'.*\n//; $_ .= "\n'$a' * '$b' * \n" if eof } $i;
- #- restore access right to secrets file, just in case.
- chmod 0600, $i;
- }
-}
-
-sub unquotify {
- my ($word) = @_;
- $$word =~ s/^(['"]?)(.*)\1$/$2/;
-}
-
-sub read_secret_backend() {
- my $conf = [];
- foreach my $i ("pap-secrets", "chap-secrets") {
- foreach (cat_("$::prefix/etc/ppp/$i")) {
- my ($login, $server, $passwd) = split(' ');
- if ($login && $passwd) {
- unquotify \$passwd;
- unquotify \$login;
- unquotify \$server;
- push @$conf, {login => $login,
- passwd => $passwd,
- server => $server };
- }
- }
- }
- $conf;
+ my ($login, $password) = @_;
+ require network::connection::ppp;
+ network::connection::ppp::write_secrets({ access => { login => $login, password => $password } });
}
sub passwd_by_login {
my ($login) = @_;
-
- unquotify \$login;
- my $secret = read_secret_backend();
- foreach (@$secret) {
- return $_->{passwd} if $_->{login} eq $login;
- }
-}
-
-sub wrap_command_for_root {
- my ($name, @args) = @_;
- #- FIXME: duplicate code from common::require_root_capability
- check_for_xserver() && fuzzy_pidofs(qr/\bkwin\b/) > 0 ?
- ("kdesu", "--ignorebutton", "-c", "$name @args") :
- ([ 'consolehelper', $name ], @args);
+ require network::connection::ppp;
+ network::connection::ppp::get_secret(undef, $login);
}
sub run_interface_command {
@@ -61,7 +23,7 @@ sub run_interface_command {
my @command =
!$> || system("/usr/sbin/usernetctl $intf report") == 0 ?
($command, $intf, if_(!$::isInstall, "daemon")) :
- wrap_command_for_root($command, $intf);
+ common::wrap_command_for_root($command, $intf);
run_program::raw({ detach => $detach, root => $::prefix }, @command);
}
@@ -93,7 +55,7 @@ sub connected_bg__raw {
local $| = 1;
if (ref($kid_pipe) && ref($$kid_pipe)) {
my $fd = $$kid_pipe->{fd};
- fcntl($fd, c::F_SETFL(), c::O_NONBLOCK()) or die "can not fcntl F_SETFL: $!";
+ common::nonblock($fd);
my $a = <$fd>;
$$status = $a if defined $a;
} else { $$kid_pipe = check_link_beat() }
@@ -177,7 +139,9 @@ sub find_matching_interface {
#- returns the current gateway, with lowest metric
sub get_current_gateway_interface() {
my $routes = get_routes();
- first(sort { $routes->{$a}{metric} <=> $routes->{$b}{metric} } grep { exists $routes->{$_}{gateway} } keys %$routes);
+ first(sort { $routes->{$a}{metric} <=> $routes->{$b}{metric} } grep {
+ $routes->{$_}{network} eq '0.0.0.0' && $routes->{$_}{gateway};
+ } keys %$routes);
}
#- returns gateway interface if found
@@ -197,7 +161,7 @@ sub get_default_gateway_interface {
sub get_interface_status {
my ($intf) = @_;
my $routes = get_routes();
- return $routes->{$intf}{network}, $routes->{$intf}{gateway};
+ return $routes->{$intf}{network}, $routes->{$intf}{network} eq '0.0.0.0' && $routes->{$intf}{gateway};
}
#- returns (gateway_interface, interface is up, gateway address, dns server address)
@@ -219,6 +183,18 @@ sub get_interface_type {
"unknown";
}
+sub get_interface_description {
+ my ($net, $interface_name) = @_;
+ my $type = get_interface_type($net->{ifcfg}{$interface_name});
+ #- FIXME: find interface description (from PCI/USB data) and translate
+ $type eq 'adsl' ? "DSL: $interface_name" :
+ $type eq 'isdn' ? "ISDN: $interface_name" :
+ $type eq 'modem' ? "Modem: $interface_name" :
+ $type eq 'wifi' ? "WiFi: $interface_name" :
+ member($type, qw(ethernet_gigabit ethernet)) ? "Ethernet: $interface_name" :
+ $interface_name;
+}
+
sub get_default_metric {
my ($type) = @_;
my @known_types = ("ethernet_gigabit", "ethernet", "adsl", "wifi", "isdn", "modem", "unknown");
@@ -243,9 +219,9 @@ sub get_routes() {
my %routes;
foreach (cat_("/proc/net/route")) {
if (/^(\S+)\s+([0-9A-F]+)\s+([0-9A-F]+)\s+[0-9A-F]+\s+\d+\s+\d+\s+(\d+)\s+([0-9A-F]+)/) {
- if (hex($2)) { $routes{$1}{network} = host_hex_to_dotted($2) }
- elsif (hex($3)) { $routes{$1}{gateway} = host_hex_to_dotted($3) }
- if ($4) { $routes{$1}{metric} = $4 }
+ if (defined $3) { $routes{$1}{gateway} = hex($3) ? host_hex_to_dotted($3) : $routes{$1}{network} }
+ if (defined $2) { $routes{$1}{network} = host_hex_to_dotted($2) }
+ if (defined $4) { $routes{$1}{metric} = $4 }
}
}
#- TODO: handle IPv6 with /proc/net/ipv6_route
diff --git a/lib/network/vpn.pm b/lib/network/vpn.pm
new file mode 100644
index 0000000..4a5afbc
--- /dev/null
+++ b/lib/network/vpn.pm
@@ -0,0 +1,191 @@
+package network::vpn;
+
+=head1 NAME
+
+network::vpn - VPN connection abstract class
+
+=cut
+
+use strict;
+use common;
+
+my $vpn_d = "/etc/sysconfig/network-scripts/vpn.d";
+
+=head1 CLASS METHODS
+
+=head2 Generic class methods
+
+=over
+
+=item list_types
+
+List supported VPN types
+
+=cut
+
+sub list_types {
+ common::load_modules_from_base(__PACKAGE__);
+}
+
+=item get_configured_connections
+
+Return list of configured connections for this class
+
+=cut
+
+sub get_configured_connections {
+ my ($class) = @_;
+ map { if_(/^(.*).conf$/, $class->new($1)) } all($::prefix . $vpn_d . '/' . $class->get_type);
+}
+
+=item new(NAME)
+
+Create a new VPN connection object named NAME
+
+=cut
+
+sub new {
+ my ($class, $name) = @_;
+ bless {
+ name => $name,
+ }, $class;
+}
+
+=back
+
+=head2 Pure virtual class methods
+
+=over
+
+=item get_type
+
+Return VPN type (preferably one lowercase word)
+
+=item get_description
+
+Return description of the VPN type
+
+=item get_packages
+
+List package required for configuration
+
+=back
+
+=head1 INSTANCE METHODS
+
+=head2 Generic instance methods
+
+=over
+
+=item get_name
+
+Return name of the VPN connection
+
+=cut
+
+sub get_name {
+ my ($connection) = @_;
+ $connection->{name};
+}
+
+=item get_label
+
+Return label of the VPN connection
+
+=cut
+
+sub get_label {
+ my ($connection) = @_;
+ sprintf("%s (%s)", $connection->get_name, $connection->get_type);
+}
+
+=item get_config_path
+
+Get configuration file path
+
+=cut
+
+sub get_config_path {
+ my ($connection) = @_;
+ $::prefix . $vpn_d . '/' . $connection->get_type . '/' . $connection->get_name . '.conf';
+}
+
+sub _run {
+ my ($connection, $action, @args) = @_;
+ my @command = ('vpn-' . $action, $connection->get_type, $connection->get_name, @args);
+ @command = common::wrap_command_for_root(@command) if $>;
+ require run_program;
+ run_program::rooted($::prefix, , @command);
+}
+
+=item start($o_in)
+
+Start the VPN connection
+
+$o_in is an interactive object used to interact with the user,
+used if some interactive username/passwords are required.
+If not specified, there is no user interaction.
+
+=cut
+
+sub start {
+ my ($connection, $_o_in) = @_;
+ $connection->_run('start');
+}
+
+=item stop
+
+Stop the VPN connection
+
+=cut
+
+sub stop {
+ my ($connection) = @_;
+ $connection->_run('stop');
+}
+
+=item is_started
+
+Returns true if the VPN connection is started
+
+=cut
+
+sub is_started {
+ my ($connection) = @_;
+ my $pid = chomp_(cat_($::prefix . '/var/run/' . $connection->get_type . '-' . $connection->get_name . '.pid'));
+ $pid && -e '/proc/' . $pid;
+}
+
+=back
+
+=head2 Pure virtual instance methods
+
+=over
+
+=item read_config
+
+Read configuration from the file returned by get_config_path()
+
+=item write_config
+
+Write configuration to the file returned by get_config_path()
+
+=item get_settings
+
+Return an array ref of interactive settings
+
+=back
+
+=head2 Optional instance methods
+
+=over
+
+=item prepare
+
+Run commands or services that are required for the VPN type
+
+=back
+
+=cut
+
+1;
diff --git a/lib/network/vpn/openvpn.pm b/lib/network/vpn/openvpn.pm
new file mode 100644
index 0000000..ac5acf1
--- /dev/null
+++ b/lib/network/vpn/openvpn.pm
@@ -0,0 +1,407 @@
+package network::vpn::openvpn;
+
+use base qw(network::vpn);
+
+use strict;
+use common;
+
+sub get_type { 'openvpn' }
+sub get_description { "OpenVPN" }
+sub get_packages { 'openvpn', if_(supports_pkcs11(), qw(openct opensc pcsc-lite)) }
+
+my $pkcs11_tokens;
+
+sub prepare {
+ require services;
+ if (supports_pkcs11()) {
+ #- don't fail if SmartCard daemons can't start, it's not mandatory
+ services::start_not_running_service($_) foreach qw(openct pcscd);
+ cache_pkcs11_tokens();
+ }
+ 1;
+}
+
+sub read_config {
+ my ($connection) = @_;
+ my ($pkcs11_slot, $pkcs11_id);
+ foreach (cat_($connection->get_config_path)) {
+ /^\s*proto\s+tcp/ and $connection->{tcp} = 1;
+ /^\s*dev\s+([[:alpha:]]+)(\d*)/ and ($connection->{dev_type}, $connection->{dev_number}) = ($1, $2);
+ if (/^\s*remote\s+(\S+)(?:\s+(\w+))?/) {
+ $connection->{gateway} = $1;
+ $connection->{port} = $2;
+ }
+ if (/^\s*tls-auth\s+(\S+)(?:\s+(\d+))?/) {
+ $connection->{'tls-auth'} = $1;
+ $connection->{key_direction} = $2;
+ }
+ foreach my $type (qw(ca cert key pkcs12 secret)) {
+ /^\s*$type\s+(.+)/ and $connection->{$type . '_file'} = $1;
+ }
+ /^\s*pkcs11-slot\s+(.+)/ and $pkcs11_slot = $1;
+ /^\s*pkcs11-id\s+(.+)/ and $pkcs11_id = $1;
+ /^\s*ns-cert-type\s+server/ and $connection->{check_server} = 1;
+ /^\s*auth-user-pass/ and $connection->{'auth-user-pass'} = 1;
+ if (/^\s*ifconfig\s+(\S+)\s+(\S+)/) {
+ $connection->{local_ip} = $1;
+ $connection->{remote_ip} = $2;
+ $connection->{addressing} = 'manual';
+ }
+ /^\s*cipher\s+(.+)/ and $connection->{cipher} = $1;
+ /^\s*keysize\s+(.+)/ and $connection->{keysize} = $1;
+ }
+ if (exists $connection->{secret_file}) {
+ $connection->{type} = 'static';
+ $connection->{key} = delete $connection->{secret_file};
+ } else {
+ $connection->{type} = 'pki';
+ $connection->{key} = delete $connection->{key_file};
+ }
+ if (defined $pkcs11_slot && defined $pkcs11_id) {
+ my $tokens = $connection->get_pkcs11_tokens('no_cache');
+ $connection->{pkcs11_object} = find { $_->{slot} eq $pkcs11_slot && $_->{id} eq $pkcs11_id } @{$tokens->{objects}};
+ $connection->{pkcs11_object} ||= {};
+ }
+}
+
+sub write_config {
+ my ($connection) = @_;
+ my $file = $connection->get_config_path;
+ unless (-e $file) {
+ mkdir_p(dirname($file));
+ cp_f("/usr/share/openvpn/sample-config-files/client.conf", $file);
+ }
+
+ delete $connection->{keysize} if !$connection->{cipher};
+ if ($connection->{type} eq 'static') {
+ $connection->{secret_file} = delete $connection->{key};
+ delete $connection->{ca_file};
+ delete $connection->{cert_file};
+ delete $connection->{key_file};
+ } else {
+ $connection->{key_file} = delete $connection->{key};
+ delete $connection->{secret_file};
+ }
+
+ my @config = $connection->build_config;
+ substInFile {
+ foreach my $conf (@config) {
+ if (/^;?$conf->{key}\b/) {
+ if ($conf->{comment}) {
+ $_ = ";$_" unless /^;/;
+ } else {
+ $_ = "$conf->{key} $conf->{value}\n";
+ $conf->{comment} = 1;
+ }
+ last;
+ }
+ }
+ $_ .= join('', map { if_(!$_->{comment}, "$_->{key} $_->{value}\n") } @config) if eof;
+ } $file;
+}
+
+sub get_key_settings {
+ my ($connection) = @_;
+ my %ciphers = get_ciphers();
+ my @types = (
+ pki => N("X509 Public Key Infrastructure"),
+ static => N("Static Key"),
+ );
+ my $pkcs11_separator = '/';
+ my $tokens = $connection->get_pkcs11_tokens;
+ my %types = @types;
+ [
+ {
+ label => N("Type"),
+ val => \$connection->{type},
+ list => first(list2kv(@types)),
+ format => sub { $types{$_[0]} },
+ },
+ (supports_pkcs11() ? {
+ label => "PKCS #11 token",
+ type => 'list',
+ list => [ undef, @{$tokens->{objects}} ],
+ format => sub { $_[0] ? join($pkcs11_separator,
+ $tokens->{slots}{$_[0]{slot}}{label} || $_[0]{slot},
+ $_[0]{label} || $_[0]{id})
+ : N("None") },
+ val => \$connection->{pkcs11_object},
+ separator => $pkcs11_separator,
+ allow_empty_list => 1,
+ disabled => sub { $connection->{type} ne 'pki' || $connection->{cert_file} || $connection->{key_file} || $connection->{pkcs12_file} },
+ } : ()),
+ {
+ label => "PKCS #12",
+ type => 'file',
+ val => \$connection->{pkcs12_file},
+ disabled => sub { $connection->{type} ne 'pki' || $connection->{cert_file} || $connection->{key_file} || $connection->{pkcs11_object} },
+ },
+ {
+ label =>
+ #-PO: please don't translate the CA acronym
+ N("Certificate Authority (CA)"),
+ type => 'file',
+ val => \$connection->{ca_file},
+ disabled => sub { $connection->{type} ne 'pki' },
+ },
+ {
+ label => N("Certificate"),
+ type => 'file',
+ val => \$connection->{cert_file},
+ disabled => sub { $connection->{type} ne 'pki' || $connection->{pkcs11_object} || $connection->{pkcs12_file} },
+ },
+ {
+ label => N("Key"),
+ type => 'file',
+ val => \$connection->{key},
+ disabled => sub { $connection->{type} eq 'pki' && ($connection->{pkcs11_object} || $connection->{pkcs12_file}) },
+ },
+ {
+ label => N("TLS control channel key"),
+ type => 'file',
+ val => \$connection->{'tls-auth'},
+ disabled => sub { $connection->{type} ne 'pki' },
+ advanced => 1,
+ },
+ {
+ label => N("Key direction"),
+ type => 'list',
+ val => \$connection->{key_direction},
+ list => [ undef, 0, 1 ],
+ format => sub { defined($_[0]) ? $_[0] : N("None") },
+ advanced => 1,
+ },
+ {
+ text => N("Authenticate using username and password"),
+ type => 'bool',
+ val => \$connection->{'auth-user-pass'},
+ advanced => 1,
+ },
+ {
+ text => N("Check server certificate"),
+ type => 'bool',
+ val => \$connection->{check_server},
+ advanced => 1,
+ },
+ {
+ label => N("Cipher algorithm"),
+ type => 'list',
+ val => \$connection->{cipher},
+ list => [ '', keys %ciphers ],
+ format => sub { exists $ciphers{$_[0]} ? $ciphers{$_[0]} : N("Default") },
+ advanced => 1,
+ },
+ {
+ label => N("Size of cipher key"),
+ val => \$connection->{keysize},
+ advanced => 1,
+ disabled => sub { !$connection->{cipher} || $connection->{cipher} eq 'none' },
+ },
+ ];
+}
+
+sub get_settings {
+ my ($connection) = @_;
+ my @addressing = (
+ automatic => N("Get from server"),
+ manual => N("Manual configuration"),
+ );
+ my %addressing = @addressing;
+ [
+ {
+ label => N("Gateway"),
+ val => \$connection->{gateway},
+ },
+ {
+ label => N("Gateway port"),
+ val => \$connection->{port},
+ advanced => 1,
+ },
+ {
+ label => N("IP address"),
+ val => \$connection->{addressing},
+ list => first(list2kv(@addressing)),
+ format => sub { $addressing{$_[0]} },
+ },
+ {
+ label => N("Local IP address"),
+ val => \$connection->{local_ip},
+ disabled => sub { $connection->{addressing} ne 'manual' },
+ },
+ {
+ label => N("Remote IP address"),
+ val => \$connection->{remote_ip},
+ disabled => sub { $connection->{addressing} ne 'manual' },
+ },
+ {
+ text => N("Use TCP protocol"),
+ type => 'bool',
+ val => \$connection->{tcp},
+ advanced => 1,
+ },
+ {
+ label => N("Virtual network device type"),
+ type => 'list',
+ list => [ 'tun', 'tap' ],
+ val => \$connection->{dev_type},
+ advanced => 1,
+ },
+ {
+ label => N("Virtual network device number (optional)"),
+ val => \$connection->{dev_number},
+ advanced => 1,
+ },
+ ];
+}
+
+my $lib = arch() =~ /x86_64/ ? "lib64" : "lib";
+my $openvpn_default_pkcs11_provider = find { -e $_ } (
+ "/usr/local/$lib/libetpkcs11.so",
+ "/usr/$lib/opensc-pkcs11.so",
+);
+
+my $supports_pkcs11;
+sub supports_pkcs11 {
+ if (!defined $supports_pkcs11) {
+ require run_program;
+ $supports_pkcs11 = to_bool(run_program::rooted($::prefix, '/usr/sbin/openvpn', '--show-pkcs11-slots', ''));
+ }
+ $supports_pkcs11;
+}
+
+sub get_pkcs11_tokens {
+ my ($_class, $o_no_cache) = @_;
+ cache_pkcs11_tokens() if !defined $pkcs11_tokens && !$o_no_cache;
+ $pkcs11_tokens;
+}
+
+sub cache_pkcs11_tokens {
+ $pkcs11_tokens = { slots => {}, objects => [] };
+ my $slot_id;
+ foreach (run_program::rooted_get_stdout($::prefix, '/usr/bin/pkcs11-tool', '--module', $openvpn_default_pkcs11_provider, '-L')) {
+ if (/^Slot\s+(\d+)\s+(.+)$/) {
+ $slot_id = $2 ne '(empty)' ? $1 : undef;
+ $pkcs11_tokens->{slots}{$slot_id}{name} = $2 if defined $slot_id;
+ } elsif (/^\s+token\s+label:\s+(.+)$/) {
+ $pkcs11_tokens->{slots}{$slot_id}{label} = $1 if defined $slot_id;
+ } elsif (/^\s+flags:\s*(.*)/) {
+ my @flags = split(/\s*,\s*/, $1);
+ if (defined $slot_id && !member("token present", @flags)) {
+ delete $pkcs11_tokens->{slots}{$slot_id};
+ undef $slot_id;
+ }
+ }
+ }
+ foreach $slot_id (keys %{$pkcs11_tokens->{slots}}) {
+ my ($type, $label);
+ my @stdout; #- do rooted_get_stdout manually because pkcs11-tool may exit with non-zero code with proprietary modules
+ run_program::rooted($::prefix, '/usr/bin/pkcs11-tool', '>', \@stdout, '--module', $openvpn_default_pkcs11_provider, '-O', '--slot', $slot_id);
+ foreach (@stdout) {
+ if (/^(\S.*?)\s+Object/) {
+ $type = $1;
+ undef $label;
+ } elsif (/^\s+label:\s+(.+)$/) {
+ $label = $1;
+ } elsif (/^\s+ID:\s+(.+)$/ && $type eq 'Public Key') {
+ push @{$pkcs11_tokens->{objects}}, { id => $1, label => $label, slot => $slot_id };
+ }
+ }
+ }
+}
+
+sub build_config {
+ my ($connection) = @_;
+ (
+ { key => 'client', comment => to_bool($connection->{secret_file}) },
+ { key => 'proto', $connection->{tcp} ? (value => 'tcp') : (comment => 1) },
+ { key => 'dev', value => $connection->{dev_type} . $connection->{dev_number} },
+ { key => 'remote', value => join(' ', $connection->{gateway}, if_($connection->{port}, $connection->{port})) },
+ (map { +{ key => $_, $connection->{$_ . '_file'} ? (value => $connection->{$_ . '_file'}) : (comment => 1) } } qw(ca cert key pkcs12 secret)),
+ { key => 'pkcs11-providers', $connection->{pkcs11_object} ? (value => $openvpn_default_pkcs11_provider) : (comment => 1) },
+ { key => 'pkcs11-slot-type', $connection->{pkcs11_object} ? (value => 'id') : (comment => 1) },
+ { key => 'pkcs11-slot', $connection->{pkcs11_object} ? (value => $connection->{pkcs11_object}{slot}) : (comment => 1) },
+ { key => 'pkcs11-id-type', $connection->{pkcs11_object} ? (value => 'id') : (comment => 1) },
+ { key => 'pkcs11-id', $connection->{pkcs11_object} ? (value => $connection->{pkcs11_object}{id}) : (comment => 1) },
+ { key => 'tls-auth', $connection->{'tls-auth'} ? (value => join(' ', $connection->{'tls-auth'}, if_($connection->{key_direction}, $connection->{key_direction}))) : (comment => 1) },
+ { key => 'ns-cert-type', $connection->{check_server} ? (value => 'server') : (comment => 1) },
+ { key => 'auth-user-pass', comment => !$connection->{'auth-user-pass'} },
+ { key => 'ifconfig', $connection->{addressing} eq 'manual' ?
+ (value => join(' ', $connection->{local_ip}, $connection->{remote_ip})) : (comment => 1) },
+ { key => 'cipher', $connection->{cipher} ? (value => $connection->{cipher}) : (comment => 1) },
+ { key => 'keysize', $connection->{keysize} ? (value => $connection->{keysize}) : (comment => 1) },
+ );
+}
+
+sub get_ciphers() {
+ my @ciphers = chomp_(`/usr/sbin/openvpn --show-ciphers`);
+ #- drop header
+ shift @ciphers while $ciphers[0] =~ /^\S/;
+ none => N("None"), map { if_($_, first(split(' ', $_)), $_) } @ciphers;
+}
+
+sub start {
+ my ($connection, $o_in) = @_;
+ $connection->read_config if keys %$connection <= 1;
+ my %interactive_passwords = if_($o_in, (
+ if_($connection->{'auth-user-pass'}, 'Auth' => 1),
+ if_($connection->{pkcs11_object}, 'Token' => 1),
+ ));
+ my $port = 2222;
+ my $started = $connection->_run('start',
+ if_(%interactive_passwords,
+ '--management', "127.0.0.1", $port,
+ '--management-query-passwords',
+ ));
+ $started && (!%interactive_passwords || $connection->ask_passwords($o_in, $port, \%interactive_passwords));
+}
+
+sub ask_passwords {
+ my ($_connection, $in, $port, $interactive_passwords) = @_;
+ require Net::Telnet;
+ my $t = new Net::Telnet;
+ $t->open(host => "localhost", port => $port, errmode => "return");
+ my $wait;
+ while (1) {
+ $wait ||= $in->wait_message(N("VPN connection"), N("Starting connection.."));
+ my ($_pre, $match) = $t->waitfor(string => ">PASSWORD:", string => ">NEED-OK:", errmode => "return",
+ #- don't quit if all interactive passwords have been entered
+ #- in case some passwords are incorrect
+ #- though, use a smaller timeout
+ timeout => (%$interactive_passwords ? 20 : 5));
+ if (!defined $match) {
+ my $msg = $t->errmsg;
+ #- no more interactive password is required, success
+ $t->close, return 1 if $msg =~ /timed-out/ && !%$interactive_passwords;
+ $t->close, return; #- potential failure
+ } elsif ($match eq ">NEED-OK:") {
+ my ($type, $msg) = $t->getline =~ /'(.*)'.* MSG:/;
+ undef $wait;
+ my $ret = $in->ask_okcancel(N("VPN connection"), $type eq 'token-insertion-request' ?
+ N("Please insert your token") :
+ $msg);
+ $t->print(qq(needok "$type" ) . ($ret ? "ok" : "cancel"));
+ $t->close, return if !$ret;
+ } elsif ($match eq ">PASSWORD:") {
+ my ($full_type) = $t->getline =~ /'(.*)'/;
+ #- assume type is "Auth" if not token
+ my $type = $full_type =~ /\btoken$/ ? 'Token' : 'Auth';
+ my ($username, $password);
+ undef $wait;
+ my $ret = $in->ask_from(N("VPN connection"), '', $type eq 'Token' ? [
+ { label => N("PIN number"), val => \$password, hidden => 1 }
+ ] : [
+ { label => N("Account Login (user name)"), val => \$username },
+ { label => N("Account Password"), val => \$password, hidden => 1 },
+ ]);
+ if ($ret) {
+ delete $interactive_passwords->{$type};
+ $t->print(qq(username "$full_type" "$username")) if $username;
+ $t->print(qq(password "$full_type" "$password"));
+ } else {
+ $t->close, return;
+ }
+ }
+ }
+}
+
+1;
diff --git a/lib/network/vpn/vpnc.pm b/lib/network/vpn/vpnc.pm
new file mode 100644
index 0000000..f0c8369
--- /dev/null
+++ b/lib/network/vpn/vpnc.pm
@@ -0,0 +1,74 @@
+package network::vpn::vpnc;
+
+use base qw(network::vpn);
+
+use strict;
+use common;
+
+sub get_type { 'vpnc' }
+sub get_description { N("Cisco VPN Concentrator") }
+sub get_packages { 'vpnc' }
+
+sub read_config {
+ my ($connection) = @_;
+ my @fields = group_by2(list_fields($connection));
+ foreach (cat_($connection->get_config_path)) {
+ foreach my $field (@fields) {
+ # all strings start exactly one space after the keyword string
+ /^$field->[0] (.*)/ and ${$field->[1]{val}} = $1;
+ }
+ }
+}
+
+sub write_config {
+ my ($connection) = @_;
+ output_with_perm($connection->get_config_path, 0600, map {
+ if_(${$_->[1]{val}}, $_->[0], ' ', ${$_->[1]{val}}, "\n");
+ } group_by2(list_fields($connection)));
+}
+
+sub get_settings {
+ my ($connection) = @_;
+ second(list2kv(list_fields($connection)));
+}
+
+sub list_fields {
+ my ($connection) = @_;
+ (
+ 'IPSec gateway' => {
+ label => N("Gateway"),
+ val => \$connection->{gateway},
+ },
+ 'IPSec ID' => {
+ label => N("Group name"),
+ val => \$connection->{id},
+ },
+ 'IPSec secret' => {
+ label => N("Group secret"),
+ val => \$connection->{secret},
+ hidden => 1,
+ },
+ 'Xauth username' => {
+ label => N("Username"),
+ val => \$connection->{username},
+ },
+ 'Xauth password' => {
+ label => N("Password"),
+ val => \$connection->{password},
+ hidden => 1,
+ },
+ 'UDP Encapsulate' => {
+ text => N("Use Cisco-UDP encapsulation"),
+ type => 'bool',
+ val => \$connection->{udp},
+ advanced => 1,
+ },
+ 'UDP Encapsulation Port' => {
+ label => N("Use specific UDP port"),
+ val => \$connection->{udp_port},
+ advanced => 1,
+ },
+ );
+}
+
+1;
diff --git a/lib/network/wireless.pm b/lib/network/wireless.pm
deleted file mode 100644
index 513c8a9..0000000
--- a/lib/network/wireless.pm
+++ /dev/null
@@ -1,239 +0,0 @@
-package network::wireless;
-
-use strict;
-use common;
-
-our %wireless_enc_modes = (
- none => N_("None"),
- open => N_("Open WEP"),
- restricted => N_("Restricted WEP"),
- 'wpa-psk' => N_("WPA Pre-Shared Key"),
-);
-
-my $wpa_supplicant_conf = "/etc/wpa_supplicant.conf";
-
-sub is_old_rt2x00 {
- my ($module) = @_;
- member($module, qw(rt2400 rt2500));
-}
-
-sub is_wpa_supplicant_blacklisted {
- my ($module) = @_;
- is_old_rt2x00($module);
-}
-
-sub get_hex_key {
- my ($key) = @_;
- if ($key =~ /^([[:xdigit:]]{4}[\:-]?)+[[:xdigit:]]{2,}$/) {
- $key =~ s/[\:-]//g;
- return lc($key);
- }
-}
-
-sub convert_wep_key_for_iwconfig {
- #- 5 or 13 characters, consider the key as ASCII and prepend "s:"
- #- else consider the key as hexadecimal, do not strip dashes
- #- always quote the key as string
- my ($real_key, $restricted) = @_;
- my $key = get_hex_key($real_key) || "s:$real_key";
- $restricted ? "restricted $key" : "open $key";
-}
-
-sub get_wep_key_from_iwconfig {
- #- strip "s:" if the key is 5 or 13 characters (ASCII)
- #- else the key as hexadecimal, do not modify
- my ($key) = @_;
- my ($mode, $real_key) = $key =~ /^(?:(open|restricted)\s+)?(.*)$/;
- $real_key =~ s/^s://;
- ($real_key, $mode eq 'restricted');
-}
-
-sub convert_key_for_wpa_supplicant {
- my ($key) = @_;
- get_hex_key($key) || qq("$key");
-}
-
-sub wlan_ng_needed {
- my ($module) = @_;
- $module =~ /^prism2_/;
-}
-
-#- FIXME: to be improved (quotes, comments) and moved in common files
-sub wlan_ng_update_vars {
- my ($file, $vars) = @_;
- substInFile {
- while (my ($key, $value) = each(%$vars)) {
- s/^#?\Q$key\E=(?:"[^#]*"|[^#\s]*)(\s*#.*)?/$key=$value$1/ and delete $vars->{$key};
- }
- $_ .= join('', map { "$_=$vars->{$_}\n" } keys %$vars) if eof;
- } $file;
-}
-
-sub wlan_ng_configure {
- my ($essid, $key, $device, $module) = @_;
- my $wlan_conf_file = "$::prefix/etc/wlan/wlan.conf";
- my @wlan_devices = split(/ /, (cat_($wlan_conf_file) =~ /^WLAN_DEVICES="(.*)"/m)[0]);
- push @wlan_devices, $device unless member($device, @wlan_devices);
- #- enable device and make it use the choosen ESSID
- wlan_ng_update_vars($wlan_conf_file,
- {
- WLAN_DEVICES => qq("@wlan_devices"),
- "SSID_$device" => qq("$essid"),
- "ENABLE_$device" => "y"
- });
-
- my $wlan_ssid_file = "$::prefix/etc/wlan/wlancfg-$essid";
- #- copy default settings for this ESSID if config file does not exist
- -f $wlan_ssid_file or cp_f("$::prefix/etc/wlan/wlancfg-DEFAULT", $wlan_ssid_file);
-
- #- enable/disable encryption
- wlan_ng_update_vars($wlan_ssid_file,
- {
- (map { $_ => $key ? "true" : "false" } qw(lnxreq_hostWEPEncrypt lnxreq_hostWEPDecrypt dot11PrivacyInvoked dot11ExcludeUnencrypted)),
- AuthType => $key ? qq("sharedkey") : qq("opensystem"),
- if_($key,
- dot11WEPDefaultKeyID => 0,
- dot11WEPDefaultKey0 => qq("$key")
- )
- });
- #- hide settings for non-root users
- chmod 0600, $wlan_conf_file;
- chmod 0600, $wlan_ssid_file;
-
- #- apply settings on wlan interface
- require services;
- services::restart($module eq 'prism2_cs' ? 'pcmcia' : 'wlan');
-}
-
-sub wpa_supplicant_get_driver {
- my ($module) = @_;
- $module =~ /^hostap_/ ? "hostap" :
- $module eq "prism54" ? "prism54" :
- $module =~ /^ath_/ ? "madwifi" :
- $module =~ /^at76c50|atmel_/ ? "atmel" :
- $module eq "ndiswrapper" ? "ndiswrapper" :
- "wext";
-}
-
-sub wpa_supplicant_add_network {
- my ($essid, $enc_mode, $key) = @_;
- my $conf = wpa_supplicant_read_conf();
- my $network = {
- ssid => qq("$essid"),
- scan_ssid => 1,
- };
-
- if ($enc_mode eq 'wpa-psk') {
- $network->{psk} = convert_key_for_wpa_supplicant($key);
- } else {
- $network->{key_mgmt} = 'NONE';
- if (member($enc_mode, qw(open restricted))) {
- put_in_hash($network, {
- wep_key0 => convert_key_for_wpa_supplicant($key),
- wep_tx_keyidx => 0,
- auth_alg => $enc_mode eq 'restricted' ? 'SHARED' : 'OPEN',
- });
- }
- }
-
- @$conf = difference2($conf, [ wpa_supplicant_find_similar($conf, $network) ]);
- push @$conf, $network;
- wpa_supplicant_write_conf($conf);
-}
-
-sub wpa_supplicant_find_similar {
- my ($conf, $network) = @_;
- grep {
- my $current = $_;
- any { exists $network->{$_} && $network->{$_} eq $current->{$_} } qw(ssid bssid);
- } @$conf;
-}
-
-sub wpa_supplicant_read_conf() {
- my @conf;
- my $network;
- foreach (cat_($::prefix . $wpa_supplicant_conf)) {
- if ($network) {
- #- in a "network = {}" block
- if (/^\s*(\w+)=(.*?)(?:\s*#.*)?$/) {
- $network->{$1} = $2;
- } elsif (/^\}/) {
- #- end of network block
- push @conf, $network;
- undef $network;
- }
- } elsif (/^\s*network={/) {
- #- beginning of a new network block
- $network = {};
- }
- }
- \@conf;
-}
-
-sub wpa_supplicant_write_conf {
- my ($conf) = @_;
- my $buf;
- my @conf = @$conf;
- my $network;
- foreach (cat_($::prefix . $wpa_supplicant_conf)) {
- if ($network) {
- #- in a "network = {}" block
- if (/^\s*(\w+)=(.*)$/) {
- push @{$network->{entries}}, { key => $1, value => $2 };
- member($1, qw(ssid bssid)) and $network->{$1} = $2;
- } elsif (/^\}/) {
- #- end of network block, write it
- $buf .= "network={$network->{comment}\n";
-
- my $new_network = first(wpa_supplicant_find_similar(\@conf, $network));
- foreach (@{$network->{entries}}) {
- my $key = $_->{key};
- if ($new_network) {
- #- do not write entry if not provided in the new network
- exists $new_network->{$key} or next;
- #- update value from the new network
- $_->{value} = delete $new_network->{$key};
- }
- $buf .= " ";
- $buf .= "$key=$_->{value}" if $key;
- $buf .= "$_->{comment}\n";
- }
- if ($new_network) {
- #- write new keys
- while (my ($key, $value) = each(%$new_network)) {
- $buf .= " $key=$value\n";
- }
- }
- $buf .= "}\n";
- $new_network and @conf = grep { $_ != $new_network } @conf;
- undef $network;
- } else {
- #- unrecognized, keep it anyway
- push @{$network->{entries}}, { comment => $_ };
- }
- } else {
- if (/^\s*network={/) {
- #- beginning of a new network block
- $network = {};
- } else {
- #- keep other options, comments
- $buf .= $_;
- }
- }
- }
-
- #- write remaining networks
- foreach (@conf) {
- $buf .= "\nnetwork={\n";
- while (my ($key, $value) = each(%$_)) {
- $buf .= " $key=$value\n";
- }
- $buf .= "}\n";
- }
-
- output($::prefix . $wpa_supplicant_conf, $buf);
- #- hide keys for non-root users
- chmod 0600, $::prefix . $wpa_supplicant_conf;
-}
-
-1;