summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2005-05-15 13:41:19 (UTC)
committer mickeyl <mickeyl>2005-05-15 13:41:19 (UTC)
commit1de015fb8f267f2451dd26d992cc713e6e02af79 (patch) (unidiff)
treea82bcaf6bce0b713910de85450a83862b2d0a73a
parent4451abf402aa1dd967ef8b70a7eba1192f13afb0 (diff)
downloadopie-1de015fb8f267f2451dd26d992cc713e6e02af79.zip
opie-1de015fb8f267f2451dd26d992cc713e6e02af79.tar.gz
opie-1de015fb8f267f2451dd26d992cc713e6e02af79.tar.bz2
submit iw_range*2 as argument to SIOCGIWRANGE.length to make it work on newer hostap drivers
let's see if this breaks it at another end again :/
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opienet/onetwork.cpp14
1 files changed, 6 insertions, 8 deletions
diff --git a/libopie2/opienet/onetwork.cpp b/libopie2/opienet/onetwork.cpp
index f4bdbe0..05513f8 100644
--- a/libopie2/opienet/onetwork.cpp
+++ b/libopie2/opienet/onetwork.cpp
@@ -484,172 +484,170 @@ struct iwreq& OWirelessNetworkInterface::iwr() const
484 484
485void OWirelessNetworkInterface::init() 485void OWirelessNetworkInterface::init()
486{ 486{
487 odebug << "OWirelessNetworkInterface::init()" << oendl; 487 odebug << "OWirelessNetworkInterface::init()" << oendl;
488 memset( &_iwr, 0, sizeof( struct iwreq ) ); 488 memset( &_iwr, 0, sizeof( struct iwreq ) );
489 buildInformation(); 489 buildInformation();
490 buildPrivateList(); 490 buildPrivateList();
491 dumpInformation(); 491 dumpInformation();
492} 492}
493 493
494 494
495bool OWirelessNetworkInterface::isAssociated() const 495bool OWirelessNetworkInterface::isAssociated() const
496{ 496{
497 //FIXME: handle different modes 497 //FIXME: handle different modes
498 return !(associatedAP() == OMacAddress::unknown); 498 return !(associatedAP() == OMacAddress::unknown);
499} 499}
500 500
501 501
502void OWirelessNetworkInterface::setAssociatedAP( const OMacAddress& mac ) const 502void OWirelessNetworkInterface::setAssociatedAP( const OMacAddress& mac ) const
503{ 503{
504 _iwr.u.ap_addr.sa_family = ARPHRD_ETHER; 504 _iwr.u.ap_addr.sa_family = ARPHRD_ETHER;
505 ::memcpy(_iwr.u.ap_addr.sa_data, mac.native(), ETH_ALEN); 505 ::memcpy(_iwr.u.ap_addr.sa_data, mac.native(), ETH_ALEN);
506 wioctl( SIOCSIWAP ); 506 wioctl( SIOCSIWAP );
507} 507}
508 508
509 509
510OMacAddress OWirelessNetworkInterface::associatedAP() const 510OMacAddress OWirelessNetworkInterface::associatedAP() const
511{ 511{
512 if ( ioctl( SIOCGIWAP ) ) 512 if ( ioctl( SIOCGIWAP ) )
513 return (const unsigned char*) &_ifr.ifr_hwaddr.sa_data[0]; 513 return (const unsigned char*) &_ifr.ifr_hwaddr.sa_data[0];
514 else 514 else
515 return OMacAddress::unknown; 515 return OMacAddress::unknown;
516} 516}
517 517
518 518
519void OWirelessNetworkInterface::buildInformation() 519void OWirelessNetworkInterface::buildInformation()
520{ 520{
521 //ML: If you listen carefully enough, you can hear lots of WLAN drivers suck 521 //ML: If you listen carefully enough, you can hear lots of WLAN drivers suck
522 //ML: The HostAP drivers need more than sizeof struct_iw range to complete 522 //ML: The HostAP drivers need more than sizeof struct_iw range to complete
523 //ML: SIOCGIWRANGE otherwise they fail with "Invalid Argument Length". 523 //ML: SIOCGIWRANGE otherwise they fail with "Invalid Argument Length".
524 //ML: The Wlan-NG drivers on the otherside fail (segfault!) if you allocate 524 //ML: The Wlan-NG drivers on the otherside fail (segfault!) if you allocate
525 //ML: _too much_ space. This is damn shitty crap *sigh* 525 //ML: _too much_ space. This is damn shitty crap *sigh*
526 //ML: We allocate a large memory region in RAM and check whether the 526 //ML: We allocate a large memory region in RAM and check whether the
527 //ML: driver pollutes this extra space. The complaint will be made on stdout, 527 //ML: driver pollutes this extra space. The complaint will be made on stdout,
528 //ML: so please forward this... 528 //ML: so please forward this...
529 529
530 struct iwreq wrq; 530 struct iwreq wrq;
531 int len = sizeof( struct iw_range )*2; 531 int len = sizeof( struct iw_range )*2;
532 char *buffer = (char*) malloc( len ); 532 char buffer[len];
533 //FIXME: Validate if we actually got the memory block
534 memset( buffer, 0, len ); 533 memset( buffer, 0, len );
535 memcpy( wrq.ifr_name, name(), IFNAMSIZ); 534 memcpy( wrq.ifr_name, name(), IFNAMSIZ);
536 wrq.u.data.pointer = (caddr_t) buffer; 535 wrq.u.data.pointer = (caddr_t) buffer;
537 wrq.u.data.length = sizeof( struct iw_range ); 536 wrq.u.data.length = sizeof buffer;
538 wrq.u.data.flags = 0; 537 wrq.u.data.flags = 0;
539 538
540 if ( ::ioctl( _sfd, SIOCGIWRANGE, &wrq ) == -1 ) 539 if ( ::ioctl( _sfd, SIOCGIWRANGE, &wrq ) == -1 )
541 { 540 {
542 owarn << "OWirelessNetworkInterface::buildInformation(): Can't get channel information - using default values." << oendl; 541 owarn << "OWirelessNetworkInterface::buildInformation(): Can't get driver information (" << strerror( errno ) << ") - using default values." << oendl;
543 _channels.insert( 2412, 1 ); // 2.412 GHz 542 _channels.insert( 2412, 1 ); // 2.412 GHz
544 _channels.insert( 2417, 2 ); // 2.417 GHz 543 _channels.insert( 2417, 2 ); // 2.417 GHz
545 _channels.insert( 2422, 3 ); // 2.422 GHz 544 _channels.insert( 2422, 3 ); // 2.422 GHz
546 _channels.insert( 2427, 4 ); // 2.427 GHz 545 _channels.insert( 2427, 4 ); // 2.427 GHz
547 _channels.insert( 2432, 5 ); // 2.432 GHz 546 _channels.insert( 2432, 5 ); // 2.432 GHz
548 _channels.insert( 2437, 6 ); // 2.437 GHz 547 _channels.insert( 2437, 6 ); // 2.437 GHz
549 _channels.insert( 2442, 7 ); // 2.442 GHz 548 _channels.insert( 2442, 7 ); // 2.442 GHz
550 _channels.insert( 2447, 8 ); // 2.447 GHz 549 _channels.insert( 2447, 8 ); // 2.447 GHz
551 _channels.insert( 2452, 9 ); // 2.452 GHz 550 _channels.insert( 2452, 9 ); // 2.452 GHz
552 _channels.insert( 2457, 10 ); // 2.457 GHz 551 _channels.insert( 2457, 10 ); // 2.457 GHz
553 _channels.insert( 2462, 11 ); // 2.462 GHz 552 _channels.insert( 2462, 11 ); // 2.462 GHz
554 553
555 memset( &_range, 0, sizeof( struct iw_range ) ); 554 memset( &_range, 0, sizeof( struct iw_range ) );
556 } 555 }
557 else 556 else
558 { 557 {
559 // <check if the driver overwrites stuff> 558 // <check if the driver overwrites stuff>
560 int max = 0; 559 int max = 0;
561 for ( int r = sizeof( struct iw_range ); r < len; r++ ) 560 for ( int r = sizeof( struct iw_range ); r < len; r++ )
562 if (buffer[r] != 0) 561 if (buffer[r] != 0)
563 max = r; 562 max = r;
564 if (max > 0) 563 if (max > 0)
565 { 564 {
566 owarn << "OWirelessNetworkInterface::buildInformation(): Driver for wireless interface '" << name() 565 owarn << "OWirelessNetworkInterface::buildInformation(): Driver for wireless interface '" << name()
567 << "' sucks! It overwrote the buffer end with at least " << max - sizeof( struct iw_range ) << " bytes!" << oendl; 566 << "' sucks! It overwrote the buffer end with at least " << max - sizeof( struct iw_range ) << " bytes!" << oendl;
568 } 567 }
569 // </check if the driver overwrites stuff> 568 // </check if the driver overwrites stuff>
570 569
571 struct iw_range range; 570 struct iw_range range;
572 memcpy( &range, buffer, sizeof range ); 571 memcpy( &range, buffer, sizeof range );
573 572
574 odebug << "OWirelessNetworkInterface::buildInformation(): Interface reported to have " << (int) range.num_frequency << " channels." << oendl; 573 odebug << "OWirelessNetworkInterface::buildInformation(): Interface reported to have " << (int) range.num_frequency << " channels." << oendl;
575 for ( int i = 0; i < range.num_frequency; ++i ) 574 for ( int i = 0; i < range.num_frequency; ++i )
576 { 575 {
577 int freq = (int) ( double( range.freq[i].m ) * pow( 10.0, range.freq[i].e ) / 1000000.0 ); 576 int freq = (int) ( double( range.freq[i].m ) * pow( 10.0, range.freq[i].e ) / 1000000.0 );
578 odebug << "OWirelessNetworkInterface::buildInformation: Adding frequency " << freq << " as channel " << i+1 << oendl; 577 odebug << "OWirelessNetworkInterface::buildInformation: Adding frequency " << freq << " as channel " << i+1 << oendl;
579 _channels.insert( freq, i+1 ); 578 _channels.insert( freq, i+1 );
580 } 579 }
581 } 580 }
582 581
583 memcpy( &_range, buffer, sizeof( struct iw_range ) ); 582 memcpy( &_range, buffer, sizeof( struct iw_range ) );
584 odebug << "OWirelessNetworkInterface::buildInformation(): Information block constructed." << oendl; 583 odebug << "OWirelessNetworkInterface::buildInformation(): Information block constructed." << oendl;
585 free(buffer);
586} 584}
587 585
588 586
589short OWirelessNetworkInterface::wirelessExtensionDriverVersion() const 587short OWirelessNetworkInterface::wirelessExtensionDriverVersion() const
590{ 588{
591 return _range.we_version_compiled; 589 return _range.we_version_compiled;
592} 590}
593 591
594 592
595void OWirelessNetworkInterface::buildPrivateList() 593void OWirelessNetworkInterface::buildPrivateList()
596{ 594{
597 odebug << "OWirelessNetworkInterface::buildPrivateList()" << oendl; 595 odebug << "OWirelessNetworkInterface::buildPrivateList()" << oendl;
598 596
599 struct iw_priv_args priv[IW_MAX_PRIV_DEF]; 597 struct iw_priv_args priv[IW_MAX_PRIV_DEF];
600 598
601 _iwr.u.data.pointer = (char*) &priv; 599 _iwr.u.data.pointer = (char*) &priv;
602 _iwr.u.data.length = IW_MAX_PRIV_DEF; // length in terms of number of (sizeof iw_priv_args), not (sizeof iw_priv_args) itself 600 _iwr.u.data.length = IW_MAX_PRIV_DEF; // length in terms of number of (sizeof iw_priv_args), not (sizeof iw_priv_args) itself
603 _iwr.u.data.flags = 0; 601 _iwr.u.data.flags = 0;
604 602
605 if ( !wioctl( SIOCGIWPRIV ) ) 603 if ( !wioctl( SIOCGIWPRIV ) )
606 { 604 {
607 owarn << "OWirelessNetworkInterface::buildPrivateList(): Can't get private ioctl information." << oendl; 605 owarn << "OWirelessNetworkInterface::buildPrivateList(): Can't get private ioctl information (" << strerror( errno ) << ")." << oendl;
608 return; 606 return;
609 } 607 }
610 608
611 for ( int i = 0; i < _iwr.u.data.length; ++i ) 609 for ( int i = 0; i < _iwr.u.data.length; ++i )
612 { 610 {
613 new OPrivateIOCTL( this, priv[i].name, priv[i].cmd, priv[i].get_args, priv[i].set_args ); 611 new OPrivateIOCTL( this, priv[i].name, priv[i].cmd, priv[i].get_args, priv[i].set_args );
614 } 612 }
615 odebug << "OWirelessNetworkInterface::buildPrivateList(): Private ioctl list constructed." << oendl; 613 odebug << "OWirelessNetworkInterface::buildPrivateList(): Private ioctl list constructed." << oendl;
616} 614}
617 615
618 616
619void OWirelessNetworkInterface::dumpInformation() const 617void OWirelessNetworkInterface::dumpInformation() const
620{ 618{
621 odebug << "OWirelessNetworkInterface::() -------------- dumping information block ----------------" << oendl; 619 odebug << "OWirelessNetworkInterface::() -------------- dumping information block ----------------" << oendl;
622 620
623 odebug << " - driver's idea of maximum throughput is " << _range.throughput 621 odebug << " - driver's idea of maximum throughput is " << _range.throughput
624 << " bps = " << ( _range.throughput / 8 ) << " byte/s = " << ( _range.throughput / 8 / 1024 ) 622 << " bps = " << ( _range.throughput / 8 ) << " byte/s = " << ( _range.throughput / 8 / 1024 )
625 << " Kb/s = " << QString().sprintf("%f.2", float( _range.throughput ) / 8.0 / 1024.0 / 1024.0 ) 623 << " Kb/s = " << QString().sprintf("%f.2", float( _range.throughput ) / 8.0 / 1024.0 / 1024.0 )
626 << " Mb/s" << oendl; 624 << " Mb/s" << oendl;
627 625
628 odebug << " - driver for '" << name() << "' (V" << _range.we_version_source 626 odebug << " - driver for '" << name() << "' (V" << _range.we_version_source
629 << ") has been compiled against WE V" << _range.we_version_compiled << oendl; 627 << ") has been compiled against WE V" << _range.we_version_compiled << oendl;
630 628
631 if ( _range.we_version_compiled != WIRELESS_EXT ) 629 if ( _range.we_version_compiled != WIRELESS_EXT )
632 { 630 {
633 owarn << "Version mismatch! WE_DRIVER = " << _range.we_version_compiled << " and WE_OPIENET = " << WIRELESS_EXT << oendl; 631 owarn << "Version mismatch! WE_DRIVER = " << _range.we_version_compiled << " and WE_OPIENET = " << WIRELESS_EXT << oendl;
634 } 632 }
635 633
636 odebug << "OWirelessNetworkInterface::() ---------------------------------------------------------" << oendl; 634 odebug << "OWirelessNetworkInterface::() ---------------------------------------------------------" << oendl;
637} 635}
638 636
639 637
640int OWirelessNetworkInterface::channel() const 638int OWirelessNetworkInterface::channel() const
641{ 639{
642 //FIXME: When monitoring enabled, then use it 640 //FIXME: When monitoring enabled, then use it
643 //FIXME: to gather the current RF channel 641 //FIXME: to gather the current RF channel
644 //FIXME: Until then, get active channel from hopper. 642 //FIXME: Until then, get active channel from hopper.
645 if ( _hopper && _hopper->isActive() ) 643 if ( _hopper && _hopper->isActive() )
646 return _hopper->channel(); 644 return _hopper->channel();
647 645
648 if ( !wioctl( SIOCGIWFREQ ) ) 646 if ( !wioctl( SIOCGIWFREQ ) )
649 { 647 {
650 return -1; 648 return -1;
651 } 649 }
652 else 650 else
653 { 651 {
654 return _channels[ static_cast<int>(double( _iwr.u.freq.m ) * pow( 10.0, _iwr.u.freq.e ) / 1000000) ]; 652 return _channels[ static_cast<int>(double( _iwr.u.freq.m ) * pow( 10.0, _iwr.u.freq.e ) / 1000000) ];
655 } 653 }
@@ -1113,103 +1111,103 @@ OStationList* OWirelessNetworkInterface::scanNetwork()
1113 /* Is there more value in the event ? */ 1111 /* Is there more value in the event ? */
1114 if((pointer + event_len) <= (stream.current + iwe.len)) 1112 if((pointer + event_len) <= (stream.current + iwe.len))
1115 /* Go to next value */ 1113 /* Go to next value */
1116 stream.value = pointer; 1114 stream.value = pointer;
1117 else { 1115 else {
1118 /* Go to next event */ 1116 /* Go to next event */
1119 stream.value = NULL; 1117 stream.value = NULL;
1120 stream.current += iwe.len; 1118 stream.current += iwe.len;
1121 } 1119 }
1122 } 1120 }
1123 1121
1124 struct iw_event *we = &iwe; 1122 struct iw_event *we = &iwe;
1125 //------ 1123 //------
1126 odebug << " - reading next event... cmd=" << we->cmd << ", len=" << we->len << oendl; 1124 odebug << " - reading next event... cmd=" << we->cmd << ", len=" << we->len << oendl;
1127 switch (we->cmd) 1125 switch (we->cmd)
1128 { 1126 {
1129 case SIOCGIWAP: 1127 case SIOCGIWAP:
1130 { 1128 {
1131 odebug << "SIOCGIWAP" << oendl; 1129 odebug << "SIOCGIWAP" << oendl;
1132 stations->append( new OStation() ); 1130 stations->append( new OStation() );
1133 stations->last()->macAddress = (const unsigned char*) &we->u.ap_addr.sa_data[0]; 1131 stations->last()->macAddress = (const unsigned char*) &we->u.ap_addr.sa_data[0];
1134 break; 1132 break;
1135 } 1133 }
1136 case SIOCGIWMODE: 1134 case SIOCGIWMODE:
1137 { 1135 {
1138 odebug << "SIOCGIWMODE" << oendl; 1136 odebug << "SIOCGIWMODE" << oendl;
1139 stations->last()->type = modeToString( we->u.mode ); 1137 stations->last()->type = modeToString( we->u.mode );
1140 break; 1138 break;
1141 } 1139 }
1142 case SIOCGIWFREQ: 1140 case SIOCGIWFREQ:
1143 { 1141 {
1144 odebug << "SIOCGIWFREQ" << oendl; 1142 odebug << "SIOCGIWFREQ" << oendl;
1145 if ( we->u.freq.m > 1000 ) 1143 if ( we->u.freq.m > 1000 )
1146 stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ]; 1144 stations->last()->channel = _channels[ static_cast<int>(double( we->u.freq.m ) * pow( 10.0, we->u.freq.e ) / 1000000) ];
1147 else 1145 else
1148 stations->last()->channel = static_cast<int>(((double) we->u.freq.m) * pow( 10.0, we->u.freq.e )); 1146 stations->last()->channel = static_cast<int>(((double) we->u.freq.m) * pow( 10.0, we->u.freq.e ));
1149 break; 1147 break;
1150 } 1148 }
1151 case SIOCGIWESSID: 1149 case SIOCGIWESSID:
1152 { 1150 {
1153 odebug << "SIOCGIWESSID" << oendl; 1151 odebug << "SIOCGIWESSID" << oendl;
1154 we->u.essid.length = '\0'; // make sure it is zero terminated 1152 we->u.essid.length = '\0'; // make sure it is zero terminated
1155 stations->last()->ssid = static_cast<const char*> (we->u.essid.pointer); 1153 stations->last()->ssid = static_cast<const char*> (we->u.essid.pointer);
1156 odebug << "ESSID: " << stations->last()->ssid << oendl; 1154 odebug << "ESSID: " << stations->last()->ssid << oendl;
1157 break; 1155 break;
1158 } 1156 }
1159 case IWEVQUAL: 1157 case IWEVQUAL:
1160 { 1158 {
1161 odebug << "IWEVQUAL" << oendl; 1159 odebug << "IWEVQUAL" << oendl;
1162 stations->last()->level = static_cast<int>(we->u.qual.level); 1160 stations->last()->level = static_cast<int>(we->u.qual.level);
1163 break; /* Quality part of statistics (scan) */ 1161 break; /* Quality part of statistics (scan) */
1164 } 1162 }
1165 case SIOCGIWENCODE: 1163 case SIOCGIWENCODE:
1166 { 1164 {
1167 odebug << "SIOCGIWENCODE" << oendl; 1165 odebug << "SIOCGIWENCODE" << oendl;
1168 stations->last()->encrypted = !(we->u.data.flags & IW_ENCODE_DISABLED); 1166 stations->last()->encrypted = !(we->u.data.flags & IW_ENCODE_DISABLED);
1169 break; 1167 break;
1170 } 1168 }
1171 1169
1172 case SIOCGIWRATE: 1170 case SIOCGIWRATE:
1173 { 1171 {
1174 odebug << "SIOCGIWRATE" << oendl; 1172 odebug << "SIOCGIWRATE" << oendl;
1175 stations->last()->rates.append(we->u.bitrate.value); 1173 stations->last()->rates.append(we->u.bitrate.value);
1176 break; 1174 break;
1177 } 1175 }
1178 case SIOCGIWSENS: odebug << "SIOCGIWSENS" << oendl; break; 1176 case SIOCGIWSENS: odebug << "SIOCGIWSENS" << oendl; break;
1179 case IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break; /* Packet dropped to excessive retry */ 1177 case IWEVTXDROP: odebug << "IWEVTXDROP" << oendl; break; /* Packet dropped to excessive retry */
1180 case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break; /* Driver specific ascii string */ 1178 case IWEVCUSTOM: odebug << "IWEVCUSTOM" << oendl; break; /* Driver specific ascii string */
1181 case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break; /* Discovered a new node (AP mode) */ 1179 case IWEVREGISTERED: odebug << "IWEVREGISTERED" << oendl; break; /* Discovered a new node (AP mode) */
1182 case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break; /* Expired a node (AP mode) */ 1180 case IWEVEXPIRED: odebug << "IWEVEXPIRED" << oendl; break; /* Expired a node (AP mode) */
1183 default: odebug << "unhandled event" << oendl; 1181 default: odebug << "unhandled event" << oendl;
1184 } 1182 }
1185 1183
1186 } while (true); 1184 } while (true);
1187 } 1185 }
1188 else 1186 else
1189 { 1187 {
1190 odebug << " - no results (timeout) :(" << oendl; 1188 odebug << " - no results (timeout) :(" << oendl;
1191 } 1189 }
1192 return stations; 1190 return stations;
1193} 1191}
1194 1192
1195 1193
1196int OWirelessNetworkInterface::signalStrength() const 1194int OWirelessNetworkInterface::signalStrength() const
1197{ 1195{
1198 iw_statistics stat; 1196 iw_statistics stat;
1199 ::memset( &stat, 0, sizeof stat ); 1197 ::memset( &stat, 0, sizeof stat );
1200 _iwr.u.data.pointer = (char*) &stat; 1198 _iwr.u.data.pointer = (char*) &stat;
1201 _iwr.u.data.flags = 0; 1199 _iwr.u.data.flags = 0;
1202 _iwr.u.data.length = sizeof stat; 1200 _iwr.u.data.length = sizeof stat;
1203 1201
1204 if ( !wioctl( SIOCGIWSTATS ) ) 1202 if ( !wioctl( SIOCGIWSTATS ) )
1205 { 1203 {
1206 return -1; 1204 return -1;
1207 } 1205 }
1208 1206
1209 int max = _range.max_qual.qual; 1207 int max = _range.max_qual.qual;
1210 int cur = stat.qual.qual; 1208 int cur = stat.qual.qual;
1211// int lev = stat.qual.level; //FIXME: Do something with them? 1209// int lev = stat.qual.level; //FIXME: Do something with them?
1212// int noi = stat.qual.noise; //FIXME: Do something with them? 1210// int noi = stat.qual.noise; //FIXME: Do something with them?
1213 1211
1214 1212
1215 return max != 0 ? cur*100/max: -1; 1213 return max != 0 ? cur*100/max: -1;