author | mickeyl <mickeyl> | 2003-04-03 23:46:04 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2003-04-03 23:46:04 (UTC) |
commit | 487971af0c1b70babcc39fd549dc0d8142cd4865 (patch) (side-by-side diff) | |
tree | e317df1359a20686ba35b17309a8b82386108fb3 /libopie2 | |
parent | 934e4d81bc078c704a39f02663607a6c16a5b29f (diff) | |
download | opie-487971af0c1b70babcc39fd549dc0d8142cd4865.zip opie-487971af0c1b70babcc39fd549dc0d8142cd4865.tar.gz opie-487971af0c1b70babcc39fd549dc0d8142cd4865.tar.bz2 |
first part of private IOCTL API for OWirelessNetworkInterface implemented
-rw-r--r-- | libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp | 8 | ||||
-rw-r--r-- | libopie2/opienet/onetutils.cpp | 33 | ||||
-rw-r--r-- | libopie2/opienet/onetutils.h | 4 | ||||
-rw-r--r-- | libopie2/opienet/onetwork.cpp | 33 | ||||
-rw-r--r-- | libopie2/opienet/onetwork.h | 5 |
5 files changed, 79 insertions, 4 deletions
diff --git a/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp b/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp index 7703b4c..b010ac5 100644 --- a/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp +++ b/libopie2/examples/opienet/onetworkdemo/onetworkdemo.cpp @@ -1,35 +1,43 @@ #include <opie2/onetwork.h> int main( int argc, char** argv ) { qDebug( "OPIE Network Demo" ); ONetwork* net = ONetwork::instance(); ONetwork::InterfaceIterator it = net->iterator(); while ( it.current() ) { qDebug( "DEMO: ONetwork contains Interface '%s'", (const char*) it.current()->name() ); qDebug( "DEMO: MAC Address is '%s'", (const char*) it.current()->macAddress().toString() ); qDebug( "Demo: IPv4 Address is '%s'", (const char*) it.current()->ipV4Address() ); if ( it.current()->isWireless() ) { OWirelessNetworkInterface* iface = static_cast<OWirelessNetworkInterface*>( it.current() ); qDebug( "DEMO: '%s' seems to feature the wireless extensions.", (const char*) iface->name() ); qDebug( "DEMO: Current SSID is '%s'", (const char*) iface->SSID() ); qDebug( "DEMO: Current NickName is '%s'", (const char*) iface->nickName() ); qDebug( "DEMO: Antenna is tuned to '%f', that is channel %d", iface->frequency(), iface->channel() ); //if ( iface->mode() == OWirelessNetworkInterface::adhoc ) //{ qDebug( "DEMO: Associated AP has MAC Address '%s'", (const char*) iface->associatedAP() ); //} + // try to set monitor mode + + // first some wrong calls to check if this is working + iface->setPrivate( "seppel", 10 ); + iface->setPrivate( "monitor", 0 ); + + // now the real deal + iface->setPrivate( "monitor", 2, 2, 3 ); } ++it; } return 0; } diff --git a/libopie2/opienet/onetutils.cpp b/libopie2/opienet/onetutils.cpp index 3e11b53..fd8f9e9 100644 --- a/libopie2/opienet/onetutils.cpp +++ b/libopie2/opienet/onetutils.cpp @@ -1,160 +1,185 @@ /* 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 <opie2/onetwork.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 +#ifdef QT_NO_DEBUG +inline +#endif +int OPrivateIOCTL::numberGetArgs() const { return _getargs & IW_PRIV_SIZE_MASK; } -inline int OPrivateIOCTL::typeGetArgs() const +#ifdef QT_NO_DEBUG +inline +#endif +int OPrivateIOCTL::typeGetArgs() const { return _getargs & IW_PRIV_TYPE_MASK >> 12; } -inline int OPrivateIOCTL::numberSetArgs() const +#ifdef QT_NO_DEBUG +inline +#endif +int OPrivateIOCTL::numberSetArgs() const { return _setargs & IW_PRIV_SIZE_MASK; } -inline int OPrivateIOCTL::typeSetArgs() const +#ifdef QT_NO_DEBUG +inline +#endif +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/onetutils.h b/libopie2/opienet/onetutils.h index 6640515..8be042b 100644 --- a/libopie2/opienet/onetutils.h +++ b/libopie2/opienet/onetutils.h @@ -53,98 +53,102 @@ class OMacAddress 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; + void invoke() const; + void setParameter( int, u_int32_t ); + 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 2548a04..66fa215 100644 --- a/libopie2/opienet/onetwork.cpp +++ b/libopie2/opienet/onetwork.cpp @@ -7,96 +7,97 @@ =. .=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. */ /* 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> +#include <stdarg.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( this, str ); qDebug( "ONetwork: interface '%s' has Wireless Extensions", (const char*) str ); } else { iface = new ONetworkInterface( this, str ); } _interfaces.insert( str, iface ); @@ -537,96 +538,128 @@ int OWirelessNetworkInterface::channels() const 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; } } +void OWirelessNetworkInterface::setPrivate( const QString& call, int numargs, ... ) +{ + OPrivateIOCTL* priv = static_cast<OPrivateIOCTL*>( child( (const char*) call ) ); + if ( !priv ) + { + qDebug( "OWirelessNetworkInterface::setPrivate(): interface '%s' does not support private ioctl '%s'", name(), (const char*) call ); + return; + } + if ( priv->numberSetArgs() != numargs ) + { + qDebug( "OWirelessNetworkInterface::setPrivate(): parameter count not matching. '%s' expects %d arguments, but got %d", (const char*) call, priv->numberSetArgs(), numargs ); + return; + } + + qDebug( "OWirelessNetworkInterface::setPrivate(): about to call '%s' on interface '%s'", (const char*) call, name() ); + memset( &_iwr, 0, sizeof _iwr ); + va_list argp; + va_start( argp, numargs ); + for ( int i = 0; i < numargs; ++i ) + { + priv->setParameter( i, va_arg( argp, int ) ); + } + va_end( argp ); + priv->invoke(); +} + + +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 { 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 ) ) diff --git a/libopie2/opienet/onetwork.h b/libopie2/opienet/onetwork.h index acf2f69..7c70873 100644 --- a/libopie2/opienet/onetwork.h +++ b/libopie2/opienet/onetwork.h @@ -138,120 +138,125 @@ class ONetworkInterface : public QObject 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; + friend class OPrivateIOCTL; + public: enum Mode { AdHoc, Managed, Monitor }; 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 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; 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; }; |