OpenWrt Forum Archive

Topic: Useful shell script to show available wifi networks and connect to the

The content of this topic has been archived between 26 Feb 2018 and 13 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi,

I am working in a build for tl-wr703n including nas and some other features which I will share soon. Since the space is so limited Luci package cannot be included. Actually in my opinion the Luci inteface is not really that useful and I have made a few shell scripts to easily do common tasks instead.

One of my shell scripts is used to show a list of available wifi networks and automatically connect to the one you select.

This is an example of how it looks when running it:

root@OpenWrt:/# conf_wifi_client
Available WIFI networks:
    1 : "daikanyama"    (secure) (Signal strength: 100%)
    2 : "MyPlace"       (secure) (Signal strength: 58%)
    3 : "au_Wi-Fi"      (secure) (Signal strength: 42%)
    4 : "007Z_344B599"  (secure) (Signal strength: 38%)
    5 : "Wi2premium"    (open)   (Signal strength: 40%)
    6 : "Wi2premium cl" (secure) (Signal strength: 40%)
Enter the numeric option for your selected network: 3
Enter password of the selected WIFI network: ************


Trying to connect to WIFI network.
(Wait a few seconds and check status with: iwconfig )

The script only works if you have an active wifi interface in 'sta' mode.

Here is the code. You just need to copy all the code in a file, for example "conf_wifi_client", put it in the /bin directory or wherever you want and give it run permissions with:  chmod +x <filename>
The only thing you will need to modify a little bit is the uci commands in the end of the script. Just change them to match the labels of your wireless config file.

killall -9 wpa_supplicant
iwlist wlan0 scanning > /tmp/wifiscan #save scan results to a temp file
scan_ok=$(grep "wlan" /tmp/wifiscan) #check if the scanning was ok with wlan0
if [ -z "$scan_ok" ]; then
    killall -9 wpa_supplicant
    iwlist wlan0-1 scanning > /tmp/wifiscan
fi
scan_ok=$(grep "wlan" /tmp/wifiscan) #check if the scanning was ok
if [ -z "$scan_ok" ]; then #if scan was not ok, finish the script
    echo -n "
WIFI scanning failed.
    
"
    exit
fi
if [ -f /tmp/ssids ]; then
    rm /tmp/ssids
fi
n_results=$(grep -c "ESSID:" /tmp/wifiscan) #save number of scanned cell
i=1
while [ "$i" -le "$n_results" ]; do
        if [ $i -lt 10 ]; then
                cell=$(echo "Cell 0$i - Address:")
        else
                cell=$(echo "Cell $i - Address:")
        fi
        j=`expr $i + 1`
        if [ $j -lt 10 ]; then
                nextcell=$(echo "Cell 0$j - Address:")
        else
                nextcell=$(echo "Cell $j - Address:")
        fi
        awk -v v1="$cell" '$0 ~ v1 {p=1}p' /tmp/wifiscan | awk -v v2="$nextcell" '$0 ~ v2 {exit}1' > /tmp/onecell #store only one cell info in a temp file

        ##################################################
        ## Uncomment following line to show mac address ##

        #oneaddress=$(grep " Address:" /tmp/onecell | awk '{print $5}')

        onessid=$(grep "ESSID:" /tmp/onecell | awk '{ sub(/^[ \t]+/, ""); print }' | awk '{gsub("ESSID:", "");print}')
        oneencryption=$(grep "Encryption key:" /tmp/onecell | awk '{ sub(/^[ \t]+/, ""); print }' | awk '{gsub("Encryption key:on", "(secure)");print}' | awk '{gsub("Encryption key:off", "(open)  ");print}')
        onepower=$(grep "Quality=" /tmp/onecell | awk '{ sub(/^[ \t]+/, ""); print }' | awk '{gsub("Quality=", "");print}' | awk -F '/70' '{print $1}')
        onepower=$(awk -v v3=$onepower 'BEGIN{ print v3 * 10 / 7}')
        onepower=${onepower%.*}
        onepower="(Signal strength: $onepower%)"
        if [ -n "$oneaddress" ]; then                                                                                                            
                echo "$onessid  $oneaddress $oneencryption $onepower" >> /tmp/ssids                                                              
        else                                                                                                                                     
                echo "$onessid  $oneencryption $onepower" >> /tmp/ssids                                                                          
        fi
        i=`expr $i + 1`
