-rw-r--r-- | libopie2/opienet/onetwork.cpp | 106 | ||||
-rw-r--r-- | libopie2/opienet/onetwork.h | 16 |
2 files changed, 69 insertions, 53 deletions
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 @@ -670,46 +670,88 @@ int OWirelessNetworkInterface::channelHopping() const 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>"; + // 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) + + if ( mode() == "monitor" ) + { + qDebug( "OWirelessNetworkInterface::setMode(): SIOCSIWMODE not sufficient - trying fallback to iwpriv..." ); + if ( _mon ) + _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" ); + } } - return modeToString( _iwr.u.mode ); } -void OWirelessNetworkInterface::setMonitorMode( bool b ) +QString OWirelessNetworkInterface::mode() const { - if ( _mon ) - _mon->setEnabled( b ); - else - qDebug( "ONetwork(): can't switch monitor mode without installed monitoring interface" ); -} + 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 ) ); -bool OWirelessNetworkInterface::monitorMode() 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? -} + // 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 ); @@ -966,18 +1008,12 @@ void OMonitoringInterface::setChannel( int c ) _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 ) { } /*====================================================================================== @@ -1089,31 +1125,21 @@ OHostAPMonitoringInterface::OHostAPMonitoringInterface( ONetworkInterface* iface 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"; @@ -1146,28 +1172,20 @@ void OOrinocoMonitoringInterface::setChannel( int 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 @@ -346,30 +346,25 @@ class OWirelessNetworkInterface : public ONetworkInterface * @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 ); /** @@ -419,12 +414,16 @@ class OWirelessNetworkInterface : public ONetworkInterface 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(); @@ -453,13 +452,12 @@ class OMonitoringInterface 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; |