summaryrefslogtreecommitdiff
path: root/libopie2/opienet/onetwork.cpp
Side-by-side diff
Diffstat (limited to 'libopie2/opienet/onetwork.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetwork.cpp11
1 files changed, 7 insertions, 4 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index e141097..67718ba 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -480,260 +480,263 @@ void OWirelessNetworkInterface::init()
odebug << "OWirelessNetworkInterface::init()" << oendl;
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 )
{
owarn << "OWirelessNetworkInterface::buildInformation(): Can't get channel information - using default values." << oendl;
_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)
{
owarn << "OWirelessNetworkInterface::buildInformation(): Driver for wireless interface '" << name()
<< "' sucks! It overwrote the buffer end with at least " << max - sizeof( struct iw_range ) << " bytes!" << oendl;
}
// </check if the driver overwrites stuff>
struct iw_range range;
memcpy( &range, buffer, sizeof range );
odebug << "OWirelessNetworkInterface::buildInformation(): Interface reported to have " << (int) range.num_frequency << " channels." << oendl;
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 );
odebug << "OWirelessNetworkInterface::buildInformation: Adding frequency " << freq << " as channel " << i+1 << oendl;
_channels.insert( freq, i+1 );
}
}
memcpy( &_range, buffer, sizeof( struct iw_range ) );
odebug << "OWirelessNetworkInterface::buildInformation(): Information block constructed." << oendl;
free(buffer);
}
short OWirelessNetworkInterface::wirelessExtensionDriverVersion() const
{
return _range.we_version_compiled;
}
void OWirelessNetworkInterface::buildPrivateList()
{
odebug << "OWirelessNetworkInterface::buildPrivateList()" << oendl;
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 ) )
{
owarn << "OWirelessNetworkInterface::buildPrivateList(): Can't get private ioctl information." << oendl;
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 );
}
odebug << "OWirelessNetworkInterface::buildPrivateList(): Private ioctl list constructed." << oendl;
}
void OWirelessNetworkInterface::dumpInformation() const
{
odebug << "OWirelessNetworkInterface::() -------------- dumping information block ----------------" << oendl;
- 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' (V%d) has been compiled against WE V%d",
- name(), _range.we_version_source, _range.we_version_compiled );
+ odebug << " - driver's idea of maximum throughput is " << _range.throughput
+ << " bps = " << ( _range.throughput / 8 ) << " byte/s = " << ( _range.throughput / 8 / 1024 )
+ << " Kb/s = " << QString().sprintf("%f.2", float( _range.throughput ) / 8.0 / 1024.0 / 1024.0 )
+ << " Mb/s" << oendl;
+
+ odebug << " - driver for '" << name() << "' (V" << _range.we_version_source
+ << ") has been compiled against WE V" << _range.we_version_compiled << oendl;
if ( _range.we_version_compiled != WIRELESS_EXT )
{
owarn << "Version mismatch! WE_DRIVER = " << _range.we_version_compiled << " and WE_OPIENET = " << WIRELESS_EXT << oendl;
}
odebug << "OWirelessNetworkInterface::() ---------------------------------------------------------" << oendl;
}
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 )
{
oerr << "OWirelessNetworkInterface::setChannel( 0 ) called - fix your application!" << oendl;
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::commit() const
{
wioctl( SIOCSIWCOMMIT );
}
void OWirelessNetworkInterface::setMode( const QString& newMode )
{
#ifdef FINALIZE
QString currentMode = mode();
if ( currentMode == newMode ) return;
#endif
odebug << "OWirelessNetworkInterface::setMode(): trying to set mode " << newMode << oendl;
_iwr.u.mode = stringToMode( newMode );
if ( _iwr.u.mode != IW_MODE_MONITOR )
{
// 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" )
{
odebug << "OWirelessNetworkInterface::setMode(): SIOCSIWMODE not sufficient - trying fallback to iwpriv..." << oendl;
if ( _mon )
_mon->setEnabled( false );
else
odebug << "ONetwork(): can't switch monitor mode without installed monitoring interface" << oendl;
}
}
else // special iwpriv fallback for monitor mode
{