done
rm /tmp/onecell
awk '{printf("%5d : %s\n", NR,$0)}' /tmp/ssids > /tmp/sec_ssids #add numbers at beginning of line
grep ESSID /tmp/wifiscan | awk '{ sub(/^[ \t]+/, ""); print }' | awk '{printf("%5d : %s\n", NR,$0)}' | awk '{gsub("ESSID:", "");print}' > /tmp/ssids #generate file with only numbers and names
echo -n "Available WIFI networks:
"
cat /tmp/sec_ssids #show ssids list
echo -n "Enter the numeric option for your selected network: "
read nsel
pattern=$(echo " $nsel : ")
wifissid=$(grep "$pattern" /tmp/ssids)
wifissid=$(echo "$wifissid" | awk -v pat="$pattern" '{gsub(pat, "");print}' | awk '{ sub(/^[ \t]+/, ""); print }')
wifissid=${wifissid:1:`expr ${#wifissid} - 2`}  #several commands to get clean name of ssid
if [ $nsel -lt 10 ]; then
    cell=$(echo "Cell 0$nsel - Address:")
else
    cell=$(echo "Cell $nsel - Address:")
fi
nextsel=`expr $nsel + 1`
if [ $nextsel -lt 10 ]; then
    nextcell=$(echo "Cell 0$nextsel - Address:")
else
    nextcell=$(echo "Cell $nextsel - Address:")
fi
awk -v v1="$cell" '$0 ~ v1 {p=1}p' /tmp/wifiscan | awk -v v2="$nextcell" '$0 ~ v2 {exit}1' > /tmp/cellinfo0 #store only the selected cell info in a temp file
grep -v ESSID /tmp/cellinfo0 > /tmp/cellinfo # delete ESSID line to avoid later grep mistakes
rm /tmp/cellinfo0
wifichannel=$(grep " Channel:" /tmp/cellinfo)
wifichannel=$(echo "$wifichannel" | awk '{gsub(" Channel:", "");print}' | awk '{ sub(/^[ \t]+/, ""); print }') #get clean wifi channel
wifimode=$(grep " WEP" /tmp/cellinfo) #check if encryption mode is WEP
if [ -n "$wifimode" ]; then   #check if $wifimode is not an empty string
    wifimode="wep"
else
    wifimode=$(grep "WPA2 " /tmp/cellinfo) #check if encryption mode is WPA2
    if [ -n "$wifimode" ]; then
        wifimode="psk2"
    else
        wifimode=$(grep "WPA " /tmp/cellinfo) #check if encryption mode is WPA
        if [ -n "$wifimode" ]; then
            wifimode="psk"
        else
            wifimode="none"
        fi
    fi
fi
encryp_on=$(grep " Encryption key:on" /tmp/cellinfo)
if [[ "$wifimode" == "none" && -n "$encryp_on" ]]; then
    echo " "
    echo "Impossible to detect wifi security mode automatically."
    echo "Please specify the seurity mode of the network."
    echo " 1: WPA"
    echo " 2: WPA2"
    echo " 3: WEP"
    echo " 4: Undefined"
    echo -n "Enter the numeric option for your security mode: "
    read sel_mode
    case "$sel_mode" in
        1)
            wifimode="psk"
            ;;
        2)
            wifimode="psk2"
            ;;
        3)
            wifimode="wep"
            ;;
        4)
            wifimode="none"
            ;;
    esac
fi
if [ "$wifimode" != "none" ]; then #ask for passwork when needed
    echo -n "Enter password of the selected WIFI network: "
    read wifipass
fi
rm /tmp/cellinfo
rm /tmp/ssids
rm /tmp/sec_ssids
rm /tmp/wifiscan
#write results in the wireless config file and reset wifi interface
uci set wireless.radio0.channel=$wifichannel
uci set wireless.wificlient.ssid="$wifissid"
uci set wireless.wificlient.encryption=$wifimode
uci set wireless.wificlient.key=$wifipass
uci commit wireless
echo -n "

Trying to connect to WIFI network.
(Wait a few seconds and check status with: iwconfig )


"
wifi down
wifi

I am just a beginner in OpenWrt and it took me a lot testing time to complete this script but I think it is working perfectly now.

Any comments or improvements are welcome.

Enjoy!

(Last edited by griguolcomerranas on 15 Dec 2012, 16:43)

yes!!!   a useful tool

I forgot to mention that you need to modify a little bit is the uci commands in the end of the script to match the labels of your wireless config file.

I have added it to the first post now.

janisalnis wrote:

Thanks for amazing work. One friend of mine asked that he would like to drive around in the city and automatically connect to Internet via free WiFi networks, like MacDonalds. Your script could be a good starting point.

Glad to hear it is useful for somebody!  big_smile

Thanks!
Very useful for my project!

