How Does Iwlist() Command Scans The Wireless Networks

How does iwlist() command scans the wireless networks?

iwlist(8) and the other wireless tools provide a common front end to different wireless device drivers that support Linux Wireless Extensions (WEXT). Each driver will register handlers with WEXT that implement the device specific operations defined by this interface. For scanning, the two handlers are trigger scan (command SIOCSIWSCAN) and get scan results (command SIOCGIWSCAN). After the device completes a scan, it sends a SIOCGIWSCAN event to WEXT via a netlink interface. An application listening to this socket can then issue a SIOCGIWSCAN command to get the scan results from the device. Note that the device is free to implement the scan how ever it chooses. For example, it can passively listen for beacons or actively scan by sending out probe requests.

The above is purposely vague on the mechanics of sending commands to a device because there is the traditional way (ioctl) and the new way (netlink - cfg80211). But to take a concrete example, consider the traditional way. The ioctl calls are implemented in the WEXT module but the code that handles this command is implemented in the device driver. When a user space application makes an ioctl, WEXT looks up the device driver's handler and runs it.

How can I get a list of available wireless networks on Linux?

The Wireless Tools package -- of which iwlist is a part -- also contains a Wireless Tools Helper Library. You need to include iwlib.h and link with libiw.a (i.e. add -liw). Then look up the documentation for the iw_set_ext function. The SIOCSIWSCAN parameter will be of most use. For an example of how to use this interface, take a look at the KWifiManager source in the KDE library (see: Interface_wireless_wirelessextensions::get_available_networks method). Alternatively, you can also download the Wireless Tools source code and take a look at how the iwlib iw_set_ext function is also used for scanning in iwlist.c.

As for privileges, I imagine the process will need to run as root to perform the scan. I'd love to know if this could be done otherwise as well.

Since you are using Ubuntu 8.04 the libiw-dev package should be of use.

iwlist output to list or variables

switched from iwlist wlan0 scan to iw wlan0 scan which gives a far cleaner output to work with.
Almost got the results I was aiming for when I stumbled upon a GitHub comment from Djey1301: 29 sept 2016

iw wlan0 scan | sed -e 's#(on wlan# (on wlan#g' | awk -f scan.awk

scan.awk:

BEGIN {

printf("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n","MAC","SSID","freq","signal","sig%","WPA","WPA2","WEP","TKIP","CCMP");

}
$1 == "SSID:" { buf = $2; for (i = 3; i <= NF; ++i) { buf = buf" "$i } ; e["SSID"] = buf ; next }
NF > 0{
if ($1 == "BSS") {
if( $2 ~ /^[a-z0-9:]{17}$/ ) {
if( e["MAC"] ){
printf("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n",e["MAC"],e["SSID"],e["freq"],e["sig"],e["sig%"],e["WPA"],e["WPA2"],e["WEP"],e["TKIP"],e["CCMP"]);
}
e["MAC"] = $2;
e["WPA"] = "n";
e["WPA2"] = "n";
e["WEP"] = "n";
e["TKIP"] = "n";
e["CCMP"] = "n";
}
}
if ($1 == "SSID:") {
e["SSID"] = $2;
}
if ($1 == "freq:") {
e["freq"] = $NF;
}
if ($1 == "signal:") {
e["sig"] = $2 " " $3;
e["sig%"] = (60 - ((-$2) - 40)) * 100 / 60;
}
if ($1 == "WPA:") {
e["WPA"] = "y";
}
if ($1 == "RSN:") {
e["WPA2"] = "y";
}
if ($1 == "WEP:") {
e["WEP"] = "y";
}
if ($4 == "CCMP" || $5 == "CCMP") {
e["CCMP"] = "y";
}
if ($4 == "TKIP" || $5 == "TKIP") {
e["TKIP"] = "y";
}
}
END {
printf("%s|%s|%s|%s|%s|%s|%s|%s|%s|%s\n",e["MAC"],e["SSID"],e["freq"],e["sig"],e["sig%"],e["WPA"],e["WPA2"],e["WEP"],e["TKIP"],e["CCMP"]);
}

And the result I'm almost happy with:

MAC|SSID|freq|signal|sig%|WPA|WPA2|WEP|TKIP|CCMP
9B:5c:44:c5:b8:92|Chinees|2437|-78.00 dBm|36.6667|y|y|n|y|y
89:03:55:e8:3a:d2|VGV7519E83ADB|2412|-83.00 dBm|28.3333|y|y|n|y|y
89:03:55:e8:3a:2b|KPN|2412|-88.00 dBm|20|n|n|n|n|n
62:d1:a3:31:d1:61|Sitecom31D16A|2452|-89.00 dBm|18.3333|n|y|n|n|y

updated with help from Scheff

Parsing iw wlan0 scan output

Here is my final solution based of Sudo_O answer:

$1 == "BSS" {
MAC = $2
wifi[MAC]["enc"] = "Open"
}
$1 == "SSID:" {
wifi[MAC]["SSID"] = $2
}
$1 == "freq:" {
wifi[MAC]["freq"] = $NF
}
$1 == "signal:" {
wifi[MAC]["sig"] = $2 " " $3
}
$1 == "WPA:" {
wifi[MAC]["enc"] = "WPA"
}
$1 == "WEP:" {
wifi[MAC]["enc"] = "WEP"
}
END {
printf "%s\t\t%s\t%s\t\t%s\n","SSID","Frequency","Signal","Encryption"

for (w in wifi) {
printf "%s\t\t%s\t\t%s\t%s\n",wifi[w]["SSID"],wifi[w]["freq"],wifi[w]["sig"],wifi[w]["enc"]
}
}'

Output:

$ sudo iw wlan0 scan | awk -f scan.awk
SSID Frequency Signal Encryption
netti 2437 -31.00 dBm Open
Koti783 2437 -84.00 dBm WPA
WLAN-AP 2462 -85.00 dBm WPA


Related Topics



Leave a reply



Submit