00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <opie2/onetwork.h>
00032 #include <opie2/ostation.h>
00033 #include <opie2/odebug.h>
00034 using namespace Opie::Core;
00035
00036
00037 #include <qfile.h>
00038 #include <qtextstream.h>
00039 #include <qapplication.h>
00040
00041
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
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
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
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
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
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
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
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
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
00514
00515
00516
00517
00518
00519
00520
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 );
00543 _channels.insert( 2417, 2 );
00544 _channels.insert( 2422, 3 );
00545 _channels.insert( 2427, 4 );
00546 _channels.insert( 2432, 5 );
00547 _channels.insert( 2437, 6 );
00548 _channels.insert( 2442, 7 );
00549 _channels.insert( 2447, 8 );
00550 _channels.insert( 2452, 9 );
00551 _channels.insert( 2457, 10 );
00552 _channels.insert( 2462, 11 );
00553
00554 memset( &_range, 0, sizeof( struct iw_range ) );
00555 }
00556 else
00557 {
00558
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
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;
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
00641
00642
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
00703
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
00739 _iwr.u.mode = stringToMode( newMode );
00740 wioctl( SIOCSIWMODE );
00741
00742
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
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
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';
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';
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;
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;
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
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,
00957 IW_HEADER_TYPE_CHAR,
00958 IW_HEADER_TYPE_PARAM,
00959 IW_HEADER_TYPE_PARAM,
00960 IW_HEADER_TYPE_FREQ,
00961 IW_HEADER_TYPE_FREQ,
00962 IW_HEADER_TYPE_UINT,
00963 IW_HEADER_TYPE_UINT,
00964 IW_HEADER_TYPE_PARAM,
00965 IW_HEADER_TYPE_PARAM,
00966 IW_HEADER_TYPE_NULL,
00967 IW_HEADER_TYPE_POINT,
00968 IW_HEADER_TYPE_NULL,
00969 IW_HEADER_TYPE_POINT,
00970 IW_HEADER_TYPE_NULL,
00971 IW_HEADER_TYPE_POINT,
00972 IW_HEADER_TYPE_POINT,
00973 IW_HEADER_TYPE_POINT,
00974 IW_HEADER_TYPE_POINT,
00975 IW_HEADER_TYPE_POINT,
00976 IW_HEADER_TYPE_ADDR,
00977 IW_HEADER_TYPE_ADDR,
00978 IW_HEADER_TYPE_NULL,
00979 IW_HEADER_TYPE_POINT,
00980 IW_HEADER_TYPE_PARAM,
00981 IW_HEADER_TYPE_POINT,
00982 IW_HEADER_TYPE_POINT,
00983 IW_HEADER_TYPE_POINT,
00984 IW_HEADER_TYPE_POINT,
00985 IW_HEADER_TYPE_POINT,
00986 IW_HEADER_TYPE_NULL,
00987 IW_HEADER_TYPE_NULL,
00988 IW_HEADER_TYPE_PARAM,
00989 IW_HEADER_TYPE_PARAM,
00990 IW_HEADER_TYPE_PARAM,
00991 IW_HEADER_TYPE_PARAM,
00992 IW_HEADER_TYPE_PARAM,
00993 IW_HEADER_TYPE_PARAM,
00994 IW_HEADER_TYPE_PARAM,
00995 IW_HEADER_TYPE_PARAM,
00996 IW_HEADER_TYPE_PARAM,
00997 IW_HEADER_TYPE_PARAM,
00998 IW_HEADER_TYPE_POINT,
00999 IW_HEADER_TYPE_POINT,
01000 IW_HEADER_TYPE_PARAM,
01001 IW_HEADER_TYPE_PARAM,
01002 };
01003
01004 const char standard_event_hdr[] = {
01005 IW_HEADER_TYPE_ADDR,
01006 IW_HEADER_TYPE_QUAL,
01007 IW_HEADER_TYPE_POINT,
01008 IW_HEADER_TYPE_ADDR,
01009 IW_HEADER_TYPE_ADDR,
01010 IW_HEADER_TYPE_POINT,
01011 IW_HEADER_TYPE_POINT,
01012 IW_HEADER_TYPE_POINT,
01013 IW_HEADER_TYPE_POINT,
01014 IW_HEADER_TYPE_POINT,
01015 };
01016
01017
01018 const int event_type_size[] = {
01019 IW_EV_LCP_LEN,
01020 0,
01021 IW_EV_CHAR_LEN,
01022 0,
01023 IW_EV_UINT_LEN,
01024 IW_EV_FREQ_LEN,
01025 IW_EV_ADDR_LEN,
01026 0,
01027 IW_EV_POINT_LEN,
01028 IW_EV_PARAM_LEN,
01029 IW_EV_QUAL_LEN,
01030 };
01031
01032
01033
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)
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
01060 event_len = event_type_size[event_type];
01061
01062
01063 if((_range.we_version_compiled > 18) && (event_type == IW_HEADER_TYPE_POINT))
01064 event_len -= IW_EV_POINT_OFF;
01065
01066
01067 if(event_len <= IW_EV_LCP_LEN) {
01068
01069 stream.current += iwe.len;
01070 continue;
01071 }
01072
01073 event_len -= IW_EV_LCP_LEN;
01074
01075
01076 if(stream.value != NULL)
01077 pointer = stream.value;
01078 else
01079 pointer = stream.current + IW_EV_LCP_LEN;
01080
01081 if((pointer + event_len) > stream.end) {
01082
01083 stream.current += iwe.len;
01084 break;
01085 }
01086
01087
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
01094 pointer += event_len;
01095
01096
01097 if(event_type == IW_HEADER_TYPE_POINT) {
01098
01099
01100 if((iwe.len - (event_len + IW_EV_LCP_LEN)) > 0)
01101
01102 iwe.u.data.pointer = pointer;
01103 else
01104
01105 iwe.u.data.pointer = NULL;
01106
01107 stream.current += iwe.len;
01108 }
01109
01110 else {
01111
01112 if((pointer + event_len) <= (stream.current + iwe.len))
01113
01114 stream.value = pointer;
01115 else {
01116
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';
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;
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;
01178 case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break;
01179 case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break;
01180 case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break;
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
01210
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
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
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
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 )
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
01305 }
01306
01307
01308 QString OCiscoMonitoringInterface::name() const
01309 {
01310 return "cisco";
01311 }
01312
01313
01314 void OCiscoMonitoringInterface::setChannel( int )
01315 {
01316
01317 }
01318
01319
01320
01321
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
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
01359
01360 QString enable = "true";
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
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
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 }