author | mickeyl <mickeyl> | 2003-04-03 14:17:03 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-04-03 14:17:03 (UTC) |
commit | f62005c53c93148eaa13eac50ea6814a41afb216 (patch) (side-by-side diff) | |
tree | 93e7e626205fd9d06b5ac7c29e78be52ce749e5d | |
parent | e9eeb493c75bfe6078f40952e85e859fb71fe970 (diff) | |
download | opie-f62005c53c93148eaa13eac50ea6814a41afb216.zip opie-f62005c53c93148eaa13eac50ea6814a41afb216.tar.gz opie-f62005c53c93148eaa13eac50ea6814a41afb216.tar.bz2 |
- ONetworkInterfaces are now QObjects
- add support for private IOCTLS
- make buildChannelList() more safe in case of faulty drivers
-rw-r--r-- | libopie2/opienet/onetutils.cpp | 59 | ||||
-rw-r--r-- | libopie2/opienet/onetutils.h | 25 | ||||
-rw-r--r-- | libopie2/opienet/onetwork.cpp | 127 | ||||
-rw-r--r-- | libopie2/opienet/onetwork.h | 21 |
4 files changed, 178 insertions, 54 deletions
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 @@ -1,101 +1,160 @@ /* This file is part of the Opie Project (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <opie2/onetutils.h> #include <net/if.h> #include <cstdio> 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 *======================================================================================*/ // static initializer for broadcast and unknown MAC Adresses const unsigned char __broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; const OMacAddress& OMacAddress::broadcast = OMacAddress( __broadcast ); const unsigned char __unknown[6] = { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 }; const OMacAddress& OMacAddress::unknown = OMacAddress( __unknown ); //TODO: Incorporate Ethernet Manufacturer database here! OMacAddress::OMacAddress( unsigned char* p ) { memcpy( _bytes, p, 6 ); // D'OH! memcpy in my sources... eeek... } OMacAddress::OMacAddress( const unsigned char* p ) { memcpy( _bytes, p, 6 ); } OMacAddress::OMacAddress( struct ifreq& ifr ) { memcpy( _bytes, ifr.ifr_hwaddr.sa_data, 6 ); } OMacAddress::~OMacAddress() { } QString OMacAddress::toString() const { QString s; s.sprintf( "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", _bytes[0]&0xff, _bytes[1]&0xff, _bytes[2]&0xff, _bytes[3]&0xff, _bytes[4]&0xff, _bytes[5]&0xff ); return s; } 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 ); 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/onetutils.h b/libopie2/opienet/onetutils.h index 0dabe8d..6640515 100644 --- a/libopie2/opienet/onetutils.h +++ b/libopie2/opienet/onetutils.h @@ -1,125 +1,150 @@ /* This file is part of the Opie Project (C) 2003 Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ONETUTILS_H #define ONETUTILS_H #include <qdict.h> #include <qmap.h> #include <qstring.h> #include <qhostaddress.h> +#include <qobject.h> + +#include <sys/types.h> struct ifreq; +class OWirelessNetworkInterface; /*====================================================================================== * OMacAddress *======================================================================================*/ class OMacAddress { public: OMacAddress( unsigned char* ); OMacAddress( const unsigned char* ); OMacAddress( struct ifreq& ); ~OMacAddress(); QString toString() const; public: static const OMacAddress& broadcast; // ff:ff:ff:ff:ff:ff static const OMacAddress& unknown; // 44:44:44:44:44:44 private: unsigned char _bytes[6]; friend bool operator==( const OMacAddress &m1, const OMacAddress &m2 ); }; bool operator==( const OMacAddress &m1, const OMacAddress &m2 ); /*====================================================================================== * OHostAddress *======================================================================================*/ class OHostAddress : public QHostAddress { public: OHostAddress(); ~OHostAddress(); }; /*====================================================================================== + * 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 *======================================================================================*/ /* dump bytes */ void dumpBytes( const unsigned char* data, int num ); /* Network to host order macros */ #ifdef LBL_ALIGN #define EXTRACT_16BITS(p) \ ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \ (u_int16_t)*((const u_int8_t *)(p) + 1))) #define EXTRACT_32BITS(p) \ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \ (u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \ (u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \ (u_int32_t)*((const u_int8_t *)(p) + 3))) #else #define EXTRACT_16BITS(p) \ ((u_int16_t)ntohs(*(const u_int16_t *)(p))) #define EXTRACT_32BITS(p) \ ((u_int32_t)ntohl(*(const u_int32_t *)(p))) #endif #define EXTRACT_24BITS(p) \ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \ (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ (u_int32_t)*((const u_int8_t *)(p) + 2))) /* Little endian protocol host order macros */ #define EXTRACT_LE_8BITS(p) (*(p)) #define EXTRACT_LE_16BITS(p) \ ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \ (u_int16_t)*((const u_int8_t *)(p) + 0))) #define EXTRACT_LE_32BITS(p) \ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \ (u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \ (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ (u_int32_t)*((const u_int8_t *)(p) + 0))) #endif // ONETUTILS_H 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 @@ -31,619 +31,656 @@ */ /* OPIE */ #include <opie2/onetwork.h> /* QT */ #include <qfile.h> #include <qtextstream.h> /* UNIX */ #include <arpa/inet.h> #include <cerrno> #include <cstring> #include <cstdlib> #include <math.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <linux/sockios.h> using namespace std; /*====================================================================================== * ONetwork *======================================================================================*/ ONetwork* ONetwork::_instance = 0; ONetwork::ONetwork() { qDebug( "ONetwork::ONetwork()" ); synchronize(); } void ONetwork::synchronize() { // gather available interfaces by inspecting /proc/net/dev // we could use SIOCGIFCONF here, but we aren't interested in virtual (e.g. eth0:0) devices _interfaces.clear(); QString str; QFile f( "/proc/net/dev" ); bool hasFile = f.open( IO_ReadOnly ); if ( !hasFile ) { qDebug( "ONetwork: /proc/net/dev not existing. No network devices available" ); return; } QTextStream s( &f ); s.readLine(); s.readLine(); while ( !s.atEnd() ) { s >> str; str.truncate( str.find( ':' ) ); qDebug( "ONetwork: found interface '%s'", (const char*) str ); 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(); } } 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_DGRAM, 0 ); + int sfd = socket( AF_INET, SOCK_STREAM, 0 ); iwreqstruct iwr; memset( &iwr, 0, sizeof( iwreqstruct ) ); 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( 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(); } ifreqstruct& 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'", (const char*) _name ); + qDebug( "ONetworkInterface::init(): Warning - can't get socket for device '%s'", name() ); return; } } bool ONetworkInterface::ioctl( int call, ifreqstruct& 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, (const char*) _name ); + 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 ); } bool ONetworkInterface::isUp() const { ioctl( SIOCGIFFLAGS ); return _ifr.ifr_flags & IFF_UP; } QString ONetworkInterface::ipV4Address() const { if ( ioctl( SIOCGIFADDR ) ) { struct sockaddr_in *sa = (struct sockaddr_in *) &_ifr.ifr_addr; //FIXME: Use QHostAddress here return QString( inet_ntoa( sa->sin_addr ) ); } else return "<unknown>"; } OMacAddress ONetworkInterface::macAddress() const { if ( ioctl( SIOCGIFHWADDR ) ) { return OMacAddress( _ifr ); } else { return OMacAddress::unknown; } } 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() ); } 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 ), _tid( 0 ) { int _maxChannel = iface->channels()+1; // generate fancy hopping sequence honoring the device capabilities if ( _maxChannel >= 1 ) _channels.append( 1 ); if ( _maxChannel >= 7 ) _channels.append( 7 ); if ( _maxChannel >= 13 ) _channels.append( 13 ); if ( _maxChannel >= 2 ) _channels.append( 2 ); if ( _maxChannel >= 8 ) _channels.append( 8 ); if ( _maxChannel >= 3 ) _channels.append( 3 ); if ( _maxChannel >= 14 ) _channels.append( 14 ); if ( _maxChannel >= 9 ) _channels.append( 9 ); if ( _maxChannel >= 4 ) _channels.append( 4 ); if ( _maxChannel >= 10 ) _channels.append( 10 ); if ( _maxChannel >= 5 ) _channels.append( 5 ); if ( _maxChannel >= 11 ) _channels.append( 11 ); if ( _maxChannel >= 6 ) _channels.append( 6 ); if ( _maxChannel >= 12 ) _channels.append( 12 ); _channel = _channels.begin(); } OChannelHopper::~OChannelHopper() { } bool OChannelHopper::isActive() const { return _tid; } int OChannelHopper::channel() const { return *_channel; } void OChannelHopper::timerEvent( QTimerEvent* ) { _iface->setChannel( *_channel ); qDebug( "OChannelHopper::timerEvent(): set channel %d on interface '%s'", *_channel, (const char*) _iface->name() ); if ( ++_channel == _channels.end() ) _channel = _channels.begin(); } 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 ) +OWirelessNetworkInterface::OWirelessNetworkInterface( QObject* parent, const char* name ) + :ONetworkInterface( parent, 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 - - 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(); } 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*) ⦥ + _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 //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 ) ); _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(); } 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 { 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, (const char*) _name ); + 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 ) ); _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 *======================================================================================*/ OCiscoMonitoringInterface::OCiscoMonitoringInterface( ONetworkInterface* iface ) :OMonitoringInterface( iface ) { iface->setMonitoring( this ); } OCiscoMonitoringInterface::~OCiscoMonitoringInterface() 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 @@ -1,288 +1,291 @@ /* This file is part of the Opie Project Copyright (C) 2003 by the Wellenreiter team: Martin J. Muench <mjm@remote-exploit.org> Max Moser <mmo@remote-exploit.org Michael 'Mickey' Lauer <mickey@tm.informatik.uni-frankfurt.de> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ONETWORK_H #define ONETWORK_H /* QT */ #include <qvaluelist.h> #include <qdict.h> #include <qmap.h> #include <qobject.h> #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 +class ONetworkInterface : public QObject { friend class OMonitoringInterface; friend class OCiscoMonitoringInterface; friend class OWlanNGMonitoringInterface; friend class OHostAPMonitoringInterface; 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 ); bool promiscuousMode() const; bool setUp( bool ); bool isUp() const; bool isLoopback() const; bool isWireless() const; QString ipV4Address() const; OMacAddress macAddress() const; protected: - const QString _name; const int _sfd; mutable ifreqstruct _ifr; OMonitoringInterface* _mon; protected: ifreqstruct& ifr() const; virtual void init(); bool ioctl( int call ) const; bool ioctl( int call, ifreqstruct& ) 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 { friend class OMonitoringInterface; friend class OCiscoMonitoringInterface; friend class OWlanNGMonitoringInterface; friend class OHostAPMonitoringInterface; friend class OOrinocoMonitoringInterface; public: enum Mode { AdHoc, Managed, Monitor }; - OWirelessNetworkInterface( const QString& name ); + OWirelessNetworkInterface( QObject* parent, const char* name ); virtual ~OWirelessNetworkInterface(); 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 bool isAssociated() const {}; virtual QString associatedAP() const; virtual void setSSID( const QString& ); virtual QString SSID() const; protected: - mutable iwreqstruct _iwr; - QMap<int,int> _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<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; }; /*====================================================================================== * OCiscoMonitoring *======================================================================================*/ class OCiscoMonitoringInterface : public OMonitoringInterface { public: OCiscoMonitoringInterface( ONetworkInterface* ); virtual ~OCiscoMonitoringInterface(); virtual void setEnabled( bool ); virtual QString name() const; virtual void setChannel( int ); }; /*====================================================================================== * OWlanNGMonitoringInterface *======================================================================================*/ class OWlanNGMonitoringInterface : public OMonitoringInterface { public: OWlanNGMonitoringInterface( ONetworkInterface* ); virtual ~OWlanNGMonitoringInterface(); public: virtual void setEnabled( bool ); virtual QString name() const; virtual void setChannel( int ); }; |