Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

onetwork.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003               =.             Copyright (C) 2003-2005 by Michael 'Mickey' Lauer <mickey@Vanille.de>
00004             .=l.
00005            .>+-=
00006  _;:,     .>    :=|.         This program is free software; you can
00007 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00008 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00009 .="- .-=="i,     .._         License as published by the Free Software
00010  - .   .-<_>     .<>         Foundation; version 2 of the License.
00011      ._= =}       :
00012     .%`+i>       _;_.
00013     .i_,=:_.      -<s.       This program is distributed in the hope that
00014      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00015     : ..    .:,     . . .    without even the implied warranty of
00016     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00017   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00018 ..}^=.=       =       ;      Library General Public License for more
00019 ++=   -.     .`     .:       details.
00020  :     =  ...= . :.=-
00021  -.   .:....=;==+<;          You should have received a copy of the GNU
00022   -_. . .   )=.  =           Library General Public License along with
00023     --        :-=`           this library; see the file COPYING.LIB.
00024                              If not, write to the Free Software Foundation,
00025                              Inc., 59 Temple Place - Suite 330,
00026                              Boston, MA 02111-1307, USA.
00027 
00028 */
00029 
00030 /* OPIE */
00031 #include <opie2/onetwork.h>
00032 #include <opie2/ostation.h>
00033 #include <opie2/odebug.h>
00034 using namespace Opie::Core;
00035 
00036 /* QT */
00037 #include <qfile.h>
00038 #include <qtextstream.h>
00039 #include <qapplication.h>
00040 
00041 /* STD */
00042 #include <assert.h>
00043 #include <arpa/inet.h>
00044 #include <errno.h>
00045 #include <stdarg.h>
00046 #include <string.h>
00047 #include <stdlib.h>
00048 #include <math.h>
00049 #include <unistd.h>
00050 #include <net/if_arp.h>
00051 #include <net/ethernet.h>
00052 #include <sys/ioctl.h>
00053 #include <sys/socket.h>
00054 #include <sys/types.h>
00055 #include <linux/types.h>
00056 #include <linux/sockios.h>
00057 #define u64 __u64
00058 #define u32 __u32
00059 #define u16 __u16
00060 #define u8 __u8
00061 #include <linux/ethtool.h>
00062 
00063 #ifndef NODEBUG
00064 #include <opie2/odebugmapper.h>
00065 using namespace Opie::Net::Internal;
00066 DebugMapper* debugmapper = new DebugMapper();
00067 #endif
00068 
00069 /*======================================================================================
00070  * ONetwork
00071  *======================================================================================*/
00072 
00073 namespace Opie {
00074 namespace Net  {
00075 ONetwork* ONetwork::_instance = 0;
00076 
00077 ONetwork::ONetwork()
00078 {
00079     odebug << "ONetwork::ONetwork()" << oendl;
00080     odebug << "ONetwork: This code has been compiled against Wireless Extensions V" << WIRELESS_EXT << oendl;
00081     synchronize();
00082 }
00083 
00084 void ONetwork::synchronize()
00085 {
00086     // gather available interfaces by inspecting /proc/net/dev
00087     _interfaces.clear();
00088     QString str;
00089     QFile f( "/proc/net/dev" );
00090     bool hasFile = f.open( IO_ReadOnly );
00091     if ( !hasFile )
00092     {
00093         odebug << "ONetwork: /proc/net/dev not existing. No network devices available" << oendl;
00094         return;
00095     }
00096     QTextStream s( &f );
00097     s.readLine();
00098     s.readLine();
00099     while ( !s.atEnd() )
00100     {
00101         s >> str;
00102         str.truncate( str.find( ':' ) );
00103         odebug << "ONetwork: found interface '" << str << "'" << oendl;
00104         if ( str.startsWith( "wifi" ) )
00105         {
00106             odebug << "ONetwork: ignoring hostap control interface" << oendl;
00107             s.readLine();
00108             continue;
00109         }
00110         ONetworkInterface* iface = 0;
00111         if ( isWirelessInterface( str ) )
00112         {
00113             iface = new OWirelessNetworkInterface( this, (const char*) str );
00114             odebug << "ONetwork: interface '" << str << "' has Wireless Extensions" << oendl;
00115         }
00116         else
00117         {
00118             iface = new ONetworkInterface( this, (const char*) str );
00119         }
00120         _interfaces.insert( str, iface );
00121         s.readLine();
00122     }
00123 }
00124 
00125 
00126 short ONetwork::wirelessExtensionCompileVersion()
00127 {
00128     return WIRELESS_EXT;
00129 }
00130 
00131 
00132 int ONetwork::count() const
00133 {
00134     return _interfaces.count();
00135 }
00136 
00137 
00138 ONetworkInterface* ONetwork::interface( const QString& iface ) const
00139 {
00140     return _interfaces[iface];
00141 }
00142 
00143 
00144 ONetwork* ONetwork::instance()
00145 {
00146     if ( !_instance ) _instance = new ONetwork();
00147     return _instance;
00148 }
00149 
00150 
00151 ONetwork::InterfaceIterator ONetwork::iterator() const
00152 {
00153     return ONetwork::InterfaceIterator( _interfaces );
00154 }
00155 
00156 
00157 bool ONetwork::isPresent( const char* name ) const
00158 {
00159     int sfd = socket( AF_INET, SOCK_STREAM, 0 );
00160     struct ifreq ifr;
00161     memset( &ifr, 0, sizeof( struct ifreq ) );
00162     strcpy( (char*) &ifr.ifr_name, name );
00163     int result = ::ioctl( sfd, SIOCGIFFLAGS, &ifr );
00164     return result != -1;
00165 }
00166 
00167 
00168 bool ONetwork::isWirelessInterface( const char* name ) const
00169 {
00170     int sfd = socket( AF_INET, SOCK_STREAM, 0 );
00171     struct iwreq iwr;
00172     memset( &iwr, 0, sizeof( struct iwreq ) );
00173     strcpy( (char*) &iwr.ifr_name, name );
00174     int result = ::ioctl( sfd, SIOCGIWNAME, &iwr );
00175     return result != -1;
00176 }
00177 
00178 /*======================================================================================
00179  * ONetworkInterface
00180  *======================================================================================*/
00181 
00182 ONetworkInterface::ONetworkInterface( QObject* parent, const char* name )
00183                  :QObject( parent, name ),
00184                  _sfd( socket( AF_INET, SOCK_DGRAM, 0 ) ), _mon( 0 )
00185 {
00186     odebug << "ONetworkInterface::ONetworkInterface()" << oendl;
00187     init();
00188 }
00189 
00190 
00191 struct ifreq& ONetworkInterface::ifr() const
00192 {
00193     return _ifr;
00194 }
00195 
00196 
00197 void ONetworkInterface::init()
00198 {
00199     odebug << "ONetworkInterface::init()" << oendl;
00200     memset( &_ifr, 0, sizeof( struct ifreq ) );
00201 
00202     if ( _sfd == -1 )
00203     {
00204         odebug << "ONetworkInterface::init(): Warning - can't get socket for device '" << name() << "'" << oendl;
00205         return;
00206     }
00207 }
00208 
00209 
00210 bool ONetworkInterface::ioctl( int call, struct ifreq& ifreq ) const
00211 {
00212     #ifndef NODEBUG
00213     int result = ::ioctl( _sfd, call, &ifreq );
00214     if ( result == -1 )
00215         odebug << "ONetworkInterface::ioctl (" << name() << ") call '" << debugmapper->map( call )
00216                << "' FAILED! " << result << " (" << strerror( errno ) << ")" << oendl;
00217     else
00218         odebug << "ONetworkInterface::ioctl (" << name() << ") call '" << debugmapper->map( call )
00219                << "' - Status: Ok." << oendl;
00220     return ( result != -1 );
00221     #else
00222     return ::ioctl( _sfd, call, &ifreq ) != -1;
00223     #endif
00224 }
00225 
00226 
00227 bool ONetworkInterface::ioctl( int call ) const
00228 {
00229     strcpy( _ifr.ifr_name, name() );
00230     return ioctl( call, _ifr );
00231 }
00232 
00233 
00234 bool ONetworkInterface::isLoopback() const
00235 {
00236     ioctl( SIOCGIFFLAGS );
00237     return _ifr.ifr_flags & IFF_LOOPBACK;
00238 }
00239 
00240 
00241 bool ONetworkInterface::setUp( bool b )
00242 {
00243     ioctl( SIOCGIFFLAGS );
00244     if ( b ) _ifr.ifr_flags |= IFF_UP;
00245     else   _ifr.ifr_flags &= (~IFF_UP);
00246     return ioctl( SIOCSIFFLAGS );
00247 }
00248 
00249 
00250 bool ONetworkInterface::isUp() const
00251 {
00252     ioctl( SIOCGIFFLAGS );
00253     return _ifr.ifr_flags & IFF_UP;
00254 }
00255 
00256 
00257 void ONetworkInterface::setIPV4Address( const QHostAddress& addr )
00258 {
00259     struct sockaddr_in *sa = (struct sockaddr_in *) &_ifr.ifr_addr;
00260     sa->sin_family = AF_INET;
00261     sa->sin_port = 0;
00262     sa->sin_addr.s_addr = htonl( addr.ip4Addr() );
00263     ioctl( SIOCSIFADDR );
00264 }
00265 
00266 
00267 OHostAddress ONetworkInterface::ipV4Address() const
00268 {
00269     struct sockaddr_in* sa = (struct sockaddr_in *) &_ifr.ifr_addr;
00270     return ioctl( SIOCGIFADDR ) ? OHostAddress( ntohl( sa->sin_addr.s_addr ) ) : OHostAddress();
00271 }
00272 
00273 
00274 void ONetworkInterface::setMacAddress( const OMacAddress& addr )
00275 {
00276     _ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
00277     memcpy( &_ifr.ifr_hwaddr.sa_data, addr.native(), 6 );
00278     ioctl( SIOCSIFHWADDR );
00279 }
00280 
00281 
00282 OMacAddress ONetworkInterface::macAddress() const
00283 {
00284     if ( ioctl( SIOCGIFHWADDR ) )
00285     {
00286         return OMacAddress( _ifr );
00287     }
00288     else
00289     {
00290         return OMacAddress::unknown;
00291     }
00292 }
00293 
00294 
00295 void ONetworkInterface::setIPV4Netmask( const QHostAddress& addr )
00296 {
00297     struct sockaddr_in *sa = (struct sockaddr_in *) &_ifr.ifr_addr;
00298     sa->sin_family = AF_INET;
00299     sa->sin_port = 0;
00300     sa->sin_addr.s_addr = htonl( addr.ip4Addr() );
00301     ioctl( SIOCSIFNETMASK );
00302 }
00303 
00304 
00305 OHostAddress ONetworkInterface::ipV4Netmask() const
00306 {
00307     struct sockaddr_in* sa = (struct sockaddr_in *) &_ifr.ifr_addr;
00308     return ioctl( SIOCGIFNETMASK ) ? OHostAddress( ntohl( sa->sin_addr.s_addr ) ) : OHostAddress();
00309 }
00310 
00311 
00312 int ONetworkInterface::dataLinkType() const
00313 {
00314     if ( ioctl( SIOCGIFHWADDR ) )
00315     {
00316         return _ifr.ifr_hwaddr.sa_family;
00317     }
00318     else
00319     {
00320         return -1;
00321     }
00322 }
00323 
00324 
00325 void ONetworkInterface::setMonitoring( OMonitoringInterface* m )
00326 {
00327     _mon = m;
00328     odebug << "ONetwork::setMonitoring(): Installed monitoring driver '" << m->name() << "' on interface '" << name() << "'" << oendl;
00329 }
00330 
00331 
00332 OMonitoringInterface* ONetworkInterface::monitoring() const
00333 {
00334     return _mon;
00335 }
00336 
00337 
00338 ONetworkInterface::~ONetworkInterface()
00339 {
00340     odebug << "ONetworkInterface::~ONetworkInterface()" << oendl;
00341     if ( _sfd != -1 ) ::close( _sfd );
00342 }
00343 
00344 
00345 bool ONetworkInterface::setPromiscuousMode( bool b )
00346 {
00347     ioctl( SIOCGIFFLAGS );
00348     if ( b ) _ifr.ifr_flags |= IFF_PROMISC;
00349     else   _ifr.ifr_flags &= (~IFF_PROMISC);
00350     return ioctl( SIOCSIFFLAGS );
00351 }
00352 
00353 
00354 bool ONetworkInterface::promiscuousMode() const
00355 {
00356     ioctl( SIOCGIFFLAGS );
00357     return _ifr.ifr_flags & IFF_PROMISC;
00358 }
00359 
00360 
00361 bool ONetworkInterface::isWireless() const
00362 {
00363     return ioctl( SIOCGIWNAME );
00364 }
00365 
00366 
00367 ONetworkInterfaceDriverInfo ONetworkInterface::driverInfo() const
00368 {
00369         struct ethtool_drvinfo info;
00370         info.cmd = ETHTOOL_GDRVINFO;
00371         _ifr.ifr_data = (caddr_t) &info;
00372         return ioctl( SIOCETHTOOL ) ? ONetworkInterfaceDriverInfo( info.driver, info.version, info.fw_version, info.bus_info) : ONetworkInterfaceDriverInfo();
00373 }
00374 
00375 /*======================================================================================
00376  * OChannelHopper
00377  *======================================================================================*/
00378 
00379 OChannelHopper::OChannelHopper( OWirelessNetworkInterface* iface )
00380                :QObject( 0, "Mickey's funky hopper" ),
00381                _iface( iface ), _interval( 0 ), _tid( 0 )
00382 {
00383     int _maxChannel = iface->channels();
00384     // generate fancy hopping sequence honoring the device capabilities
00385     if ( _maxChannel >=  1 ) _channels.append(  1 );
00386     if ( _maxChannel >=  7 ) _channels.append(  7 );
00387     if ( _maxChannel >= 13 ) _channels.append( 13 );
00388     if ( _maxChannel >=  2 ) _channels.append(  2 );
00389     if ( _maxChannel >=  8 ) _channels.append(  8 );
00390     if ( _maxChannel >=  3 ) _channels.append(  3 );
00391     if ( _maxChannel >= 14 ) _channels.append( 14 );
00392     if ( _maxChannel >=  9 ) _channels.append(  9 );
00393     if ( _maxChannel >=  4 ) _channels.append(  4 );
00394     if ( _maxChannel >= 10 ) _channels.append( 10 );
00395     if ( _maxChannel >=  5 ) _channels.append(  5 );
00396     if ( _maxChannel >= 11 ) _channels.append( 11 );
00397     if ( _maxChannel >=  6 ) _channels.append(  6 );
00398     if ( _maxChannel >= 12 ) _channels.append( 12 );
00399     //FIXME: Add 802.11a/g channels
00400     _channel = _channels.begin();
00401 }
00402 
00403 
00404 OChannelHopper::~OChannelHopper()
00405 {
00406 }
00407 
00408 
00409 bool OChannelHopper::isActive() const
00410 {
00411     return _tid;
00412 }
00413 
00414 
00415 int OChannelHopper::channel() const
00416 {
00417     return *_channel;
00418 }
00419 
00420 
00421 void OChannelHopper::timerEvent( QTimerEvent* )
00422 {
00423     _iface->setChannel( *_channel );
00424     emit( hopped( *_channel ) );
00425     odebug << "OChannelHopper::timerEvent(): set channel " << *_channel << " on interface '" << _iface->name() << "'" << oendl;
00426     if ( ++_channel == _channels.end() ) _channel = _channels.begin();
00427 }
00428 
00429 
00430 void OChannelHopper::setInterval( int interval )
00431 {
00432     if ( interval == _interval )
00433         return;
00434 
00435     if ( _interval )
00436         killTimer( _tid );
00437 
00438     _tid = 0;
00439     _interval = interval;
00440 
00441     if ( _interval )
00442     {
00443         _tid = startTimer( interval );
00444     }
00445 }
00446 
00447 
00448 int OChannelHopper::interval() const
00449 {
00450     return _interval;
00451 }
00452 
00453 
00454 /*======================================================================================
00455  * OWirelessNetworkInterface
00456  *======================================================================================*/
00457 
00458 OWirelessNetworkInterface::OWirelessNetworkInterface( QObject* parent, const char* name )
00459                          :ONetworkInterface( parent, name ), _hopper( 0 )
00460 {
00461     odebug << "OWirelessNetworkInterface::OWirelessNetworkInterface()" << oendl;
00462     init();
00463 }
00464 
00465 
00466 OWirelessNetworkInterface::~OWirelessNetworkInterface()
00467 {
00468 }
00469 
00470 
00471 struct iwreq& OWirelessNetworkInterface::iwr() const
00472 {
00473     return _iwr;
00474 }
00475 
00476 
00477 void OWirelessNetworkInterface::init()
00478 {
00479     odebug << "OWirelessNetworkInterface::init()" << oendl;
00480     memset( &_iwr, 0, sizeof( struct iwreq ) );
00481     buildInformation();
00482     buildPrivateList();
00483     dumpInformation();
00484 }
00485 
00486 
00487 bool OWirelessNetworkInterface::isAssociated() const
00488 {
00489     //FIXME: handle different modes
00490     return !(associatedAP() == OMacAddress::unknown);
00491 }
00492 
00493 
00494 void OWirelessNetworkInterface::setAssociatedAP( const OMacAddress& mac ) const
00495 {
00496     _iwr.u.ap_addr.sa_family = ARPHRD_ETHER;
00497     ::memcpy(_iwr.u.ap_addr.sa_data, mac.native(), ETH_ALEN);
00498     wioctl( SIOCSIWAP );
00499 }
00500 
00501 
00502 OMacAddress OWirelessNetworkInterface::associatedAP() const
00503 {
00504     if ( ioctl( SIOCGIWAP ) )
00505         return (const unsigned char*) &_ifr.ifr_hwaddr.sa_data[0];
00506     else
00507         return OMacAddress::unknown;
00508 }
00509 
00510 
00511 void OWirelessNetworkInterface::buildInformation()
00512 {
00513     //ML: If you listen carefully enough, you can hear lots of WLAN drivers suck
00514     //ML: The HostAP drivers need more than sizeof struct_iw range to complete
00515     //ML: SIOCGIWRANGE otherwise they fail with "Invalid Argument Length".
00516     //ML: The Wlan-NG drivers on the otherside fail (segfault!) if you allocate
00517     //ML: _too much_ space. This is damn shitty crap *sigh*
00518     //ML: We allocate a large memory region in RAM and check whether the
00519     //ML: driver pollutes this extra space. The complaint will be made on stdout,
00520     //ML: so please forward this...
00521 
00522     struct iwreq wrq;
00523     int len = sizeof( struct iw_range )*2;
00524     char buffer[len];
00525     memset( buffer, 0, len );
00526     memcpy( wrq.ifr_name, name(), IFNAMSIZ);
00527     wrq.u.data.pointer = (caddr_t) buffer;
00528     wrq.u.data.length = sizeof buffer;
00529     wrq.u.data.flags = 0;
00530 
00531     int result = ::ioctl( _sfd, SIOCGIWRANGE, &wrq );
00532     if ( result == -1 )
00533     {
00534         owarn << "OWirelessNetworkInterface::buildInformation(): SIOCGIWRANGE failed (" << strerror( errno ) << ") - retrying with smaller buffer..." << oendl;
00535         wrq.u.data.length = sizeof( struct iw_range );
00536         result = ::ioctl( _sfd, SIOCGIWRANGE, &wrq );
00537     }
00538 
00539     if ( result == -1 )
00540     {
00541         owarn << "OWirelessNetworkInterface::buildInformation(): Can't get driver information (" << strerror( errno ) << ") - using default values." << oendl;
00542         _channels.insert( 2412,  1 ); // 2.412 GHz
00543         _channels.insert( 2417,  2 ); // 2.417 GHz
00544         _channels.insert( 2422,  3 ); // 2.422 GHz
00545         _channels.insert( 2427,  4 ); // 2.427 GHz
00546         _channels.insert( 2432,  5 ); // 2.432 GHz
00547         _channels.insert( 2437,  6 ); // 2.437 GHz
00548         _channels.insert( 2442,  7 ); // 2.442 GHz
00549         _channels.insert( 2447,  8 ); // 2.447 GHz
00550         _channels.insert( 2452,  9 ); // 2.452 GHz
00551         _channels.insert( 2457, 10 ); // 2.457 GHz
00552         _channels.insert( 2462, 11 ); // 2.462 GHz
00553 
00554         memset( &_range, 0, sizeof( struct iw_range ) );
00555     }
00556     else
00557     {
00558         // <check if the driver overwrites stuff>
00559         int max = 0;
00560         for ( int r = sizeof( struct iw_range ); r < len; r++ )
00561             if (buffer[r] != 0)
00562                 max = r;
00563         if (max > 0)
00564         {
00565             owarn << "OWirelessNetworkInterface::buildInformation(): Driver for wireless interface '" << name()
00566                   << "' sucks! It overwrote the buffer end with at least " << max - sizeof( struct iw_range ) << " bytes!" << oendl;
00567         }
00568         // </check if the driver overwrites stuff>
00569 
00570         struct iw_range range;
00571         memcpy( &range, buffer, sizeof range );
00572 
00573         odebug << "OWirelessNetworkInterface::buildInformation(): Interface reported to have " << (int) range.num_frequency << " channels." << oendl;
00574         for ( int i = 0; i < range.num_frequency; ++i )
00575         {
00576             int freq = (int) ( double( range.freq[i].m ) * pow( 10.0, range.freq[i].e ) / 1000000.0 );
00577             odebug << "OWirelessNetworkInterface::buildInformation: Adding frequency " << freq << " as channel " << i+1 << oendl;
00578             _channels.insert( freq, i+1 );
00579         }
00580     }
00581 
00582     memcpy( &_range, buffer, sizeof( struct iw_range ) );
00583     odebug << "OWirelessNetworkInterface::buildInformation(): Information block constructed." << oendl;
00584 }
00585 
00586 
00587 short OWirelessNetworkInterface::wirelessExtensionDriverVersion() const
00588 {
00589     return _range.we_version_compiled;
00590 }
00591 
00592 
00593 void OWirelessNetworkInterface::buildPrivateList()
00594 {
00595     odebug << "OWirelessNetworkInterface::buildPrivateList()" << oendl;
00596 
00597     struct iw_priv_args priv[IW_MAX_PRIV_DEF];
00598 
00599     _iwr.u.data.pointer = (char*) &priv;
00600     _iwr.u.data.length = IW_MAX_PRIV_DEF; // length in terms of number of (sizeof iw_priv_args), not (sizeof iw_priv_args) itself
00601     _iwr.u.data.flags = 0;
00602 
00603     if ( !wioctl( SIOCGIWPRIV ) )
00604     {
00605         owarn << "OWirelessNetworkInterface::buildPrivateList(): Can't get private ioctl information (" << strerror( errno ) << ")." << oendl;
00606         return;
00607     }
00608 
00609     for ( int i = 0; i < _iwr.u.data.length; ++i )
00610     {
00611         new OPrivateIOCTL( this, priv[i].name, priv[i].cmd, priv[i].get_args, priv[i].set_args );
00612     }
00613     odebug << "OWirelessNetworkInterface::buildPrivateList(): Private ioctl list constructed." << oendl;
00614 }
00615 
00616 
00617 void OWirelessNetworkInterface::dumpInformation() const
00618 {
00619     odebug << "OWirelessNetworkInterface::() -------------- dumping information block ----------------" << oendl;
00620 
00621     odebug << " - driver's idea of maximum throughput is " << _range.throughput
00622            << " bps = " << ( _range.throughput / 8 ) << " byte/s = " << ( _range.throughput / 8 / 1024 )
00623            << " Kb/s = " << QString().sprintf("%f.2", float( _range.throughput ) / 8.0 / 1024.0 / 1024.0 )
00624            << " Mb/s" << oendl;
00625 
00626     odebug << " - driver for '" << name() << "' (V" << _range.we_version_source
00627            << ") has been compiled against WE V" << _range.we_version_compiled << oendl;
00628 
00629     if ( _range.we_version_compiled != WIRELESS_EXT )
00630     {
00631         owarn << "Version mismatch! WE_DRIVER = " << _range.we_version_compiled << " and WE_OPIENET = " << WIRELESS_EXT << oendl;
00632     }
00633 
00634     odebug << "OWirelessNetworkInterface::() ---------------------------------------------------------" << oendl;
00635 }
00636 
00637 
00638 int OWirelessNetworkInterface::channel() const
00639 {
00640     //FIXME: When monitoring enabled, then use it
00641     //FIXME: to gather the current RF channel
00642     //FIXME: Until then, get active channel from hopper.
00643     if ( _hopper && _hopper->isActive() )
00644         return _hopper->channel();
00645 
00646     if ( !wioctl( SIOCGIWFREQ ) )
00647     {
00648         return -1;
00649     }
00650     else
00651     {
00652         return _channels[ static_cast<int>(double( _iwr.u.freq.m ) * pow( 10.0, _iwr.u.freq.e ) / 1000000) ];
00653     }
00654 }
00655 
00656 
00657 void OWirelessNetworkInterface::setChannel( int c ) const
00658 {
00659     if ( !c )
00660     {
00661         oerr << "OWirelessNetworkInterface::setChannel( 0 ) called - fix your application!" << oendl;
00662         return;
00663     }
00664 
00665     if ( !_mon )
00666     {
00667         memset( &_iwr, 0, sizeof( struct iwreq ) );
00668         _iwr.u.freq.m = c;
00669         _iwr.u.freq.e = 0;
00670         wioctl( SIOCSIWFREQ );
00671     }
00672     else
00673     {
00674         _mon->setChannel( c );
00675     }
00676 }
00677 
00678 
00679 double OWirelessNetworkInterface::frequency() const
00680 {
00681     if ( !wioctl( SIOCGIWFREQ ) )
00682     {
00683         return -1.0;
00684     }
00685     else
00686     {
00687         return double( _iwr.u.freq.m ) * pow( 10.0, _iwr.u.freq.e ) / 1000000000.0;
00688     }
00689 }
00690 
00691 
00692 int OWirelessNetworkInterface::channels() const
00693 {
00694     return _channels.count();
00695 }
00696 
00697 
00698 void OWirelessNetworkInterface::setChannelHopping( int interval )
00699 {
00700     if ( !_hopper ) _hopper = new OChannelHopper( this );
00701     _hopper->setInterval( interval );
00702     //FIXME: When and by whom will the channel hopper be deleted?
00703     //TODO: rely on QObject hierarchy
00704 }
00705 
00706 
00707 int OWirelessNetworkInterface::channelHopping() const
00708 {
00709     return _hopper->interval();
00710 }
00711 
00712 
00713 OChannelHopper* OWirelessNetworkInterface::channelHopper() const
00714 {
00715     return _hopper;
00716 }
00717 
00718 
00719 void OWirelessNetworkInterface::commit() const
00720 {
00721     wioctl( SIOCSIWCOMMIT );
00722 }
00723 
00724 
00725 void OWirelessNetworkInterface::setMode( const QString& newMode )
00726 {
00727     #ifdef FINALIZE
00728     QString currentMode = mode();
00729     if ( currentMode == newMode ) return;
00730     #endif
00731 
00732     odebug << "OWirelessNetworkInterface::setMode(): trying to set mode " << newMode << oendl;
00733 
00734     _iwr.u.mode = stringToMode( newMode );
00735 
00736     if ( _iwr.u.mode != IW_MODE_MONITOR )
00737     {
00738         // IWR.U.MODE WIRD DURCH ABFRAGE DES MODE HIER PLATTGEMACHT!!!!!!!!!!!!!!!!!!!!! DEPP!
00739         _iwr.u.mode = stringToMode( newMode );
00740         wioctl( SIOCSIWMODE );
00741 
00742         // special iwpriv fallback for monitor mode (check if we're really out of monitor mode now)
00743 
00744         if ( mode() == "monitor" )
00745         {
00746             odebug << "OWirelessNetworkInterface::setMode(): SIOCSIWMODE not sufficient - trying fallback to iwpriv..." << oendl;
00747             if ( _mon )
00748                 _mon->setEnabled( false );
00749             else
00750                 odebug << "ONetwork(): can't switch monitor mode without installed monitoring interface" << oendl;
00751         }
00752 
00753     }
00754     else    // special iwpriv fallback for monitor mode
00755     {
00756         if ( wioctl( SIOCSIWMODE ) )
00757         {
00758             odebug << "OWirelessNetworkInterface::setMode(): IW_MODE_MONITOR ok" << oendl;
00759         }
00760         else
00761         {
00762             odebug << "OWirelessNetworkInterface::setMode(): SIOCSIWMODE not working - trying fallback to iwpriv..." << oendl;
00763 
00764             if ( _mon )
00765                 _mon->setEnabled( true );
00766             else
00767                 odebug << "ONetwork(): can't switch monitor mode without installed monitoring interface" << oendl;
00768         }
00769     }
00770 }
00771 
00772 
00773 QString OWirelessNetworkInterface::mode() const
00774 {
00775     memset( &_iwr, 0, sizeof( struct iwreq ) );
00776 
00777     if ( !wioctl( SIOCGIWMODE ) )
00778     {
00779         return "<unknown>";
00780     }
00781 
00782     odebug << "OWirelessNetworkInterface::setMode(): WE's idea of current mode seems to be " << modeToString( _iwr.u.mode ) << oendl;
00783 
00784     // legacy compatible monitor mode check
00785 
00786     if ( dataLinkType() == ARPHRD_IEEE80211 || dataLinkType() == 802 )
00787     {
00788         return "monitor";
00789     }
00790     else
00791     {
00792         return modeToString( _iwr.u.mode );
00793     }
00794 }
00795 
00796 void OWirelessNetworkInterface::setNickName( const QString& nickname )
00797 {
00798     _iwr.u.essid.pointer = const_cast<char*>( (const char*) nickname );
00799     _iwr.u.essid.length = nickname.length();
00800     wioctl( SIOCSIWNICKN );
00801 }
00802 
00803 
00804 QString OWirelessNetworkInterface::nickName() const
00805 {
00806     char str[IW_ESSID_MAX_SIZE];
00807     _iwr.u.data.pointer = &str[0];
00808     _iwr.u.data.length = IW_ESSID_MAX_SIZE;
00809     if ( !wioctl( SIOCGIWNICKN ) )
00810     {
00811         return "<unknown>";
00812     }
00813     else
00814     {
00815         str[_iwr.u.data.length] = '\0'; // some drivers don't zero-terminate the string
00816         return str;
00817     }
00818 }
00819 
00820 
00821 void OWirelessNetworkInterface::setPrivate( const QString& call, int numargs, ... )
00822 {
00823     OPrivateIOCTL* priv = static_cast<OPrivateIOCTL*>( child( (const char*) call ) );
00824     if ( !priv )
00825     {
00826         owarn << "OWirelessNetworkInterface::setPrivate(): interface '" << name()
00827               << "' does not support private ioctl '" << call << "'" << oendl;
00828         return;
00829     }
00830     if ( priv->numberSetArgs() != numargs )
00831     {
00832         owarn << "OWirelessNetworkInterface::setPrivate(): parameter count not matching. '"
00833               << call << "' expects " << priv->numberSetArgs() << ", but got " << numargs << oendl;
00834         return;
00835     }
00836 
00837     odebug << "OWirelessNetworkInterface::setPrivate(): about to call '" << call << "' on interface '" << name() << "'" << oendl;
00838     memset( &_iwr, 0, sizeof _iwr );
00839     va_list argp;
00840     va_start( argp, numargs );
00841     for ( int i = 0; i < numargs; ++i )
00842     {
00843         priv->setParameter( i, va_arg( argp, int ) );
00844     }
00845     va_end( argp );
00846     priv->invoke();
00847 }
00848 
00849 
00850 void OWirelessNetworkInterface::getPrivate( const QString&  )
00851 {
00852     oerr << "OWirelessNetworkInterface::getPrivate() is not implemented yet." << oendl;
00853 }
00854 
00855 
00856 bool OWirelessNetworkInterface::hasPrivate( const QString& call )
00857 {
00858     return child( call.local8Bit() );
00859 }
00860 
00861 
00862 QString OWirelessNetworkInterface::SSID() const
00863 {
00864     char str[IW_ESSID_MAX_SIZE];
00865     _iwr.u.essid.pointer = &str[0];
00866     _iwr.u.essid.length = IW_ESSID_MAX_SIZE;
00867     if ( !wioctl( SIOCGIWESSID ) )
00868     {
00869         return "<unknown>";
00870     }
00871     else
00872     {
00873         str[_iwr.u.essid.length] = '\0'; // some drivers don't zero-terminate the string
00874         return str;
00875     }
00876 }
00877 
00878 
00879 void OWirelessNetworkInterface::setSSID( const QString& ssid )
00880 {
00881     _iwr.u.essid.pointer = const_cast<char*>( (const char*) ssid );
00882     _iwr.u.essid.length = ssid.length()+1; // zero byte
00883     wioctl( SIOCSIWESSID );
00884 }
00885 
00886 
00887 OStationList* OWirelessNetworkInterface::scanNetwork()
00888 {
00889     _iwr.u.param.flags = IW_SCAN_DEFAULT;
00890     _iwr.u.param.value = 0;
00891     if ( !wioctl( SIOCSIWSCAN ) )
00892     {
00893         return 0;
00894     }
00895 
00896     OStationList* stations = new OStationList();
00897 
00898     int timeout = 10000000;
00899 
00900     odebug << "ONetworkInterface::scanNetwork() - scan started." << oendl;
00901 
00902     bool results = false;
00903     struct timeval tv;
00904     tv.tv_sec = 0;
00905     tv.tv_usec = 250000; // initial timeout ~ 250ms
00906     char buffer[IW_SCAN_MAX_DATA];
00907 
00908     while ( !results && timeout > 0 )
00909     {
00910         timeout -= tv.tv_usec;
00911         select( 0, 0, 0, 0, &tv );
00912 
00913         _iwr.u.data.pointer = &buffer[0];
00914         _iwr.u.data.flags = 0;
00915         _iwr.u.data.length = sizeof buffer;
00916         if ( wioctl( SIOCGIWSCAN ) )
00917         {
00918             results = true;
00919             continue;
00920         }
00921         else if ( errno == EAGAIN)
00922         {
00923             odebug << "ONetworkInterface::scanNetwork() - scan in progress..." << oendl;
00924             if ( qApp )
00925             {
00926                 qApp->processEvents( 100 );
00927                 continue;
00928             }
00929             tv.tv_sec = 0;
00930             tv.tv_usec = 100000;
00931             continue;
00932         }
00933     }
00934 
00935     odebug << "ONetworkInterface::scanNetwork() - scan finished." << oendl;
00936 
00937     if ( results )
00938     {
00939         odebug << " - result length = " << _iwr.u.data.length << oendl;
00940         if ( !_iwr.u.data.length )
00941         {
00942             odebug << " - no results (empty neighbourhood)" << oendl;
00943             return stations;
00944         }
00945 
00946         odebug << " - results are in!" << oendl;
00947         dumpBytes( (const unsigned char*) &buffer[0], _iwr.u.data.length );
00948 
00949         // parse results
00950         struct iw_event iwe;
00951         struct iw_stream_descr stream;
00952         unsigned int cmd_index, event_type, event_len;
00953         char *pointer;
00954 
00955         const char standard_ioctl_hdr[] = {
00956                 IW_HEADER_TYPE_NULL,    /* SIOCSIWCOMMIT */
00957                 IW_HEADER_TYPE_CHAR,    /* SIOCGIWNAME */
00958                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWNWID */
00959                 IW_HEADER_TYPE_PARAM,   /* SIOCGIWNWID */
00960                 IW_HEADER_TYPE_FREQ,    /* SIOCSIWFREQ */
00961                 IW_HEADER_TYPE_FREQ,    /* SIOCGIWFREQ */
00962                 IW_HEADER_TYPE_UINT,    /* SIOCSIWMODE */
00963                 IW_HEADER_TYPE_UINT,    /* SIOCGIWMODE */
00964                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWSENS */
00965                 IW_HEADER_TYPE_PARAM,   /* SIOCGIWSENS */
00966                 IW_HEADER_TYPE_NULL,    /* SIOCSIWRANGE */
00967                 IW_HEADER_TYPE_POINT,   /* SIOCGIWRANGE */
00968                 IW_HEADER_TYPE_NULL,    /* SIOCSIWPRIV */
00969                 IW_HEADER_TYPE_POINT,   /* SIOCGIWPRIV */
00970                 IW_HEADER_TYPE_NULL,    /* SIOCSIWSTATS */
00971                 IW_HEADER_TYPE_POINT,   /* SIOCGIWSTATS */
00972                 IW_HEADER_TYPE_POINT,   /* SIOCSIWSPY */
00973                 IW_HEADER_TYPE_POINT,   /* SIOCGIWSPY */
00974                 IW_HEADER_TYPE_POINT,   /* SIOCSIWTHRSPY */
00975                 IW_HEADER_TYPE_POINT,   /* SIOCGIWTHRSPY */
00976                 IW_HEADER_TYPE_ADDR,    /* SIOCSIWAP */
00977                 IW_HEADER_TYPE_ADDR,    /* SIOCGIWAP */
00978                 IW_HEADER_TYPE_NULL,    /* -- hole -- */
00979                 IW_HEADER_TYPE_POINT,   /* SIOCGIWAPLIST */
00980                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWSCAN */
00981                 IW_HEADER_TYPE_POINT,   /* SIOCGIWSCAN */
00982                 IW_HEADER_TYPE_POINT,   /* SIOCSIWESSID */
00983                 IW_HEADER_TYPE_POINT,   /* SIOCGIWESSID */
00984                 IW_HEADER_TYPE_POINT,   /* SIOCSIWNICKN */
00985                 IW_HEADER_TYPE_POINT,   /* SIOCGIWNICKN */
00986                 IW_HEADER_TYPE_NULL,    /* -- hole -- */
00987                 IW_HEADER_TYPE_NULL,    /* -- hole -- */
00988                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWRATE */
00989                 IW_HEADER_TYPE_PARAM,   /* SIOCGIWRATE */
00990                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWRTS */
00991                 IW_HEADER_TYPE_PARAM,   /* SIOCGIWRTS */
00992                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWFRAG */
00993                 IW_HEADER_TYPE_PARAM,   /* SIOCGIWFRAG */
00994                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWTXPOW */
00995                 IW_HEADER_TYPE_PARAM,   /* SIOCGIWTXPOW */
00996                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWRETRY */
00997                 IW_HEADER_TYPE_PARAM,   /* SIOCGIWRETRY */
00998                 IW_HEADER_TYPE_POINT,   /* SIOCSIWENCODE */
00999                 IW_HEADER_TYPE_POINT,   /* SIOCGIWENCODE */
01000                 IW_HEADER_TYPE_PARAM,   /* SIOCSIWPOWER */
01001                 IW_HEADER_TYPE_PARAM,   /* SIOCGIWPOWER */
01002         };
01003 
01004         const char standard_event_hdr[] = {
01005                 IW_HEADER_TYPE_ADDR,    /* IWEVTXDROP */
01006                 IW_HEADER_TYPE_QUAL,    /* IWEVQUAL */
01007                 IW_HEADER_TYPE_POINT,   /* IWEVCUSTOM */
01008                 IW_HEADER_TYPE_ADDR,    /* IWEVREGISTERED */
01009                 IW_HEADER_TYPE_ADDR,    /* IWEVEXPIRED */
01010                 IW_HEADER_TYPE_POINT,   /* IWEVGENIE */
01011                 IW_HEADER_TYPE_POINT,   /* IWEVMICHAELMICFAILURE */
01012                 IW_HEADER_TYPE_POINT,   /* IWEVASSOCREQIE */
01013                 IW_HEADER_TYPE_POINT,   /* IWEVASSOCRESPIE */
01014                 IW_HEADER_TYPE_POINT,   /* IWEVPMKIDCAND */
01015         };
01016 
01017 
01018         const int event_type_size[] = {
01019                 IW_EV_LCP_LEN,          /* IW_HEADER_TYPE_NULL */
01020                 0,
01021                 IW_EV_CHAR_LEN,         /* IW_HEADER_TYPE_CHAR */
01022                 0,
01023                 IW_EV_UINT_LEN,         /* IW_HEADER_TYPE_UINT */
01024                 IW_EV_FREQ_LEN,         /* IW_HEADER_TYPE_FREQ */
01025                 IW_EV_ADDR_LEN,         /* IW_HEADER_TYPE_ADDR */
01026                 0,
01027                 IW_EV_POINT_LEN,        /* Without variable payload */
01028                 IW_EV_PARAM_LEN,        /* IW_HEADER_TYPE_PARAM */
01029                 IW_EV_QUAL_LEN,         /* IW_HEADER_TYPE_QUAL */
01030         };
01031 
01032 
01033         //Initialize the stream
01034         memset( &stream, 0, sizeof(struct iw_stream_descr) );
01035         stream.current = buffer;
01036         stream.end = buffer + _iwr.u.data.length;
01037 
01038         do
01039         {
01040             if ((stream.current + IW_EV_LCP_LEN) > stream.end)
01041                 break;
01042             memcpy((char *) &iwe, stream.current, IW_EV_LCP_LEN);
01043 
01044             if (iwe.len <= IW_EV_LCP_LEN) //If yes, it is an invalid event
01045                 break;
01046             if (iwe.cmd <= SIOCIWLAST) {
01047                 cmd_index = iwe.cmd - SIOCIWFIRST;
01048 
01049                 if(cmd_index < sizeof(standard_ioctl_hdr))
01050                     event_type = standard_ioctl_hdr[cmd_index];
01051             }
01052             else {
01053                 cmd_index = iwe.cmd - IWEVFIRST;
01054 
01055                 if(cmd_index < sizeof(standard_event_hdr))
01056                     event_type = standard_event_hdr[cmd_index];
01057             }
01058 
01059             /* Unknown events -> event_type=0 => IW_EV_LCP_LEN */
01060             event_len = event_type_size[event_type];
01061 
01062             /* Fixup for later version of WE */
01063             if((_range.we_version_compiled > 18) && (event_type == IW_HEADER_TYPE_POINT))
01064                 event_len -= IW_EV_POINT_OFF;
01065 
01066             /* Check if we know about this event */
01067             if(event_len <= IW_EV_LCP_LEN) {
01068                 /* Skip to next event */
01069                 stream.current += iwe.len;
01070                 continue;
01071             }
01072 
01073             event_len -= IW_EV_LCP_LEN;
01074 
01075             /* Set pointer on data */
01076             if(stream.value != NULL)
01077                 pointer = stream.value;                    /* Next value in event */
01078             else
01079                 pointer = stream.current + IW_EV_LCP_LEN;  /* First value in event */
01080 
01081             if((pointer + event_len) > stream.end) {
01082                 /* Go to next event */
01083                 stream.current += iwe.len;
01084                 break;
01085             }
01086 
01087             /* Fixup for later version of WE */
01088             if((_range.we_version_compiled > 18) && (event_type == IW_HEADER_TYPE_POINT))
01089                 memcpy((char *) &iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, pointer, event_len);
01090             else
01091                 memcpy((char *) &iwe + IW_EV_LCP_LEN, pointer, event_len);
01092 
01093             /* Skip event in the stream */
01094             pointer += event_len;
01095 
01096             /* Special processing for iw_point events */
01097             if(event_type == IW_HEADER_TYPE_POINT) {
01098             /* Check the length of the payload */
01099 
01100                 if((iwe.len - (event_len + IW_EV_LCP_LEN)) > 0)
01101                     /* Set pointer on variable part (warning : non aligned) */
01102                     iwe.u.data.pointer = pointer;
01103                 else
01104                     /* No data */
01105                     iwe.u.data.pointer = NULL;
01106                     /* Go to next event */
01107                     stream.current += iwe.len;
01108             }
01109 
01110             else {
01111                 /* Is there more value in the event ? */
01112                 if((pointer + event_len) <= (stream.current + iwe.len))
01113                     /* Go to next value */
01114                      stream.value = pointer;
01115                 else {
01116                     /* Go to next event */
01117                     stream.value = NULL;
01118                     stream.current += iwe.len;
01119                 }
01120             }
01121 
01122             struct iw_event *we = &iwe;
01123             //------
01124             odebug << " - reading next event... cmd=" << we->cmd << ", len=" << we->len << oendl;
01125             switch (we->cmd)
01126             {
01127                 case SIOCGIWAP:
01128                 {
01129                     odebug << "SIOCGIWAP" << oendl;
01130                     stations->append( new OStation() );
01131                     stations->last()->macAddress = (const unsigned char*) &we->u.ap_addr.sa_data[0];
01132                     break;
01133                 }
01134                 case SIOCGIWMODE:
01135                 {
01136                     odebug << "SIOCGIWMODE" << oendl;
01137                     stations->last()->type = modeToString( we->u.mode );
01138                     break;
01139                 }
01140                 case SIOCGIWFREQ:
01141                 {
01142                     odebug << "SIOCGIWFREQ" << oendl;
01143                     if ( we->u.freq.m > 1000 )
01144                         stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ];
01145                     else
01146                         stations->last()->channel = static_cast<int>(((double) we->u.freq.m) * pow( 10.0, we->u.freq.e ));
01147                     break;
01148                 }
01149                 case SIOCGIWESSID:
01150                 {
01151                     odebug << "SIOCGIWESSID" << oendl;
01152                     we->u.essid.length = '\0'; // make sure it is zero terminated
01153                     stations->last()->ssid = static_cast<const char*> (we->u.essid.pointer);
01154                     odebug << "ESSID: " << stations->last()->ssid << oendl;
01155                     break;
01156                 }
01157                 case IWEVQUAL:
01158                 {
01159                     odebug << "IWEVQUAL" << oendl;
01160                     stations->last()->level = static_cast<int>(we->u.qual.level);
01161                     break;             /* Quality part of statistics (scan) */
01162                 }
01163                 case SIOCGIWENCODE:
01164                 {
01165                     odebug << "SIOCGIWENCODE" << oendl;
01166                     stations->last()->encrypted = !(we->u.data.flags & IW_ENCODE_DISABLED);
01167                     break;
01168                 }
01169 
01170                 case SIOCGIWRATE:
01171                 {
01172                     odebug << "SIOCGIWRATE" << oendl;
01173                     stations->last()->rates.append(we->u.bitrate.value);
01174                     break;
01175                 }
01176                 case SIOCGIWSENS: odebug << "SIOCGIWSENS" << oendl; break;
01177                 case IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break;         /* Packet dropped to excessive retry */
01178                 case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break;         /* Driver specific ascii string */
01179                 case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break; /* Discovered a new node (AP mode) */
01180                 case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break;       /* Expired a node (AP mode) */
01181                 default: odebug << "unhandled event" << oendl;
01182             }
01183 
01184         } while (true);
01185     }
01186     else
01187     {
01188         odebug << " - no results (timeout) :(" << oendl;
01189     }
01190     return stations;
01191 }
01192 
01193 
01194 int OWirelessNetworkInterface::signalStrength() const
01195 {
01196     iw_statistics stat;
01197     ::memset( &stat, 0, sizeof stat );
01198     _iwr.u.data.pointer = (char*) &stat;
01199     _iwr.u.data.flags = 0;
01200     _iwr.u.data.length = sizeof stat;
01201 
01202     if ( !wioctl( SIOCGIWSTATS ) )
01203     {
01204         return -1;
01205     }
01206 
01207     int max = _range.max_qual.qual;
01208     int cur = stat.qual.qual;
01209 //    int lev = stat.qual.level; //FIXME: Do something with them?
01210 //    int noi = stat.qual.noise; //FIXME: Do something with them?
01211 
01212 
01213     return max != 0 ? cur*100/max: -1;
01214 }
01215 
01216 
01217 bool OWirelessNetworkInterface::wioctl( int call, struct iwreq& iwreq ) const
01218 {
01219     #ifndef NODEBUG
01220     int result = ::ioctl( _sfd, call, &iwreq );
01221 
01222     if ( result == -1 )
01223         odebug << "ONetworkInterface::wioctl (" << name() << ") call '"
01224                << debugmapper->map( call ) << "' FAILED! " << result << " (" << strerror( errno ) << ")" << oendl;
01225     else
01226         odebug << "ONetworkInterface::wioctl (" << name() << ") call '"
01227                << debugmapper->map( call ) << "' - Status: Ok." << oendl;
01228 
01229     return ( result != -1 );
01230     #else
01231     return ::ioctl( _sfd, call, &iwreq ) != -1;
01232     #endif
01233 }
01234 
01235 
01236 bool OWirelessNetworkInterface::wioctl( int call ) const
01237 {
01238     strcpy( _iwr.ifr_name, name() );
01239     return wioctl( call, _iwr );
01240 }
01241 
01242 
01243 /*======================================================================================
01244  * OMonitoringInterface
01245  *======================================================================================*/
01246 
01247 OMonitoringInterface::OMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
01248                       :_if( static_cast<OWirelessNetworkInterface*>( iface ) ), _prismHeader( prismHeader )
01249 {
01250 }
01251 
01252 
01253 OMonitoringInterface::~OMonitoringInterface()
01254 {
01255 }
01256 
01257 
01258 void OMonitoringInterface::setChannel( int c )
01259 {
01260     // use standard WE channel switching protocol
01261     memset( &_if->_iwr, 0, sizeof( struct iwreq ) );
01262     _if->_iwr.u.freq.m = c;
01263     _if->_iwr.u.freq.e = 0;
01264     _if->wioctl( SIOCSIWFREQ );
01265 }
01266 
01267 
01268 void OMonitoringInterface::setEnabled( bool  )
01269 {
01270 }
01271 
01272 
01273 /*======================================================================================
01274  * OCiscoMonitoringInterface
01275  *======================================================================================*/
01276 
01277 OCiscoMonitoringInterface::OCiscoMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
01278                            :OMonitoringInterface( iface, prismHeader )
01279 {
01280     iface->setMonitoring( this );
01281 }
01282 
01283 
01284 OCiscoMonitoringInterface::~OCiscoMonitoringInterface()
01285 {
01286 }
01287 
01288 
01289 void OCiscoMonitoringInterface::setEnabled( bool /*b*/ )
01290 {
01291     QString fname;
01292     fname.sprintf( "/proc/driver/aironet/%s", (const char*) _if->name() );
01293     QFile f( fname );
01294     if ( !f.exists() ) return;
01295 
01296     if ( f.open( IO_WriteOnly ) )
01297     {
01298         QTextStream s( &f );
01299         s << "Mode: r";
01300         s << "Mode: y";
01301         s << "XmitPower: 1";
01302     }
01303 
01304     // flushing and closing will be done automatically when f goes out of scope
01305 }
01306 
01307 
01308 QString OCiscoMonitoringInterface::name() const
01309 {
01310     return "cisco";
01311 }
01312 
01313 
01314 void OCiscoMonitoringInterface::setChannel( int )
01315 {
01316     // cisco devices automatically switch channels when in monitor mode
01317 }
01318 
01319 
01320 /*======================================================================================
01321  * OWlanNGMonitoringInterface
01322  *======================================================================================*/
01323 
01324 
01325 OWlanNGMonitoringInterface::OWlanNGMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
01326                            :OMonitoringInterface( iface, prismHeader )
01327 {
01328     iface->setMonitoring( this );
01329 }
01330 
01331 
01332 OWlanNGMonitoringInterface::~OWlanNGMonitoringInterface()
01333 {
01334 }
01335 
01336 
01337 void OWlanNGMonitoringInterface::setEnabled( bool b )
01338 {
01339     //FIXME: do nothing if its already in the same mode
01340 
01341     QString enable = b ? "true" : "false";
01342     QString prism = _prismHeader ? "true" : "false";
01343     QString cmd;
01344     cmd.sprintf( "$(which wlanctl-ng) %s lnxreq_wlansniff channel=%d enable=%s prismheader=%s",
01345                  (const char*) _if->name(), 1, (const char*) enable, (const char*) prism );
01346     system( cmd );
01347 }
01348 
01349 
01350 QString OWlanNGMonitoringInterface::name() const
01351 {
01352     return "wlan-ng";
01353 }
01354 
01355 
01356 void OWlanNGMonitoringInterface::setChannel( int c )
01357 {
01358     //NOTE: Older wlan-ng drivers automatically hopped channels while lnxreq_wlansniff=true. Newer ones don't.
01359 
01360     QString enable = "true"; //_if->monitorMode() ? "true" : "false";
01361     QString prism = _prismHeader ? "true" : "false";
01362     QString cmd;
01363     cmd.sprintf( "$(which wlanctl-ng) %s lnxreq_wlansniff channel=%d enable=%s prismheader=%s",
01364                  (const char*) _if->name(), c, (const char*) enable, (const char*) prism );
01365     system( cmd );
01366 }
01367 
01368 
01369 /*======================================================================================
01370  * OHostAPMonitoringInterface
01371  *======================================================================================*/
01372 
01373 OHostAPMonitoringInterface::OHostAPMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
01374                            :OMonitoringInterface( iface, prismHeader )
01375 {
01376     iface->setMonitoring( this );
01377 }
01378 
01379 OHostAPMonitoringInterface::~OHostAPMonitoringInterface()
01380 {
01381 }
01382 
01383 void OHostAPMonitoringInterface::setEnabled( bool b )
01384 {
01385     int monitorCode = _prismHeader ? 1 : 2;
01386     if ( b )
01387     {
01388         _if->setPrivate( "monitor", 1, monitorCode );
01389     }
01390     else
01391     {
01392         _if->setPrivate( "monitor", 1, 0 );
01393     }
01394 }
01395 
01396 
01397 QString OHostAPMonitoringInterface::name() const
01398 {
01399     return "hostap";
01400 }
01401 
01402 
01403 /*======================================================================================
01404  * OOrinocoNetworkInterface
01405  *======================================================================================*/
01406 
01407 OOrinocoMonitoringInterface::OOrinocoMonitoringInterface( ONetworkInterface* iface, bool prismHeader )
01408                            :OMonitoringInterface( iface, prismHeader )
01409 {
01410     iface->setMonitoring( this );
01411 }
01412 
01413 
01414 OOrinocoMonitoringInterface::~OOrinocoMonitoringInterface()
01415 {
01416 }
01417 
01418 
01419 void OOrinocoMonitoringInterface::setChannel( int c )
01420 {
01421     if ( !_if->hasPrivate( "monitor" ) )
01422     {
01423         this->OMonitoringInterface::setChannel( c );
01424     }
01425     else
01426     {
01427         int monitorCode = _prismHeader ? 1 : 2;
01428         _if->setPrivate( "monitor", 2, monitorCode, c );
01429     }
01430 }
01431 
01432 
01433 void OOrinocoMonitoringInterface::setEnabled( bool b )
01434 {
01435     if ( b )
01436     {
01437         setChannel( 1 );
01438     }
01439     else
01440     {
01441         _if->setPrivate( "monitor", 2, 0, 0 );
01442     }
01443 }
01444 
01445 
01446 QString OOrinocoMonitoringInterface::name() const
01447 {
01448     return "orinoco";
01449 }
01450 
01451 }
01452 }

Generated on Sat Nov 5 16:16:12 2005 for OPIE by  doxygen 1.4.2