If there is a wish list ;-) Add Quality and Adress too. Like this :

    5 : "eduroam" (secure) 00:13:C4:0E:1D:24 25/70 -85 dBm

Thanks again!

rullbandspelare wrote:

Thanks!
Very useful for my project!

If there is a wish list ;-) Add Quality and Adress too. Like this :

    5 : "eduroam" (secure) 00:13:C4:0E:1D:24 25/70 -85 dBm

Thanks again!

I like the idea of the signal power. May be I can add it on a 0 to 5 scale to make it more readable.

I don't think the address is so useful for the average users but if I have time I can send you a version including the address info by private message.

Hi again,

I have updated the script to show the signal strength of every scanned wifi network, in a scale of 5 points.

I have updated the first post with the new code and information.

Let me know if any problems.

Hi,

I m trying to execute the above script. but getting error messages..
I am new to wlan and kinldy help me to resolve the issue

The output looks like this

Available WIFI networks:
    1 : "ABCD_DLINK"    (secure) (Signal strength: 5 of 5)
    2 : "BOTHE"    (secure) (Signal strength: 1.4 of 5)
    3 : "DLink0_Guest1"    (open)   (Signal strength: 5 of 5)
Enter the numeric option for your selected network: 1
wifiscan_client.sh: line 93: uci: command not found
wifiscan_client.sh: line 94: uci: command not found
wifiscan_client.sh: line 95: uci: command not found
wifiscan_client.sh: line 96: uci: command not found
wifiscan_client.sh: line 97: uci: command not found
Trying to connect to WIFI network.(Wait a few seconds and check status with: iwconfig )wifiscan_client.sh: line 99: wifi: command not found
wifiscan_client.sh: line 100: wifi: command not found

Wlan wrote:

Hi,

I m trying to execute the above script. but getting error messages..
I am new to wlan and kinldy help me to resolve the issue

The output looks like this

Available WIFI networks:
    1 : "ABCD_DLINK"    (secure) (Signal strength: 5 of 5)
    2 : "BOTHE"    (secure) (Signal strength: 1.4 of 5)
    3 : "DLink0_Guest1"    (open)   (Signal strength: 5 of 5)
Enter the numeric option for your selected network: 1
wifiscan_client.sh: line 93: uci: command not found
wifiscan_client.sh: line 94: uci: command not found
wifiscan_client.sh: line 95: uci: command not found
wifiscan_client.sh: line 96: uci: command not found
wifiscan_client.sh: line 97: uci: command not found
Trying to connect to WIFI network.(Wait a few seconds and check status with: iwconfig )wifiscan_client.sh: line 99: wifi: command not found
wifiscan_client.sh: line 100: wifi: command not found

As I said in the first post you probably need to modify the uci commands in the end of the script to match the format of your wireless configuration file.
If you post here your wireles config file I can probably tell you what you need to change (you can delete your passwords before posting it here).

"uci: command not found" and "wifi: command not found" looks like he attempts to run the script on a non-OpenWrt platform or under a very old version (whiterussian)

jow wrote:

"uci: command not found" and "wifi: command not found" looks like he attempts to run the script on a non-OpenWrt platform or under a very old version (whiterussian)

Right. If the uci command is not matching his config file it should say something like "uci: Invalid argument" but "uci: command not found" sounds strange.

Can you try to type just "uci"? If the command works you should see the uci help file.

griguolcomerranas wrote:
Wlan wrote:

Hi,

I m trying to execute the above script. but getting error messages..
I am new to wlan and kinldy help me to resolve the issue

The output looks like this

Available WIFI networks:
    1 : "ABCD_DLINK"    (secure) (Signal strength: 5 of 5)
    2 : "BOTHE"    (secure) (Signal strength: 1.4 of 5)
    3 : "DLink0_Guest1"    (open)   (Signal strength: 5 of 5)
Enter the numeric option for your selected network: 1
wifiscan_client.sh: line 93: uci: command not found
wifiscan_client.sh: line 94: uci: command not found
wifiscan_client.sh: line 95: uci: command not found
wifiscan_client.sh: line 96: uci: command not found
wifiscan_client.sh: line 97: uci: command not found
Trying to connect to WIFI network.(Wait a few seconds and check status with: iwconfig )wifiscan_client.sh: line 99: wifi: command not found
wifiscan_client.sh: line 100: wifi: command not found

As I said in the first post you probably need to modify the uci commands in the end of the script to match the format of your wireless configuration file.
If you post here your wireles config file I can probably tell you what you need to change (you can delete your passwords before posting it here).


I am executing this script on Ubuntu 12.04 & I am not aware of location of wirelss configuration file.
is the configuration file located here :- /etc/network ?

