summaryrefslogtreecommitdiff
path: root/libopie2/opienet/onetwork.cpp
authormickeyl <mickeyl>2003-04-04 10:31:26 (UTC)
committer mickeyl <mickeyl>2003-04-04 10:31:26 (UTC)
commit089385bb8ab768fbf6f394f326e565e3589163fc (patch) (unidiff)
tree23891b81b11310186c43179612531bc92e52ae65 /libopie2/opienet/onetwork.cpp
parent7da7e9cbfb52988ce801310f66b1336e0809db28 (diff)
downloadopie-089385bb8ab768fbf6f394f326e565e3589163fc.zip
opie-089385bb8ab768fbf6f394f326e565e3589163fc.tar.gz
opie-089385bb8ab768fbf6f394f326e565e3589163fc.tar.bz2
low-level network programming is sick. some wlan-drivers don't honor struct sizes
and simply write bytes _after_ the struct... this patch makes calling SIOCGIWRANGE more failure-proof.
Diffstat (limited to 'libopie2/opienet/onetwork.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetwork.cpp57
1 files changed, 40 insertions, 17 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index 66fa215..789e8ca 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -128,8 +128,8 @@ ONetwork::InterfaceIterator ONetwork::iterator() const
128bool ONetwork::isWirelessInterface( const char* name ) const 128bool ONetwork::isWirelessInterface( const char* name ) const
129{ 129{
130 int sfd = socket( AF_INET, SOCK_STREAM, 0 ); 130 int sfd = socket( AF_INET, SOCK_STREAM, 0 );
131 iwreqstruct iwr; 131 struct iwreq iwr;
132 memset( &iwr, 0, sizeof( iwreqstruct ) ); 132 memset( &iwr, 0, sizeof( struct iwreq ) );
133 strcpy( (char*) &iwr.ifr_name, name ); 133 strcpy( (char*) &iwr.ifr_name, name );
134 int result = ::ioctl( sfd, SIOCGIWNAME, &iwr ); 134 int result = ::ioctl( sfd, SIOCGIWNAME, &iwr );
135 if ( result == -1 ) 135 if ( result == -1 )
@@ -152,7 +152,7 @@ ONetworkInterface::ONetworkInterface( QObject* parent, const char* name )
152} 152}
153 153
154 154
155ifreqstruct& ONetworkInterface::ifr() const 155struct ifreq& ONetworkInterface::ifr() const
156{ 156{
157 return _ifr; 157 return _ifr;
158} 158}
@@ -172,7 +172,7 @@ void ONetworkInterface::init()
172} 172}
173 173
174 174
175bool ONetworkInterface::ioctl( int call, ifreqstruct& ifreq ) const 175bool ONetworkInterface::ioctl( int call, struct ifreq& ifreq ) const
176{ 176{
177 int result = ::ioctl( _sfd, call, &ifreq ); 177 int result = ::ioctl( _sfd, call, &ifreq );
178 if ( result == -1 ) 178 if ( result == -1 )
@@ -377,7 +377,7 @@ OWirelessNetworkInterface::~OWirelessNetworkInterface()
377} 377}
378 378
379 379
380iwreqstruct& OWirelessNetworkInterface::iwr() const 380struct iwreq& OWirelessNetworkInterface::iwr() const
381{ 381{
382 return _iwr; 382 return _iwr;
383} 383}
@@ -417,20 +417,26 @@ QString OWirelessNetworkInterface::associatedAP() const
417 417
418void OWirelessNetworkInterface::buildChannelList() 418void OWirelessNetworkInterface::buildChannelList()
419{ 419{
420 // IEEE802.11(b) radio frequency channels
421 struct iw_range range;
422
423 //ML: If you listen carefully enough, you can hear lots of WLAN drivers suck 420 //ML: If you listen carefully enough, you can hear lots of WLAN drivers suck
424 //ML: The HostAP drivers need more than sizeof struct_iw range to complete 421 //ML: The HostAP drivers need more than sizeof struct_iw range to complete
425 //ML: SIOCGIWRANGE otherwise they fail with "Invalid Argument Length". 422 //ML: SIOCGIWRANGE otherwise they fail with "Invalid Argument Length".
426 //ML: The Wlan-NG drivers on the otherside fail (segfault!) if you allocate 423 //ML: The Wlan-NG drivers on the otherside fail (segfault!) if you allocate
427 //ML: _too much_ space. This is damn shitty crap *sigh* 424 //ML: _too much_ space. This is damn shitty crap *sigh*
428 425 //ML: We allocate a large memory region in RAM and check whether the
429 _iwr.u.data.pointer = (char*) &range; 426 //ML: driver pollutes this extra space. The complaint will be made on stdout,
430 _iwr.u.data.length = IW_MAX_FREQUENCIES; //sizeof range; 427 //ML: so please forward this...
431 _iwr.u.data.flags = 0; 428
432 429 struct iwreq wrq;
433 if ( !wioctl( SIOCGIWRANGE ) ) 430 int len = sizeof( struct iw_range )*2;
431 char *buffer = (char*) malloc( len );
432 //FIXME: Validate if we actually got the memory block
433 memset( buffer, 0, len );
434 memcpy( wrq.ifr_name, name(), IFNAMSIZ);
435 wrq.u.data.pointer = (caddr_t) buffer;
436 wrq.u.data.length = sizeof( struct iw_range );
437 wrq.u.data.flags = 0;
438
439 if ( ::ioctl( _sfd, SIOCGIWRANGE, &wrq ) == -1 )
434 { 440 {
435 qDebug( "OWirelessNetworkInterface::buildChannelList(): SIOCGIWRANGE failed (%s) - defaulting to 11 channels", strerror( errno ) ); 441 qDebug( "OWirelessNetworkInterface::buildChannelList(): SIOCGIWRANGE failed (%s) - defaulting to 11 channels", strerror( errno ) );
436 _channels.insert( 2412, 1 ); // 2.412 GHz 442 _channels.insert( 2412, 1 ); // 2.412 GHz
@@ -447,6 +453,21 @@ void OWirelessNetworkInterface::buildChannelList()
447 } 453 }
448 else 454 else
449 { 455 {
456 // <check if the driver overwrites stuff>
457 int max = 0;
458 for ( int r = sizeof( struct iw_range ); r < len; r++ )
459 if (buffer[r] != 0)
460 max = r;
461 if (max > 0)
462 {
463 qWarning( "OWirelessNetworkInterface::buildChannelList(): Driver for wireless interface '%s'"
464 "overwrote buffer end with at least %i bytes!\n", name(), max - sizeof( struct iw_range ) );
465 }
466 // </check if the driver overwrites stuff>
467
468 struct iw_range range;
469 memcpy( &range, buffer, sizeof range );
470
450 qDebug( "OWirelessNetworkInterface::buildChannelList(): Interface %s reported to have %d channels.", name(), range.num_frequency ); 471 qDebug( "OWirelessNetworkInterface::buildChannelList(): Interface %s reported to have %d channels.", name(), range.num_frequency );
451 for ( int i = 0; i < range.num_frequency; ++i ) 472 for ( int i = 0; i < range.num_frequency; ++i )
452 { 473 {
@@ -454,7 +475,9 @@ void OWirelessNetworkInterface::buildChannelList()
454 _channels.insert( freq, i+1 ); 475 _channels.insert( freq, i+1 );
455 } 476 }
456 } 477 }
478
457 qDebug( "OWirelessNetworkInterface::buildChannelList(): Channel list constructed." ); 479 qDebug( "OWirelessNetworkInterface::buildChannelList(): Channel list constructed." );
480 free(buffer);
458} 481}
459 482
460 483
@@ -505,7 +528,7 @@ void OWirelessNetworkInterface::setChannel( int c ) const
505{ 528{
506 if ( !_mon ) 529 if ( !_mon )
507 { 530 {
508 memset( &_iwr, 0, sizeof( iwreqstruct ) ); 531 memset( &_iwr, 0, sizeof( struct iwreq ) );
509 _iwr.u.freq.m = c; 532 _iwr.u.freq.m = c;
510 _iwr.u.freq.e = 0; 533 _iwr.u.freq.e = 0;
511 wioctl( SIOCSIWFREQ ); 534 wioctl( SIOCSIWFREQ );
@@ -639,7 +662,7 @@ void OWirelessNetworkInterface::setSSID( const QString& ssid )
639} 662}
640 663
641 664
642bool OWirelessNetworkInterface::wioctl( int call, iwreqstruct& iwreq ) const 665bool OWirelessNetworkInterface::wioctl( int call, struct iwreq& iwreq ) const
643{ 666{
644 int result = ::ioctl( _sfd, call, &iwreq ); 667 int result = ::ioctl( _sfd, call, &iwreq );
645 if ( result == -1 ) 668 if ( result == -1 )
@@ -675,7 +698,7 @@ OMonitoringInterface::~OMonitoringInterface()
675void OMonitoringInterface::setChannel( int c ) 698void OMonitoringInterface::setChannel( int c )
676{ 699{
677 // use standard WE channel switching protocol 700 // use standard WE channel switching protocol
678 memset( &_if->_iwr, 0, sizeof( iwreqstruct ) ); 701 memset( &_if->_iwr, 0, sizeof( struct iwreq ) );
679 _if->_iwr.u.freq.m = c; 702 _if->_iwr.u.freq.m = c;
680 _if->_iwr.u.freq.e = 0; 703 _if->_iwr.u.freq.e = 0;
681 _if->wioctl( SIOCSIWFREQ ); 704 _if->wioctl( SIOCSIWFREQ );