-rw-r--r-- | libopie2/opienet/onetwork.cpp | 21 |
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";
}
- -} -} +
+}
+}
|