summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetwork.cpp21
1 files changed, 11 insertions, 10 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index ab3e77f..26a6c81 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -1,168 +1,168 @@
/*
                This file is part of the Opie Project
              Copyright (C) 2003-2004 by Michael 'Mickey' Lauer
=. <mickey@Vanille.de>
.=l.
           .>+-=
 _;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
 - .   .-<_>     .<> Foundation; either version 2 of the License,
     ._= =}       : or (at your option) any later version.
    .%`+i>       _;_.
    .i_,=:_.      -<s. 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
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
 :     =  ...= . :.=-
 -.   .:....=;==+<; You should have received a copy of the GNU
  -_. . .   )=.  = Library General Public License along with
    --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/* OPIE */
#include <opie2/onetwork.h>
#include <opie2/ostation.h>
#include <opie2/odebug.h>
/* QT */
#include <qfile.h>
#include <qtextstream.h>
/* UNIX */
#include <assert.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/sockios.h>
#include <net/if_arp.h>
#include <stdarg.h>
#ifndef NODEBUG
#include <opie2/odebugmapper.h>
-
-
-using namespace Opie::Core;
-using namespace Opie::Net::Private;
+
+
+using namespace Opie::Core;
+using namespace Opie::Net::Private;
DebugMapper* debugmapper = new DebugMapper();
#endif
/*======================================================================================
* ONetwork
*======================================================================================*/
-namespace Opie {
-namespace Net {
+namespace Opie {
+namespace Net {
ONetwork* ONetwork::_instance = 0;
ONetwork::ONetwork()
{
odebug << "ONetwork::ONetwork()" << oendl;
odebug << "ONetwork: This code has been compiled against Wireless Extensions V" << WIRELESS_EXT << oendl;
synchronize();
}
void ONetwork::synchronize()
{
// gather available interfaces by inspecting /proc/net/dev
//FIXME: we could use SIOCGIFCONF here, but we aren't interested in virtual (e.g. eth0:0) devices
//FIXME: Use SIOCGIFCONF anway, because we can disable listing of aliased devices
//FIXME: Best is use SIOCGIFCONF and if this doesn't work (result=-1), then fallback to parsing /proc/net/dev
_interfaces.clear();
QString str;
QFile f( "/proc/net/dev" );
bool hasFile = f.open( IO_ReadOnly );
if ( !hasFile )
{
odebug << "ONetwork: /proc/net/dev not existing. No network devices available" << oendl;
return;
}
QTextStream s( &f );
s.readLine();
s.readLine();
while ( !s.atEnd() )
{
s >> str;
str.truncate( str.find( ':' ) );
odebug << "ONetwork: found interface '" << str << "'" << oendl;
ONetworkInterface* iface;
if ( isWirelessInterface( str ) )
{
iface = new OWirelessNetworkInterface( this, (const char*) str );
odebug << "ONetwork: interface '" << str << "' has Wireless Extensions" << oendl;
}
else
{
iface = new ONetworkInterface( this, (const char*) str );
}
_interfaces.insert( str, iface );
s.readLine();
}
}
short ONetwork::wirelessExtensionVersion()
{
return WIRELESS_EXT;
}
int ONetwork::count() const
{
return _interfaces.count();
}
ONetworkInterface* ONetwork::interface( const QString& iface ) const
{
return _interfaces[iface];
}
ONetwork* ONetwork::instance()
{
if ( !_instance ) _instance = new ONetwork();
return _instance;
}
ONetwork::InterfaceIterator ONetwork::iterator() const
{
return ONetwork::InterfaceIterator( _interfaces );
}
bool ONetwork::isPresent( const char* name ) const
{
int sfd = socket( AF_INET, SOCK_STREAM, 0 );
struct ifreq ifr;
memset( &ifr, 0, sizeof( struct ifreq ) );
strcpy( (char*) &ifr.ifr_name, name );
int result = ::ioctl( sfd, SIOCGIFFLAGS, &ifr );
return result != -1;
}
bool ONetwork::isWirelessInterface( const char* name ) const
{
int sfd = socket( AF_INET, SOCK_STREAM, 0 );
struct iwreq iwr;
memset( &iwr, 0, sizeof( struct iwreq ) );
@@ -913,193 +913,194 @@ OStationList* OWirelessNetworkInterface::scanNetwork()
odebug << "ONetworkInterface::scanNetwork() - scan finished." << oendl;
if ( results )
{
odebug << " - result length = " << _iwr.u.data.length << oendl;
if ( !_iwr.u.data.length )
{
odebug << " - no results (empty neighbourhood)" << oendl;
return stations;
}
odebug << " - results are in!" << oendl;
dumpBytes( (const unsigned char*) &buffer[0], _iwr.u.data.length );
// parse results
int offset = 0;
struct iw_event* we = (struct iw_event*) &buffer[0];
while ( offset < _iwr.u.data.length )
{
//const char* cmd = *(*_ioctlmap)[we->cmd];
//if ( !cmd ) cmd = "<unknown>";
odebug << " - reading next event... cmd=" << we->cmd << ", len=" << we->len << oendl;
switch (we->cmd)
{
case SIOCGIWAP:
{
odebug << "SIOCGIWAP" << oendl;
stations->append( new OStation() );
stations->last()->macAddress = (const unsigned char*) &we->u.ap_addr.sa_data[0];
break;
}
case SIOCGIWMODE:
{
odebug << "SIOCGIWMODE" << oendl;
stations->last()->type = modeToString( we->u.mode );
break;
}
case SIOCGIWFREQ:
{
odebug << "SIOCGIWFREQ" << oendl;
stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ];
break;
}
case SIOCGIWESSID:
{
odebug << "SIOCGIWESSID" << oendl;
stations->last()->ssid = we->u.essid.pointer;
break;
}
case SIOCGIWSENS: odebug << "SIOCGIWSENS" << oendl; break;
case SIOCGIWENCODE: odebug << "SIOCGIWENCODE" << oendl; break;
case IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break; /* Packet dropped to excessive retry */
case IWEVQUAL: odebug << "IWEVQUAL" << oendl; break; /* Quality part of statistics (scan) */
case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break; /* Driver specific ascii string */
case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break; /* Discovered a new node (AP mode) */
case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break; /* Expired a node (AP mode) */
default: odebug << "unhandled event" << oendl;
}
offset += we->len;
we = (struct iw_event*) &buffer[offset];
}
return stations;
return stations;
}
else
{
odebug << " - no results (timeout) :(" << oendl;
return stations;
}
}
int OWirelessNetworkInterface::signalStrength() const
{
iw_statistics stat;
::memset( &stat, 0, sizeof stat );
_iwr.u.data.pointer = (char*) &stat;
_iwr.u.data.flags = 0;
_iwr.u.data.length = sizeof stat;
if ( !wioctl( SIOCGIWSTATS ) )
{
return -1;
}
int max = _range.max_qual.qual;
int cur = stat.qual.qual;
int lev = stat.qual.level; //FIXME: Do something with them?
int noi = stat.qual.noise; //FIXME: Do something with them?
- return cur*100/max;
+
+ return max != 0 ? cur*100/max: -1;
}
bool OWirelessNetworkInterface::wioctl( int call, struct iwreq& iwreq ) const
{
#ifndef NODEBUG
int result = ::ioctl( _sfd, call, &iwreq );
if ( result == -1 )
odebug << "ONetworkInterface::wioctl (" << name() << ") call '"
<< debugmapper->map( call ) << "' FAILED! " << result << " (" << strerror( errno ) << ")" << oendl;
else
odebug << "ONetworkInterface::wioctl (" << name() << ") call '"
<< debugmapper->map( call ) << "' - Status: Ok." << oendl;
return ( result != -1 );
#else
return ::ioctl( _sfd, call, &iwreq ) != -1;
#endif
}
bool OWirelessNetworkInterface::wioctl( int call ) const
{
strcpy( _iwr.ifr_name, name() );
return wioctl( call, _iwr );
}
/*======================================================================================
* OMonitoringInterface
*======================================================================================*/
OMonitoringInterface::OMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
:_if( static_cast<OWirelessNetworkInterface*>( iface ) ), _prismHeader( prismHeader )
{
}
OMonitoringInterface::~OMonitoringInterface()
{
}
void OMonitoringInterface::setChannel( int c )
{
// use standard WE channel switching protocol
memset( &_if->_iwr, 0, sizeof( struct iwreq ) );
_if->_iwr.u.freq.m = c;
_if->_iwr.u.freq.e = 0;
_if->wioctl( SIOCSIWFREQ );
}
void OMonitoringInterface::setEnabled( bool b )
{
}
/*======================================================================================
* OCiscoMonitoringInterface
*======================================================================================*/
OCiscoMonitoringInterface::OCiscoMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
:OMonitoringInterface( iface, prismHeader )
{
iface->setMonitoring( this );
}
OCiscoMonitoringInterface::~OCiscoMonitoringInterface()
{
}
void OCiscoMonitoringInterface::setEnabled( bool b )
{
QString fname;
fname.sprintf( "/proc/driver/aironet/%s", (const char*) _if->name() );
QFile f( fname );
if ( !f.exists() ) return;
if ( f.open( IO_WriteOnly ) )
{
QTextStream s( &f );
s << "Mode: r";
s << "Mode: y";
s << "XmitPower: 1";
}
// flushing and closing will be done automatically when f goes out of scope
}
QString OCiscoMonitoringInterface::name() const
{
@@ -1150,99 +1151,99 @@ QString OWlanNGMonitoringInterface::name() const
void OWlanNGMonitoringInterface::setChannel( int c )
{
//NOTE: Older wlan-ng drivers automatically hopped channels while lnxreq_wlansniff=true. Newer ones don't.
QString enable = "true"; //_if->monitorMode() ? "true" : "false";
QString prism = _prismHeader ? "true" : "false";
QString cmd;
cmd.sprintf( "$(which wlanctl-ng) %s lnxreq_wlansniff channel=%d enable=%s prismheader=%s",
(const char*) _if->name(), c, (const char*) enable, (const char*) prism );
system( cmd );
}
/*======================================================================================
* OHostAPMonitoringInterface
*======================================================================================*/
OHostAPMonitoringInterface::OHostAPMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
:OMonitoringInterface( iface, prismHeader )
{
iface->setMonitoring( this );
}
OHostAPMonitoringInterface::~OHostAPMonitoringInterface()
{
}
void OHostAPMonitoringInterface::setEnabled( bool b )
{
int monitorCode = _prismHeader ? 1 : 2;
if ( b )
{
_if->setPrivate( "monitor", 1, monitorCode );
}
else
{
_if->setPrivate( "monitor", 1, 0 );
}
}
QString OHostAPMonitoringInterface::name() const
{
return "hostap";
}
/*======================================================================================
* OOrinocoNetworkInterface
*======================================================================================*/
OOrinocoMonitoringInterface::OOrinocoMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
:OMonitoringInterface( iface, prismHeader )
{
iface->setMonitoring( this );
}
OOrinocoMonitoringInterface::~OOrinocoMonitoringInterface()
{
}
void OOrinocoMonitoringInterface::setChannel( int c )
{
if ( !_if->hasPrivate( "monitor" ) )
{
this->OMonitoringInterface::setChannel( c );
}
else
{
int monitorCode = _prismHeader ? 1 : 2;
_if->setPrivate( "monitor", 2, monitorCode, c );
}
}
void OOrinocoMonitoringInterface::setEnabled( bool b )
{
if ( b )
{
setChannel( 1 );
}
else
{
_if->setPrivate( "monitor", 2, 0, 0 );
}
}
QString OOrinocoMonitoringInterface::name() const
{
return "orinoco";
}
-
-}
-}
+
+}
+}