summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--libopie2/examples/opiecore/odebugdemo/odebugdemo.pro3
-rw-r--r--libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp37
-rw-r--r--libopie2/opienet/onetwork.cpp98
-rw-r--r--libopie2/opienet/onetwork.h16
4 files changed, 103 insertions, 51 deletions
diff --git a/libopie2/examples/opiecore/odebugdemo/odebugdemo.pro b/libopie2/examples/opiecore/odebugdemo/odebugdemo.pro
index c52cd02..aa37394 100644
--- a/libopie2/examples/opiecore/odebugdemo/odebugdemo.pro
+++ b/libopie2/examples/opiecore/odebugdemo/odebugdemo.pro
@@ -1,19 +1,20 @@
TEMPLATE = app
CONFIG = qt warn_on debug
HEADERS =
SOURCES = odebugdemo.cpp
INCLUDEPATH += $(OPIEDIR)/include
DEPENDPATH += $(OPIEDIR)/include
LIBS += -lopiecore2
TARGET = odebugdemo
-MOC_DIR = moc
OBJECTS_DIR = obj
!contains( platform, x11 ) {
include ( $(OPIEDIR)/include.pro )
}
contains( platform, x11 ) {
LIBS += -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib
}
+
+MOC_DIR = moc
diff --git a/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp b/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp
index 21026e1..06b8b19 100644
--- a/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp
+++ b/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp
@@ -1,107 +1,142 @@
#include <opie2/onetwork.h>
#include <opie2/ostation.h>
#include <opie2/omanufacturerdb.h>
+#include <unistd.h>
+
int main( int argc, char** argv )
{
qDebug( "OPIE Network Demo" );
ONetwork* net = ONetwork::instance();
ONetwork::InterfaceIterator it = net->iterator();
while ( it.current() )
{
qDebug( "DEMO: ONetwork contains Interface '%s'", (const char*) it.current()->name() );
+ qDebug( "DEMO: Datalink code is '%d'", it.current()->dataLinkType() );
qDebug( "DEMO: MAC Address is '%s'", (const char*) it.current()->macAddress().toString() );
qDebug( "DEMO: MAC Address is '%s'", (const char*) it.current()->macAddress().toString(true) );
qDebug( "DEMO: MAC Manufacturer seems to be '%s'", (const char*) it.current()->macAddress().manufacturer() );
qDebug( "DEMO: Manufacturertest1 = '%s'", (const char*) OManufacturerDB::instance()->lookupExt( "08:00:87" ) );
qDebug( "DEMO: Manufacturertest2 = '%s'", (const char*) OManufacturerDB::instance()->lookupExt( "E2:0C:0F" ) );
qDebug( "Demo: IPv4 Address is '%s'", (const char*) it.current()->ipV4Address() );
if ( it.current()->isWireless() )
{
OWirelessNetworkInterface* iface = static_cast<OWirelessNetworkInterface*>( it.current() );
qDebug( "DEMO: '%s' seems to feature the wireless extensions.", (const char*) iface->name() );
qDebug( "DEMO: Current SSID is '%s'", (const char*) iface->SSID() );
qDebug( "DEMO: Antenna is tuned to '%f', that is channel %d", iface->frequency(), iface->channel() );
//if ( iface->mode() == OWirelessNetworkInterface::adhoc )
//{
- qDebug( "DEMO: Associated AP has MAC Address '%s'", (const char*) iface->associatedAP().toString() );
+ //qDebug( "DEMO: Associated AP has MAC Address '%s'", (const char*) iface->associatedAP().toString() );
//}
+ /*
+
// nickname
qDebug( "DEMO: Current NickName is '%s'", (const char*) iface->nickName() );
iface->setNickName( "MyNickName" );
if ( iface->nickName() != "MyNickName" )
qDebug( "DEMO: Warning! Can't change nickname" );
else
qDebug( "DEMO: Nickname change successful." );
+ /*
+
// operation mode
qDebug( "DEMO: Current OperationMode is '%s'", (const char*) iface->mode() );
iface->setMode( "adhoc" );
if ( iface->mode() != "adhoc" )
qDebug( "DEMO: Warning! Can't change operation mode" );
else
qDebug( "DEMO: Operation Mode change successful." );
// RF channel
qDebug( "DEMO: Current Channel is '%d'", iface->channel() );
iface->setChannel( 1 );
if ( iface->channel() != 1 )
qDebug( "DEMO: Warning! Can't change RF channel" );
else
qDebug( "DEMO: RF channel change successful." );
iface->setMode( "managed" );
+ */
+
+ /*
+
// network scan
OStationList* stations = iface->scanNetwork();
if ( stations )
{
qDebug( "DEMO: # of stations around = %d", stations->count() );
OStation* station;
for ( station = stations->first(); station != 0; station = stations->next() )
{
qDebug( "DEMO: station dump following..." );
station->dump();
}
}
else
{
qDebug( "DEMO: Warning! Scan didn't work!" );
}
/*
// first some wrong calls to check if this is working
iface->setPrivate( "seppel", 10 );
iface->setPrivate( "monitor", 0 );
// now the real deal
iface->setPrivate( "monitor", 2, 2, 3 );
// trying to set hw address to 12:34:56:AB:CD:EF
/*
OMacAddress addr = OMacAddress::fromString( "12:34:56:AB:CD:EF" );
iface->setUp( false );
iface->setMacAddress( addr );
iface->setUp( true );
qDebug( "DEMO: MAC Address now is '%s'", (const char*) iface->macAddress().toString() );
*/
+ // monitor test
+
+ /*
+
+ qDebug( "DEMO: current interface mode is '%s'", (const char*) iface->mode() );
+ iface->setMode( "monitor" );
+ qDebug( "DEMO: current interface mode is '%s'", (const char*) iface->mode() );
+
+ sleep( 1 ); */
+
+ iface->setMode( "master" );
+
+ //sleep( 1 );
+ qDebug( "DEMO: current interface mode is '%s'", (const char*) iface->mode() );
+
+ /*iface->setMode( "adhoc" );
+ sleep( 1 );
+ qDebug( "DEMO: current interface mode is '%s'", (const char*) iface->mode() );
+ iface->setMode( "managed" );
+ sleep( 1 );
+ qDebug( "DEMO: current interface mode is '%s'", (const char*) iface->mode() );
+ iface->setMode( "master" );
+ sleep( 1 );
+ qDebug( "DEMO: current interface mode is '%s'", (const char*) iface->mode() );*/
}
++it;
}
return 0;
}
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index 50c6679..c329e9a 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -420,755 +420,773 @@ void OChannelHopper::setInterval( int interval )
if ( interval == _interval )
return;
if ( _interval )
killTimer( _tid );
_tid = 0;
_interval = interval;
if ( _interval )
{
_tid = startTimer( interval );
}
}
int OChannelHopper::interval() const
{
return _interval;
}
/*======================================================================================
* OWirelessNetworkInterface
*======================================================================================*/
OWirelessNetworkInterface::OWirelessNetworkInterface( QObject* parent, const char* name )
:ONetworkInterface( parent, name ), _hopper( 0 )
{
qDebug( "OWirelessNetworkInterface::OWirelessNetworkInterface()" );
init();
}
OWirelessNetworkInterface::~OWirelessNetworkInterface()
{
}
struct iwreq& OWirelessNetworkInterface::iwr() const
{
return _iwr;
}
void OWirelessNetworkInterface::init()
{
qDebug( "OWirelessNetworkInterface::init()" );
memset( &_iwr, 0, sizeof( struct iwreq ) );
buildInformation();
buildPrivateList();
dumpInformation();
}
bool OWirelessNetworkInterface::isAssociated() const
{
//FIXME: handle different modes
return !(associatedAP() == OMacAddress::unknown);
}
OMacAddress OWirelessNetworkInterface::associatedAP() const
{
if ( ioctl( SIOCGIWAP ) )
return (const unsigned char*) &_ifr.ifr_hwaddr.sa_data[0];
else
return OMacAddress::unknown;
}
void OWirelessNetworkInterface::buildInformation()
{
//ML: If you listen carefully enough, you can hear lots of WLAN drivers suck
//ML: The HostAP drivers need more than sizeof struct_iw range to complete
//ML: SIOCGIWRANGE otherwise they fail with "Invalid Argument Length".
//ML: The Wlan-NG drivers on the otherside fail (segfault!) if you allocate
//ML: _too much_ space. This is damn shitty crap *sigh*
//ML: We allocate a large memory region in RAM and check whether the
//ML: driver pollutes this extra space. The complaint will be made on stdout,
//ML: so please forward this...
struct iwreq wrq;
int len = sizeof( struct iw_range )*2;
char *buffer = (char*) malloc( len );
//FIXME: Validate if we actually got the memory block
memset( buffer, 0, len );
memcpy( wrq.ifr_name, name(), IFNAMSIZ);
wrq.u.data.pointer = (caddr_t) buffer;
wrq.u.data.length = sizeof( struct iw_range );
wrq.u.data.flags = 0;
if ( ::ioctl( _sfd, SIOCGIWRANGE, &wrq ) == -1 )
{
qDebug( "OWirelessNetworkInterface::buildInformation(): SIOCGIWRANGE failed (%s) - using default values.", strerror( errno ) );
_channels.insert( 2412, 1 ); // 2.412 GHz
_channels.insert( 2417, 2 ); // 2.417 GHz
_channels.insert( 2422, 3 ); // 2.422 GHz
_channels.insert( 2427, 4 ); // 2.427 GHz
_channels.insert( 2432, 5 ); // 2.432 GHz
_channels.insert( 2437, 6 ); // 2.437 GHz
_channels.insert( 2442, 7 ); // 2.442 GHz
_channels.insert( 2447, 8 ); // 2.447 GHz
_channels.insert( 2452, 9 ); // 2.452 GHz
_channels.insert( 2457, 10 ); // 2.457 GHz
_channels.insert( 2462, 11 ); // 2.462 GHz
memset( &_range, 0, sizeof( struct iw_range ) );
}
else
{
// <check if the driver overwrites stuff>
int max = 0;
for ( int r = sizeof( struct iw_range ); r < len; r++ )
if (buffer[r] != 0)
max = r;
if (max > 0)
{
qWarning( "OWirelessNetworkInterface::buildInformation(): Driver for wireless interface '%s' sucks!\n"
"It overwrote the buffer end with at least %i bytes!\n", name(), max - sizeof( struct iw_range ) );
}
// </check if the driver overwrites stuff>
struct iw_range range;
memcpy( &range, buffer, sizeof range );
qDebug( "OWirelessNetworkInterface::buildInformation(): Interface %s reported to have %d channels.", name(), range.num_frequency );
for ( int i = 0; i < range.num_frequency; ++i )
{
int freq = (int) ( double( range.freq[i].m ) * pow( 10.0, range.freq[i].e ) / 1000000.0 );
_channels.insert( freq, i+1 );
}
}
memcpy( &_range, buffer, sizeof( struct iw_range ) );
qDebug( "OWirelessNetworkInterface::buildInformation(): Information block constructed." );
free(buffer);
}
void OWirelessNetworkInterface::buildPrivateList()
{
qDebug( "OWirelessNetworkInterface::buildPrivateList()" );
struct iw_priv_args priv[IW_MAX_PRIV_DEF];
_iwr.u.data.pointer = (char*) &priv;
_iwr.u.data.length = IW_MAX_PRIV_DEF; // length in terms of number of (sizeof iw_priv_args), not (sizeof iw_priv_args) itself
_iwr.u.data.flags = 0;
if ( !wioctl( SIOCGIWPRIV ) )
{
qDebug( "OWirelessNetworkInterface::buildPrivateList(): SIOCGIWPRIV failed (%s) - can't get private ioctl information.", strerror( errno ) );
return;
}
for ( int i = 0; i < _iwr.u.data.length; ++i )
{
new OPrivateIOCTL( this, priv[i].name, priv[i].cmd, priv[i].get_args, priv[i].set_args );
}
qDebug( "OWirelessNetworkInterface::buildPrivateList(): Private IOCTL list constructed." );
}
void OWirelessNetworkInterface::dumpInformation() const
{
qDebug( "OWirelessNetworkInterface::() -------------- dumping information block ----------------" );
qDebug( " - driver's idea of maximum throughput is %d bps = %d byte/s = %d Kb/s = %f.2 Mb/s", _range.throughput, _range.throughput / 8, _range.throughput / 8 / 1024, float( _range.throughput ) / 8.0 / 1024.0 / 1024.0 );
qDebug( " - driver for '%s' has been compiled against WE V%d (source=V%d)", name(), _range.we_version_compiled, _range.we_version_source );
qDebug( "OWirelessNetworkInterface::() ---------------------------------------------------------" );
}
int OWirelessNetworkInterface::channel() const
{
//FIXME: When monitoring enabled, then use it
//FIXME: to gather the current RF channel
//FIXME: Until then, get active channel from hopper.
if ( _hopper && _hopper->isActive() )
return _hopper->channel();
if ( !wioctl( SIOCGIWFREQ ) )
{
return -1;
}
else
{
return _channels[ static_cast<int>(double( _iwr.u.freq.m ) * pow( 10.0, _iwr.u.freq.e ) / 1000000) ];
}
}
void OWirelessNetworkInterface::setChannel( int c ) const
{
if ( !c )
{
qWarning( "OWirelessNetworkInterface::setChannel( 0 ) called - fix your application!" );
return;
}
if ( !_mon )
{
memset( &_iwr, 0, sizeof( struct iwreq ) );
_iwr.u.freq.m = c;
_iwr.u.freq.e = 0;
wioctl( SIOCSIWFREQ );
}
else
{
_mon->setChannel( c );
}
}
double OWirelessNetworkInterface::frequency() const
{
if ( !wioctl( SIOCGIWFREQ ) )
{
return -1.0;
}
else
{
return double( _iwr.u.freq.m ) * pow( 10.0, _iwr.u.freq.e ) / 1000000000.0;
}
}
int OWirelessNetworkInterface::channels() const
{
return _channels.count();
}
void OWirelessNetworkInterface::setChannelHopping( int interval )
{
if ( !_hopper ) _hopper = new OChannelHopper( this );
_hopper->setInterval( interval );
//FIXME: When and by whom will the channel hopper be deleted?
//TODO: rely on QObject hierarchy
}
int OWirelessNetworkInterface::channelHopping() const
{
return _hopper->interval();
}
OChannelHopper* OWirelessNetworkInterface::channelHopper() const
{
return _hopper;
}
-void OWirelessNetworkInterface::setMode( const QString& mode )
+void OWirelessNetworkInterface::commit() const
{
- _iwr.u.mode = stringToMode( mode );
- wioctl( SIOCSIWMODE );
+ wioctl( SIOCSIWCOMMIT );
}
-QString OWirelessNetworkInterface::mode() const
+void OWirelessNetworkInterface::setMode( const QString& newMode )
{
- if ( !wioctl( SIOCGIWMODE ) )
+ #ifdef FINALIZE
+ QString currentMode = mode();
+ if ( currentMode == newMode ) return;
+ #endif
+
+ qDebug( "OWirelessNetworkInterface::setMode(): trying to set mode '%s' (%d)", (const char*) newMode, stringToMode( newMode ) );
+
+ _iwr.u.mode = stringToMode( newMode );
+
+ if ( _iwr.u.mode != IW_MODE_MONITOR )
{
- return "<unknown>";
- }
- return modeToString( _iwr.u.mode );
-}
+ // IWR.U.MODE WIRD DURCH ABFRAGE DES MODE HIER PLATTGEMACHT!!!!!!!!!!!!!!!!!!!!! DEPP!
+ _iwr.u.mode = stringToMode( newMode );
+ wioctl( SIOCSIWMODE );
+ // special iwpriv fallback for monitor mode (check if we're really out of monitor mode now)
-void OWirelessNetworkInterface::setMonitorMode( bool b )
+ if ( mode() == "monitor" )
{
+ qDebug( "OWirelessNetworkInterface::setMode(): SIOCSIWMODE not sufficient - trying fallback to iwpriv..." );
if ( _mon )
- _mon->setEnabled( b );
+ _mon->setEnabled( false );
else
qDebug( "ONetwork(): can't switch monitor mode without installed monitoring interface" );
}
+ }
+ else // special iwpriv fallback for monitor mode
+ {
+ if ( wioctl( SIOCSIWMODE ) )
+ {
+ qDebug( "OWirelessNetworkInterface::setMode(): IW_MODE_MONITOR ok" );
+ }
+ else
+ {
+ qDebug( "OWirelessNetworkInterface::setMode(): SIOCSIWMODE not working - trying fallback to iwpriv..." );
+
+ if ( _mon )
+ _mon->setEnabled( true );
+ else
+ qDebug( "ONetwork(): can't switch monitor mode without installed monitoring interface" );
+ }
+ }
+}
+
-bool OWirelessNetworkInterface::monitorMode() const
+QString OWirelessNetworkInterface::mode() const
{
- qDebug( "dataLinkType = %d", dataLinkType() );
- return ( dataLinkType() == ARPHRD_IEEE80211 || dataLinkType() == 802 );
- //FIXME: 802 is the header type for PRISM - Linux support for this is pending...
- //FIXME: What is 119, by the way?
+ memset( &_iwr, 0, sizeof( struct iwreq ) );
+
+ if ( !wioctl( SIOCGIWMODE ) )
+ {
+ return "<unknown>";
}
+ qDebug( "DEBUG: WE's idea of current mode seems to be '%s'", (const char*) modeToString( _iwr.u.mode ) );
+
+ // legacy compatible monitor mode check
+
+ if ( dataLinkType() == ARPHRD_IEEE80211 || dataLinkType() == 802 )
+ {
+ return "monitor";
+ }
+ else
+ {
+ return modeToString( _iwr.u.mode );
+ }
+}
void OWirelessNetworkInterface::setNickName( const QString& nickname )
{
_iwr.u.essid.pointer = const_cast<char*>( (const char*) nickname );
_iwr.u.essid.length = nickname.length();
wioctl( SIOCSIWNICKN );
}
QString OWirelessNetworkInterface::nickName() const
{
char str[IW_ESSID_MAX_SIZE];
_iwr.u.data.pointer = &str[0];
_iwr.u.data.length = IW_ESSID_MAX_SIZE;
if ( !wioctl( SIOCGIWNICKN ) )
{
return "<unknown>";
}
else
{
str[_iwr.u.data.length] = 0x0; // some drivers (e.g. wlan-ng) don't zero-terminate the string
return str;
}
}
void OWirelessNetworkInterface::setPrivate( const QString& call, int numargs, ... )
{
OPrivateIOCTL* priv = static_cast<OPrivateIOCTL*>( child( (const char*) call ) );
if ( !priv )
{
qDebug( "OWirelessNetworkInterface::setPrivate(): interface '%s' does not support private ioctl '%s'", name(), (const char*) call );
return;
}
if ( priv->numberSetArgs() != numargs )
{
qDebug( "OWirelessNetworkInterface::setPrivate(): parameter count not matching. '%s' expects %d arguments, but got %d", (const char*) call, priv->numberSetArgs(), numargs );
return;
}
qDebug( "OWirelessNetworkInterface::setPrivate(): about to call '%s' on interface '%s'", (const char*) call, name() );
memset( &_iwr, 0, sizeof _iwr );
va_list argp;
va_start( argp, numargs );
for ( int i = 0; i < numargs; ++i )
{
priv->setParameter( i, va_arg( argp, int ) );
}
va_end( argp );
priv->invoke();
}
void OWirelessNetworkInterface::getPrivate( const QString& call )
{
qWarning( "OWirelessNetworkInterface::getPrivate() is not implemented yet." );
}
bool OWirelessNetworkInterface::hasPrivate( const QString& call )
{
return child( (const char*) call );
}
QString OWirelessNetworkInterface::SSID() const
{
char str[IW_ESSID_MAX_SIZE];
_iwr.u.essid.pointer = &str[0];
_iwr.u.essid.length = IW_ESSID_MAX_SIZE;
if ( !wioctl( SIOCGIWESSID ) )
{
return "<unknown>";
}
else
{
return str;
}
}
void OWirelessNetworkInterface::setSSID( const QString& ssid )
{
_iwr.u.essid.pointer = const_cast<char*>( (const char*) ssid );
_iwr.u.essid.length = ssid.length();
wioctl( SIOCSIWESSID );
}
OStationList* OWirelessNetworkInterface::scanNetwork()
{
_iwr.u.param.flags = IW_SCAN_DEFAULT;
_iwr.u.param.value = 0;
if ( !wioctl( SIOCSIWSCAN ) )
{
return 0;
}
OStationList* stations = new OStationList();
int timeout = 1000000;
qDebug( "ONetworkInterface::scanNetwork() - scan started." );
bool results = false;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 250000; // initial timeout ~ 250ms
char buffer[IW_SCAN_MAX_DATA];
while ( !results && timeout > 0 )
{
timeout -= tv.tv_usec;
select( 0, 0, 0, 0, &tv );
_iwr.u.data.pointer = &buffer[0];
_iwr.u.data.flags = 0;
_iwr.u.data.length = sizeof buffer;
if ( wioctl( SIOCGIWSCAN ) )
{
results = true;
continue;
}
else if ( errno == EAGAIN)
{
qDebug( "ONetworkInterface::scanNetwork() - scan in progress..." );
#if 0
if ( qApp )
{
qApp->processEvents( 100 );
continue;
}
#endif
tv.tv_sec = 0;
tv.tv_usec = 100000;
continue;
}
}
qDebug( "ONetworkInterface::scanNetwork() - scan finished." );
if ( results )
{
qDebug( " - result length = %d", _iwr.u.data.length );
if ( !_iwr.u.data.length )
{
qDebug( " - no results (empty neighbourhood)" );
return stations;
}
qDebug( " - results are in!" );
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>";
qDebug( "reading next event... cmd=%d, len=%d", we->cmd, we->len );
switch (we->cmd)
{
case SIOCGIWAP:
{
qDebug( "SIOCGIWAP" );
stations->append( new OStation() );
stations->last()->macAddress = (const unsigned char*) &we->u.ap_addr.sa_data[0];
break;
}
case SIOCGIWMODE:
{
qDebug( "SIOCGIWMODE" );
stations->last()->type = modeToString( we->u.mode );
break;
}
case SIOCGIWFREQ:
{
qDebug( "SIOCGIWFREQ" );
stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ];
break;
}
case SIOCGIWESSID:
{
qDebug( "SIOCGIWESSID" );
stations->last()->ssid = we->u.essid.pointer;
break;
}
case SIOCGIWSENS: qDebug( "SIOCGIWSENS" ); break;
case SIOCGIWENCODE: qDebug( "SIOCGIWENCODE" ); break;
case IWEVTXDROP: qDebug( "IWEVTXDROP" ); break; /* Packet dropped to excessive retry */
case IWEVQUAL: qDebug( "IWEVQUAL" ); break; /* Quality part of statistics (scan) */
case IWEVCUSTOM: qDebug( "IWEVCUSTOM" ); break; /* Driver specific ascii string */
case IWEVREGISTERED: qDebug( "IWEVREGISTERED" ); break; /* Discovered a new node (AP mode) */
case IWEVEXPIRED: qDebug( "IWEVEXPIRED" ); break; /* Expired a node (AP mode) */
default: qDebug( "unhandled event" );
}
offset += we->len;
we = (struct iw_event*) &buffer[offset];
}
return stations;
}
else
{
qDebug( " - no results (timeout) :(" );
return stations;
}
}
bool OWirelessNetworkInterface::wioctl( int call, struct iwreq& iwreq ) const
{
#ifndef NODEBUG
int result = ::ioctl( _sfd, call, &iwreq );
if ( result == -1 )
qDebug( "ONetworkInterface::wioctl (%s) call %s (0x%04X) - Status: Failed: %d (%s)", name(), (const char*) *(*_ioctlmap)[call], call, result, strerror( errno ) );
else
qDebug( "ONetworkInterface::wioctl (%s) call %s (0x%04X) - Status: Ok.", name(), (const char*) *(*_ioctlmap)[call], call );
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 );
}
-bool OMonitoringInterface::enabled() const
-{
- return _if->monitorMode();
-}
-
-
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
{
return "cisco";
}
void OCiscoMonitoringInterface::setChannel( int )
{
// cisco devices automatically switch channels when in monitor mode
}
/*======================================================================================
* OWlanNGMonitoringInterface
*======================================================================================*/
OWlanNGMonitoringInterface::OWlanNGMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
:OMonitoringInterface( iface, prismHeader )
{
iface->setMonitoring( this );
}
OWlanNGMonitoringInterface::~OWlanNGMonitoringInterface()
{
}
void OWlanNGMonitoringInterface::setEnabled( bool b )
{
//FIXME: do nothing if its already in the same mode
QString enable = b ? "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(), 1, (const char*) enable, (const char*) prism );
system( cmd );
}
QString OWlanNGMonitoringInterface::name() const
{
return "wlan-ng";
}
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 )
{
- // IW_MODE_MONITOR was introduced in Wireless Extensions Version 15
- // Wireless Extensions < Version 15 need iwpriv commandos for monitoring
-
- #if WIRELESS_EXT > 14
- if ( b )
- _if->setMode( "monitor" ); // IW_MODE_MONITOR doesn't support prism header
- else
- _if->setMode( "managed" );
- #else
int monitorCode = _prismHeader ? 1 : 2;
if ( b )
{
_if->setPrivate( "monitor", 1, monitorCode );
}
else
{
_if->setPrivate( "monitor", 1, 0 );
}
- #endif
}
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 )
{
int monitorCode = _prismHeader ? 1 : 2;
_if->setPrivate( "monitor", 2, monitorCode, c );
}
void OOrinocoMonitoringInterface::setEnabled( bool b )
{
// IW_MODE_MONITOR was introduced in Wireless Extensions Version 15
// Wireless Extensions < Version 15 need iwpriv commandos for monitoring
// However, as of recent orinoco drivers, IW_MODE_MONITOR is still not supported
- #if 0
- //#if WIRELESS_EXT > 14
- if ( b )
- _if->setMode( "monitor" ); // IW_MODE_MONITOR doesn't support prism header
- else
- _if->setMode( "managed" );
- #else
if ( b )
{
setChannel( 1 );
}
else
{
_if->setPrivate( "monitor", 2, 0, 0 );
}
- #endif
}
QString OOrinocoMonitoringInterface::name() const
{
return "orinoco";
}
diff --git a/libopie2/opienet/onetwork.h b/libopie2/opienet/onetwork.h
index 0eb4542..eb6c86e 100644
--- a/libopie2/opienet/onetwork.h
+++ b/libopie2/opienet/onetwork.h
@@ -96,449 +96,447 @@ class ONetwork : public QObject
*/
ONetworkInterface* interface( const QString& interface ) const;
/**
* @internal Rebuild the internal interface database
* @note Sometimes it might be useful to call this from client code,
* e.g. after issuing a cardctl insert
*/
void synchronize();
/**
* @returns the wireless extension version used at compile time.
**/
static short wirelessExtensionVersion();
protected:
ONetwork();
private:
static ONetwork* _instance;
InterfaceMap _interfaces;
};
/*======================================================================================
* ONetworkInterface
*======================================================================================*/
/**
* @brief A network interface wrapper.
*
* This class provides a wrapper for a network interface. All the cumbersume details of
* Linux ioctls are hidden under a convenient high-level interface.
* @warning Most of the setting methods contained in this class require the appropriate
* process permissions to work.
*
* @author Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
*/
class ONetworkInterface : public QObject
{
friend class OMonitoringInterface;
friend class OCiscoMonitoringInterface;
friend class OWlanNGMonitoringInterface;
friend class OHostAPMonitoringInterface;
friend class OOrinocoMonitoringInterface;
public:
/**
* Constructor. Normally you don't create @ref ONetworkInterface objects yourself,
* but access them via @ref ONetwork::interface().
*/
ONetworkInterface( QObject* parent, const char* name );
/**
* Destructor.
*/
virtual ~ONetworkInterface();
/**
* Associates a @a monitoring interface with this network interface.
* @note This is currently only useful with @ref OWirelessNetworkInterface objects.
*/
void setMonitoring( OMonitoringInterface* monitoring );
/**
* @returns the currently associated monitoring interface or 0, if no monitoring is associated.
*/
OMonitoringInterface* monitoring() const;
/**
* Setting an interface to promiscuous mode enables the device to receive
* all packets on the shared medium - as opposed to packets which are addressed to this interface.
*/
bool setPromiscuousMode( bool );
/**
* @returns true if the interface is set to promiscuous mode.
*/
bool promiscuousMode() const;
/**
* Setting an interface to up enables it to receive packets.
*/
bool setUp( bool );
/**
* @returns true if the interface is up.
*/
bool isUp() const;
/**
* @returns true if the interface is a loopback interface.
*/
bool isLoopback() const;
/**
* @returns true if the interface is featuring supports the wireless extension protocol.
*/
bool isWireless() const;
/**
* Associate the IP address @ addr with the interface.
*/
void setIPV4Address( const QHostAddress& addr );
/**
* @returns the IPv4 address associated with the interface.
*/
QString ipV4Address() const; //TODO: make this return an OHostAddress
/**
* Associate the MAC address @a addr with the interface.
* @note It can be necessary to shut down the interface prior to calling this method.
* @warning This is not supported by all drivers.
*/
void setMacAddress( const OMacAddress& addr );
/**
* @returns the MAC address associated with the interface.
*/
OMacAddress macAddress() const;
/**
* Associate the IPv4 @a netmask with the interface.
*/
void setIPV4Netmask( const QHostAddress& netmask );
/**
* @returns the IPv4 netmask associated with the interface.
*/
QString ipV4Netmask() const; //TODO: make this return an OHostAddress
/**
* @returns the data link type currently associated with the interface.
* @see #include <net/if_arp.h> for possible values.
*/
int dataLinkType() const;
protected:
const int _sfd;
mutable ifreq _ifr;
OMonitoringInterface* _mon;
protected:
struct ifreq& ifr() const;
virtual void init();
bool ioctl( int call ) const;
bool ioctl( int call, struct ifreq& ) const;
};
/*======================================================================================
* OChannelHopper
*======================================================================================*/
/**
* @brief A radio frequency channel hopper.
*
* This class provides a channel hopper for radio frequencies. A channel hopper frequently
* changes the radio frequency channel of its associated @ref OWirelessNetworkInterface.
* This is necessary when in monitoring mode and scanning for other devices, because
* the radio frequency hardware can only detect packets sent on the same frequency.
*
* @author Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
*/
class OChannelHopper : public QObject
{
Q_OBJECT
public:
/**
* Constructor.
*/
OChannelHopper( OWirelessNetworkInterface* );
/**
* Destructor.
*/
virtual ~OChannelHopper();
/**
* @returns true, if the channel hopper is hopping channels
*/
bool isActive() const;
/**
* @returns the last hopped channel
*/
int channel() const;
/**
* Set the channel hopping @a interval.
* An interval of 0 deactivates the channel hopper.
*/
void setInterval( int interval );
/**
* @returns the channel hopping interval
*/
int interval() const;
signals:
/**
* This signal is emitted right after the channel hopper performed a hop
*/
void hopped( int );
protected:
virtual void timerEvent( QTimerEvent* );
private:
OWirelessNetworkInterface* _iface;
int _interval;
int _tid;
QValueList<int> _channels;
QValueList<int>::Iterator _channel;
};
/*======================================================================================
* OWirelessNetworkInterface
*======================================================================================*/
/**
* @brief A network interface wrapper for interfaces supporting the wireless extensions protocol.
*
* This class provides a high-level encapsulation of the Linux wireless extension API.
*
* @author Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de>
*/
class OWirelessNetworkInterface : public ONetworkInterface
{
friend class OMonitoringInterface;
friend class OCiscoMonitoringInterface;
friend class OWlanNGMonitoringInterface;
friend class OHostAPMonitoringInterface;
friend class OOrinocoMonitoringInterface;
friend class OPrivateIOCTL;
public:
/**
* Constructor.
*/
OWirelessNetworkInterface( QObject* parent, const char* name );
/**
* Destructor.
*/
virtual ~OWirelessNetworkInterface();
/**
* Setting the @a channel of the interface changes the radio frequency (RF)
* of the corresponding wireless network device.
* @note Common channel range is within [1-14]. A value of 0 is not allowed.
* @see channels()
*/
virtual void setChannel( int channel ) const;
/**
* @returns the channel index of the current radio frequency.
*/
virtual int channel() const;
/**
* @returns the current radio frequency (in MHz).
*/
virtual double frequency() const;
/**
* @returns the number of radio frequency channels for the
* corresponding wireless network device.
* @note European devices usually have 14 channels, while American typically feature 11 channels.
*/
virtual int channels() const;
/**
* Set the IEEE 802.11 operation @a mode.
* Valid values are <ul><li>adhoc<li>managed<li>monitor<li>master
* @warning Not all drivers support the all modes.
* @note You might have to change the SSID to get the operation mode change into effect.
*/
virtual void setMode( const QString& mode );
/**
* @returns the current IEEE 802.11 operation mode.
* Possible values are <ul><li>adhoc<li>managed<li>monitor<li>master or <li>unknown
- */
- virtual QString mode() const;
- /**
+ *
+ * @note: Important note concerning the 'monitor' mode:
* Setting the monitor mode on a wireless network interface enables
* listening to IEEE 802.11 data and management frames which normally
* are handled by the device firmware. This can be used to detect
* other wireless network devices, e.g. Access Points or Ad-hoc stations.
* @warning Standard wireless network drives don't support the monitor mode.
* @warning You need a patched driver for this to work.
* @note Enabling the monitor mode is highly driver dependent and requires
* the proper @ref OMonitoringInterface to be associated with the interface.
* @see OMonitoringInterface
*/
- virtual void setMonitorMode( bool ); //FIXME: ==> setMode( "monitor" ); Use IW_MONITOR first, if this doesn't work, then use iwpriv!
- /**
- * @returns true if the device is listening in IEEE 802.11 monitor mode
- */
- virtual bool monitorMode() const; //FIXME: ==> mode()
+ virtual QString mode() const;
/**
* Set the channel hopping @a interval. An @a interval of 0 disables channel hopping.
* @see OChannelHopper
*/
virtual void setChannelHopping( int interval = 0 );
/**
* @returns the channel hopping interval or 0, if channel hopping is disabled.
*/
virtual int channelHopping() const;
/**
* @returns the @ref OChannelHopper of this interface or 0, if channel hopping has not been activated before
*/
virtual OChannelHopper* channelHopper() const;
/**
* Set the station @a nickname.
*/
virtual void setNickName( const QString& nickname );
/**
* @returns the current station nickname.
*/
virtual QString nickName() const;
/**
* Invoke the private IOCTL @a command with a @number of parameters on the network interface.
* @see OPrivateIOCTL
*/
virtual void setPrivate( const QString& command, int number, ... );
/**
* @returns true if the interface is featuring the private IOCTL @command.
*/
virtual bool hasPrivate( const QString& command );
virtual void getPrivate( const QString& command ); //FIXME: Implement and document this
/**
* @returns true if the interface is associated to an access point
* @note: This information is only valid if the interface is in managed mode.
*/
virtual bool isAssociated() const;
/**
* @returns the MAC address of the Access Point if the device is in infrastructure mode.
* @returns a (more or less random) cell ID address if the device is in adhoc mode.
*/
virtual OMacAddress associatedAP() const;
/**
* Set the @a ssid (Service Set ID) string. This is used to decide
* which network to associate with (use "any" to let the driver decide).
*/
virtual void setSSID( const QString& ssid );
/**
* @returns the current SSID (Service Set ID).
*/
virtual QString SSID() const;
/**
* Perform scanning the wireless network neighbourhood.
* @note: UNSTABLE API - UNDER CONSTRUCTION - DON'T USE!
*/
virtual OStationList* scanNetwork();
+ /** @internal commit pending changes to the driver
+ *
+ */
+ void commit() const;
protected:
void buildInformation();
void buildPrivateList();
void dumpInformation() const;
virtual void init();
struct iwreq& iwr() const;
bool wioctl( int call ) const;
bool wioctl( int call, struct iwreq& ) const;
protected:
mutable struct iwreq _iwr;
QMap<int,int> _channels;
struct iw_range _range;
private:
OChannelHopper* _hopper;
};
/*======================================================================================
* OMonitoringInterface
*======================================================================================*/
class OMonitoringInterface
{
public:
OMonitoringInterface();
OMonitoringInterface( ONetworkInterface*, bool _prismHeader );
virtual ~OMonitoringInterface();
public:
virtual void setEnabled( bool );
- virtual bool enabled() const;
virtual void setChannel( int );
virtual QString name() const = 0;
protected:
OWirelessNetworkInterface* _if;
bool _prismHeader;
};
/*======================================================================================
* OCiscoMonitoring
*======================================================================================*/
class OCiscoMonitoringInterface : public OMonitoringInterface
{
public:
OCiscoMonitoringInterface( ONetworkInterface*, bool _prismHeader );
virtual ~OCiscoMonitoringInterface();
virtual void setEnabled( bool );
virtual QString name() const;
virtual void setChannel( int );
};
/*======================================================================================
* OWlanNGMonitoringInterface
*======================================================================================*/
class OWlanNGMonitoringInterface : public OMonitoringInterface
{
public:
OWlanNGMonitoringInterface( ONetworkInterface*, bool _prismHeader );
virtual ~OWlanNGMonitoringInterface();
public:
virtual void setEnabled( bool );
virtual QString name() const;
virtual void setChannel( int );
};
/*======================================================================================
* OHostAPMonitoringInterface
*======================================================================================*/
class OHostAPMonitoringInterface : public OMonitoringInterface
{
public:
OHostAPMonitoringInterface( ONetworkInterface*, bool _prismHeader );
virtual ~OHostAPMonitoringInterface();
public:
virtual void setEnabled( bool );
virtual QString name() const;
};
/*======================================================================================
* OOrinocoMonitoringInterface
*======================================================================================*/
class OOrinocoMonitoringInterface : public OMonitoringInterface
{
public:
OOrinocoMonitoringInterface( ONetworkInterface*, bool _prismHeader );
virtual ~OOrinocoMonitoringInterface();
public:
virtual void setChannel( int );
virtual void setEnabled( bool );
virtual QString name() const;
};
#endif // ONETWORK_H