diff options
author | Olivier Blin <oblin@mandriva.com> | 2007-05-25 15:39:46 +0000 |
---|---|---|
committer | Olivier Blin <oblin@mandriva.com> | 2007-05-25 15:39:46 +0000 |
commit | 1d37bfdbbe874abd6dcb5563eea19f531de09e1c (patch) | |
tree | 74845e43ed8fa59c7aaafd1a87efaa6b0c83c228 /lib/network/connection | |
parent | c6ba983db7d5a82ee63599e775be0f8211447c72 (diff) | |
download | drakx-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/connection')
-rw-r--r-- | lib/network/connection/cable.pm | 77 | ||||
-rw-r--r-- | lib/network/connection/cellular.pm | 52 | ||||
-rw-r--r-- | lib/network/connection/cellular_bluetooth.pm | 94 | ||||
-rw-r--r-- | lib/network/connection/cellular_card.pm | 180 | ||||
-rw-r--r-- | lib/network/connection/dvb.pm | 73 | ||||
-rw-r--r-- | lib/network/connection/ethernet.pm | 512 | ||||
-rw-r--r-- | lib/network/connection/isdn.pm | 228 | ||||
-rw-r--r-- | lib/network/connection/isdn/consts.pm | 460 | ||||
-rw-r--r-- | lib/network/connection/pots.pm | 133 | ||||
-rw-r--r-- | lib/network/connection/ppp.pm | 138 | ||||
-rw-r--r-- | lib/network/connection/providers/cellular.pm | 28 | ||||
-rw-r--r-- | lib/network/connection/providers/xdsl.pm | 1252 | ||||
-rw-r--r-- | lib/network/connection/wireless.pm | 744 | ||||
-rw-r--r-- | lib/network/connection/xdsl.pm | 375 |
14 files changed, 4346 insertions, 0 deletions
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/connection/isdn.pm b/lib/network/connection/isdn.pm new file mode 100644 index 0000000..4b85d1d --- /dev/null +++ b/lib/network/connection/isdn.pm @@ -0,0 +1,228 @@ +package network::connection::isdn; + +use base qw(network::connection); + +use strict; +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 apply_config { + my ($in, $isdn) = @_; + + $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( +I4L_USERNAME="$isdn->{login}" +I4L_SYSNAME="" +I4L_LOCALMSN="$isdn->{phone_in}" +I4L_REMOTE_OUT="$isdn->{phone_out}" +I4L_DIALMODE="$isdn->{dialing_mode}" +I4L_IDLETIME="$isdn->{huptimeout}" +) . if_($isdn->{speed} =~ /128/, 'SLAVE="ippp1" +')); + output "$::prefix/etc/isdn/profile/card/mycard", + qq( +I4L_MODULE="$isdn->{driver}" +I4L_TYPE="$isdn->{type}" +I4L_IRQ="$isdn->{irq}" +I4L_MEMBASE="$isdn->{mem}" +I4L_PORT="$isdn->{io}" +I4L_IO0="$isdn->{io0}" +I4L_IO1="$isdn->{io1}" +I4L_ID="HiSax" +I4L_FIRMWARE="$isdn->{firmware}" +I4L_PROTOCOL="$isdn->{protocol}" +); + + output "$::prefix/etc/ppp/ioptions", + "lock +usepeerdns +defaultroute +"; + + network::tools::write_secret_backend($isdn->{login}, $isdn->{passwd}); + + 1; +} + +sub write_capi_conf { + my ($capi_card) = @_; + my $capi_conf; + my $firmware = $capi_card->{firmware} || '-'; + if ($capi_card->{driver} eq "fcclassic") { + $capi_conf = "fcclassic - - 0x300 5 - -\n# adjust IRQ and IO !! ^^^^^ ^^^\n"; + } elsif ($capi_card->{driver} eq "fcpnp") { + $capi_conf = "fcpnp - - 0x300 5 - -\n# adjust IRQ and IO !! ^^^^^ ^^^\n"; + } 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) = @_; + + my %match = (I4L_USERNAME => 'login', + I4L_LOCALMSN => 'phone_in', + I4L_REMOTE_OUT => 'phone_out', + I4L_DIALMODE => 'dialing_mode', + I4L_IDLETIME => 'huptimeout', + I4L_MODULE => 'driver', + I4L_TYPE => 'type', + I4L_IRQ => 'irq', + I4L_MEMBASE => 'mem', + I4L_PORT => 'io', + I4L_IO0 => 'io0', + I4L_IO1 => 'io1', + I4L_FIRMWARE => 'firmware'); + foreach ('link/myisp', 'card/mycard') { + my %conf = getVarsFromSh("$::prefix/etc/isdn/profile/$_"); + foreach (keys %conf) { + $isdn->{$match{$_}} = $conf{$_} if $match{$_} && $conf{$_}; + } + } + + $isdn->{passwd} = network::tools::passwd_by_login($isdn->{login}); +} + +my $file = "$ENV{SHARE_PATH}/ldetect-lst/isdn.db"; +$file = "$::prefix$file" if !-e $file; + +sub get_info_providers_backend { + my ($isdn, $name) = @_; + $name eq N("Unlisted - edit manually") and return; + foreach (catMaybeCompressed($file)) { + chop; + my ($name_, $phone, $real, $dns1, $dns2) = split '=>'; + if ($name eq $name_) { + @$isdn{qw(user_name phone_out DOMAINNAME2 dnsServer3 dnsServer2)} = + ((split(/\|/, $name_))[2], $phone, $real, $dns1, $dns2); + } + } +} + +sub read_providers_backend() { map { /(.*?)=>/ } catMaybeCompressed($file) } + + +sub detect_backend { + my ($modules_conf) = @_; + my @isdn; + require detect_devices; + each_index { + my $c = $_; + my $isdn = { map { $_ => $c->{$_} } qw(description vendor id driver card_type type) }; + $isdn->{intf_id} = $::i; + $isdn->{$_} = sprintf("%0x", $isdn->{$_}) foreach 'vendor', 'id'; + $isdn->{card_type} = $c->{bus} eq 'USB' ? 'usb' : 'pci'; + $isdn->{description} =~ s/.*\|//; +# $c->{options} !~ /id=HiSax/ && $isdn->{driver} eq "hisax" and $c->{options} .= " id=HiSax"; + if ($c->{options} !~ /protocol=/ && $isdn->{protocol} =~ /\d/) { + $modules_conf->set_options($c->{driver}, $c->{options} . " protocol=" . $isdn->{protocol}); + } + $c->{options} =~ /protocol=(\d)/ and $isdn->{protocol} = $1; + push @isdn, $isdn; + } detect_devices::probe_category('network/isdn'); + \@isdn; +} + +sub get_cards_by_type { + my ($isdn_type) = @_; + grep { $_->{card} eq $isdn_type } @isdndata; +} + + +sub get_cards() { + my %buses = ( + isa => N("ISA / PCMCIA") . "/" . N("I do not know"), + pci => N("PCI"), + usb => N("USB"), + ); + # pmcia alias (we should really split up pcmcia from isa in isdn db): + $buses{pcmcia} = $buses{isa}; + + map { $buses{$_->{card}} . "|" . $_->{description} => $_ } @isdndata; +} + + +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_capi_card($isdn) or return; + + #- check if the capi driver is available + 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; + } + + $capi_card; +} + +1; diff --git a/lib/network/connection/isdn/consts.pm b/lib/network/connection/isdn/consts.pm new file mode 100644 index 0000000..a53ddbe --- /dev/null +++ b/lib/network/connection/isdn/consts.pm @@ -0,0 +1,460 @@ +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); + +our @isdndata = + ( + { description => "Teles|16.0", #1 irq, mem, io + driver => 'hisax', + type => '1', + irq => '5', + mem => '0xd000', + io => '0xd80', + card => 'isa', + }, + { description => "Teles|8.0", #2 irq, mem + driver => 'hisax', + type => '2', + irq => '9', + mem => '0xd800', + card => 'isa', + }, + { description => "Teles|16.3 (ISA non PnP)", #3 irq, io + driver => 'hisax', + type => '3', + irq => '9', + io => '0xd80', + card => 'isa', + }, + { description => "Teles|16.3c (ISA PnP)", #14 irq, io + driver => 'hisax', + type => '14', + irq => '9', + io => '0xd80', + card => 'isa', + }, + { description => "Creatix/Teles|Generic (ISA PnP)", #4 irq, io0 (ISAC), io1 (HSCX) + driver => 'hisax', + type => '4', + irq => '5', + io0 => '0x0000', + io1 => '0x0000', + card => 'isa', + }, + { description => "Teles|generic", #21 no parameter + driver => 'hisax', + type => '21', + card => 'pci', + }, + { description => "Teles|16.3 (PCMCIA)", #8 irq, io + driver => 'hisax', + type => '8', + irq => '', + io => '0x', + card => 'isa', + }, + { description => "Teles|S0Box", #25 irq, io (of the used lpt port) + driver => 'hisax', + type => '25', + irq => '7', + io => '0x378', + card => 'isa', + }, + { description => "ELSA|PCC/PCF cards", #6 io or nothing for autodetect (the io is required only if you have n>1 ELSA|card) + driver => 'hisax', + type => '6', + io => "", + card => 'isa', + }, + { description => "ELSA|Quickstep 1000", #7 irq, io (from isapnp setup) + driver => 'hisax', + type => '7', + irq => '5', + io => '0x300', + card => 'isa', + }, + { description => "ELSA|Quickstep 1000", #18 no parameter + driver => 'hisax', + type => '18', + card => 'pci', + }, + { description => "ELSA|Quickstep 3000", #18 no parameter + driver => 'hisax', + type => '18', + card => 'pci', + }, + { description => "ELSA|generic (PCMCIA)", #10 irq, io (set with card manager) + driver => 'hisax', + type => '10', + irq => '', + io => '0x', + card => 'isa', + }, + { description => "ELSA|MicroLink (PCMCIA)", #10 irq, io (set with card manager) + driver => 'elsa_cs', + card => 'isa', + }, + { description => "ITK|ix1-micro Rev.2", #9 irq, io + driver => 'hisax', + type => '9', + irq => '9', + io => '0xd80', + card => 'isa', + }, + { description => "Eicon.Diehl|Diva (ISA PnP)", #11 irq, io + driver => 'hisax', + type => '11', + irq => '9', + io => '0x180', + card => 'isa', + }, + { description => "Eicon.Diehl|Diva 20", #11 no parameter + driver => 'hisax', + type => '11', + card => 'pci', + }, + { description => "Eicon.Diehl|Diva 20PRO", #11 no parameter + driver => 'hisax', + type => '11', + card => 'pci', + }, + { description => "Eicon.Diehl|Diva 20_U", #11 no parameter + driver => 'hisax', + type => '11', + card => 'pci', + }, + { description => "Eicon.Diehl|Diva 20PRO_U", #11 no parameter + driver => 'hisax', + type => '11', + card => 'pci', + }, + { description => "ASUS|COM ISDNLink", #12 irq, io (from isapnp setup) + driver => 'hisax', + type => '12', + irq => '5', + io => '0x200', + card => 'isa', + }, + { description => "ASUS|COM ISDNLink", + driver => 'hisax', + type => '35', + card => 'pci', + }, + { description => "DynaLink|Any", + driver => 'hisax', + type => '12', + card => 'pci', + }, + { description => "DynaLink|IS64PH, ASUSCOM", #36 + driver => 'hisax', + type => '36', + card => 'pci', + }, + { description => "HFC|2BS0 based cards", #13 irq, io + driver => 'hisax', + type => '13', + irq => '9', + io => '0xd80', + card => 'isa', + }, + { description => "HFC|2BDS0", #35 none + driver => 'hisax', + type => '35', + card => 'pci', + }, + { description => "HFC|2BDS0 S+, SP (PCMCIA)", #37 irq,io (pcmcia must be set with cardmgr) + driver => 'hisax', + type => '37', + card => 'isa', + }, + { description => "Sedlbauer|Speed Card", #15 irq, io + driver => 'hisax', + type => '15', + irq => '9', + io => '0xd80', + card => 'isa', + }, + { description => "Sedlbauer|PC/104", #15 irq, io + driver => 'hisax', + type => '15', + irq => '9', + io => '0xd80', + card => 'isa', + }, + { description => "Sedlbauer|Speed Card", #15 no parameter + driver => 'hisax', + type => '15', + card => 'pci', + }, + { description => "Sedlbauer|Speed Star (PCMCIA)", #22 irq, io (set with card manager) + driver => 'sedlbauer_cs', + card => 'isa', + }, + { description => "Sedlbauer|Speed Fax+ (ISA Pnp)", #28 irq, io (from isapnp setup) + driver => 'hisax', + type => '28', + irq => '9', + io => '0xd80', + card => 'isa', + firmware => '/usr/lib/isdn/ISAR.BIN', + }, + { description => "Sedlbauer|Speed Fax+", #28 no parameter + driver => 'hisax', + type => '28', + card => 'pci', + firmware => '/usr/lib/isdn/ISAR.BIN', + }, + { description => "USR|Sportster internal", #16 irq, io + driver => 'hisax', + type => '16', + irq => '9', + io => '0xd80', + card => 'isa', + }, + { description => "Generic|MIC card", #17 irq, io + driver => 'hisax', + type => '17', + irq => '9', + io => '0xd80', + card => 'isa', + }, + { description => "Compaq|ISDN S0 card", #19 irq, io0, io1, io (from isapnp setup io=IO2) + driver => 'hisax', + type => '19', + irq => '5', + io => '0x0000', + io0 => '0x0000', + io1 => '0x0000', + card => 'isa', + }, + { description => "Generic|NETjet card", #20 no parameter + driver => 'hisax', + type => '20', + card => 'pci', + }, + { description => "Dr. Neuhaus|Niccy (ISA PnP)", #24 irq, io0, io1 (from isapnp setup) + driver => 'hisax', + type => '24', + irq => '5', + io0 => '0x0000', + io1 => '0x0000', + card => 'isa', + }, + { description => "Dr. Neuhaus|Niccy", ##24 no parameter + driver => 'hisax', + type => '24', + card => 'pci', + }, + { description => "AVM|A1 (Fritz) (ISA non PnP)", #5 irq, io + driver => 'hisax', + type => '5', + irq => '10', + io => '0x300', + card => 'isa', + }, + { description => "AVM|ISA Pnp generic", #27 irq, io (from isapnp setup) + driver => 'hisax', + type => '27', + irq => '5', + io => '0x300', + card => 'isa', + }, + { description => "AVM|A1 (Fritz) (PCMCIA)", #26 irq, io (set with card manager) + driver => 'hisax', + type => '26', + irq => '', + card => 'isa', + }, + { description => "AVM|PCI (Fritz!)", #27 no parameter + driver => 'hisax', + type => '27', + card => 'pci', + }, + { description => "AVM|B1", + driver => 'b1pci', + card => 'pci', + }, + { description => "Siemens|I-Surf 1.0 (ISA Pnp)", #29 irq, io, memory (from isapnp setup) + driver => 'hisax', + type => '29', + irq => '9', + io => '0xd80', + mem => '0xd000', + card => 'isa', + }, + { description => "ACER|P10 (ISA Pnp)", #30 irq, io (from isapnp setup) + driver => 'hisax', + type => '30', + irq => '5', + io => '0x300', + card => 'isa', + }, + { description => "HST|Saphir (ISA Pnp)", #31 irq, io + driver => 'hisax', + type => '31', + irq => '5', + io => '0x300', + card => 'isa', + }, + { description => "Telekom|A4T", #32 none + driver => 'hisax', + type => '32', + card => 'pci', + }, + { description => "Scitel|Quadro", #33 subcontroller (4*S0, subctrl 1...4) + driver => 'hisax', + type => '33', + card => 'pci', + }, + { description => "Gazel|ISDN cards", #34 irq,io + driver => 'hisax', + type => '34', + irq => '5', + io => '0x300', + card => 'isa', + }, + { description => "Gazel|Gazel ISDN cards", #34 none + driver => 'hisax', + type => '34', + card => 'pci', + }, + { description => "Winbond|W6692 and Winbond based cards", #36 none + driver => 'hisax', + type => '36', + card => 'pci', + }, + { description => "BeWAN|R834", + driver => 'hisax_st5481', + type => '99', + card => 'usb', + }, + { description => "Gazel|128", + driver => 'hisax_st5481', + type => '99', + card => 'usb', + }, + ); + +#- cards than can be used with capi drivers +our @isdn_capi = + ( + { + vendor => 0x1131, + id => 0x5402, + description => 'AVM Audiovisuelles|Fritz DSL ISDN/DSL Adapter', + bus => 'PCI', + driver => 'fcdsl', + firmware => 'fdslbase.bin' + }, + { + vendor => 0x1244, + id => 0x0a00, + description => 'AVM Audiovisuelles|A1 ISDN Adapter [Fritz] CAPI', + bus => 'PCI', + driver => 'fcpci' + }, + { + vendor => 0x1244, + id => 0x0e00, + description => 'AVM Audiovisuelles|A1 ISDN Adapter [Fritz] CAPI', + bus => 'PCI', + driver => 'fcpci' + }, + { + vendor => 0x1244, + id => 0x0f00, + description => 'AVM Audiovisuelles|Fritz DSL ISDN/DSL Adapter', + bus => 'PCI', + driver => 'fcdsl', + firmware => 'fdslbase.bin' + }, + { + vendor => 0x1244, + id => 0x2700, + description => 'AVM Audiovisuelles|Fritz!Card DSL SL', + bus => 'PCI', + driver => 'fcdslsl', + firmware => 'fdssbase.bin' + }, + { + vendor => 0x1244, + id => 0x2900, + description => 'AVM Audiovisuelles|Fritz DSL Ver. 2.0', + bus => 'PCI', + driver => 'fcdsl2', + firmware => 'fds2base.bin' + }, + { + vendor => 0x057c, + id => 0x0c00, + description => 'AVM GmbH|FritzCard USB ISDN TA', + bus => 'USB', + driver => 'fcusb' + }, + { + vendor => 0x057c, + id => 0x1000, + description => 'AVM GmbH|FritzCard USB 2 Ver. 2.0 ISDN TA', + bus => 'USB', + driver => 'fcusb2', + firmware => 'fus2base.frm' + }, + { + vendor => 0x057c, + id => 0x1900, + description => 'AVM GmbH|FritzCard USB 2 Ver. 3.0 ISDN TA', + bus => 'USB', + driver => 'fcusb2', + firmware => 'fus3base.frm' + }, + { + vendor => 0x057c, + id => 0x2000, + description => 'AVM GmbH|Fritz X USB ISDN TA', + bus => 'USB', + driver => 'fxusb' + }, + { + vendor => 0x057c, + id => 0x2300, + description => 'AVM GmbH|FtitzCard USB DSL ISDN TA/ DSL Modem', + bus => 'USB', + driver => 'fcdslusb', + firmware => 'fdsubase.frm' + }, + { + vendor => 0x057c, + id => 0x2800, + description => 'AVM GmbH|Fritz X USB OEM ISDN TA', + bus => 'USB', + driver => 'fxusb_CZ' + }, + { + vendor => 0x057c, + id => 0x3000, + description => 'AVM GmbH|FtitzCard USB DSL SL USB', + bus => 'USB', + driver => 'fcdslusba', + firmware => 'fdlabase.frm' + }, + { + vendor => 0x057c, + id => 0x3500, + description => 'AVM GmbH|FtitzCard USB DSL SL USB Analog', + bus => 'USB', + driver => 'fcdslslusb', + firmware => 'fdlubase.frm', + }, + { + vendor => 0x057c, + id => 0x3600, + description => 'AVM FRITZ!Card DSL USB v2.0', + bus => 'USB', + driver => 'fcdslusb2', + firmware => 'fds2base.frm', + }, + ); + + +1; 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/connection/providers/xdsl.pm b/lib/network/connection/providers/xdsl.pm new file mode 100644 index 0000000..6956e1c --- /dev/null +++ b/lib/network/connection/providers/xdsl.pm @@ -0,0 +1,1252 @@ +# -*- 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 common; +use utf8; + +# 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 %data = ( + ## format chosen is the following : + # country|provider => { VPI, VCI_hexa, ... } all parameters + # country is automagically translated into LANG with N function + # provider is kept "as-is", not translated + # provider_id is used by eagleconfig to identify an ISP (I use ISO_3166-1) + # see http://en.wikipedia.org/wiki/ISO_3166-1 + # url_tech : technical URL providing info about ISP + # vpi : virtual path identifier + # vci : virtual channel identifier (in hexa below !!) + # Encapsulation: + # 1=PPPoE LLC, 2=PPPoE VCmux (never used ?) + # 3=RFC1483/2684 Routed IP LLC, + # 4=RFC1483/2684 Routed IP (IPoA VCmux) + # 5 RFC2364 PPPoA LLC, + # 6 RFC2364 PPPoA VCmux + # see http://faq.eagle-usb.org/wakka.php?wiki=AdslDescription + # dns are provided for when !usepeerdns in peers config file + # dnsServers : array ref with any valid DNS (order matters) + # DOMAINNAME2 : used for search key in /etc/resolv.conf + # method : PPPoA, pppoe, static or dhcp + # 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) + + N("Algeria") . "|Wanadoo" => + { + provider_id => 'DZ01', + vpi => 0, + vci => 23, + Encapsulation => 1, + method => 'pppoe', + 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 => 8, + vci => 23, + Encapsulation => 1, + method => 'pppoe', + 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" => + { + provider_id => 'AT00', + vpi => 8, + vci => 30, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Austria") . "|AON" => + { + provider_id => 'AT01', + vpi => 1, + vci => 20, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Austria") . "|Telstra" => + { + provider_id => 'AT02', + vpi => 8, + vci => 23, + Encapsulation => 1, + 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', + vpi => 8, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("Belgium") . "|Tiscali BE" => + { + provider_id => 'BE01', + vpi => 8, + vci => 23, + Encapsulation => 6, + method => 'pppoa', + dnsServers => [ qw(212.35.2.1 212.35.2.2 212.233.1.34 212.233.2.34) ], + DOMAINNAME2 => 'tiscali.be', + }, + + N("Belgium") . "|Belgacom" => + { + provider_id => 'BE03', + vpi => 8, + vci => 23, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Belgium") . "|Turboline" => + { + provider_id => 'BE02', + vpi => 8, + vci => 23, + Encapsulation => 5, + method => 'pppoa', + }, + + N("Belgium") . "|Scarlet ADSL" => + { + provider_id => 'BE05', + vpi => 8, + vci => 20, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Brazil") . "|Speedy/Telefonica" => + { + provider_id => 'BR01', + vpi => 8, + vci => 23, + Encapsulation => 1, + method => 'pppoe', + dnsServers => [ qw(200.204.0.10 200.204.0.138) ], + }, + + N("Brazil") . "|Velox/Telemar" => + { + provider_id => 'BR02', + vpi => 0, + vci => 21, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Brazil") . "|Turbo/Brasil Telecom" => + { + provider_id => 'BR03', + vpi => 0, + vci => 23, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Brazil") . "|Rio Grande do Sul (RS)" => + { + provider_id => 'BR04', + vpi => 1, + vci => 20, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Bulgaria") . "|BTK ISDN" => + { + provider_id => 'BG02', + vpi => 1, + vci => 20, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Bulgaria") . "|BTK POTS" => + { + provider_id => 'BG01', + vpi => 0, + vci => 23, + Encapsulation => 1, + method => 'pppoe', + }, + + N("China") . "|China Netcom|Beijing" => + { + provider_id => 'CN01', + vpi => 0, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Netcom|Changchun" => + { + provider_id => 'CN02', + vpi => 8, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Netcom|Harbin" => + { + provider_id => 'CN03', + vpi => 8, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Netcom|Jilin" => + { + provider_id => 'CN04', + vpi => 0, + vci => 27, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Netcom|Lanzhou" => + { + provider_id => 'CN05', + vpi => 0, + vci => 20, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Netcom|Tianjin" => + { + provider_id => 'CN06', + vpi => 0, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Netcom|Xi'an" => + { + provider_id => 'CN07', + vpi => 8, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Chongqing" => + { + provider_id => 'CN08', + vpi => 0, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Fujian" => + { + provider_id => 'CN09', + vpi => 0, + vci => 0xc8, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Guangxi" => + { + provider_id => 'CN10', + vpi => 0, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Guangzhou" => + { + provider_id => 'CN11', + vpi => 8, + vci => 20, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Hangzhou" => + { + provider_id => 'CN12', + vpi => 0, + vci => 20, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Netcom|Hunan" => + { + provider_id => 'CN13', + vpi => 0, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Nanjing" => + { + provider_id => 'CN14', + vpi => 8, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Shanghai" => + { + provider_id => 'CN15', + vpi => 8, + vci => 51, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Shenzhen" => + { + provider_id => 'CN16', + vpi => 8, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Urumqi" => + { + provider_id => 'CN17', + vpi => 0, + vci => 20, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Wuhan" => + { + provider_id => 'CN18', + vpi => 0, + vci => 20, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Yunnan" => + { + provider_id => 'CN19', + vpi => 0, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("China") . "|China Telecom|Zhuhai" => + { + provider_id => 'CN20', + vpi => 0, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + 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 => 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, + 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" => + { + provider_id => 'FI01', + vpi => 0, + vci => 64, + Encapsulation => 3, + method => 'pppoe', + }, + + N("France") . "|Free non dégroupé 512/128 & 1024/128" => + { + provider_id => 'FR01', + vpi => 8, + vci => 23, + Encapsulation => 6, + 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', + }, + + N("France") . "|Free dégroupé 1024/256 (mini)" => + { + provider_id => 'FR04', + vpi => 8, + vci => 24, + Encapsulation => 4, + 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', + }, + + N("France") . "|n9uf tel9com 512 & dégroupé 1024" => + { + provider_id => 'FR05', + vpi => 8, + vci => 23, + Encapsulation => 6, + CMVep => 'FR', + dnsServers => [ qw(212.30.93.108 212.203.124.146 62.62.156.12 62.62.156.13) ], + method => 'pppoa', + }, + + N("France") . "|Cegetel non dégroupé 512 IP/ADSL et dégroupé" => + { + provider_id => 'FR08', + vpi => 8, + vci => 23, + Encapsulation => 6, + 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" => + { + provider_id => 'FR06', + vpi => 8, + vci => 23, + Encapsulation => 6, + CMVep => 'FR', + dnsServers => [ qw(194.117.200.10 194.117.200.15) ], + method => 'pppoa', + DOMAINNAME2 => 'club-internet.fr', + }, + + N("France") . "|Wanadoo" => + { + provider_id => 'FR09', + vpi => 8, + vci => 23, + Encapsulation => 6, + CMVep => 'FR', + dnsServers => [ qw(80.10.246.2 80.10.246.129) ], + method => 'pppoa', + login_format => 'fti/login', + DOMAINNAME2 => 'wanadoo.fr', + }, + + N("France") . "|Télé2" => + { + provider_id => 'FR02', + vpi => 8, + vci => 23, + Encapsulation => 6, + CMVep => 'FR', + dnsServers => [ qw(212.151.136.242 130.244.127.162 212.151.136.246) ], + method => 'pppoa', + }, + + N("France") . "|Tiscali.fr 128k" => + { + provider_id => 'FR03', + vpi => 8, + vci => 23, + Encapsulation => 5, + CMVep => 'FR', + dnsServers => [ qw(213.36.80.1 213.36.80.2) ], + method => 'pppoa', + }, + + N("France") . "|Tiscali.fr 512k" => + { + provider_id => 'FR07', + vpi => 8, + vci => 23, + Encapsulation => 6, + CMVep => 'FR', + dnsServers => [ qw(213.36.80.1 213.36.80.2) ], + method => 'pppoa', + }, + + N("Germany") . "|Deutsche Telekom (DT)" => + { + provider_id => 'DE01', + vpi => 1, + vci => 20, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Germany") . "|1&1" => + { + provider_id => 'DE02', + vpi => 1, + vci => 20, + Encapsulation => 1, + 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', + }, + + N("Greece") . "|Any" => + { + provider_id => 'GR01', + vpi => 8, + vci => 23, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Hungary") . "|Matav" => + { + provider_id => 'HU01', + vpi => 1, + vci => 20, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Ireland") . "|Any" => + { + provider_id => 'IE01', + vpi => 8, + vci => 23, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Israel") . "|Bezeq" => + { + provider_id => 'IL01', + vpi => 8, + vci => 30, + Encapsulation => 6, + dnsServers => [ qw(192.115.106.10 192.115.106.11 192.115.106.35) ], + method => 'pppoa', + }, + + N("India") . "|Any" => + { + provider_id => 'IN01', + vpi => 0, + vci => 20, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Iceland") . "|Islandssimi" => + { + provider_id => 'IS01', + vpi => 0, + vci => 23, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Iceland") . "|Landssimi" => + { + provider_id => 'IS02', + vpi => 8, + vci => 30, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Italy") . "|Telecom Italia" => + { + provider_id => 'IT01', + vpi => 8, + vci => 23, + Encapsulation => 6, + CMVep => 'IT', + dnsServers => [ qw(195.20.224.234 194.25.2.129) ], + method => 'pppoa', + }, + + N("Italy") . "|Telecom Italia/Office Users (ADSL Smart X)" => + { + provider_id => 'IT02', + vpi => 8, + vci => 23, + Encapsulation => 3, + CMVep => 'IT', + method => 'static', + }, + + N("Italy") . "|Tiscali.it, Alice" => + { + provider_id => 'IT03', + vpi => 8, + vci => 23, + Encapsulation => 6, + 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" => + { + provider_id => 'LT01', + vpi => 8, + vci => 23, + Encapsulation => 1, + 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, + dnsServers => [ qw(212.217.0.1 212.217.0.12) ], + method => 'pppoa', + }, + + N("Netherlands") . "|KPN" => + { + provider_id => 'NL01', + vpi => 8, + vci => 30, + Encapsulation => 6, + method => 'pppoa', + }, + + N("Netherlands") . "|Eager Telecom" => + { + provider_id => 'NL02', + vpi => 0, + vci => 21, + Encapsulation => 3, + method => 'pppoe', + }, + + N("Netherlands") . "|Tiscali" => + { + provider_id => 'NL03', + vpi => 0, + vci => 22, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Netherlands") . "|Versatel" => + { + provider_id => 'NL04', + vpi => 0, + vci => 20, + Encapsulation => 3, + 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, + dnsServers => [ qw(194.204.152.34 217.98.63.164) ], + method => 'pppoa', + }, + + N("Poland") . "|Netia neostrada" => + { + provider_id => 'PL02', + url_tech => 'http://www.netia.pl/?o=d&s=210', + vpi => 8, + vci => 23, + Encapsulation => 1, + dnsServers => [ qw(195.114.181.130 195.114.161.61) ], + method => 'pppoe', + }, + + N("Portugal") . "|PT" => + { + provider_id => 'PT01', + vpi => 0, + vci => 23, + Encapsulation => 1, + method => 'pppoe', + }, + + N("Russia") . "|MTU-Intel" => + { + provider_id => 'RU01', + url_tech => 'http://stream.ru/s-requirements', + vpi => 1, + vci => 32, + Encapsulation => 1, + 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', + vpi => 0, + vci => 35, + Encapsulation => 6, + method => 'pppoa', + DOMAINNAME2 => 'sentoo.sn', + }, + + N("Slovenia") . "|SiOL" => + { + provider_id => 'SL01', + vpi => 1, + vci => 20, + method => 'pppoe', + Encapsulation => 1, + dnsServers => [ qw(193.189.160.11 193.189.160.12) ], + DOMAINNAME2 => 'siol.net', + }, + + N("Spain") . "|Telefónica IP dinámica" => + { + provider_id => 'ES01', + vpi => 8, + vci => 20, + Encapsulation => 1, + 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" => + { + provider_id => 'ES02', + vpi => 8, + vci => 20, + Encapsulation => 3, + CMVep => 'ES', + dnsServers => [ qw(80.58.32.33 80.58.0.97) ], + method => 'static', + login_format => 'adslppp@telefonicanetpa / adslppp', + }, + + N("Spain") . "|Wanadoo/Eresmas Retevision" => + { + provider_id => 'ES03', + vpi => 8, + vci => 23, + Encapsulation => 6, + CMVep => 'ES', + dnsServers => [ qw(80.58.0.33 80.58.32.97) ], + method => 'pppoa', + login_format => 'rtxxxxx@wanadooadsl', + encryption => 1, + }, + + N("Spain") . "|Wanadoo PPPoE" => + { + provider_id => 'ES04', + vpi => 8, + vci => 20, + Encapsulation => 1, + CMVep => 'ES', + method => 'pppoe', + }, + + N("Spain") . "|Wanadoo ip fija" => + { + provider_id => 'ES05', + vpi => 8, + vci => 20, + Encapsulation => 3, + CMVep => 'ES', + method => 'static', + }, + + N("Spain") . "|Tiscali" => + { + provider_id => 'ES06', + vpi => 1, + vci => 20, + Encapsulation => 6, + CMVep => 'ES', + method => 'pppoa', + login_format => 'login@tiscali.es', + }, + + N("Spain") . "|Arrakis" => + { + provider_id => 'ES07', + vpi => 0, + vci => 23, + Encapsulation => 6, + CMVep => 'ES', + method => 'pppoa', + }, + + N("Spain") . "|Auna" => + { + provider_id => 'ES08', + vpi => 0, + vci => 23, + Encapsulation => 6, + CMVep => 'ES', + method => 'pppoa', + }, + + N("Spain") . "|Communitel" => + { + provider_id => 'ES09', + vpi => 0, + vci => 21, + Encapsulation => 6, + CMVep => 'ES', + method => 'pppoa', + }, + + N("Spain") . "|Euskatel" => + { + provider_id => 'ES10', + vpi => 8, + vci => 20, + Encapsulation => 1, + CMVep => 'ES', + method => 'pppoe', + }, + + N("Spain") . "|Uni2" => + { + provider_id => 'ES11', + vpi => 1, + vci => 21, + Encapsulation => 6, + CMVep => 'ES', + method => 'pppoa', + }, + + N("Spain") . "|Ya.com PPPoE" => + { + provider_id => 'ES12', + vpi => 8, + vci => 20, + Encapsulation => 1, + CMVep => 'ES', + method => 'pppoe', + login_format => 'adXXXXXXXXX@yacomadsl', + }, + + N("Spain") . "|Ya.com static" => + { + provider_id => 'ES13', + 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" => + { + provider_id => 'SE01', + vpi => 8, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("Switzerland") . "|Any" => + { + provider_id => 'CH01', + vpi => 8, + vci => 23, + Encapsulation => 3, + method => 'pppoe', + }, + + N("Switzerland") . "|BlueWin / Swisscom" => + { + provider_id => 'CH02', + vpi => 8, + vci => 23, + Encapsulation => 5, + dnsServers => [ qw(195.186.4.108 195.186.4.109) ], + method => 'pppoa', + }, + + N("Switzerland") . "|VTX Datacomm (ex-Tiscali)" => + { + provider_id => 'CH03', + vpi => 8, + vci => 23, + Encapsulation => 1, + method => 'pppoa', + }, + + N("Thailand") . "|Asianet" => + { + provider_id => 'TH01', + vpi => 0, + vci => 64, + Encapsulation => 1, + dnsServers => [ qw(203.144.225.242 203.144.225.72 203.144.223.66) ], + method => 'pppoe', + }, + + N("Tunisia") . "|Planet.tn" => + { + provider_id => 'TU01', + url_tech => 'http://www.planet.tn/', + vpi => 0, + vci => 23, + Encapsulation => 5, + 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" => + { + provider_id => 'AE01', + vpi => 0, + vci => 32, + Encapsulation => 5, + dnsServers => [ qw(213.42.20.20 195.229.241.222) ], + method => 'pppoa', + }, + + N("United Kingdom") . "|Tiscali UK " => + { + provider_id => 'UK01', + vpi => 0, + vci => 26, + Encapsulation => 6, + dnsServers => [ qw(212.74.112.66 212.74.112.67) ], + method => 'pppoa', + }, + + N("United Kingdom") . "|British Telecom " => + { + provider_id => 'UK02', + vpi => 0, + vci => 26, + Encapsulation => 6, + 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; |