following are the files located in etc/network
if-down.d/
if-post-down.d/
if-pre-up.d/
if-up.d/
interfaces
run -> /run/network/

When I checked interface I got the following content
auto lo
iface lo inet loopback

am I refering to the correct file?
Kindly help me.

Thanks in advance.

Wlan, check the FAQ at the top of the page. This forum is about openWRT, not Ubuntu.
I don't even know if there is uci in Ubuntu.

Thanks ;
This is tool is very usefull
Could you please help me in getting the signal level also using this script. I am very new to the Shell scripting

The output may some what look like this
"AP1" (secure or Open) <mac address.> <Singanl quality(25/70) <signal level(-30 dBm) 

is there any mechanism to convert signal level from DBM to percentage?

Thanks in advance:

wifi2012 wrote:

Thanks ;
This is tool is very usefull
Could you please help me in getting the signal level also using this script. I am very new to the Shell scripting

The output may some what look like this
"AP1" (secure or Open) <mac address.> <Singanl quality(25/70) <signal level(-30 dBm) 

is there any mechanism to convert signal level from DBM to percentage?

Thanks in advance:

Hi,

I have updated the script in the first post to show the signal level in percentage but I don't really want to add the mac address to the list. I think it would be a bit messy with so much information.

I have also added some lines of code for the cases where it is not possible to detect the wifi security mode automatically. In those cases the script would ask the user to input the security mode manually.

Please try the updated script. I hope it is useful for you.  smile

(Last edited by griguolcomerranas on 15 Dec 2012, 16:01)

I too would like the MAC adress.

Maybe You could implement it, but just coment it out so that people interested could uncoment it for this functionality?

Thanks!!!

I'd love to have something like this via a web interface.  Any php / python gurus out there?

What I would love to have is something that presents the available networks, lets you select one, enter the key if necessary, and then saves it via uci either for session only or permanently.

Anyone have anything like that?

rullbandspelare wrote:

I too would like the MAC adress.

Maybe You could implement it, but just coment it out so that people interested could uncoment it for this functionality?

Thanks!!!

Ok, since there are a few of you interested in the MAC address I have added it to the script in the first post. You just need to uncomment one line which is clearly marked inside the script.

Thank you
Can we have the output something like..
:-
Instead of prompting the user to select the WIFI network & then wrting the results in the wireless config file,
can we not directly select the wifi access point which has the maximum signal strenght & then write the results in wireless config file.
(May be a print statement on shell prompt saying....This <access point has maximum signal strenght and the results are written to ... config file)
user should get the Prompt only if access point has secuirty password.

I am new to shell scripting..any changes to the above script would help me
Thanks;

wifi2012 wrote:

Instead of prompting the user to select the WIFI network & then wrting the results in the wireless config file,
can we not directly select the wifi access point which has the maximum signal strenght & then write the results in wireless config file.

I am sorry but I don't think it is a good idea to select automatically the strongest network. Sometimes the closest one is not the strongest.

It takes just a few seconds to select a network from the list and I think it is better to let the user decide.

well, if luci2 comes out officially, it can be added to the luci web so that even a noob can make use of it easily.

thanks.

The "iwlist" command is unknown in "BARRIER BREAKER (Bleeding Edge, r39469)".

Which package do I have to install to get this script to work?

bluepuma wrote:

The "iwlist" command is unknown in "BARRIER BREAKER (Bleeding Edge, r39469)".

Which package do I have to install to get this script to work?

I tried it in ATTITUDE ADJUSTMENT, never tried BARRIER BRAKER, but the problem might be that your wifi chipset doesn't support that command.

The command should work for Atheros chipsets like the one in the tl-wr703n router.

I tried it on a similar device, the tl-wr710n

iw works in BB trunk. The scripts needs to be modified to parse the info:

 -----------------------------------------------------
 BARRIER BREAKER (Bleeding Edge, r39509)
 -----------------------------------------------------
root@OpenWrt:~# iw dev wlan0 scan
BSS 10:bf:48:xx:xx:35(on wlan0)
        TSF: 528096110818 usec (6d, 02:41:36)
        freq: 2412
        beacon interval: 100 TUs
        capability: ESS Privacy ShortSlotTime (0x0411)
        signal: -73.00 dBm
        last seen: 690 ms ago
        Information elements from Probe Response frame:
        SSID: XXXXXXXXXX
        Supported rates: 1.0* 2.0* 5.5* 11.0* 18.0 24.0 36.0 54.0
        DS Parameter set: channel 1
        ERP: <no flags>
...

(Last edited by hnyman on 7 Feb 2014, 17:16)