]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
hostapd: Find device by MAC address
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 16 Apr 2021 09:53:30 +0000 (11:53 +0200)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 16 Apr 2021 10:05:57 +0000 (10:05 +0000)
With wireless device as members in bridges, we cannot predict the name
very well. So we will use the MAC address and find the correct device
name when we launch hostapd.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
config/cfgroot/network-functions.pl
html/cgi-bin/wlanap.cgi
src/initscripts/packages/hostapd
src/paks/hostapd/install.sh

index 9908ee8abd2089962f8a482f8222edc1066c7106..2f704dfbfe5efe889680d72ece0299e8f8fb65ac 100644 (file)
@@ -332,6 +332,28 @@ sub setup_upstream_proxy() {
        }
 }
 
+sub list_wireless_interfaces() {
+       my %interfaces = ();
+
+       opendir(INTERFACES, "/sys/class/net");
+
+       my $intf;
+       while ($intf = readdir(INTERFACES)) {
+               # Is this a wireless interface?
+               opendir(PHY80211, "/sys/class/net/$intf/phy80211") or next;
+               closedir(PHY80211);
+
+               # Read the MAC address
+               my $address = &get_nic_property($intf, "address");
+
+               $interfaces{$address} = "$address ($intf)";
+       }
+
+       closedir(INTERFACES);
+
+       return %interfaces;
+}
+
 my %wireless_status = ();
 
 sub _get_wireless_status($) {
@@ -416,7 +438,7 @@ sub get_nic_property {
        my $property = shift;
        my $result;
 
-       open(FILE, "/sys/class/net/$nicname/$property") or die("Could not read property");
+       open(FILE, "/sys/class/net/$nicname/$property") or die("Could not read property $property for $nicname");
        $result = <FILE>;
        close(FILE);
 
@@ -465,6 +487,28 @@ sub get_mac_by_name($) {
        return $mac;
 }
 
+sub get_intf_by_address($) {
+       my $address = shift;
+
+       opendir(INTERFACES, "/sys/class/net");
+
+       while (my $intf = readdir(INTERFACES)) {
+               next if ($intf eq "." or $intf eq "..");
+
+               my $intf_address = &get_nic_property($intf, "address");
+
+               # Skip interfaces without addresses
+               next if ($intf_address eq "");
+
+               # Return a match
+               return $intf if ($intf_address eq $address);
+       }
+
+       closedir(INTERFACES);
+
+       return undef;
+}
+
 #
 ## Function to get a list of all available network zones.
 #
index 01dcaeea28bc93c01b752ca5250d7a32d46ed54f..85fe42d965a078add3a5cbed6a61fa7202e7929a 100644 (file)
@@ -81,6 +81,9 @@ $wlanapsettings{'IEEE80211W'} = 'off';
 &General::readhash("/var/ipfire/wlanap/settings", \%wlanapsettings);
 &Header::getcgihash(\%wlanapsettings);
 
+# Find the selected interface
+my $INTF = &Network::get_intf_by_address($wlanapsettings{'INTERFACE'});
+
 my @macs = $wlanapsettings{'MACS'};
 
 delete $wlanapsettings{'__CGI__'};
@@ -193,8 +196,11 @@ my $wlan_card_status = 'dummy';
 my $wlan_ap_status = '';
 my $message = "";
 
-$selected{'INTERFACE'}{'green0'} = '';
-$selected{'INTERFACE'}{'blue0'} = '';
+my %INTERFACES = &Network::list_wireless_interfaces();
+
+foreach my $intf (keys %INTERFACES) {
+       $selected{'INTERFACE'}{$intf} = '';
+}
 $selected{'ENC'}{$wlanapsettings{'INTERFACE'}} = "selected='selected'";
 
 if ( ($wlanapsettings{'INTERFACE'} eq '') ){
@@ -206,11 +212,12 @@ $message<br />
 <select name='INTERFACE'>
 END
 ;
-       if ( $netsettings{'BLUE_DEV'} ne ''){
-               print "<option value='blue0' $selected{'INTERFACE'}{'blue0'}>blue0</option>";
+
+       foreach my $intf (sort keys %INTERFACES) {
+               print "<option value='${intf}' $selected{'INTERFACE'}{$intf}>$INTERFACES{$intf}</option>";
        }
+
 print <<END
-               <option value='green0' $selected{'INTERFACE'}{'green0'}>green0</option>
 </select>
 <br /><br />
 <hr size='1'>
@@ -222,18 +229,18 @@ END
        &Header::closepage();
        exit;
 }else{
-       my $cmd_out = `/usr/sbin/iwconfig $wlanapsettings{'INTERFACE'} 2>/dev/null`;
+       my $cmd_out = `/usr/sbin/iwconfig $INTF 2>/dev/null`;
 
        if ( $cmd_out eq '' ){
                $message = "$Lang::tr{'wlanap no interface'}";
                $wlan_card_status = '';
        }else{
-               $cmd_out = `/sbin/ifconfig | /bin/grep $wlanapsettings{'INTERFACE'}`;
+               $cmd_out = `/sbin/ifconfig $INTF`;
                if ( $cmd_out eq '' ){
                        $wlan_card_status = 'down';
                }else{
                        $wlan_card_status = 'up';
-                       $cmd_out = `/usr/sbin/iwconfig $wlanapsettings{'INTERFACE'} | /bin/grep "Mode:Master"`;
+                       $cmd_out = `/usr/sbin/iwconfig $INTF | /bin/grep "Mode:Master"`;
                        if ( $cmd_out ne '' ){
                                $wlan_ap_status = 'up';
                        }
@@ -270,16 +277,16 @@ $selected{'TXPOWER'}{$wlanapsettings{'TXPOWER'}} = "selected='selected'";
 $selected{'HW_MODE'}{$wlanapsettings{'HW_MODE'}} = "selected='selected'";
 $selected{'MACMODE'}{$wlanapsettings{'MACMODE'}} = "selected='selected'";
 
-my $monwlaninterface = $wlanapsettings{'INTERFACE'};
-if ( -d '/sys/class/net/mon.'.$wlanapsettings{'INTERFACE'} ) {
-       $monwlaninterface =  'mon.'.$wlanapsettings{'INTERFACE'};
+my $monwlaninterface = $INTF;
+if ( -d '/sys/class/net/mon.' . $INTF) {
+       $monwlaninterface =  'mon.' . $INTF;
 }
 
 my @channellist_cmd;
 my @channellist = (0);
 
 if ( $wlanapsettings{'DRIVER'} eq 'NL80211' ){
-my $wiphy = `iw dev $wlanapsettings{'INTERFACE'} info | grep wiphy | cut -d" " -f2`;
+my $wiphy = `iw dev $INTF info | grep wiphy | cut -d" " -f2`;
 chomp $wiphy;
 
 @channellist_cmd = `iw phy phy$wiphy info | grep " MHz \\\[" | grep -v "(disabled)" | grep -v "no IBSS" | grep -v "no IR" | grep -v "passive scanning" 2>/dev/null`;
@@ -318,7 +325,7 @@ my @countrylist = @temp;
 
 my @txpower_cmd = `iwlist $monwlaninterface txpower 2>/dev/null`;
 if ( $wlanapsettings{'DRIVER'} eq 'NL80211' ){
-       # There is a bug with NL80211 only all devices can displayed
+       # There is a bug with NL80211 only all devices can displaye
        @txpower_cmd = `iwlist txpower 2>/dev/null | sed -e "s|unknown transmit-power information.||g"`;
 }
 # get available power
@@ -488,7 +495,7 @@ print <<END
 </table>
 END
 ;
-if ( $wlanapsettings{'INTERFACE'} =~ /green0/ ){
+if ( $INTF =~ /green0/ ){
        print <<END
 <br />
 <table width='80%' cellspacing='0' class='tbl' border='1'>
@@ -523,7 +530,7 @@ END
 ;
 my @status;
 if ( $wlanapsettings{'DRIVER'} eq 'NL80211' ){
-        @status =  `iw dev $wlanapsettings{'INTERFACE'} info && iw dev $wlanapsettings{'INTERFACE'} station dump && echo ""`;
+        @status =  `iw dev $INTF info && iw dev $INTF station dump && echo ""`;
 }
 print <<END
 <br />
@@ -588,7 +595,6 @@ sub WriteConfig_hostapd{
 driver=$wlanapsettings{'DRIVER_HOSTAPD'}
 ######################### basic hostapd configuration ##########################
 #
-interface=$wlanapsettings{'INTERFACE'}
 country_code=$wlanapsettings{'COUNTRY'}
 ieee80211d=1
 ieee80211h=1
index 7aee84e52046ec683b27811067a9868d1d660ea4..c559b26f0d9990cfce181f4d0cb468644e5d4d05 100644 (file)
@@ -2,6 +2,20 @@
 . /etc/sysconfig/rc
 . ${rc_functions}
 
+find_interface() {
+       local address="${1}"
+
+       local path
+       for path in /sys/class/net/*; do
+               if [ -s "${path}/address" ] && [ "$(<${path}/address)" = "${address}" ]; then
+                       basename "${path}"
+                       return 0
+               fi
+       done
+
+       return 1;
+}
+
 CHANNEL="6"
 COUNTRY="00"
 TXPOWER="auto"
@@ -12,8 +26,15 @@ eval $(/usr/local/bin/readhash /var/ipfire/wlanap/settings)
 
 case "${1}" in
        start)
+               interface="$(find_interface "${INTERFACE}")"
+               if [ -z "${interface}" ]; then
+                       boot_mesg "Could not find interface with address ${INTERFACE} for wireless access point"
+                       echo_failure
+                       exit 1
+               fi
+
                boot_mesg "Starting hostapd... "
-               loadproc /usr/bin/hostapd -B /etc/hostapd.conf
+               loadproc /usr/bin/hostapd -B /etc/hostapd.conf -i "${interface}"
                ;;
 
        stop)
index bd2441e55a18de92745e9159ffaa0c4a5bb661f0..2dae5364eef64b7676bb7d2a13151f7559e6cdbd 100644 (file)
 . /opt/pakfire/lib/functions.sh
 extract_files
 restore_backup ${NAME}
+
+# Convert INTERFACE setting to MAC address
+(
+       eval $(/usr/local/bin/readhash /var/ipfire/wlanap/settings)
+
+       if [ -n "${INTERFACE}" -a -d "/sys/class/net/${INTERFACE}" ]; then
+               sed -i /var/ipfire/wlanap/settings \
+                       -e "s/^INTERFACE=.*/INTERFACE=$(</sys/class/net/${INTERFACE}/address)/"
+       fi
+)
+
 ln -s ../init.d/hostapd /etc/rc.d/rc3.d/S18hostapd
 ln -s ../init.d/hostapd /etc/rc.d/rc0.d/K81hostapd
 ln -s ../init.d/hostapd /etc/rc.d/rc6.d/K81hostapd