summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetutils.cpp1
-rw-r--r--libopie2/opienet/onetwork.cpp57
-rw-r--r--libopie2/opienet/onetwork.h19
3 files changed, 47 insertions, 30 deletions
diff --git a/libopie2/opienet/onetutils.cpp b/libopie2/opienet/onetutils.cpp
index fd8f9e9..b317810 100644
--- a/libopie2/opienet/onetutils.cpp
+++ b/libopie2/opienet/onetutils.cpp
@@ -154,32 +154,33 @@ int OPrivateIOCTL::typeSetArgs() const
return _setargs & IW_PRIV_TYPE_MASK >> 12;
}
void OPrivateIOCTL::invoke() const
{
( (OWirelessNetworkInterface*) parent() )->wioctl( _ioctl );
}
void OPrivateIOCTL::setParameter( int num, u_int32_t value )
{
u_int32_t* arglist = (u_int32_t*) &( (OWirelessNetworkInterface*) parent() )->_iwr.u.name;
arglist[num] = value;
}
/*======================================================================================
* assorted functions
*======================================================================================*/
void dumpBytes( const unsigned char* data, int num )
{
printf( "Dumping %d bytes @ %0x", num, data );
printf( "-------------------------------------------\n" );
for ( int i = 0; i < num; ++i )
{
printf( "%02x ", data[i] );
if ( !((i+1) % 32) ) printf( "\n" );
}
printf( "\n\n" );
}
+
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index 66fa215..789e8ca 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -99,109 +99,109 @@ void ONetwork::synchronize()
else
{
iface = new ONetworkInterface( this, str );
}
_interfaces.insert( str, iface );
s.readLine();
}
}
ONetworkInterface* ONetwork::interface( QString iface ) const
{
return _interfaces[iface];
}
ONetwork* ONetwork::instance()
{
if ( !_instance ) _instance = new ONetwork();
return _instance;
}
ONetwork::InterfaceIterator ONetwork::iterator() const
{
return ONetwork::InterfaceIterator( _interfaces );
}
bool ONetwork::isWirelessInterface( const char* name ) const
{
int sfd = socket( AF_INET, SOCK_STREAM, 0 );
- iwreqstruct iwr;
- memset( &iwr, 0, sizeof( iwreqstruct ) );
+ struct iwreq iwr;
+ memset( &iwr, 0, sizeof( struct iwreq ) );
strcpy( (char*) &iwr.ifr_name, name );
int result = ::ioctl( sfd, SIOCGIWNAME, &iwr );
if ( result == -1 )
qDebug( "ONetwork::ioctl(): SIOCGIWNAME failed: %d (%s)", result, strerror( errno ) );
else
qDebug( "ONetwork::ioctl(): SIOCGIWNAME ok." );
return ( result != -1 );
}
/*======================================================================================
* ONetworkInterface
*======================================================================================*/
ONetworkInterface::ONetworkInterface( QObject* parent, const char* name )
:QObject( parent, name ),
_sfd( socket( AF_INET, SOCK_DGRAM, 0 ) ), _mon( 0 )
{
qDebug( "ONetworkInterface::ONetworkInterface()" );
init();
}
-ifreqstruct& ONetworkInterface::ifr() const
+struct ifreq& ONetworkInterface::ifr() const
{
return _ifr;
}
void ONetworkInterface::init()
{
qDebug( "ONetworkInterface::init()" );
memset( &_ifr, 0, sizeof( struct ifreq ) );
if ( _sfd == -1 )
{
qDebug( "ONetworkInterface::init(): Warning - can't get socket for device '%s'", name() );
return;
}
}
-bool ONetworkInterface::ioctl( int call, ifreqstruct& ifreq ) const
+bool ONetworkInterface::ioctl( int call, struct ifreq& ifreq ) const
{
int result = ::ioctl( _sfd, call, &ifreq );
if ( result == -1 )
qDebug( "ONetworkInterface::ioctl(): Call %d - Status: Failed: %d (%s)", call, result, strerror( errno ) );
else
qDebug( "ONetworkInterface::ioctl(): Call %d - Status: Ok.", call );
return ( result != -1 );
}
bool ONetworkInterface::ioctl( int call ) const
{
strcpy( _ifr.ifr_name, name() );
return ioctl( call, _ifr );
}
bool ONetworkInterface::isLoopback() const
{
ioctl( SIOCGIFFLAGS );
return _ifr.ifr_flags & IFF_LOOPBACK;
}
bool ONetworkInterface::setUp( bool b )
{
ioctl( SIOCGIFFLAGS );
if ( b ) _ifr.ifr_flags |= IFF_UP;
else _ifr.ifr_flags &= (~IFF_UP);
return ioctl( SIOCSIFFLAGS );
}
@@ -348,193 +348,216 @@ void OChannelHopper::setInterval( int interval )
_interval = interval;
if ( _interval )
{
_tid = startTimer( interval );
}
}
int OChannelHopper::interval() const
{
return _interval;
}
/*======================================================================================
* OWirelessNetworkInterface
*======================================================================================*/
OWirelessNetworkInterface::OWirelessNetworkInterface( QObject* parent, const char* name )
:ONetworkInterface( parent, name ), _hopper( 0 )
{
qDebug( "OWirelessNetworkInterface::OWirelessNetworkInterface()" );
init();
}
OWirelessNetworkInterface::~OWirelessNetworkInterface()
{
}
-iwreqstruct& OWirelessNetworkInterface::iwr() const
+struct iwreq& OWirelessNetworkInterface::iwr() const
{
return _iwr;
}
void OWirelessNetworkInterface::init()
{
qDebug( "OWirelessNetworkInterface::init()" );
memset( &_iwr, 0, sizeof( struct iwreq ) );
buildChannelList();
buildPrivateList();
}
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;
}
void OWirelessNetworkInterface::buildChannelList()
{
- // IEEE802.11(b) radio frequency channels
- struct iw_range range;
-
//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*
-
- _iwr.u.data.pointer = (char*) &range;
- _iwr.u.data.length = IW_MAX_FREQUENCIES; //sizeof range;
- _iwr.u.data.flags = 0;
-
- if ( !wioctl( SIOCGIWRANGE ) )
+ //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 )
{
qDebug( "OWirelessNetworkInterface::buildChannelList(): SIOCGIWRANGE failed (%s) - defaulting to 11 channels", strerror( errno ) );
_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
}
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)
+ {
+ qWarning( "OWirelessNetworkInterface::buildChannelList(): Driver for wireless interface '%s'"
+ "overwrote buffer end with at least %i bytes!\n", name(), max - sizeof( struct iw_range ) );
+ }
+ // </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 ( !_mon )
{
- memset( &_iwr, 0, sizeof( iwreqstruct ) );
+ 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 )
{
@@ -610,101 +633,101 @@ void OWirelessNetworkInterface::setPrivate( const QString& call, int numargs, ..
}
void OWirelessNetworkInterface::getPrivate( const QString& call )
{
}
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
+bool OWirelessNetworkInterface::wioctl( int call, struct iwreq& iwreq ) const
{
int result = ::ioctl( _sfd, call, &iwreq );
if ( result == -1 )
qDebug( "ONetworkInterface::wioctl(): Call %d - Status: Failed: %d (%s)", call, result, strerror( errno ) );
else
qDebug( "ONetworkInterface::wioctl(): Call %d - Status: Ok.", call );
return ( result != -1 );
}
bool OWirelessNetworkInterface::wioctl( int call ) const
{
strcpy( _iwr.ifr_name, name() );
return wioctl( call, _iwr );
}
/*======================================================================================
* OMonitoringInterface
*======================================================================================*/
OMonitoringInterface::OMonitoringInterface( ONetworkInterface* iface )
:_enabled( false ), _if( static_cast<OWirelessNetworkInterface*>( iface ) )
{
}
OMonitoringInterface::~OMonitoringInterface()
{
}
void OMonitoringInterface::setChannel( int c )
{
// use standard WE channel switching protocol
- memset( &_if->_iwr, 0, sizeof( iwreqstruct ) );
+ memset( &_if->_iwr, 0, sizeof( struct iwreq ) );
_if->_iwr.u.freq.m = c;
_if->_iwr.u.freq.e = 0;
_if->wioctl( SIOCSIWFREQ );
}
bool OMonitoringInterface::enabled() const
{
return _enabled;
}
void OMonitoringInterface::setEnabled( bool b )
{
// open a packet capturer here or leave this to
// the client code?
/*
if ( b )
{
OPacketCapturer* opcap = new OPacketCapturer();
opcap->open( _if->name() );
}
*/
_enabled = b;
}
/*======================================================================================
* OCiscoMonitoringInterface
*======================================================================================*/
diff --git a/libopie2/opienet/onetwork.h b/libopie2/opienet/onetwork.h
index 7c70873..509c3db 100644
--- a/libopie2/opienet/onetwork.h
+++ b/libopie2/opienet/onetwork.h
@@ -43,136 +43,129 @@
#include <qhostaddress.h>
/* OPIE */
#include <opie2/onetutils.h>
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
#ifndef IW_MAX_PRIV_DEF
#define IW_MAX_PRIV_DEF 128
#endif
// ML: Yeah, I hate to include kernel headers, but it's necessary here
// ML: Here comes an ugly hack to prevent <linux/wireless.h> including <linux/if.h>
// ML: which conflicts with the user header <net/if.h>
// ML: We really a user header for the Wireless Extensions, something like <net/wireless.h>
// ML: I will drop Jean an mail on that subject
#include <net/if.h>
#define _LINUX_IF_H
#include <linux/wireless.h>
#ifndef SIOCIWFIRSTPRIV
#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
#endif
class ONetworkInterface;
class OWirelessNetworkInterface;
class OChannelHopper;
class OMonitoringInterface;
-typedef struct ifreq ifreqstruct;
-typedef struct iwreq iwreqstruct;
-typedef struct iw_event iweventstruct;
-typedef struct iw_freq iwfreqstruct;
-typedef struct iw_priv_args iwprivargsstruct;
-typedef struct iw_range iwrangestruct;
-
/*======================================================================================
* ONetwork
*======================================================================================*/
class ONetwork : public QObject
{
Q_OBJECT
public:
typedef QDict<ONetworkInterface> InterfaceMap;
typedef QDictIterator<ONetworkInterface> InterfaceIterator;
public:
static ONetwork* instance();
InterfaceIterator iterator() const;
bool isWirelessInterface( const char* ) const;
ONetworkInterface* interface( QString ) const;
protected:
ONetwork();
void synchronize();
private:
static ONetwork* _instance;
InterfaceMap _interfaces;
};
/*======================================================================================
* ONetworkInterface
*======================================================================================*/
class ONetworkInterface : public QObject
{
friend class OMonitoringInterface;
friend class OCiscoMonitoringInterface;
friend class OWlanNGMonitoringInterface;
friend class OHostAPMonitoringInterface;
friend class OOrinocoMonitoringInterface;
public:
ONetworkInterface( QObject* parent, const char* name );
virtual ~ONetworkInterface();
void setMonitoring( OMonitoringInterface* );
OMonitoringInterface* monitoring() const;
bool setPromiscuousMode( bool );
bool promiscuousMode() const;
bool setUp( bool );
bool isUp() const;
bool isLoopback() const;
bool isWireless() const;
QString ipV4Address() const;
OMacAddress macAddress() const;
protected:
const int _sfd;
- mutable ifreqstruct _ifr;
+ mutable ifreq _ifr;
OMonitoringInterface* _mon;
protected:
- ifreqstruct& ifr() const;
+ struct ifreq& ifr() const;
virtual void init();
bool ioctl( int call ) const;
- bool ioctl( int call, ifreqstruct& ) const;
+ bool ioctl( int call, struct ifreq& ) const;
};
/*======================================================================================
* OChannelHopper
*======================================================================================*/
class OChannelHopper : public QObject
{
public:
OChannelHopper( OWirelessNetworkInterface* );
virtual ~OChannelHopper();
bool isActive() const;
int channel() const;
virtual void timerEvent( QTimerEvent* );
void setInterval( int );
int interval() const;
private:
OWirelessNetworkInterface* _iface;
int _interval;
int _tid;
QValueList<int> _channels;
QValueList<int>::Iterator _channel;
};
/*======================================================================================
* OWirelessNetworkInterface
*======================================================================================*/
class OWirelessNetworkInterface : public ONetworkInterface
@@ -193,70 +186,70 @@ class OWirelessNetworkInterface : public ONetworkInterface
virtual void setChannel( int ) const;
virtual int channel() const;
virtual double frequency() const;
virtual int channels() const;
//virtual double frequency(int) const;
virtual void setMode( Mode ) {};
virtual bool mode() const {};
virtual void setMonitorMode( bool );
virtual bool monitorMode() const;
virtual void setChannelHopping( int interval = 0 );
virtual int channelHopping() const;
virtual void setNickName( const QString& ) {};
virtual QString nickName() const;
virtual void setPrivate( const QString&, int, ... );
virtual void getPrivate( const QString& );
virtual bool isAssociated() const {};
virtual QString associatedAP() const;
virtual void setSSID( const QString& );
virtual QString SSID() const;
protected:
void buildChannelList();
void buildPrivateList();
virtual void init();
- iwreqstruct& iwr() const;
+ struct iwreq& iwr() const;
bool wioctl( int call ) const;
- bool wioctl( int call, iwreqstruct& ) const;
+ bool wioctl( int call, struct iwreq& ) const;
protected:
- mutable iwreqstruct _iwr;
+ mutable struct iwreq _iwr;
QMap<int,int> _channels;
private:
OChannelHopper* _hopper;
};
/*======================================================================================
* OMonitoringInterface
*======================================================================================*/
class OMonitoringInterface
{
public:
OMonitoringInterface();
OMonitoringInterface( ONetworkInterface* );
virtual ~OMonitoringInterface();
public:
virtual void setEnabled( bool );
virtual bool enabled() const;
virtual void setChannel( int );
virtual QString name() const = 0;
protected:
bool _enabled;
const OWirelessNetworkInterface* _if;
};