summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2003-03-30 14:48:08 (UTC)
committer mickeyl <mickeyl>2003-03-30 14:48:08 (UTC)
commitf921599651459b393e6a9846a1ecf7551323f4c2 (patch) (side-by-side diff)
tree1fe6c881d29597c289a2dbbc30ad020996faac91
parent9e3dc048e171af6d88f0cc3f16ad0c9fb6a15ce2 (diff)
downloadopie-f921599651459b393e6a9846a1ecf7551323f4c2.zip
opie-f921599651459b393e6a9846a1ecf7551323f4c2.tar.gz
opie-f921599651459b393e6a9846a1ecf7551323f4c2.tar.bz2
- implement switching monitor mode on hostap
- work around damn buggy hostap drivers needing more space for SIOCGIWRANGE than defined by sizeof(struct iw_range)...
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetwork.cpp41
1 files changed, 29 insertions, 12 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index 21fa390..cd36f16 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -316,134 +316,136 @@ int OChannelHopper::channel() const
void OChannelHopper::timerEvent( QTimerEvent* )
{
if ( !--_channel ) _channel = _maxChannel;
_iface->setChannel( _channel );
qDebug( "OChannelHopper::timerEvent(): set channel %d on interface '%s'",
_channel, (const char*) _iface->name() );
}
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( const QString& name )
:ONetworkInterface( name ), _hopper( 0 )
{
qDebug( "OWirelessNetworkInterface::OWirelessNetworkInterface()" );
init();
}
OWirelessNetworkInterface::~OWirelessNetworkInterface()
{
}
iwreqstruct& OWirelessNetworkInterface::iwr() const
{
return _iwr;
}
void OWirelessNetworkInterface::init()
{
qDebug( "OWirelessNetworkInterface::init()" );
memset( &_iwr, 0, sizeof( struct iwreq ) );
// IEEE802.11(b) radio frequency channels
- //FIXME: get these directly from the interface
- //FIXME: check if these channels are off-by-one
iwrangestruct range;
+ //ML: work around an ugly HostAP bug, which needs
+ //ML: extra space or will complain with "invalid argument length"... :-(
+ char __extraBufferForBuggyDrivers[sizeof range];
_iwr.u.data.pointer = (char*) &range;
- _iwr.u.data.length = sizeof( iwrangestruct );
+ _iwr.u.data.length = (sizeof range) * 2;
+ _iwr.u.data.flags = 0;
if ( !wioctl( SIOCGIWRANGE ) )
{
qDebug( "OWirelessNetworkInterface::init(): SIOCGIWRANGE failed (%s)", strerror( errno ) );
return;
}
for ( int i = 0; i < range.num_frequency; ++i )
{
int freq = (int) ( double( range.freq[i].m ) * pow( 10, range.freq[i].e ) / 1000000.0 );
_channels.insert( freq, i+1 );
}
}
QString OWirelessNetworkInterface::associatedAP() const
{
//FIXME: use OMacAddress
QString mac;
if ( ioctl( SIOCGIWAP ) )
{
mac.sprintf( "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
_ifr.ifr_hwaddr.sa_data[0]&0xff,
_ifr.ifr_hwaddr.sa_data[1]&0xff,
_ifr.ifr_hwaddr.sa_data[2]&0xff,
_ifr.ifr_hwaddr.sa_data[3]&0xff,
_ifr.ifr_hwaddr.sa_data[4]&0xff,
_ifr.ifr_hwaddr.sa_data[5]&0xff );
}
else
{
mac = "<Unknown>";
}
return mac;
}
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, _iwr.u.freq.e ) / 1000000) ];
}
}
void OWirelessNetworkInterface::setChannel( int c ) const
{
if ( !_mon )
{
memset( &_iwr, 0, sizeof( iwreqstruct ) );
_iwr.u.freq.m = c;
_iwr.u.freq.e = 0;
wioctl( SIOCSIWFREQ );
@@ -660,133 +662,148 @@ void OCiscoMonitoringInterface::setChannel( int )
}
/*======================================================================================
* OWlanNGMonitoringInterface
*======================================================================================*/
OWlanNGMonitoringInterface::OWlanNGMonitoringInterface( ONetworkInterface* iface )
:OMonitoringInterface( iface )
{
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 cmd;
cmd.sprintf( "$(which wlanctl-ng) %s lnxreq_wlansniff channel=%d enable=%s", (const char*) _if->name(), 1, (const char*) enable );
system( cmd );
OMonitoringInterface::setEnabled( b );
}
QString OWlanNGMonitoringInterface::name() const
{
return "wlan-ng";
}
void OWlanNGMonitoringInterface::setChannel( int )
{
// wlan-ng devices automatically switch channels when in monitor mode
}
/*======================================================================================
* OHostAPMonitoringInterface
*======================================================================================*/
OHostAPMonitoringInterface::OHostAPMonitoringInterface( ONetworkInterface* iface )
:OMonitoringInterface( iface )
{
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->_iwr.u.mode = IW_MODE_MONITOR;
- _if->wioctl( SIOCSIWMODE );
- #else
- int* args = (int*) &_if->_iwr.u.name;
- args[0] = 2;
- args[1] = 0;
- _if->wioctl( SIOCDEVPRIVATE );
- #endif
+ if ( b )
+ {
+ #if WIRELESS_EXT > 14
+ _if->_iwr.u.mode = IW_MODE_MONITOR;
+ _if->wioctl( SIOCSIWMODE );
+ #else
+ int* args = (int*) &_if->_iwr.u.name;
+ args[0] = 2;
+ args[1] = 0;
+ _if->wioctl( SIOCDEVPRIVATE );
+ #endif
+ }
+ else
+ {
+ #if WIRELESS_EXT > 14
+ _if->_iwr.u.mode = IW_MODE_INFRA;
+ _if->wioctl( SIOCSIWMODE );
+ #else
+ int* args = (int*) &_if->_iwr.u.name;
+ args[0] = 0;
+ args[1] = 0;
+ _if->wioctl( SIOCDEVPRIVATE );
+ #endif
+ }
OMonitoringInterface::setEnabled( b );
}
QString OHostAPMonitoringInterface::name() const
{
return "hostap";
}
/*======================================================================================
* OOrinocoNetworkInterface
*======================================================================================*/
OOrinocoMonitoringInterface::OOrinocoMonitoringInterface( ONetworkInterface* iface )
:OMonitoringInterface( iface )
{
iface->setMonitoring( this );
}
OOrinocoMonitoringInterface::~OOrinocoMonitoringInterface()
{
}
void OOrinocoMonitoringInterface::setChannel( int c )
{
// call iwpriv <device> monitor 2 <channel>
int* args = (int*) &_if->_iwr.u.name;
args[0] = 2;
args[1] = c;
_if->wioctl( SIOCIWFIRSTPRIV + 0x8 );
}
void OOrinocoMonitoringInterface::setEnabled( bool b )
{
if ( b )
{
setChannel( 1 );
}
else
{
// call iwpriv <device> monitor 0 0
int* args = (int*) &_if->_iwr.u.name;
args[0] = 0;
args[1] = 0;
_if->wioctl( SIOCIWFIRSTPRIV + 0x8 );
}
OMonitoringInterface::setEnabled( b );
}
QString OOrinocoMonitoringInterface::name() const
{
return "orinoco";
}