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.cpp40
1 files changed, 29 insertions, 11 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index 1d3b9fe..25c70e0 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -246,284 +246,302 @@ void ONetworkInterface::setMonitoring( OMonitoringInterface* m )
OMonitoringInterface* ONetworkInterface::monitoring() const
{
return _mon;
}
const QString& ONetworkInterface::name() const
{
return _name;
}
ONetworkInterface::~ONetworkInterface()
{
qDebug( "ONetworkInterface::~ONetworkInterface()" );
if ( _sfd != -1 ) ::close( _sfd );
}
bool ONetworkInterface::setPromiscuousMode( bool b )
{
ioctl( SIOCGIFFLAGS );
if ( b ) _ifr.ifr_flags |= IFF_PROMISC;
else _ifr.ifr_flags &= (~IFF_PROMISC);
return ioctl( SIOCSIFFLAGS );
}
bool ONetworkInterface::promiscuousMode() const
{
ioctl( SIOCGIFFLAGS );
return _ifr.ifr_flags & IFF_PROMISC;
}
bool ONetworkInterface::isWireless() const
{
return ioctl( SIOCGIWNAME );
}
/*======================================================================================
* OChannelHopper
*======================================================================================*/
OChannelHopper::OChannelHopper( OWirelessNetworkInterface* iface )
:QObject( 0, "Mickey's funky hopper" ),
- _iface( iface ), _interval( 0 ), _channel( 0 ), _tid( 0 )
+ _iface( iface ), _interval( 0 ), _channel( 1 ), _tid( 0 ),
+ _maxChannel( iface->channels()+1 )
{
}
OChannelHopper::~OChannelHopper()
{
}
+bool OChannelHopper::isActive() const
+{
+ return _tid;
+}
+
+
+int OChannelHopper::channel() const
+{
+ return _channel;
+}
+
+
void OChannelHopper::timerEvent( QTimerEvent* )
{
- //FIXME: Get available channels from OWirelessNetworkInterface
- if ( --_channel < 0 ) _channel = 13;
+ 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( this )
+ :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;
_iwr.u.data.pointer = (char*) &range;
_iwr.u.data.length = sizeof( iwrangestruct );
if ( !wioctl( SIOCGIWRANGE ) )
{
qDebug( "OWirelessNetworkInterface::init(): SIOCGIWRANGE failed (%s)", strerror( errno ) );
return;
}
- //TODO: Find out what the difference between num_channel and
- // num_frequency is about.
-
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 );
+ _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
{
- //FIXME: This is off-by-one !? Why?
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 );
}
else
{
_mon->setChannel( c );
}
}
double OWirelessNetworkInterface::frequency() const
{
if ( !wioctl( SIOCGIWFREQ ) )
{
return -1.0;
}
else
{
return double( _iwr.u.freq.m ) * pow( 10, _iwr.u.freq.e ) / 1000000000.0;
}
}
int OWirelessNetworkInterface::channels() const
{
return _channels.count();
}
void OWirelessNetworkInterface::setChannelHopping( int interval )
{
- _hopper.setInterval( interval );
+ if ( !_hopper ) _hopper = new OChannelHopper( this );
+ _hopper->setInterval( interval );
+ //FIXME: When and by whom will the channel hopper be deleted?
}
int OWirelessNetworkInterface::channelHopping() const
{
- return _hopper.interval();
+ return _hopper->interval();
}
void OWirelessNetworkInterface::setMonitorMode( bool b )
{
if ( _mon )
_mon->setEnabled( b );
else
qDebug( "ONetwork(): can't switch monitor mode without installed monitoring interface" );
}
+
bool OWirelessNetworkInterface::monitorMode() const
{
return _mon ? _mon->enabled() : false;
}
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;
}
}
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 );
}
bool OWirelessNetworkInterface::wioctl( int call, iwreqstruct& iwreq ) const