#!/usr/bin/perl ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2007-2021 IPFire Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # # # ############################################################################### use strict; # enable only the following on debugging purpose #use warnings; #use CGI::Carp 'fatalsToBrowser'; require '/var/ipfire/general-functions.pl'; require '/var/ipfire/lang.pl'; require '/var/ipfire/header.pl'; my $errormessage = ''; my %selected=(); my %checked=(); my %wlanapsettings=(); # Read the configuration file &General::readhash("/var/ipfire/wlanap/settings", \%wlanapsettings); # Set defaults &General::set_defaults(\%wlanapsettings, { "APMODE" => "on", "SSID" => "IPFire", "HIDESSID" => "off", "ENC" => "wpa2", "TXPOWER" => "auto", "CHANNEL" => "0", "COUNTRY" => "00", "HW_MODE" => "g", "PWD" => "", "HTCAPS" => "", "VHTCAPS" => "", "NOSCAN" => "on", "CLIENTISOLATION" => "off", "IEEE80211W" => "off", }); my %cgiparams = (); # Fetch arguments from browser &Header::getcgihash(\%cgiparams); # Find the selected interface my $INTF = &Network::get_intf_by_address($wlanapsettings{'INTERFACE'}); delete $wlanapsettings{'__CGI__'}; delete $wlanapsettings{'x'}; delete $wlanapsettings{'y'}; &Header::showhttpheaders(); if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}") { # verify WPA Passphrase - only with enabled enc if ($cgiparams{'ENC'} ne "none") { # must be 8 .. 63 characters if ((length($cgiparams{'PWD'}) < 8) || (length($cgiparams{'PWD'}) > 63)) { $errormessage .= "$Lang::tr{'wlanap invalid wpa'}
"; } # only ASCII alowed if (!($cgiparams{'PWD'} !~ /[^\x00-\x7f]/)) { $errormessage .= "$Lang::tr{'wlanap invalid wpa'}
"; } } # XXX This needs validation $wlanapsettings{'INTERFACE'} = $cgiparams{'INTERFACE'}; $wlanapsettings{'SSID'} = $cgiparams{'SSID'}; $wlanapsettings{'HIDESSID'} = ($cgiparams{'HIDESSID'} eq 'on') ? 'on' : 'off'; $wlanapsettings{'CLIENTISOLATION'} = ($cgiparams{'CLIENTISOLATION'} eq 'on') ? 'on' : 'off'; $wlanapsettings{'COUNTRY'} = $cgiparams{'COUNTRY'}; $wlanapsettings{'HW_MODE'} = $cgiparams{'HW_MODE'}; $wlanapsettings{'CHANNEL'} = $cgiparams{'CHANNEL'}; $wlanapsettings{'NOSCAN'} = ($cgiparams{'NOSCAN'} eq 'on') ? 'on' : 'off'; $wlanapsettings{'ENC'} = $cgiparams{'ENC'}; $wlanapsettings{'PWD'} = $cgiparams{'PWD'}; $wlanapsettings{'IEEE80211W'} = ($cgiparams{'IEEE80211W'} eq 'on') ? 'on' : 'off'; $wlanapsettings{'HTCAPS'} = $cgiparams{'HTCAPS'}; $wlanapsettings{'VHTCAPS'} = $cgiparams{'VHTCAPS'}; $wlanapsettings{'TX_POWER'} = $cgiparams{'TX_POWER'}; if ($errormessage eq '') { &General::writehash("/var/ipfire/wlanap/settings", \%wlanapsettings); &WriteConfig_hostapd(); &General::system("/usr/local/bin/wlanapctrl", "restart"); } # Start } elsif ($cgiparams{'ACTION'} eq "$Lang::tr{'start'}") { &General::system("/usr/local/bin/wlanapctrl", "start"); # Stop } elsif ($cgiparams{'ACTION'} eq "$Lang::tr{'stop'}") { &General::system("/usr/local/bin/wlanapctrl", "stop"); } &Header::openpage($Lang::tr{'wlanap configuration'}, 1, '', ''); &Header::openbigbox('100%', 'left', '', $errormessage); # Show any errors &Header::errorbox($errormessage); # # Driver and status detection # my $message = ""; my %INTERFACES = &Network::list_wireless_interfaces(); foreach my $intf (keys %INTERFACES) { $selected{'INTERFACE'}{$intf} = ''; } $selected{'INTERFACE'}{$wlanapsettings{'INTERFACE'}} = "selected='selected'"; # Change old "n" to "gn" if ( $wlanapsettings{'HW_MODE'} eq 'n' ) { $wlanapsettings{'HW_MODE'}='gn'; } $checked{'HIDESSID'}{'off'} = ''; $checked{'HIDESSID'}{'on'} = ''; $checked{'HIDESSID'}{$wlanapsettings{'HIDESSID'}} = "checked='checked'"; $checked{'NOSCAN'}{'off'} = ''; $checked{'NOSCAN'}{'on'} = ''; $checked{'NOSCAN'}{$wlanapsettings{'NOSCAN'}} = "checked='checked'"; $checked{'CLIENTISOLATION'}{'off'} = ''; $checked{'CLIENTISOLATION'}{'on'} = ''; $checked{'CLIENTISOLATION'}{$wlanapsettings{'CLIENTISOLATION'}} = "checked='checked'"; $selected{'IEEE80211W'}{'off'} = ''; $selected{'IEEE80211W'}{'optional'} = ''; $selected{'IEEE80211W'}{'on'} = ''; $selected{'IEEE80211W'}{$wlanapsettings{'IEEE80211W'}} = "selected"; $selected{'ENC'}{$wlanapsettings{'ENC'}} = "selected='selected'"; $selected{'CHANNEL'}{$wlanapsettings{'CHANNEL'}} = "selected='selected'"; $selected{'COUNTRY'}{$wlanapsettings{'COUNTRY'}} = "selected='selected'"; $selected{'TXPOWER'}{$wlanapsettings{'TXPOWER'}} = "selected='selected'"; $selected{'HW_MODE'}{$wlanapsettings{'HW_MODE'}} = "selected='selected'"; # Fetch all available channels my @channellist = &get_channellist($INTF); # Fetch countries my @countrylist = &get_countrylist(); # Show status &Header::opensection(); &Header::ServiceStatus({ "$Lang::tr{'wlanap'}" => { "process" => "hostapd", } }); print <
EOF &Header::closesection(); # # Configuration # &Header::openbox("100%", "center", $Lang::tr{'wlanap configuration'}); print <
$Lang::tr{'wlanap configuration'}
$Lang::tr{'wlanap interface'}
$Lang::tr{'wlanap ssid'}
$Lang::tr{'wlanap hide ssid'}
$Lang::tr{'wlanap client isolation'}
$Lang::tr{'wlanap country'}
$Lang::tr{'wlanap wireless mode'}
$Lang::tr{'wlanap channel'}
$Lang::tr{'wlanap neighbor scan'} $Lang::tr{'wlanap neighbor scan warning'}
$Lang::tr{'wlanap encryption'}
$Lang::tr{'wlanap psk'}
$Lang::tr{'wlanap management frame protection'}
HT Caps
VHT Caps
Tx Power
END ; &Header::closebox(); if ($INTF) { &Header::opensection(); my @status = `iw dev $INTF info`; if (@status) { print <$Lang::tr{'wlanap wlan status'}
@status
END } @status = `iw dev $INTF station dump`; if (@status) { print <$Lang::tr{'wlanap clients'}
@status
END } &Header::closesection(); } &Header::closebigbox(); &Header::closepage(); sub WriteConfig_hostapd{ open (CONFIGFILE, ">/var/ipfire/wlanap/hostapd.conf"); print CONFIGFILE <) { chomp $_; $phy = $_; last; } close($file); return $phy; } sub get_channellist($) { my $intf = shift; # Fetch the PHY ID my $phy = &get_phy($intf); my @channels = (0); open(my $command, "iw phy phy$phy info |"); while (<$command>) { # Skip everything we are not interested in next unless ($_ =~ m/MHz \[(\d+)\]/); my $channel = $1; # Skip disabled and otherwise unusable channels next if ($_ =~ m/disabled/); next if ($_ =~ m/no IBSS/); next if ($_ =~ m/no IR/); next if ($_ =~ m/passive scanning/); push(@channels, $channel); } close($command); return @channels; } sub get_countrylist() { open(my $file, ") { if ($_ =~ m/^country ([A-Z0-9]{2}):/) { push(@countries, $1); } } close($file); return @countries; }