From f62005c53c93148eaa13eac50ea6814a41afb216 Mon Sep 17 00:00:00 2001 From: mickeyl Date: Thu, 03 Apr 2003 14:17:03 +0000 Subject: - ONetworkInterfaces are now QObjects - add support for private IOCTLS - make buildChannelList() more safe in case of faulty drivers --- (limited to 'libopie2/opienet') diff --git a/libopie2/opienet/onetutils.cpp b/libopie2/opienet/onetutils.cpp index 8006f41..3e11b53 100644 --- a/libopie2/opienet/onetutils.cpp +++ b/libopie2/opienet/onetutils.cpp @@ -36,6 +36,16 @@ #include using namespace std; +#define IW_PRIV_TYPE_MASK 0x7000 +#define IW_PRIV_TYPE_NONE 0x0000 +#define IW_PRIV_TYPE_BYTE 0x1000 +#define IW_PRIV_TYPE_CHAR 0x2000 +#define IW_PRIV_TYPE_INT 0x4000 +#define IW_PRIV_TYPE_FLOAT 0x5000 +#define IW_PRIV_TYPE_ADDR 0x6000 +#define IW_PRIV_SIZE_FIXED 0x0800 +#define IW_PRIV_SIZE_MASK 0x07FF + /*====================================================================================== * OMacAddress *======================================================================================*/ @@ -87,6 +97,55 @@ bool operator==( const OMacAddress &m1, const OMacAddress &m2 ) return memcmp( &m1._bytes, &m2._bytes, 6 ) == 0; } + +/*====================================================================================== + * OHostAddress + *======================================================================================*/ + + +/*====================================================================================== + * OPrivateIOCTL + *======================================================================================*/ + +OPrivateIOCTL::OPrivateIOCTL( QObject* parent, const char* name, int cmd, int getargs, int setargs ) + :QObject( parent, name ), _ioctl( cmd ), _getargs( getargs ), _setargs( setargs ) +{ +} + + +OPrivateIOCTL::~OPrivateIOCTL() +{ +} + + +inline int OPrivateIOCTL::numberGetArgs() const +{ + return _getargs & IW_PRIV_SIZE_MASK; +} + + +inline int OPrivateIOCTL::typeGetArgs() const +{ + return _getargs & IW_PRIV_TYPE_MASK >> 12; +} + + +inline int OPrivateIOCTL::numberSetArgs() const +{ + return _setargs & IW_PRIV_SIZE_MASK; +} + + +inline int OPrivateIOCTL::typeSetArgs() const +{ + return _setargs & IW_PRIV_TYPE_MASK >> 12; +} + + +/*====================================================================================== + * assorted functions + *======================================================================================*/ + void dumpBytes( const unsigned char* data, int num ) { printf( "Dumping %d bytes @ %0x", num, data ); diff --git a/libopie2/opienet/onetutils.h b/libopie2/opienet/onetutils.h index 0dabe8d..6640515 100644 --- a/libopie2/opienet/onetutils.h +++ b/libopie2/opienet/onetutils.h @@ -36,8 +36,12 @@ #include #include #include +#include + +#include struct ifreq; +class OWirelessNetworkInterface; /*====================================================================================== * OMacAddress @@ -80,6 +84,27 @@ class OHostAddress : public QHostAddress /*====================================================================================== + * OPrivateIOCTL + *======================================================================================*/ + +class OPrivateIOCTL : public QObject +{ + public: + OPrivateIOCTL( QObject* parent, const char* name, int cmd, int getargs, int setargs ); + ~OPrivateIOCTL(); + + int numberGetArgs() const; + int typeGetArgs() const; + int numberSetArgs() const; + int typeSetArgs() const; + + private: + u_int32_t _ioctl; + u_int16_t _getargs; + u_int16_t _setargs; +}; + + /*====================================================================================== * Miscellaneous *======================================================================================*/ diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp index ac2857a..2548a04 100644 --- a/libopie2/opienet/onetwork.cpp +++ b/libopie2/opienet/onetwork.cpp @@ -92,12 +92,12 @@ void ONetwork::synchronize() ONetworkInterface* iface; if ( isWirelessInterface( str ) ) { - iface = new OWirelessNetworkInterface( str ); + iface = new OWirelessNetworkInterface( this, str ); qDebug( "ONetwork: interface '%s' has Wireless Extensions", (const char*) str ); } else { - iface = new ONetworkInterface( str ); + iface = new ONetworkInterface( this, str ); } _interfaces.insert( str, iface ); s.readLine(); @@ -126,7 +126,7 @@ ONetwork::InterfaceIterator ONetwork::iterator() const bool ONetwork::isWirelessInterface( const char* name ) const { - int sfd = socket( AF_INET, SOCK_DGRAM, 0 ); + int sfd = socket( AF_INET, SOCK_STREAM, 0 ); iwreqstruct iwr; memset( &iwr, 0, sizeof( iwreqstruct ) ); strcpy( (char*) &iwr.ifr_name, name ); @@ -142,8 +142,9 @@ bool ONetwork::isWirelessInterface( const char* name ) const * ONetworkInterface *======================================================================================*/ -ONetworkInterface::ONetworkInterface( const QString& name ) - :_name( name ), _sfd( socket( AF_INET, SOCK_DGRAM, 0 ) ), _mon( 0 ) +ONetworkInterface::ONetworkInterface( QObject* parent, const char* name ) + :QObject( parent, name ), + _sfd( socket( AF_INET, SOCK_DGRAM, 0 ) ), _mon( 0 ) { qDebug( "ONetworkInterface::ONetworkInterface()" ); init(); @@ -164,7 +165,7 @@ void ONetworkInterface::init() if ( _sfd == -1 ) { - qDebug( "ONetworkInterface::init(): Warning - can't get socket for device '%s'", (const char*) _name ); + qDebug( "ONetworkInterface::init(): Warning - can't get socket for device '%s'", name() ); return; } } @@ -183,7 +184,7 @@ bool ONetworkInterface::ioctl( int call, ifreqstruct& ifreq ) const bool ONetworkInterface::ioctl( int call ) const { - strcpy( _ifr.ifr_name, (const char*) _name ); + strcpy( _ifr.ifr_name, name() ); return ioctl( call, _ifr ); } @@ -240,7 +241,7 @@ OMacAddress ONetworkInterface::macAddress() const void ONetworkInterface::setMonitoring( OMonitoringInterface* m ) { _mon = m; - qDebug( "ONetwork::setMonitoring(): Installed monitoring driver '%s' on interface '%s'", (const char*) m->name(), (const char*) _name ); + qDebug( "ONetwork::setMonitoring(): Installed monitoring driver '%s' on interface '%s'", (const char*) m->name(), name() ); } @@ -250,12 +251,6 @@ OMonitoringInterface* ONetworkInterface::monitoring() const } -const QString& ONetworkInterface::name() const -{ - return _name; -} - - ONetworkInterface::~ONetworkInterface() { qDebug( "ONetworkInterface::~ONetworkInterface()" ); @@ -368,8 +363,8 @@ int OChannelHopper::interval() const * OWirelessNetworkInterface *======================================================================================*/ -OWirelessNetworkInterface::OWirelessNetworkInterface( const QString& name ) - :ONetworkInterface( name ), _hopper( 0 ) +OWirelessNetworkInterface::OWirelessNetworkInterface( QObject* parent, const char* name ) + :ONetworkInterface( parent, name ), _hopper( 0 ) { qDebug( "OWirelessNetworkInterface::OWirelessNetworkInterface()" ); init(); @@ -390,35 +385,9 @@ iwreqstruct& OWirelessNetworkInterface::iwr() const void OWirelessNetworkInterface::init() { qDebug( "OWirelessNetworkInterface::init()" ); - memset( &_iwr, 0, sizeof( struct iwreq ) ); - - // IEEE802.11(b) radio frequency channels - - iwrangestruct range; - //ML: work around an ugly HostAP bug, which needs - //ML: extra space or will complain with "invalid argument length"... :-( - //ML: But don't allocate too much or prism2_usb will segfault *sigh* - char __extraBufferForBuggyDrivers[20]; - - qDebug( "sizeof(iwrangestruct)=%d, sizeof range=%d, sizeof range*2=%d", sizeof(iwrangestruct), sizeof range, (sizeof range)*2 ); - - _iwr.u.data.pointer = (char*) ⦥ - _iwr.u.data.length = sizeof(iwrangestruct)+20; - _iwr.u.data.flags = 0; - if ( !wioctl( SIOCGIWRANGE ) ) - { - qDebug( "OWirelessNetworkInterface::init(): SIOCGIWRANGE failed (%s)", strerror( errno ) ); - return; - } - - qDebug( "OWirelessNetworkInterface::init(): Interface %s reported to have %d channels.", (const char*) _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 ); - } + buildChannelList(); + buildPrivateList(); } @@ -445,6 +414,73 @@ QString OWirelessNetworkInterface::associatedAP() const } +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*) ⦥ + _iwr.u.data.length = IW_MAX_FREQUENCIES; //sizeof range; + _iwr.u.data.flags = 0; + + if ( !wioctl( SIOCGIWRANGE ) ) + { + 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 + { + 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." ); +} + + +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 @@ -504,6 +540,7 @@ 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 } @@ -582,7 +619,7 @@ bool OWirelessNetworkInterface::wioctl( int call, iwreqstruct& iwreq ) const bool OWirelessNetworkInterface::wioctl( int call ) const { - strcpy( _iwr.ifr_name, (const char*) _name ); + strcpy( _iwr.ifr_name, name() ); return wioctl( call, _iwr ); } diff --git a/libopie2/opienet/onetwork.h b/libopie2/opienet/onetwork.h index b57ac3f..acf2f69 100644 --- a/libopie2/opienet/onetwork.h +++ b/libopie2/opienet/onetwork.h @@ -49,6 +49,9 @@ #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 including @@ -108,7 +111,7 @@ class ONetwork : public QObject * ONetworkInterface *======================================================================================*/ -class ONetworkInterface +class ONetworkInterface : public QObject { friend class OMonitoringInterface; friend class OCiscoMonitoringInterface; @@ -117,10 +120,9 @@ class ONetworkInterface friend class OOrinocoMonitoringInterface; public: - ONetworkInterface( const QString& name ); + ONetworkInterface( QObject* parent, const char* name ); virtual ~ONetworkInterface(); - const QString& name() const; void setMonitoring( OMonitoringInterface* ); OMonitoringInterface* monitoring() const; bool setPromiscuousMode( bool ); @@ -133,7 +135,6 @@ class ONetworkInterface OMacAddress macAddress() const; protected: - const QString _name; const int _sfd; mutable ifreqstruct _ifr; OMonitoringInterface* _mon; @@ -185,7 +186,7 @@ class OWirelessNetworkInterface : public ONetworkInterface public: enum Mode { AdHoc, Managed, Monitor }; - OWirelessNetworkInterface( const QString& name ); + OWirelessNetworkInterface( QObject* parent, const char* name ); virtual ~OWirelessNetworkInterface(); virtual void setChannel( int ) const; @@ -213,15 +214,17 @@ class OWirelessNetworkInterface : public ONetworkInterface virtual QString SSID() const; protected: - mutable iwreqstruct _iwr; - QMap _channels; - - protected: + void buildChannelList(); + void buildPrivateList(); virtual void init(); iwreqstruct& iwr() const; bool wioctl( int call ) const; bool wioctl( int call, iwreqstruct& ) const; + protected: + mutable iwreqstruct _iwr; + QMap _channels; + private: OChannelHopper* _hopper; }; -- cgit v0.9.0.2