summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2003-10-09 16:01:08 (UTC)
committer mickeyl <mickeyl>2003-10-09 16:01:08 (UTC)
commit802c9ab6b89fd10f709aa012e8ff075e9b4a5d7f (patch) (side-by-side diff)
treec6a33ab027752ca04d0d98a2e71a238aa954978d
parentc5c5c9f9fc6cab574f35f8be21076ac81f8c0369 (diff)
downloadopie-802c9ab6b89fd10f709aa012e8ff075e9b4a5d7f.zip
opie-802c9ab6b89fd10f709aa012e8ff075e9b4a5d7f.tar.gz
opie-802c9ab6b89fd10f709aa012e8ff075e9b4a5d7f.tar.bz2
- fix monitor mode on orinoco. Although WE > 14 define the standard mode
"MONITOR", the orinoco monitor patch for 0.13e still does not use that... - add documentation, a warning, and a runtime check for setChannel(0)
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetwork.cpp12
-rw-r--r--libopie2/opienet/onetwork.h2
2 files changed, 12 insertions, 2 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index 45ee4c0..767651e 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -532,128 +532,134 @@ void OWirelessNetworkInterface::buildChannelList()
}
// </check if the driver overwrites stuff>
struct iw_range range;
memcpy( &range, buffer, sizeof range );
qDebug( "OWirelessNetworkInterface::buildChannelList(): 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 );
}
}
qDebug( "OWirelessNetworkInterface::buildChannelList(): Channel list 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." );
}
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 )
{
if ( mode == "auto" ) _iwr.u.mode = IW_MODE_AUTO;
else if ( mode == "adhoc" ) _iwr.u.mode = IW_MODE_ADHOC;
else if ( mode == "managed" ) _iwr.u.mode = IW_MODE_INFRA;
else if ( mode == "master" ) _iwr.u.mode = IW_MODE_MASTER;
else if ( mode == "repeater" ) _iwr.u.mode = IW_MODE_REPEAT;
else if ( mode == "secondary" ) _iwr.u.mode = IW_MODE_SECOND;
#if WIRELESS_EXT > 14
else if ( mode == "monitor" ) _iwr.u.mode = IW_MODE_MONITOR;
@@ -878,163 +884,165 @@ void OCiscoMonitoringInterface::setEnabled( bool b )
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+1, (const char*) enable, (const char*) prism );
+ (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 WIRELESS_EXT > 14
+ #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 2553a61..00d1ebb 100644
--- a/libopie2/opienet/onetwork.h
+++ b/libopie2/opienet/onetwork.h
@@ -275,128 +275,130 @@ class OChannelHopper : public QObject
* @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;
/**
* 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" );
/**
* @returns true if the device is listening in IEEE 802.11 monitor mode
*/
virtual bool monitorMode() const; //FIXME: ==> mode()
/**
* 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.
*/