|
|
|
/***************************************************************************
|
|
|
|
interface_wireless_wirelessextensions.cpp - description
|
|
|
|
-------------------
|
|
|
|
begin : Sun May 6 2001
|
|
|
|
copyright : (C) 2001 by Stefan Winter
|
|
|
|
email : mail@stefan-winter.de
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* *
|
|
|
|
* 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 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "interface_wireless_wirelessextensions.h"
|
|
|
|
#include <iwlib.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqtable.h>
|
|
|
|
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
|
|
|
|
#ifndef WITHOUT_ARTS
|
|
|
|
#include <arts/artsflow.h>
|
|
|
|
#include <arts/connect.h>
|
|
|
|
#include <arts/iomanager.h>
|
|
|
|
#include <arts/referenceclean.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef PROC_NET_DEV
|
|
|
|
#define PROC_NET_DEV "/proc/net/dev"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kprocio.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
|
|
// domi:the wireless-tools people managed to change their interfaces
|
|
|
|
// around. Someone with more knowledge of this code should look into
|
|
|
|
// moving to use the new iw_range interfaces.
|
|
|
|
#ifdef HAVE_IW_27
|
|
|
|
|
|
|
|
#ifndef HAVE_IW_27pre19
|
|
|
|
#define WIFI_CONFIG(config,field) config.field
|
|
|
|
#define WIFI_EXTRACT_EVENT_STREAM(stream, event) \
|
|
|
|
iw_extract_event_stream(stream, event)
|
|
|
|
#else
|
|
|
|
#define WIFI_CONFIG(config,field) config.b.field
|
|
|
|
#define WIFI_EXTRACT_EVENT_STREAM(stream, event) \
|
|
|
|
iw_extract_event_stream(stream, event, WIRELESS_EXT)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define WIFI_GET_STATS(skfd, ifname, stats) \
|
|
|
|
iw_get_stats (skfd, ifname, stats, 0, 0)
|
|
|
|
#define WIFI_PRINT_STATS(buff, event) \
|
|
|
|
iw_print_stats(buffer, sizeof(buffer), &event->u.qual, 0, 0);
|
|
|
|
|
|
|
|
#else // HAVE_IW_25
|
|
|
|
#define WIFI_CONFIG(config,field) config.field
|
|
|
|
#define WIFI_EXTRACT_EVENT_STREAM(stream, event) \
|
|
|
|
iw_extract_event_stream(stream, event)
|
|
|
|
#define WIFI_GET_STATS(skfd, ifname, stats) \
|
|
|
|
iw_get_stats (skfd, ifname, stats)
|
|
|
|
#define WIFI_PRINT_STATS(buff, event) \
|
|
|
|
iw_print_stats(buffer, &event->u.qual, 0, 0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* ================================== FROM IWCONFIG.C ================================== */
|
|
|
|
int
|
|
|
|
Interface_wireless_wirelessextensions::get_info (int skfd, const TQString& interface,
|
|
|
|
struct wireless_info& info)
|
|
|
|
{
|
|
|
|
struct iwreq wrq;
|
|
|
|
char ifname[20];
|
|
|
|
snprintf(ifname, sizeof(ifname), "%s", interface.latin1() );
|
|
|
|
memset (&info, 0, sizeof(info));
|
|
|
|
|
|
|
|
/* Get wireless name */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWNAME, &wrq) < 0)
|
|
|
|
{
|
|
|
|
/* If no wireless name : no wireless extensions */
|
|
|
|
/* But let's check if the interface exists at all */
|
|
|
|
struct ifreq ifr;
|
|
|
|
|
|
|
|
strcpy (ifr.ifr_name, ifname);
|
|
|
|
if (ioctl (skfd, SIOCGIFFLAGS, &ifr) < 0)
|
|
|
|
return (-ENODEV);
|
|
|
|
else
|
|
|
|
return (-ENOTSUP);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strncpy (WIFI_CONFIG(info,name), wrq.u.name, IFNAMSIZ);
|
|
|
|
WIFI_CONFIG(info,name)[IFNAMSIZ] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get ranges */
|
|
|
|
if (iw_get_range_info (skfd, ifname, &(info.range)) >= 0)
|
|
|
|
info.has_range = 1;
|
|
|
|
|
|
|
|
/* Get network ID */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWNWID, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
WIFI_CONFIG(info,has_nwid) = 1;
|
|
|
|
memcpy (&(WIFI_CONFIG(info,nwid)), &(wrq.u.nwid), sizeof (iwparam));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get frequency / channel */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWFREQ, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
WIFI_CONFIG(info,has_freq) = 1;
|
|
|
|
WIFI_CONFIG(info,freq) = iw_freq2float (&(wrq.u.freq));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get sensitivity */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWSENS, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
info.has_sens = 1;
|
|
|
|
memcpy (&(info.sens), &(wrq.u.sens), sizeof (iwparam));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get encryption information */
|
|
|
|
wrq.u.data.pointer = (caddr_t) WIFI_CONFIG(info,key);
|
|
|
|
wrq.u.data.length = IW_ENCODING_TOKEN_MAX;
|
|
|
|
wrq.u.data.flags = 0;
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWENCODE, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
WIFI_CONFIG(info,has_key) = 1;
|
|
|
|
WIFI_CONFIG(info,key_size) = wrq.u.data.length;
|
|
|
|
WIFI_CONFIG(info,key_flags) = wrq.u.data.flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get ESSID */
|
|
|
|
/* prepare NULL-terminated buffer in case the string returned by SIOCGIWESSID is NOT NULL-terminated */
|
|
|
|
memset(wrq.u.essid.pointer, '\0', IW_ESSID_MAX_SIZE + 1);
|
|
|
|
wrq.u.essid.pointer = (caddr_t) WIFI_CONFIG(info,essid);
|
|
|
|
wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
|
|
|
|
wrq.u.essid.flags = 0;
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWESSID, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
WIFI_CONFIG(info,has_essid) = 1;
|
|
|
|
WIFI_CONFIG(info,essid_on) = wrq.u.data.flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get AP address */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWAP, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
info.has_ap_addr = 1;
|
|
|
|
memcpy (&(info.ap_addr), &(wrq.u.ap_addr), sizeof (sockaddr));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get NickName */
|
|
|
|
wrq.u.essid.pointer = (caddr_t) info.nickname;
|
|
|
|
wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1;
|
|
|
|
wrq.u.essid.flags = 0;
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWNICKN, &wrq) >= 0)
|
|
|
|
if (wrq.u.data.length > 1)
|
|
|
|
info.has_nickname = 1;
|
|
|
|
|
|
|
|
/* Get bit rate */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWRATE, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
info.has_bitrate = 1;
|
|
|
|
memcpy (&(info.bitrate), &(wrq.u.bitrate), sizeof (iwparam));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get RTS threshold */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWRTS, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
info.has_rts = 1;
|
|
|
|
memcpy (&(info.rts), &(wrq.u.rts), sizeof (iwparam));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get fragmentation threshold */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWFRAG, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
info.has_frag = 1;
|
|
|
|
memcpy (&(info.frag), &(wrq.u.frag), sizeof (iwparam));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get operation mode */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWMODE, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
WIFI_CONFIG(info,mode) = wrq.u.mode;
|
|
|
|
if ((WIFI_CONFIG(info,mode) < IW_NUM_OPER_MODE) && (WIFI_CONFIG(info,mode) >= 0))
|
|
|
|
WIFI_CONFIG(info,has_mode) = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get Power Management settings */
|
|
|
|
wrq.u.power.flags = 0;
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWPOWER, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
info.has_power = 1;
|
|
|
|
memcpy (&(info.power), &(wrq.u.power), sizeof (iwparam));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if WIRELESS_EXT > 9
|
|
|
|
/* Get Transmit Power and check if it is disabled */
|
|
|
|
bool emitTXPowerChanged = false;
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWTXPOW, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
if (txpower_disabled != info.txpower.disabled)
|
|
|
|
{
|
|
|
|
emitTXPowerChanged = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
info.has_txpower = 1;
|
|
|
|
memcpy (&(info.txpower), &(wrq.u.txpower), sizeof (iwparam));
|
|
|
|
}
|
|
|
|
has_txpower = info.has_txpower;
|
|
|
|
txpower_disabled = ( int )info.txpower.disabled;
|
|
|
|
if (emitTXPowerChanged)
|
|
|
|
{
|
|
|
|
emit txPowerChanged();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if WIRELESS_EXT > 10
|
|
|
|
/* Get retry limit/lifetime */
|
|
|
|
if (iw_get_ext (skfd, ifname, SIOCGIWRETRY, &wrq) >= 0)
|
|
|
|
{
|
|
|
|
info.has_retry = 1;
|
|
|
|
memcpy (&(info.retry), &(wrq.u.retry), sizeof (iwparam));
|
|
|
|
}
|
|
|
|
#endif /* WIRELESS_EXT > 10 */
|
|
|
|
|
|
|
|
/* Get stats */
|
|
|
|
if (WIFI_GET_STATS (skfd, (char *) ifname, &(info.stats)) >= 0)
|
|
|
|
{
|
|
|
|
info.has_stats = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ================================ END IWCONFIG.C ================================ */
|
|
|
|
|
|
|
|
|
|
|
|
Interface_wireless_wirelessextensions::Interface_wireless_wirelessextensions (TQStringList * ignoreInterfaces)
|
|
|
|
: Interface_wireless(ignoreInterfaces)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Interface_wireless_wirelessextensions::isSocketOpen()
|
|
|
|
{
|
|
|
|
if (socket <= 0)
|
|
|
|
socket = iw_sockets_open ();
|
|
|
|
|
|
|
|
return (socket > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interface_wireless_wirelessextensions::setActiveDevice( TQString device )
|
|
|
|
{
|
|
|
|
kdDebug () << "activating wireless device " << device << endl;
|
|
|
|
interface_name = device;
|
|
|
|
|
|
|
|
if (!isSocketOpen())
|
|
|
|
return;
|
|
|
|
|
|
|
|
emit interfaceChanged ();
|
|
|
|
emit strengthChanged ();
|
|
|
|
emit statusChanged ();
|
|
|
|
emit modeChanged ();
|
|
|
|
emit speedChanged ();
|
|
|
|
valid[current] = false;
|
|
|
|
emit statsUpdated ();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Interface_wireless_wirelessextensions::setNoActiveDevice( )
|
|
|
|
{
|
|
|
|
// interface has disappeared - unplugged?
|
|
|
|
// reset all info except stats
|
|
|
|
has_frequency = false;
|
|
|
|
frequency = 0.0;
|
|
|
|
has_mode = false;
|
|
|
|
mode = 0;
|
|
|
|
has_key = 0;
|
|
|
|
key = TQString::null;
|
|
|
|
key_size = 0;
|
|
|
|
key_flags = 0;
|
|
|
|
essid = TQString::null;
|
|
|
|
access_point_address = TQString::null;
|
|
|
|
ip_address = TQString::null;
|
|
|
|
bitrate = 0;
|
|
|
|
has_range = false;
|
|
|
|
has_txpower = false;
|
|
|
|
txpower_disabled = 0;
|
|
|
|
|
|
|
|
// propagate the changes
|
|
|
|
setActiveDevice( TQString::null );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList Interface_wireless_wirelessextensions::available_wifi_devices()
|
|
|
|
{
|
|
|
|
TQFile procnetdev(PROC_NET_DEV);
|
|
|
|
procnetdev.open (IO_ReadOnly);
|
|
|
|
|
|
|
|
kdDebug () << "Autodetecting..." << endl;
|
|
|
|
|
|
|
|
TQStringList liste;
|
|
|
|
TQString device;
|
|
|
|
while (!procnetdev.atEnd()) {
|
|
|
|
procnetdev.readLine (device, 9999);
|
|
|
|
int pos = device.find (':');
|
|
|
|
if (pos == -1)
|
|
|
|
continue;
|
|
|
|
device = device.left(pos).stripWhiteSpace();
|
|
|
|
if (device.isEmpty())
|
|
|
|
continue;
|
|
|
|
// Some drivers create two interfaces, ethX and wifiX. The
|
|
|
|
// wifiX device are not useful to users because they only
|
|
|
|
// control the physical wlan settings, not the logical ones. If
|
|
|
|
// we find a wifiX device then we move it to the start of the
|
|
|
|
// list which means the first instance of KWifiManger will pick
|
|
|
|
// up the ethX and only the second instance will pick up the
|
|
|
|
// wifiX.
|
|
|
|
if (device.startsWith("wifi"))
|
|
|
|
liste.prepend(device);
|
|
|
|
else
|
|
|
|
liste.append(device);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (liste.isEmpty())
|
|
|
|
kdDebug () << "No wireless interface found." << endl;
|
|
|
|
|
|
|
|
return liste;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Interface_wireless_wirelessextensions::autodetect_device()
|
|
|
|
{
|
|
|
|
if (!isSocketOpen())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQStringList liste = available_wifi_devices();
|
|
|
|
|
|
|
|
for (TQStringList::Iterator it = liste.begin (); it != liste.end (); ++it)
|
|
|
|
{
|
|
|
|
TQString device = *it;
|
|
|
|
kdDebug () << "[ " << device << " ] " << endl;
|
|
|
|
wireless_info info;
|
|
|
|
int result = get_info (socket, device, info);
|
|
|
|
if ((result != -ENODEV) && (result != -ENOTSUP) &&
|
|
|
|
(!ignoreInterfaces || ignoreInterfaces->findIndex(device)==-1))
|
|
|
|
{
|
|
|
|
setActiveDevice(device);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (interface_name.isEmpty())
|
|
|
|
{
|
|
|
|
close(socket);
|
|
|
|
socket = -1;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Interface_wireless_wirelessextensions::poll_device_info ()
|
|
|
|
{
|
|
|
|
if (current < MAX_HISTORY-1)
|
|
|
|
++current;
|
|
|
|
else
|
|
|
|
current = 0;
|
|
|
|
|
|
|
|
if (interface_name.isEmpty())
|
|
|
|
if (!autodetect_device())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
wireless_info info;
|
|
|
|
int result = get_info (socket, interface_name, info);
|
|
|
|
if ((result == -ENODEV) || (result == -ENOTSUP))
|
|
|
|
{
|
|
|
|
// interface has disappeared - unplugged?
|
|
|
|
// reset all info except stats
|
|
|
|
setNoActiveDevice();
|
|
|
|
|
|
|
|
close(socket);
|
|
|
|
socket = -1;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
emitStatusChanged = false, emitModeChanged = false, emitEssidChanged =
|
|
|
|
false, emitSpeedChanged = false, emitStrengthChanged = false;
|
|
|
|
|
|
|
|
iwstats tempic2;
|
|
|
|
WIFI_GET_STATS (socket, (char *) interface_name.latin1(), &tempic2);
|
|
|
|
has_frequency = WIFI_CONFIG(info,has_freq);
|
|
|
|
if (has_frequency)
|
|
|
|
{
|
|
|
|
if (frequency != WIFI_CONFIG(info,freq))
|
|
|
|
emitStatusChanged = true;
|
|
|
|
frequency = WIFI_CONFIG(info,freq);
|
|
|
|
}
|
|
|
|
has_mode = WIFI_CONFIG(info,has_mode);
|
|
|
|
if (has_mode)
|
|
|
|
{
|
|
|
|
if (mode != WIFI_CONFIG(info,mode))
|
|
|
|
emitModeChanged = true;
|
|
|
|
mode = WIFI_CONFIG(info,mode);
|
|
|
|
}
|
|
|
|
has_key = WIFI_CONFIG(info,has_key);
|
|
|
|
if (has_key)
|
|
|
|
{
|
|
|
|
if ((key != (char *) WIFI_CONFIG(info,key)) || (key_size != WIFI_CONFIG(info,key_size))
|
|
|
|
|| (key_flags != WIFI_CONFIG(info,key_flags)))
|
|
|
|
emitStatusChanged = true;
|
|
|
|
key = (char *) WIFI_CONFIG(info,key);
|
|
|
|
key_size = WIFI_CONFIG(info,key_size);
|
|
|
|
key_flags = WIFI_CONFIG(info,key_flags);
|
|
|
|
}
|
|
|
|
if (essid != WIFI_CONFIG(info,essid))
|
|
|
|
{
|
|
|
|
emitStatusChanged = true;
|
|
|
|
emitEssidChanged = true;
|
|
|
|
}
|
|
|
|
essid = (WIFI_CONFIG(info,essid_on) ? WIFI_CONFIG(info,essid) : "any");
|
|
|
|
char
|
|
|
|
ap_addr[256];
|
|
|
|
iw_ether_ntop ( (const ether_addr *) info.ap_addr.sa_data, ap_addr);
|
|
|
|
if (access_point_address != ap_addr)
|
|
|
|
emitStatusChanged = true;
|
|
|
|
access_point_address = ap_addr;
|
|
|
|
if (bitrate != info.bitrate.value)
|
|
|
|
emitSpeedChanged = true;
|
|
|
|
bitrate = info.bitrate.value;
|
|
|
|
has_range = info.has_range;
|
|
|
|
|
|
|
|
sigLevel[current] = tempic2.qual.level;
|
|
|
|
noiseLevel[current] = tempic2.qual.noise;
|
|
|
|
|
|
|
|
if (has_range) {
|
|
|
|
|
|
|
|
range = info.range.max_qual.qual;
|
|
|
|
|
|
|
|
// the following checks adjust values for sig levels that are in dBm
|
|
|
|
// according to iwlib.c. If offset is applied, the resulting
|
|
|
|
// value is negative and the GUI knows it can add the scale
|
|
|
|
// unit dBm.
|
|
|
|
|
|
|
|
if (tempic2.qual.level > info.range.max_qual.level) {
|
|
|
|
sigLevel[current] = tempic2.qual.level - 0x100;
|
|
|
|
noiseLevel[current] = tempic2.qual.noise - 0x100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sigLevel[current] < sigLevelMin)
|
|
|
|
sigLevelMin = sigLevel[current];
|
|
|
|
if (sigLevel[current] > sigLevelMax)
|
|
|
|
sigLevelMax = sigLevel[current];
|
|
|
|
|
|
|
|
if (noiseLevel[current] < noiseLevelMin)
|
|
|
|
noiseLevelMin = noiseLevel[current];
|
|
|
|
if (noiseLevel[current] > noiseLevelMax)
|
|
|
|
noiseLevelMax = noiseLevel[current];
|
|
|
|
int
|
|
|
|
tempqual = tempic2.qual.qual;
|
|
|
|
if (has_range && (range != 0))
|
|
|
|
tempqual = tempqual * 100 / range;
|
|
|
|
if ( qual[current != 0 ? current - 1 : MAX_HISTORY-1] != tempqual)
|
|
|
|
emitStrengthChanged = true;
|
|
|
|
|
|
|
|
qual[current] = ( tempqual <= 100 ? tempqual : 100 );
|
|
|
|
valid[current] = true;
|
|
|
|
|
|
|
|
// try to get our local IP address
|
|
|
|
struct sockaddr *
|
|
|
|
sa;
|
|
|
|
struct sockaddr_in *
|
|
|
|
sin;
|
|
|
|
struct ifreq
|
|
|
|
ifr;
|
|
|
|
/* Copy the interface name into the buffer */
|
|
|
|
strncpy (ifr.ifr_name, interface_name.latin1 (), IFNAMSIZ);
|
|
|
|
|
|
|
|
if (ioctl (socket, SIOCGIFADDR, &ifr) == -1)
|
|
|
|
{
|
|
|
|
if (ip_address != "unavailable")
|
|
|
|
emitStatusChanged = true;
|
|
|
|
ip_address = "unavailable";
|
|
|
|
}
|
|
|
|
/* Now the buffer will contain the information we requested */
|
|
|
|
sa = (struct sockaddr *) &(ifr.ifr_addr);
|
|
|
|
if (sa->sa_family == AF_INET)
|
|
|
|
{
|
|
|
|
sin = (struct sockaddr_in *) sa;
|
|
|
|
if (ip_address != (TQString) inet_ntoa (sin->sin_addr))
|
|
|
|
emitStatusChanged = true;
|
|
|
|
ip_address = (TQString) inet_ntoa (sin->sin_addr);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ip_address = "unavailable";
|
|
|
|
}
|
|
|
|
if (emitStatusChanged)
|
|
|
|
emit statusChanged ();
|
|
|
|
if (emitStrengthChanged)
|
|
|
|
emit strengthChanged ();
|
|
|
|
if (emitModeChanged)
|
|
|
|
emit modeChanged ();
|
|
|
|
if (emitSpeedChanged)
|
|
|
|
emit speedChanged ();
|
|
|
|
if (emitEssidChanged)
|
|
|
|
emit essidChanged (essid);
|
|
|
|
emit statsUpdated ();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQTable* Interface_wireless_wirelessextensions::get_available_networks ()
|
|
|
|
{
|
|
|
|
|
|
|
|
networks = new TQTable(0,4,0);
|
|
|
|
networks->horizontalHeader()->setLabel( 0, i18n("Network Name") );
|
|
|
|
networks->horizontalHeader()->setLabel( 1, i18n("Mode") );
|
|
|
|
networks->horizontalHeader()->setLabel( 2, i18n("Quality") );
|
|
|
|
networks->horizontalHeader()->setLabel( 3, i18n("WEP") );
|
|
|
|
|
|
|
|
KProcIO *iwlist = new KProcIO;
|
|
|
|
TQString iwlist_bin = KStandardDirs::findExe("iwlist");
|
|
|
|
if(iwlist_bin.isEmpty())
|
|
|
|
iwlist_bin = KStandardDirs::findExe("iwlist", "/usr/local/sbin:/usr/sbin:/sbin");
|
|
|
|
if(iwlist_bin.isEmpty())
|
|
|
|
iwlist_bin = "iwlist"; // try our best ;/
|
|
|
|
|
|
|
|
*iwlist << iwlist_bin << interface_name << "scanning";
|
|
|
|
|
|
|
|
// connect ( iwlist, TQT_SIGNAL ( readReady ( KProcIO * ) ), this, TQT_SLOT ( parseScanData ( KProcIO * ) ) );
|
|
|
|
|
|
|
|
if ( !iwlist->start ( KProcess::Block ) )
|
|
|
|
KMessageBox::sorry ( 0, i18n ( "Unable to perform the scan. Please make sure the executable \"iwlist\" is in your $PATH." ),
|
|
|
|
i18n ( "Scanning not possible" ) );
|
|
|
|
|
|
|
|
// this should never happen. But there was a report about Block not being as blocking as it should, so let's be safe about it
|
|
|
|
while (iwlist->isRunning()) sleep ( 1 );
|
|
|
|
|
|
|
|
parseScanData ( iwlist );
|
|
|
|
|
|
|
|
for (int i = 0; i<4; i++ ) networks->adjustColumn(i);
|
|
|
|
|
|
|
|
return networks;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
Interface_wireless_wirelessextensions::parseScanData ( KProcIO * iwlist )
|
|
|
|
{
|
|
|
|
TQString data;
|
|
|
|
int cellcount = 0, iteratecount = 0;
|
|
|
|
bool ignoreRemainingBits = false;
|
|
|
|
while ( iwlist->readln ( data, true ) >= 0 )
|
|
|
|
{
|
|
|
|
kdDebug ( ) << "iwlist: " << data << "\n";
|
|
|
|
if ( data.contains ( "does not support scanning" ) )
|
|
|
|
KMessageBox::sorry ( 0,
|
|
|
|
i18n
|
|
|
|
( "Your card does not support scanning. The results window will not contain any results." ),
|
|
|
|
i18n ( "Scanning not possible" ) );
|
|
|
|
if ( data.contains ( "Scan completed" ) )
|
|
|
|
cellcount = 0; // at the very beginning of a scan
|
|
|
|
if ( data.contains ( "Cell" ) ) {
|
|
|
|
cellcount++; // new cell discovered
|
|
|
|
networks->setNumRows ( networks->numRows() +1 );
|
|
|
|
ignoreRemainingBits = false;
|
|
|
|
}
|
|
|
|
if ( data.contains ( "ESSID:" ) )
|
|
|
|
{
|
|
|
|
TQString ssid = data.mid ( data.find ( "\"" ) + 1, data.length ( ) - data.find ( "\"" ) - 2 );
|
|
|
|
if ((ssid=="") || (ssid==" ")) ssid = "(hidden cell)";
|
|
|
|
networks->setText ( cellcount - 1, 0, ssid );
|
|
|
|
}
|
|
|
|
if ( data.contains ( "Mode:" ) )
|
|
|
|
{
|
|
|
|
if ( data.contains ( "Master" ) )
|
|
|
|
networks->setText ( cellcount - 1, 1, TQString ( i18n ( "Managed" ) ) );
|
|
|
|
if ( data.contains ( "Ad-Hoc" ) )
|
|
|
|
networks->setText ( cellcount - 1, 1, TQString ( i18n ( "Ad-Hoc" ) ) );
|
|
|
|
// if could be that this cell belongs to an SSID already discovered, or that there are more than one
|
|
|
|
// hidden cells, which doesn't give any new information. So, we first search for duplicates and delete
|
|
|
|
// this row if it's a duplicate. If the same SSID is there once as Managed and once as Ad-Hoc it is no
|
|
|
|
// duplicate of course, but "something completely different"
|
|
|
|
for (iteratecount = 0; iteratecount < cellcount - 1; iteratecount++)
|
|
|
|
{
|
|
|
|
kdDebug() << "Comparing <" << networks->text(cellcount - 1, 0) << "," << networks->text(iteratecount,0) << " and <"
|
|
|
|
<< networks->text(cellcount - 1, 1) << "," << networks->text(iteratecount,1) << ">.\n";
|
|
|
|
if ((networks->text(cellcount - 1 , 0) == networks->text(iteratecount,0)) &&
|
|
|
|
(networks->text(cellcount - 1 , 1) == networks->text(iteratecount,1)) )
|
|
|
|
{
|
|
|
|
networks->setNumRows ( networks->numRows() - 1 );
|
|
|
|
cellcount--;
|
|
|
|
ignoreRemainingBits = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( !ignoreRemainingBits && data.contains ( "Encryption key:" ) )
|
|
|
|
{
|
|
|
|
if ( data.contains ( "off" ) )
|
|
|
|
networks->setText ( cellcount - 1, 3, TQString ( "off" ) );
|
|
|
|
else
|
|
|
|
networks->setText ( cellcount - 1, 3, TQString ( "on" ) );
|
|
|
|
}
|
|
|
|
if ( !ignoreRemainingBits && data.contains ( "Quality:" ) )
|
|
|
|
{
|
|
|
|
TQString quality = data.mid ( data.find ( ":" ) + 1, data.find ( "/" ) - data.find ( ":" ) - 1 );
|
|
|
|
networks->setText ( cellcount - 1, 2, quality );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !ignoreRemainingBits && data.contains ( "Quality=" ) )
|
|
|
|
{
|
|
|
|
TQString quality = data.mid ( data.find ( "=" ) + 1, data.find ( "/" ) - data.find ( "=" ) - 1 );
|
|
|
|
networks->setText ( cellcount - 1, 2, quality );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !ignoreRemainingBits && data.contains ( "wpa_ie" ) )
|
|
|
|
{
|
|
|
|
networks->setText ( cellcount - 1, 3, TQString ( "WPA" ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !ignoreRemainingBits && data.contains ( "rsn_ie" ) )
|
|
|
|
{
|
|
|
|
networks->setText ( cellcount - 1, 3, TQString ( "WPA2" ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "interface_wireless_wirelessextensions.moc"
|